2
* op function for ltree and lquery
3
* Teodor Sigaev <teodor@stack.net>
8
#include "utils/array.h"
10
PG_FUNCTION_INFO_V1(ltq_regex);
11
PG_FUNCTION_INFO_V1(ltq_rregex);
13
PG_FUNCTION_INFO_V1(lt_q_regex);
14
PG_FUNCTION_INFO_V1(lt_q_rregex);
16
#define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
29
getlexem(char *start, char *end, int *len)
33
while (start < end && *start == '_')
40
while (ptr < end && *ptr != '_')
48
compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
50
char *endt = t->name + t->len;
51
char *endq = qn + len;
57
while ((qn = getlexem(qn, endq, &lenq)) != NULL)
61
while ((tn = getlexem(tn, endt, &lent)) != NULL)
66
(lent > lenq && anyend)
68
(*cmpptr) (qn, tn, lenq) == 0)
86
checkLevel(lquery_level * curq, ltree_level * curt)
88
int (*cmpptr) (const char *, const char *, size_t);
89
lquery_variant *curvar = LQL_FIRST(curq);
92
for (i = 0; i < curq->numvar; i++)
94
cmpptr = (curvar->flag & LVAR_INCASE) ? pg_strncasecmp : strncmp;
96
if (curvar->flag & LVAR_SUBLEXEM)
98
if (compare_subnode(curt, curvar->name, curvar->len, cmpptr, (curvar->flag & LVAR_ANYEND)))
103
curvar->len == curt->len ||
104
(curt->len > curvar->len && (curvar->flag & LVAR_ANYEND))
106
(*cmpptr) (curvar->name, curt->name, curvar->len) == 0)
111
curvar = LVAR_NEXT(curvar);
118
printFieldNot(FieldNot *fn ) {
120
elog(NOTICE,"posQ:%d lenQ:%d posT:%d lenT:%d", fn->posq,fn->nq,fn->post,fn->nt);
137
checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_numlevel, FieldNot * ptr)
142
int tlen = tree_numlevel,
143
qlen = query_numlevel;
145
lquery_level *prevq = NULL;
146
ltree_level *prevt = NULL;
150
high_pos = SomeStack.high_pos;
153
curq = LQL_NEXT(curq);
154
SomeStack.muse = false;
157
while (tlen > 0 && qlen > 0)
162
while (cur_tpos < low_pos)
164
curt = LEVEL_NEXT(curt);
173
if (ptr && curq->flag & LQL_NOT)
175
if (!(prevq && prevq->numvar == 0))
182
ptr->nq = 1 + ((prevq == curq) ? 0 : 1);
183
ptr->posq = query_numlevel - qlen - ((prevq == curq) ? 0 : 1);
184
ptr->post = cur_tpos;
192
if (qlen == 1 && ptr->q->numvar == 0)
193
ptr->nt = tree_numlevel - ptr->post;
194
curt = LEVEL_NEXT(curt);
197
if (high_pos < cur_tpos)
203
while (cur_tpos <= high_pos && tlen > 0 && !isok)
205
isok = checkLevel(curq, curt);
206
curt = LEVEL_NEXT(curt);
209
if (isok && prevq && prevq->numvar == 0 && tlen > 0 && cur_tpos <= high_pos)
214
memcpy(&tmpptr, ptr, sizeof(FieldNot));
215
SomeStack.high_pos = high_pos - cur_tpos;
216
SomeStack.muse = true;
217
if (checkCond(prevq, qlen + 1, curt, tlen, (ptr) ? &tmpptr : NULL))
228
if (checkCond(ptr->q, ptr->nq, ptr->t, ptr->nt, NULL))
238
low_pos = cur_tpos + curq->low;
239
high_pos = cur_tpos + curq->high;
244
ptr->nt = tree_numlevel - ptr->post;
249
curq = LQL_NEXT(curq);
253
if (low_pos > tree_numlevel || tree_numlevel > high_pos)
260
if (!(curq->flag & LQL_NOT))
265
low_pos = cur_tpos + curq->low;
266
high_pos = cur_tpos + curq->high;
269
curq = LQL_NEXT(curq);
273
if (low_pos > tree_numlevel || tree_numlevel > high_pos)
276
if (ptr && ptr->q && checkCond(ptr->q, ptr->nq, ptr->t, ptr->nt, NULL))
283
ltq_regex(PG_FUNCTION_ARGS)
285
ltree *tree = PG_GETARG_LTREE(0);
286
lquery *query = PG_GETARG_LQUERY(1);
289
if (query->flag & LQUERY_HASNOT)
295
res = checkCond(LQUERY_FIRST(query), query->numlevel,
296
LTREE_FIRST(tree), tree->numlevel, &fn);
300
res = checkCond(LQUERY_FIRST(query), query->numlevel,
301
LTREE_FIRST(tree), tree->numlevel, NULL);
304
PG_FREE_IF_COPY(tree, 0);
305
PG_FREE_IF_COPY(query, 1);
310
ltq_rregex(PG_FUNCTION_ARGS)
312
PG_RETURN_DATUM(DirectFunctionCall2(ltq_regex,
319
lt_q_regex(PG_FUNCTION_ARGS)
321
ltree *tree = PG_GETARG_LTREE(0);
322
ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
323
lquery *query = (lquery *) ARR_DATA_PTR(_query);
325
int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
327
if (ARR_NDIM(_query) != 1)
329
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
330
errmsg("array must be one-dimensional")));
334
if (DatumGetBool(DirectFunctionCall2(ltq_regex,
335
PointerGetDatum(tree), PointerGetDatum(query))))
342
query = NEXTVAL(query);
345
PG_FREE_IF_COPY(tree, 0);
346
PG_FREE_IF_COPY(_query, 1);
351
lt_q_rregex(PG_FUNCTION_ARGS)
353
PG_RETURN_DATUM(DirectFunctionCall2(lt_q_regex,