#include "postgres.h"#include <ctype.h>#include "access/htup_details.h"#include "catalog/pg_statistic.h"#include "utils/builtins.h"#include "utils/lsyscache.h"#include "utils/selfuncs.h"#include "ltree.h"
Go to the source code of this file.
Defines | |
| #define | RUNCMP |
| #define | DEFAULT_PARENT_SEL 0.001 |
Functions | |
| PG_FUNCTION_INFO_V1 (ltree_cmp) | |
| PG_FUNCTION_INFO_V1 (ltree_lt) | |
| PG_FUNCTION_INFO_V1 (ltree_le) | |
| PG_FUNCTION_INFO_V1 (ltree_eq) | |
| PG_FUNCTION_INFO_V1 (ltree_ne) | |
| PG_FUNCTION_INFO_V1 (ltree_ge) | |
| PG_FUNCTION_INFO_V1 (ltree_gt) | |
| PG_FUNCTION_INFO_V1 (nlevel) | |
| 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) | |
| PG_FUNCTION_INFO_V1 (ltreeparentsel) | |
| Datum | ltree_cmp (PG_FUNCTION_ARGS) |
| Datum | ltree_lt (PG_FUNCTION_ARGS) |
| Datum | ltree_le (PG_FUNCTION_ARGS) |
| Datum | ltree_eq (PG_FUNCTION_ARGS) |
| Datum | ltree_ne (PG_FUNCTION_ARGS) |
| Datum | ltree_ge (PG_FUNCTION_ARGS) |
| 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) |
| Datum | ltreeparentsel (PG_FUNCTION_ARGS) |
| int | ltree_compare (const ltree *a, const ltree *b) |
| bool | inner_isparent (const ltree *c, const ltree *p) |
| Datum | ltree_isparent (PG_FUNCTION_ARGS) |
| Datum | ltree_risparent (PG_FUNCTION_ARGS) |
| static ltree * | inner_subltree (ltree *t, int32 startpos, int32 endpos) |
| static ltree * | ltree_concat (ltree *a, ltree *b) |
| ltree * | lca_inner (ltree **a, int len) |
Variables | |
| PG_MODULE_MAGIC | |
| #define DEFAULT_PARENT_SEL 0.001 |
Definition at line 558 of file ltree_op.c.
Referenced by ltreeparentsel().
| #define RUNCMP |
ltree *a = PG_GETARG_LTREE(0); \ ltree *b = PG_GETARG_LTREE(1); \ int res = ltree_compare(a,b); \ PG_FREE_IF_COPY(a,0); \ PG_FREE_IF_COPY(b,1); \
Definition at line 88 of file ltree_op.c.
Referenced by ltree_cmp(), ltree_eq(), ltree_ge(), ltree_gt(), ltree_le(), ltree_lt(), and ltree_ne().
Definition at line 155 of file ltree_op.c.
References ltree_level::len, LEVEL_NEXT, LTREE_FIRST, memcmp(), ltree_level::name, and ltree::numlevel.
Referenced by ltree_consistent(), ltree_isparent(), and ltree_risparent().
{
ltree_level *cl = LTREE_FIRST(c);
ltree_level *pl = LTREE_FIRST(p);
int pn = p->numlevel;
if (pn > c->numlevel)
return false;
while (pn > 0)
{
if (cl->len != pl->len)
return false;
if (memcmp(cl->name, pl->name, cl->len))
return false;
pn--;
cl = LEVEL_NEXT(cl);
pl = LEVEL_NEXT(pl);
}
return true;
}
Definition at line 204 of file ltree_op.c.
References end, ereport, errcode(), errmsg(), ERROR, i, LEVEL_NEXT, LTREE_FIRST, LTREE_HDRSIZE, ltree::numlevel, palloc(), and SET_VARSIZE.
Referenced by subltree(), and subpath().
{
char *start = NULL,
*end = NULL;
ltree_level *ptr = LTREE_FIRST(t);
ltree *res;
int i;
if (startpos < 0 || endpos < 0 || startpos >= t->numlevel || startpos > endpos)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid positions")));
if (endpos > t->numlevel)
endpos = t->numlevel;
start = end = (char *) ptr;
for (i = 0; i < endpos; i++)
{
if (i == startpos)
start = (char *) ptr;
if (i == endpos - 1)
{
end = (char *) LEVEL_NEXT(ptr);
break;
}
ptr = LEVEL_NEXT(ptr);
}
res = (ltree *) palloc(LTREE_HDRSIZE + (end - start));
SET_VARSIZE(res, LTREE_HDRSIZE + (end - start));
res->numlevel = endpos - startpos;
memcpy(LTREE_FIRST(res), start, end - start);
return res;
}
| Datum lca | ( | PG_FUNCTION_ARGS | ) |
Definition at line 490 of file ltree_op.c.
References i, lca_inner(), palloc(), pfree(), PG_FREE_IF_COPY, PG_GETARG_LTREE, PG_RETURN_NULL, and PG_RETURN_POINTER.
{
int i;
ltree **a,
*res;
a = (ltree **) palloc(sizeof(ltree *) * fcinfo->nargs);
for (i = 0; i < fcinfo->nargs; i++)
a[i] = PG_GETARG_LTREE(i);
res = lca_inner(a, (int) fcinfo->nargs);
for (i = 0; i < fcinfo->nargs; i++)
PG_FREE_IF_COPY(a[i], i);
pfree(a);
if (res)
PG_RETURN_POINTER(res);
else
PG_RETURN_NULL();
}
Definition at line 425 of file ltree_op.c.
References i, LEVEL_HDRSIZE, LEVEL_NEXT, LTREE_FIRST, LTREE_HDRSIZE, MAXALIGN, memcmp(), Min, ltree::numlevel, palloc(), and SET_VARSIZE.
Referenced by _lca(), and lca().
{
int tmp,
num = ((*a)->numlevel) ? (*a)->numlevel - 1 : 0;
ltree **ptr = a + 1;
int i,
reslen = LTREE_HDRSIZE;
ltree_level *l1,
*l2;
ltree *res;
if ((*a)->numlevel == 0)
return NULL;
while (ptr - a < len)
{
if ((*ptr)->numlevel == 0)
return NULL;
else if ((*ptr)->numlevel == 1)
num = 0;
else
{
l1 = LTREE_FIRST(*a);
l2 = LTREE_FIRST(*ptr);
tmp = num;
num = 0;
for (i = 0; i < Min(tmp, (*ptr)->numlevel - 1); i++)
{
if (l1->len == l2->len && memcmp(l1->name, l2->name, l1->len) == 0)
num = i + 1;
else
break;
l1 = LEVEL_NEXT(l1);
l2 = LEVEL_NEXT(l2);
}
}
ptr++;
}
l1 = LTREE_FIRST(*a);
for (i = 0; i < num; i++)
{
reslen += MAXALIGN(l1->len + LEVEL_HDRSIZE);
l1 = LEVEL_NEXT(l1);
}
res = (ltree *) palloc(reslen);
SET_VARSIZE(res, reslen);
res->numlevel = num;
l1 = LTREE_FIRST(*a);
l2 = LTREE_FIRST(res);
for (i = 0; i < num; i++)
{
memcpy(l2, l1, MAXALIGN(l1->len + LEVEL_HDRSIZE));
l1 = LEVEL_NEXT(l1);
l2 = LEVEL_NEXT(l2);
}
return res;
}
| Datum ltree2text | ( | PG_FUNCTION_ARGS | ) |
Definition at line 528 of file ltree_op.c.
References i, ltree_level::len, LEVEL_NEXT, LTREE_FIRST, ltree_level::name, ltree::numlevel, palloc(), PG_FREE_IF_COPY, PG_GETARG_LTREE, PG_RETURN_POINTER, SET_VARSIZE, VARDATA, and VARSIZE.
{
ltree *in = PG_GETARG_LTREE(0);
char *ptr;
int i;
ltree_level *curlevel;
text *out;
out = (text *) palloc(VARSIZE(in) + 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);
}
SET_VARSIZE(out, ptr - ((char *) out));
PG_FREE_IF_COPY(in, 0);
PG_RETURN_POINTER(out);
}
| Datum ltree_addltree | ( | PG_FUNCTION_ARGS | ) |
Definition at line 302 of file ltree_op.c.
References ltree_concat(), PG_FREE_IF_COPY, PG_GETARG_LTREE, and PG_RETURN_POINTER.
{
ltree *a = PG_GETARG_LTREE(0);
ltree *b = PG_GETARG_LTREE(1);
ltree *r;
r = ltree_concat(a, b);
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POINTER(r);
}
| Datum ltree_addtext | ( | PG_FUNCTION_ARGS | ) |
Definition at line 315 of file ltree_op.c.
References DatumGetPointer, DirectFunctionCall1, ltree_concat(), ltree_in(), pfree(), PG_FREE_IF_COPY, PG_GETARG_LTREE, PG_GETARG_TEXT_PP, PG_RETURN_POINTER, PointerGetDatum, and text_to_cstring().
{
ltree *a = PG_GETARG_LTREE(0);
text *b = PG_GETARG_TEXT_PP(1);
char *s;
ltree *r,
*tmp;
s = text_to_cstring(b);
tmp = (ltree *) DatumGetPointer(DirectFunctionCall1(ltree_in,
PointerGetDatum(s)));
pfree(s);
r = ltree_concat(a, tmp);
pfree(tmp);
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POINTER(r);
}
| Datum ltree_cmp | ( | PG_FUNCTION_ARGS | ) |
Definition at line 96 of file ltree_op.c.
References PG_RETURN_INT32, and RUNCMP.
{
RUNCMP
PG_RETURN_INT32(res);
}
Definition at line 61 of file ltree_op.c.
References ltree_level::len, LEVEL_NEXT, LTREE_FIRST, memcmp(), Min, ltree_level::name, and ltree::numlevel.
Referenced by gist_ischild(), gist_isparent(), ltree_consistent(), ltree_penalty(), ltree_picksplit(), ltree_union(), and treekey_cmp().
{
ltree_level *al = LTREE_FIRST(a);
ltree_level *bl = LTREE_FIRST(b);
int an = a->numlevel;
int bn = b->numlevel;
int res = 0;
while (an > 0 && bn > 0)
{
if ((res = memcmp(al->name, bl->name, Min(al->len, bl->len))) == 0)
{
if (al->len != bl->len)
return (al->len - bl->len) * 10 * (an + 1);
}
else
return res * 10 * (an + 1);
an--;
bn--;
al = LEVEL_NEXT(al);
bl = LEVEL_NEXT(bl);
}
return (a->numlevel - b->numlevel) * 10 * (an + 1);
}
Definition at line 286 of file ltree_op.c.
References LTREE_FIRST, LTREE_HDRSIZE, ltree::numlevel, palloc(), SET_VARSIZE, and VARSIZE.
Referenced by ltree_addltree(), ltree_addtext(), and ltree_textadd().
{
ltree *r;
r = (ltree *) palloc(VARSIZE(a) + VARSIZE(b) - LTREE_HDRSIZE);
SET_VARSIZE(r, VARSIZE(a) + VARSIZE(b) - LTREE_HDRSIZE);
r->numlevel = a->numlevel + b->numlevel;
memcpy(LTREE_FIRST(r), LTREE_FIRST(a), VARSIZE(a) - LTREE_HDRSIZE);
memcpy(((char *) LTREE_FIRST(r)) + VARSIZE(a) - LTREE_HDRSIZE,
LTREE_FIRST(b),
VARSIZE(b) - LTREE_HDRSIZE);
return r;
}
| Datum ltree_eq | ( | PG_FUNCTION_ARGS | ) |
Definition at line 117 of file ltree_op.c.
References PG_RETURN_BOOL, and RUNCMP.
{
RUNCMP
PG_RETURN_BOOL((res == 0) ? true : false);
}
| Datum ltree_ge | ( | PG_FUNCTION_ARGS | ) |
Definition at line 124 of file ltree_op.c.
References PG_RETURN_BOOL, and RUNCMP.
{
RUNCMP
PG_RETURN_BOOL((res >= 0) ? true : false);
}
| Datum ltree_gt | ( | PG_FUNCTION_ARGS | ) |
Definition at line 131 of file ltree_op.c.
References PG_RETURN_BOOL, and RUNCMP.
{
RUNCMP
PG_RETURN_BOOL((res > 0) ? true : false);
}
| Datum ltree_index | ( | PG_FUNCTION_ARGS | ) |
Definition at line 340 of file ltree_op.c.
References i, ltree_level::len, LEVEL_NEXT, LTREE_FIRST, memcmp(), ltree_level::name, ltree::numlevel, PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_LTREE, and PG_RETURN_INT32.
{
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 && memcmp(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_isparent | ( | PG_FUNCTION_ARGS | ) |
Definition at line 179 of file ltree_op.c.
References inner_isparent(), PG_FREE_IF_COPY, PG_GETARG_LTREE, and PG_RETURN_BOOL.
Referenced by _ltree_extract_isparent(), and _ltree_isparent().
{
ltree *c = PG_GETARG_LTREE(1);
ltree *p = PG_GETARG_LTREE(0);
bool res = inner_isparent(c, p);
PG_FREE_IF_COPY(c, 1);
PG_FREE_IF_COPY(p, 0);
PG_RETURN_BOOL(res);
}
| Datum ltree_le | ( | PG_FUNCTION_ARGS | ) |
Definition at line 110 of file ltree_op.c.
References PG_RETURN_BOOL, and RUNCMP.
{
RUNCMP
PG_RETURN_BOOL((res <= 0) ? true : false);
}
| Datum ltree_lt | ( | PG_FUNCTION_ARGS | ) |
Definition at line 103 of file ltree_op.c.
References PG_RETURN_BOOL, and RUNCMP.
{
RUNCMP
PG_RETURN_BOOL((res < 0) ? true : false);
}
| Datum ltree_ne | ( | PG_FUNCTION_ARGS | ) |
Definition at line 138 of file ltree_op.c.
References PG_RETURN_BOOL, and RUNCMP.
{
RUNCMP
PG_RETURN_BOOL((res != 0) ? true : false);
}
| Datum ltree_risparent | ( | PG_FUNCTION_ARGS | ) |
Definition at line 191 of file ltree_op.c.
References inner_isparent(), PG_FREE_IF_COPY, PG_GETARG_LTREE, and PG_RETURN_BOOL.
Referenced by _ltree_extract_risparent(), and _ltree_risparent().
{
ltree *c = PG_GETARG_LTREE(0);
ltree *p = PG_GETARG_LTREE(1);
bool res = inner_isparent(c, p);
PG_FREE_IF_COPY(c, 0);
PG_FREE_IF_COPY(p, 1);
PG_RETURN_BOOL(res);
}
| Datum ltree_textadd | ( | PG_FUNCTION_ARGS | ) |
Definition at line 400 of file ltree_op.c.
References DatumGetPointer, DirectFunctionCall1, ltree_concat(), ltree_in(), pfree(), PG_FREE_IF_COPY, PG_GETARG_LTREE, PG_GETARG_TEXT_PP, PG_RETURN_POINTER, PointerGetDatum, and text_to_cstring().
{
ltree *a = PG_GETARG_LTREE(1);
text *b = PG_GETARG_TEXT_PP(0);
char *s;
ltree *r,
*tmp;
s = text_to_cstring(b);
tmp = (ltree *) DatumGetPointer(DirectFunctionCall1(ltree_in,
PointerGetDatum(s)));
pfree(s);
r = ltree_concat(tmp, a);
pfree(tmp);
PG_FREE_IF_COPY(a, 1);
PG_FREE_IF_COPY(b, 0);
PG_RETURN_POINTER(r);
}
| Datum ltreeparentsel | ( | PG_FUNCTION_ARGS | ) |
Definition at line 564 of file ltree_op.c.
References CLAMP_PROBABILITY, DEFAULT_PARENT_SEL, fmgr_info(), get_opcode(), get_restriction_variable(), GETSTRUCT, HeapTupleIsValid, histogram_selectivity(), IsA, mcv_selectivity(), PG_GETARG_INT32, PG_GETARG_POINTER, PG_RETURN_FLOAT8, ReleaseVariableStats, and VariableStatData::statsTuple.
{
PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
Oid operator = PG_GETARG_OID(1);
List *args = (List *) PG_GETARG_POINTER(2);
int varRelid = PG_GETARG_INT32(3);
VariableStatData vardata;
Node *other;
bool varonleft;
double selec;
/*
* If expression is not variable <@ something or something <@ variable,
* then punt and return a default estimate.
*/
if (!get_restriction_variable(root, args, varRelid,
&vardata, &other, &varonleft))
PG_RETURN_FLOAT8(DEFAULT_PARENT_SEL);
/*
* If the something is a NULL constant, assume operator is strict and
* return zero, ie, operator will never return TRUE.
*/
if (IsA(other, Const) &&
((Const *) other)->constisnull)
{
ReleaseVariableStats(vardata);
PG_RETURN_FLOAT8(0.0);
}
if (IsA(other, Const))
{
/* Variable is being compared to a known non-null constant */
Datum constval = ((Const *) other)->constvalue;
FmgrInfo contproc;
double mcvsum;
double mcvsel;
double nullfrac;
int hist_size;
fmgr_info(get_opcode(operator), &contproc);
/*
* Is the constant "<@" to any of the column's most common values?
*/
mcvsel = mcv_selectivity(&vardata, &contproc, constval, varonleft,
&mcvsum);
/*
* If the histogram is large enough, see what fraction of it the
* constant is "<@" to, and assume that's representative of the
* non-MCV population. Otherwise use the default selectivity for the
* non-MCV population.
*/
selec = histogram_selectivity(&vardata, &contproc,
constval, varonleft,
10, 1, &hist_size);
if (selec < 0)
{
/* Nope, fall back on default */
selec = DEFAULT_PARENT_SEL;
}
else if (hist_size < 100)
{
/*
* For histogram sizes from 10 to 100, we combine the histogram
* and default selectivities, putting increasingly more trust in
* the histogram for larger sizes.
*/
double hist_weight = hist_size / 100.0;
selec = selec * hist_weight +
DEFAULT_PARENT_SEL * (1.0 - hist_weight);
}
/* In any case, don't believe extremely small or large estimates. */
if (selec < 0.0001)
selec = 0.0001;
else if (selec > 0.9999)
selec = 0.9999;
if (HeapTupleIsValid(vardata.statsTuple))
nullfrac = ((Form_pg_statistic) GETSTRUCT(vardata.statsTuple))->stanullfrac;
else
nullfrac = 0.0;
/*
* Now merge the results from the MCV and histogram calculations,
* realizing that the histogram covers only the non-null values that
* are not listed in MCV.
*/
selec *= 1.0 - nullfrac - mcvsum;
selec += mcvsel;
}
else
selec = DEFAULT_PARENT_SEL;
ReleaseVariableStats(vardata);
/* result should be in range, but make sure... */
CLAMP_PROBABILITY(selec);
PG_RETURN_FLOAT8((float8) selec);
}
| Datum nlevel | ( | PG_FUNCTION_ARGS | ) |
Definition at line 145 of file ltree_op.c.
References ltree::numlevel, PG_FREE_IF_COPY, PG_GETARG_LTREE, and PG_RETURN_INT32.
{
ltree *a = PG_GETARG_LTREE(0);
int res = a->numlevel;
PG_FREE_IF_COPY(a, 0);
PG_RETURN_INT32(res);
}
| PG_FUNCTION_INFO_V1 | ( | subpath | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_lt | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_cmp | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_index | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree2text | ) |
| PG_FUNCTION_INFO_V1 | ( | ltreeparentsel | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_textadd | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_eq | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_risparent | ) |
| PG_FUNCTION_INFO_V1 | ( | lca | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_addltree | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_ne | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_le | ) |
| PG_FUNCTION_INFO_V1 | ( | subltree | ) |
| PG_FUNCTION_INFO_V1 | ( | text2ltree | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_isparent | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_addtext | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_gt | ) |
| PG_FUNCTION_INFO_V1 | ( | nlevel | ) |
| PG_FUNCTION_INFO_V1 | ( | ltree_ge | ) |
| Datum subltree | ( | PG_FUNCTION_ARGS | ) |
Definition at line 243 of file ltree_op.c.
References inner_subltree(), PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_LTREE, and PG_RETURN_POINTER.
{
ltree *t = PG_GETARG_LTREE(0);
ltree *res = inner_subltree(t, PG_GETARG_INT32(1), PG_GETARG_INT32(2));
PG_FREE_IF_COPY(t, 0);
PG_RETURN_POINTER(res);
}
| Datum subpath | ( | PG_FUNCTION_ARGS | ) |
Definition at line 253 of file ltree_op.c.
References inner_subltree(), ltree::numlevel, PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_LTREE, and PG_RETURN_POINTER.
Referenced by _outMaterialPath(), _outUniquePath(), cost_bitmap_and_node(), cost_bitmap_or_node(), create_append_path(), create_append_plan(), create_merge_append_path(), create_merge_append_plan(), and walkdir().
{
ltree *t = PG_GETARG_LTREE(0);
int32 start = PG_GETARG_INT32(1);
int32 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
int32 end;
ltree *res;
end = start + len;
if (start < 0)
{
start = t->numlevel + start;
end = start + len;
}
if (start < 0)
{ /* start > t->numlevel */
start = t->numlevel + start;
end = start + len;
}
if (len < 0)
end = t->numlevel + len;
else if (len == 0)
end = (fcinfo->nargs == 3) ? start : 0xffff;
res = inner_subltree(t, start, end);
PG_FREE_IF_COPY(t, 0);
PG_RETURN_POINTER(res);
}
| Datum text2ltree | ( | PG_FUNCTION_ARGS | ) |
Definition at line 511 of file ltree_op.c.
References DatumGetPointer, DirectFunctionCall1, ltree_in(), pfree(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, PG_RETURN_POINTER, PointerGetDatum, and text_to_cstring().
{
text *in = PG_GETARG_TEXT_PP(0);
char *s;
ltree *out;
s = text_to_cstring(in);
out = (ltree *) DatumGetPointer(DirectFunctionCall1(ltree_in,
PointerGetDatum(s)));
pfree(s);
PG_FREE_IF_COPY(in, 0);
PG_RETURN_POINTER(out);
}
Definition at line 17 of file ltree_op.c.
1.7.1