mirror of https://github.com/citusdata/citus.git
250 lines
6.6 KiB
C
250 lines
6.6 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* tdigest_extension.c
|
|
* Helper functions to get access to tdigest specific data.
|
|
*
|
|
* Copyright (c) Citus Data, Inc.
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#include "postgres.h"
|
|
|
|
#include "access/genam.h"
|
|
#include "access/htup_details.h"
|
|
#include "catalog/pg_extension.h"
|
|
#include "catalog/pg_type.h"
|
|
#include "distributed/metadata_cache.h"
|
|
#include "distributed/tdigest_extension.h"
|
|
#include "distributed/version_compat.h"
|
|
#include "parser/parse_func.h"
|
|
#include "utils/fmgroids.h"
|
|
#include "utils/lsyscache.h"
|
|
|
|
|
|
static Oid LookupTDigestFunction(const char *functionName, int argcount, Oid *argtypes);
|
|
|
|
/*
|
|
* TDigestExtensionSchema finds the schema the tdigest extension is installed in. The
|
|
* function will return InvalidOid if the extension is not installed.
|
|
*/
|
|
Oid
|
|
TDigestExtensionSchema()
|
|
{
|
|
ScanKeyData entry[1];
|
|
Form_pg_extension extensionForm = NULL;
|
|
Oid tdigestExtensionSchema = InvalidOid;
|
|
|
|
Relation relation = table_open(ExtensionRelationId, AccessShareLock);
|
|
|
|
ScanKeyInit(&entry[0],
|
|
Anum_pg_extension_extname,
|
|
BTEqualStrategyNumber, F_NAMEEQ,
|
|
CStringGetDatum("tdigest"));
|
|
|
|
SysScanDesc scandesc = systable_beginscan(relation, ExtensionNameIndexId, true,
|
|
NULL, 1, entry);
|
|
|
|
HeapTuple extensionTuple = systable_getnext(scandesc);
|
|
|
|
/*
|
|
* We assume that there can be at most one matching tuple, if no tuple found the
|
|
* extension is not installed. The value of InvalidOid will not be changed.
|
|
*/
|
|
if (HeapTupleIsValid(extensionTuple))
|
|
{
|
|
extensionForm = (Form_pg_extension) GETSTRUCT(extensionTuple);
|
|
tdigestExtensionSchema = extensionForm->extnamespace;
|
|
Assert(OidIsValid(tdigestExtensionSchema));
|
|
}
|
|
|
|
systable_endscan(scandesc);
|
|
|
|
table_close(relation, AccessShareLock);
|
|
|
|
return tdigestExtensionSchema;
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionTypeOid performs a lookup for the Oid of the type representing the
|
|
* tdigest as installed by the tdigest extension returns InvalidOid if the type cannot be
|
|
* found.
|
|
*/
|
|
Oid
|
|
TDigestExtensionTypeOid()
|
|
{
|
|
Oid tdigestSchemaOid = TDigestExtensionSchema();
|
|
if (!OidIsValid(tdigestSchemaOid))
|
|
{
|
|
return InvalidOid;
|
|
}
|
|
char *namespaceName = get_namespace_name(tdigestSchemaOid);
|
|
return LookupTypeOid(namespaceName, "tdigest");
|
|
}
|
|
|
|
|
|
/*
|
|
* LookupTDigestFunction is a helper function specifically to lookup functions in the
|
|
* namespace/schema where the tdigest extension is installed. This makes the lookup of
|
|
* following aggregate functions easier and less repetitive.
|
|
*/
|
|
static Oid
|
|
LookupTDigestFunction(const char *functionName, int argcount, Oid *argtypes)
|
|
{
|
|
Oid tdigestSchemaOid = TDigestExtensionSchema();
|
|
if (!OidIsValid(tdigestSchemaOid))
|
|
{
|
|
return InvalidOid;
|
|
}
|
|
|
|
char *namespaceName = get_namespace_name(tdigestSchemaOid);
|
|
return LookupFuncName(
|
|
list_make2(makeString(namespaceName), makeString(pstrdup(functionName))),
|
|
argcount, argtypes, true);
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigest1 performs a lookup for the Oid of the tdigest aggregate;
|
|
* tdigest(tdigest)
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigest1()
|
|
{
|
|
return LookupTDigestFunction("tdigest", 1, (Oid[]) { TDigestExtensionTypeOid() });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigest2 performs a lookup for the Oid of the tdigest aggregate;
|
|
* tdigest(value double precision, compression int)
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigest2()
|
|
{
|
|
return LookupTDigestFunction("tdigest", 2, (Oid[]) { FLOAT8OID, INT4OID });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigestPercentile2 performs a lookup for the Oid of the tdigest
|
|
* aggregate;
|
|
* tdigest_percentile(tdigest, double precision)
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigestPercentile2()
|
|
{
|
|
return LookupTDigestFunction("tdigest_percentile", 2,
|
|
(Oid[]) { TDigestExtensionTypeOid(), FLOAT8OID });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigestPercentile2a performs a lookup for the Oid of the tdigest
|
|
* aggregate;
|
|
* tdigest_percentile(tdigest, double precision[])
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigestPercentile2a(void)
|
|
{
|
|
return LookupTDigestFunction("tdigest_percentile", 2,
|
|
(Oid[]) { TDigestExtensionTypeOid(), FLOAT8ARRAYOID });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigestPercentile3 performs a lookup for the Oid of the tdigest
|
|
* aggregate;
|
|
* tdigest_percentile(double precision, int, double precision)
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigestPercentile3()
|
|
{
|
|
return LookupTDigestFunction("tdigest_percentile", 3,
|
|
(Oid[]) { FLOAT8OID, INT4OID, FLOAT8OID });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigestPercentile3a performs a lookup for the Oid of the tdigest
|
|
* aggregate;
|
|
* tdigest_percentile(double precision, int, double precision[])
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigestPercentile3a(void)
|
|
{
|
|
return LookupTDigestFunction("tdigest_percentile", 3,
|
|
(Oid[]) { FLOAT8OID, INT4OID, FLOAT8ARRAYOID });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigestPercentileOf2 performs a lookup for the Oid of the tdigest
|
|
* aggregate;
|
|
* tdigest_percentile_of(tdigest, double precision)
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigestPercentileOf2()
|
|
{
|
|
return LookupTDigestFunction("tdigest_percentile_of", 2,
|
|
(Oid[]) { TDigestExtensionTypeOid(), FLOAT8OID });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigestPercentileOf2a performs a lookup for the Oid of the tdigest
|
|
* aggregate;
|
|
* tdigest_percentile_of(tdigest, double precision[])
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigestPercentileOf2a(void)
|
|
{
|
|
return LookupTDigestFunction("tdigest_percentile_of", 2,
|
|
(Oid[]) { TDigestExtensionTypeOid(), FLOAT8ARRAYOID });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigestPercentileOf3 performs a lookup for the Oid of the tdigest
|
|
* aggregate;
|
|
* tdigest_percentile_of(double precision, int, double precision)
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigestPercentileOf3()
|
|
{
|
|
return LookupTDigestFunction("tdigest_percentile_of", 3,
|
|
(Oid[]) { FLOAT8OID, INT4OID, FLOAT8OID });
|
|
}
|
|
|
|
|
|
/*
|
|
* TDigestExtensionAggTDigestPercentileOf3a performs a lookup for the Oid of the tdigest
|
|
* aggregate;
|
|
* tdigest_percentile_of(double precision, int, double precision[])
|
|
*
|
|
* If the aggregate is not found InvalidOid is returned.
|
|
*/
|
|
Oid
|
|
TDigestExtensionAggTDigestPercentileOf3a(void)
|
|
{
|
|
return LookupTDigestFunction("tdigest_percentile_of", 3,
|
|
(Oid[]) { FLOAT8OID, INT4OID, FLOAT8ARRAYOID });
|
|
}
|