2 * op function for ltree
3 * Teodor Sigaev <teodor@stack.net>
4 * contrib/ltree/ltree_op.c
21/* compare functions */
53 while (an > 0 && bn > 0)
60 return (al->
len - bl->
len) * 10 * (an + 1);
68 return res * 10 * (an + 1);
77 return (
a->numlevel -
b->numlevel) * 10 * (an + 1);
81ltree *a = PG_GETARG_LTREE_P(0); \
82ltree *b = PG_GETARG_LTREE_P(1); \
83int res = ltree_compare(a,b); \
84PG_FREE_IF_COPY(a,0); \
136/* Compute a hash for the ltree */
142 int an =
a->numlevel;
150 * Combine hash values of successive elements by multiplying the
151 * current value by 31 and adding on the new element's hash value.
153 * This method is borrowed from hash_array(), which see for further
156 result = (result << 5) - result + levelHash;
166/* Compute an extended hash for the ltree */
173 int an =
a->numlevel;
177 * If the path has length zero, return 1 + seed to ensure that the low 32
178 * bits of the result match hash_ltree when the seed is 0, as required by
179 * the hash index support functions, but to also return a different value
180 * when there is a seed.
192 result = (result << 5) - result + levelHash;
206 int res =
a->numlevel;
219 if (pn >
c->numlevel)
272 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
273 errmsg(
"invalid positions")));
278 start = end = (
char *) ptr;
282 start = (
char *) ptr;
327 {
/* start > t->numlevel */
335 end = (fcinfo->nargs == 3) ?
start : 0xffff;
347 int numlevel = (int)
a->numlevel +
b->numlevel;
351 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
352 errmsg(
"number of ltree levels (%d) exceeds the maximum allowed (%d)",
419 if (-
start >=
a->numlevel)
425 if (
a->numlevel - start < b->numlevel ||
a->numlevel == 0 ||
b->numlevel == 0)
433 for (
i = 0;
i <=
a->numlevel -
b->numlevel;
i++)
439 for (
j = 0;
j <
b->numlevel;
j++)
447 if (
j ==
b->numlevel)
490 * Common code for variants of lca(), find longest common ancestor of inputs
492 * Returns NULL if there is no common ancestor, ie, the longest common
508 return NULL;
/* no inputs? */
509 if ((*a)->numlevel == 0)
510 return NULL;
/* any empty input means NULL result */
512 /* num is the length of the longest common ancestor so far */
515 /* Compare each additional input to *a */
517 while (ptr -
a <
len)
519 if ((*ptr)->numlevel == 0)
521 else if ((*ptr)->numlevel == 1)
527 tmp =
Min(num, (*ptr)->numlevel - 1);
529 for (
i = 0;
i < tmp;
i++)
543 /* Now compute size of result ... */
546 for (
i = 0;
i < num;
i++)
552 /* ... and construct it by copying from *a */
560 for (
i = 0;
i < num;
i++)
578 for (
i = 0;
i < fcinfo->nargs;
i++)
581 for (
i = 0;
i < fcinfo->nargs;
i++)
627 memcpy(ptr, curlevel->
name, curlevel->
len);
628 ptr += curlevel->
len;
640 * ltreeparentsel - Selectivity of parent relationship for ltree data types.
642 * This function is not used anymore, if the ltree extension has been
643 * updated to 1.2 or later.
654 /* Use generic restriction selectivity logic, with default 0.001. */
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_FREE_IF_COPY(ptr, n)
#define PG_RETURN_UINT32(x)
#define PG_GETARG_TEXT_PP(n)
#define PG_RETURN_FLOAT8(x)
#define PG_GETARG_POINTER(n)
#define DirectFunctionCall1(func, arg1)
#define PG_GETARG_INT64(n)
#define PG_RETURN_UINT64(x)
#define PG_RETURN_INT32(x)
#define PG_GETARG_INT32(n)
#define PG_RETURN_POINTER(x)
#define PG_RETURN_BOOL(x)
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
static Datum hash_any(const unsigned char *k, int keylen)
if(TABLE==NULL||TABLE_index==NULL)
#define PG_GETARG_LTREE_P(n)
PGDLLEXPORT Datum ltree_in(PG_FUNCTION_ARGS)
Datum lca(PG_FUNCTION_ARGS)
bool inner_isparent(const ltree *c, const ltree *p)
Datum hash_ltree_extended(PG_FUNCTION_ARGS)
Datum ltree_index(PG_FUNCTION_ARGS)
Datum ltree_cmp(PG_FUNCTION_ARGS)
Datum subltree(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(ltree_cmp)
Datum ltree_gt(PG_FUNCTION_ARGS)
static ltree * ltree_concat(ltree *a, ltree *b)
ltree * lca_inner(ltree **a, int len)
PG_MODULE_MAGIC_EXT(.name="ltree",.version=PG_VERSION)
Datum nlevel(PG_FUNCTION_ARGS)
Datum ltree_textadd(PG_FUNCTION_ARGS)
int ltree_compare(const ltree *a, const ltree *b)
Datum ltreeparentsel(PG_FUNCTION_ARGS)
Datum ltree_eq(PG_FUNCTION_ARGS)
Datum ltree_ge(PG_FUNCTION_ARGS)
Datum ltree_isparent(PG_FUNCTION_ARGS)
static ltree * inner_subltree(ltree *t, int32 startpos, int32 endpos)
Datum ltree_addtext(PG_FUNCTION_ARGS)
Datum ltree_ne(PG_FUNCTION_ARGS)
Datum text2ltree(PG_FUNCTION_ARGS)
Datum ltree_risparent(PG_FUNCTION_ARGS)
Datum ltree2text(PG_FUNCTION_ARGS)
Datum hash_ltree(PG_FUNCTION_ARGS)
Datum ltree_le(PG_FUNCTION_ARGS)
Datum ltree_lt(PG_FUNCTION_ARGS)
Datum ltree_addltree(PG_FUNCTION_ARGS)
Datum subpath(PG_FUNCTION_ARGS)
void pfree(void *pointer)
void * palloc0(Size size)
static XLogRecPtr startpos
static uint32 DatumGetUInt32(Datum X)
static uint64 DatumGetUInt64(Datum X)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
double generic_restriction_selectivity(PlannerInfo *root, Oid oproid, Oid collation, List *args, int varRelid, double default_selectivity)
char name[FLEXIBLE_ARRAY_MEMBER]
static Size VARSIZE(const void *PTR)
static char * VARDATA(const void *PTR)
static void SET_VARSIZE(void *PTR, Size len)
char * text_to_cstring(const text *t)