|
|
|
@ -19,10 +19,13 @@ PG_FUNCTION_INFO_V1(ltree_isparent); |
|
|
|
|
PG_FUNCTION_INFO_V1(ltree_risparent); |
|
|
|
|
PG_FUNCTION_INFO_V1(subltree); |
|
|
|
|
PG_FUNCTION_INFO_V1(subpath); |
|
|
|
|
PG_FUNCTION_INFO_V1(ltree_index); |
|
|
|
|
PG_FUNCTION_INFO_V1(ltree_addltree); |
|
|
|
|
PG_FUNCTION_INFO_V1(ltree_addtext); |
|
|
|
|
PG_FUNCTION_INFO_V1(ltree_textadd); |
|
|
|
|
PG_FUNCTION_INFO_V1(lca); |
|
|
|
|
PG_FUNCTION_INFO_V1(ltree2text); |
|
|
|
|
PG_FUNCTION_INFO_V1(text2ltree); |
|
|
|
|
Datum ltree_cmp(PG_FUNCTION_ARGS); |
|
|
|
|
Datum ltree_lt(PG_FUNCTION_ARGS); |
|
|
|
|
Datum ltree_le(PG_FUNCTION_ARGS); |
|
|
|
@ -33,10 +36,13 @@ Datum ltree_gt(PG_FUNCTION_ARGS); |
|
|
|
|
Datum nlevel(PG_FUNCTION_ARGS); |
|
|
|
|
Datum subltree(PG_FUNCTION_ARGS); |
|
|
|
|
Datum subpath(PG_FUNCTION_ARGS); |
|
|
|
|
Datum ltree_index(PG_FUNCTION_ARGS); |
|
|
|
|
Datum ltree_addltree(PG_FUNCTION_ARGS); |
|
|
|
|
Datum ltree_addtext(PG_FUNCTION_ARGS); |
|
|
|
|
Datum ltree_textadd(PG_FUNCTION_ARGS); |
|
|
|
|
Datum lca(PG_FUNCTION_ARGS); |
|
|
|
|
Datum ltree2text(PG_FUNCTION_ARGS); |
|
|
|
|
Datum text2ltree(PG_FUNCTION_ARGS); |
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
ltree_compare(const ltree * a, const ltree * b) |
|
|
|
@ -317,6 +323,57 @@ ltree_addtext(PG_FUNCTION_ARGS) |
|
|
|
|
PG_RETURN_POINTER(r); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Datum |
|
|
|
|
ltree_index(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
ltree *a = PG_GETARG_LTREE(0); |
|
|
|
|
ltree *b = PG_GETARG_LTREE(1); |
|
|
|
|
int start=(fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0; |
|
|
|
|
int i,j; |
|
|
|
|
ltree_level *startptr, *aptr, *bptr; |
|
|
|
|
bool found=false; |
|
|
|
|
|
|
|
|
|
if ( start < 0 ) { |
|
|
|
|
if ( -start >= a->numlevel )
|
|
|
|
|
start=0; |
|
|
|
|
else
|
|
|
|
|
start = (int)(a->numlevel)+start; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( a->numlevel - start < b->numlevel || a->numlevel==0 || b->numlevel==0 ) { |
|
|
|
|
PG_FREE_IF_COPY(a, 0); |
|
|
|
|
PG_FREE_IF_COPY(b, 1); |
|
|
|
|
PG_RETURN_INT32(-1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
startptr=LTREE_FIRST(a); |
|
|
|
|
for(i=0; i<=a->numlevel-b->numlevel; i++) { |
|
|
|
|
if ( i>=start ) { |
|
|
|
|
aptr=startptr; |
|
|
|
|
bptr=LTREE_FIRST(b); |
|
|
|
|
for(j=0;j<b->numlevel;j++) { |
|
|
|
|
if ( !(aptr->len==bptr->len && strncmp(aptr->name,bptr->name, aptr->len)==0) ) |
|
|
|
|
break;
|
|
|
|
|
aptr=LEVEL_NEXT(aptr); |
|
|
|
|
bptr=LEVEL_NEXT(bptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( j==b->numlevel ) { |
|
|
|
|
found=true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
startptr=LEVEL_NEXT(startptr);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( !found )
|
|
|
|
|
i=-1; |
|
|
|
|
|
|
|
|
|
PG_FREE_IF_COPY(a, 0); |
|
|
|
|
PG_FREE_IF_COPY(b, 1); |
|
|
|
|
PG_RETURN_INT32(i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Datum |
|
|
|
|
ltree_textadd(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
@ -431,3 +488,55 @@ lca(PG_FUNCTION_ARGS) |
|
|
|
|
else |
|
|
|
|
PG_RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Datum |
|
|
|
|
text2ltree(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
text *in = PG_GETARG_TEXT_P(0); |
|
|
|
|
char *s = (char *) palloc(VARSIZE(in) - VARHDRSZ + 1); |
|
|
|
|
ltree *out; |
|
|
|
|
|
|
|
|
|
memcpy(s, VARDATA(in), VARSIZE(in) - VARHDRSZ); |
|
|
|
|
s[VARSIZE(in) - VARHDRSZ] = '\0'; |
|
|
|
|
|
|
|
|
|
out = (ltree *) DatumGetPointer(DirectFunctionCall1( |
|
|
|
|
ltree_in, |
|
|
|
|
PointerGetDatum(s) |
|
|
|
|
)); |
|
|
|
|
pfree(s); |
|
|
|
|
PG_FREE_IF_COPY(in,0); |
|
|
|
|
PG_RETURN_POINTER(out); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Datum |
|
|
|
|
ltree2text(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
ltree *in = PG_GETARG_LTREE(0); |
|
|
|
|
char *ptr; |
|
|
|
|
int i; |
|
|
|
|
ltree_level *curlevel; |
|
|
|
|
text *out; |
|
|
|
|
|
|
|
|
|
out=(text*)palloc(in->len+VARHDRSZ); |
|
|
|
|
ptr = VARDATA(out);
|
|
|
|
|
curlevel = LTREE_FIRST(in); |
|
|
|
|
for (i = 0; i < in->numlevel; i++) { |
|
|
|
|
if (i != 0) { |
|
|
|
|
*ptr = '.'; |
|
|
|
|
ptr++; |
|
|
|
|
} |
|
|
|
|
memcpy(ptr, curlevel->name, curlevel->len); |
|
|
|
|
ptr += curlevel->len; |
|
|
|
|
curlevel = LEVEL_NEXT(curlevel); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VARATT_SIZEP(out) = VARHDRSZ + (ptr-VARDATA(out));
|
|
|
|
|
PG_FREE_IF_COPY(in, 0); |
|
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(out); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|