2 * txtquery operations with ltree
3 * Teodor Sigaev <teodor@stack.net>
12 PG_FUNCTION_INFO_V1(ltxtq_exec
);
13 PG_FUNCTION_INFO_V1(ltxtq_rexec
);
16 * check for boolean condition
19 ltree_execute(ITEM
*curitem
, void *checkval
, bool calcnot
, bool (*chkcond
) (void *checkval
, ITEM
*val
))
21 if (curitem
->type
== VAL
)
22 return (*chkcond
) (checkval
, curitem
);
23 else if (curitem
->val
== (int4
) '!')
26 ((ltree_execute(curitem
+ 1, checkval
, calcnot
, chkcond
)) ? false : true)
29 else if (curitem
->val
== (int4
) '&')
31 if (ltree_execute(curitem
+ curitem
->left
, checkval
, calcnot
, chkcond
))
32 return ltree_execute(curitem
+ 1, checkval
, calcnot
, chkcond
);
38 if (ltree_execute(curitem
+ curitem
->left
, checkval
, calcnot
, chkcond
))
41 return ltree_execute(curitem
+ 1, checkval
, calcnot
, chkcond
);
53 checkcondition_str(void *checkval
, ITEM
*val
)
55 ltree_level
*level
= LTREE_FIRST(((CHKVAL
*) checkval
)->node
);
56 int tlen
= ((CHKVAL
*) checkval
)->node
->numlevel
;
57 char *op
= ((CHKVAL
*) checkval
)->operand
+ val
->distance
;
58 int (*cmpptr
) (const char *, const char *, size_t);
60 cmpptr
= (val
->flag
& LVAR_INCASE
) ? ltree_strncasecmp
: strncmp
;
63 if (val
->flag
& LVAR_SUBLEXEME
)
65 if (compare_subnode(level
, op
, val
->length
, cmpptr
, (val
->flag
& LVAR_ANYEND
)))
70 val
->length
== level
->len
||
71 (level
->len
> val
->length
&& (val
->flag
& LVAR_ANYEND
))
73 (*cmpptr
) (op
, level
->name
, val
->length
) == 0)
77 level
= LEVEL_NEXT(level
);
84 ltxtq_exec(PG_FUNCTION_ARGS
)
86 ltree
*val
= PG_GETARG_LTREE(0);
87 ltxtquery
*query
= PG_GETARG_LTXTQUERY(1);
92 chkval
.operand
= GETOPERAND(query
);
94 result
= ltree_execute(
101 PG_FREE_IF_COPY(val
, 0);
102 PG_FREE_IF_COPY(query
, 1);
103 PG_RETURN_BOOL(result
);
107 ltxtq_rexec(PG_FUNCTION_ARGS
)
109 PG_RETURN_DATUM(DirectFunctionCall2(ltxtq_exec
,