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_risparent(PG_FUNCTION_ARGS) { 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_addltree(PG_FUNCTION_ARGS) { 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 ltree2text(PG_FUNCTION_ARGS) { 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 subpath(PG_FUNCTION_ARGS) { ltree *t = PG_GETARG_LTREE(0); int4 start = PG_GETARG_INT32(1); int4 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0; int4 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 ltree_textadd(PG_FUNCTION_ARGS) { ltree *a = PG_GETARG_LTREE(1); text *b = PG_GETARG_TEXT_P(0); char *s; ltree *r, *tmp; s = (char *) palloc(VARSIZE(b) - VARHDRSZ + 1); memcpy(s, VARDATA(b), VARSIZE(b) - VARHDRSZ); s[VARSIZE(b) - VARHDRSZ] = '\0'; 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 ltree_out(PG_FUNCTION_ARGS) { ltree *in = PG_GETARG_LTREE(0); char *buf, *ptr; int i; ltree_level *curlevel; ptr = buf = (char *) palloc(VARSIZE(in)); 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); } *ptr = '\0'; PG_FREE_IF_COPY(in, 0); PG_RETURN_POINTER(buf); }
Datum lt_q_regex(PG_FUNCTION_ARGS) { ltree *tree = PG_GETARG_LTREE(0); ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1); lquery *query = (lquery *) ARR_DATA_PTR(_query); bool res = false; int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query)); if (ARR_NDIM(_query) != 1) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("array must be one-dimensional"))); while (num > 0) { if (DatumGetBool(DirectFunctionCall2(ltq_regex, PointerGetDatum(tree), PointerGetDatum(query)))) { res = true; break; } num--; query = NEXTVAL(query); } PG_FREE_IF_COPY(tree, 0); PG_FREE_IF_COPY(_query, 1); PG_RETURN_BOOL(res); }
Datum ltq_regex(PG_FUNCTION_ARGS) { ltree *tree = PG_GETARG_LTREE(0); lquery *query = PG_GETARG_LQUERY(1); bool res = false; if (query->flag & LQUERY_HASNOT) { FieldNot fn; fn.q = NULL; res = checkCond(LQUERY_FIRST(query), query->numlevel, LTREE_FIRST(tree), tree->numlevel, &fn); } else { res = checkCond(LQUERY_FIRST(query), query->numlevel, LTREE_FIRST(tree), tree->numlevel, NULL); } PG_FREE_IF_COPY(tree, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(res); }
Datum subltree(PG_FUNCTION_ARGS) { 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 nlevel(PG_FUNCTION_ARGS) { ltree *a = PG_GETARG_LTREE(0); int res = a->numlevel; PG_FREE_IF_COPY(a, 0); PG_RETURN_INT32(res); }
Datum _ltree_risparent(PG_FUNCTION_ARGS) { ArrayType *la = PG_GETARG_ARRAYTYPE_P(0); ltree *query = PG_GETARG_LTREE(1); bool res = array_iterator(la, ltree_risparent, (void *) query, NULL); PG_FREE_IF_COPY(la, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(res); }
Datum lca(PG_FUNCTION_ARGS) { 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(); }
Datum ltxtq_exec(PG_FUNCTION_ARGS) { ltree *val = PG_GETARG_LTREE(0); ltxtquery *query = PG_GETARG_LTXTQUERY(1); CHKVAL chkval; bool result; chkval.node = val; chkval.operand = GETOPERAND(query); result = ltree_execute( GETQUERY(query), &chkval, true, checkcondition_str ); PG_FREE_IF_COPY(val, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(result); }
Datum _ltree_extract_risparent(PG_FUNCTION_ARGS) { ArrayType *la = PG_GETARG_ARRAYTYPE_P(0); ltree *query = PG_GETARG_LTREE(1); ltree *found, *item; if (!array_iterator(la, ltree_risparent, (void *) query, &found)) { PG_FREE_IF_COPY(la, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_NULL(); } item = (ltree *) palloc(VARSIZE(found)); memcpy(item, found, VARSIZE(found)); PG_FREE_IF_COPY(la, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_POINTER(item); }
Datum ltree_textadd(PG_FUNCTION_ARGS) { 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); }