2 * txtquery operations with ltree
3 * Teodor Sigaev <teodor@stack.net>
4 * contrib/ltree/ltxtquery_op.c
11 #include "miscadmin.h"
13 PG_FUNCTION_INFO_V1(ltxtq_exec
);
14 PG_FUNCTION_INFO_V1(ltxtq_rexec
);
17 * check for boolean condition
20 ltree_execute(ITEM
*curitem
, void *checkval
, bool calcnot
, bool (*chkcond
) (void *checkval
, ITEM
*val
))
22 /* since this function recurses, it could be driven to stack overflow */
25 if (curitem
->type
== VAL
)
26 return (*chkcond
) (checkval
, curitem
);
27 else if (curitem
->val
== (int32
) '!')
30 ((ltree_execute(curitem
+ 1, checkval
, calcnot
, chkcond
)) ? false : true)
33 else if (curitem
->val
== (int32
) '&')
35 if (ltree_execute(curitem
+ curitem
->left
, checkval
, calcnot
, chkcond
))
36 return ltree_execute(curitem
+ 1, checkval
, calcnot
, chkcond
);
42 if (ltree_execute(curitem
+ curitem
->left
, checkval
, calcnot
, chkcond
))
45 return ltree_execute(curitem
+ 1, checkval
, calcnot
, chkcond
);
56 checkcondition_str(void *checkval
, ITEM
*val
)
58 ltree_level
*level
= LTREE_FIRST(((CHKVAL
*) checkval
)->node
);
59 int tlen
= ((CHKVAL
*) checkval
)->node
->numlevel
;
60 char *op
= ((CHKVAL
*) checkval
)->operand
+ val
->distance
;
61 int (*cmpptr
) (const char *, const char *, size_t);
63 cmpptr
= (val
->flag
& LVAR_INCASE
) ? ltree_strncasecmp
: strncmp
;
66 if (val
->flag
& LVAR_SUBLEXEME
)
68 if (compare_subnode(level
, op
, val
->length
, cmpptr
, (val
->flag
& LVAR_ANYEND
)))
71 else if ((val
->length
== level
->len
||
72 (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_P(0);
87 ltxtquery
*query
= PG_GETARG_LTXTQUERY_P(1);
92 chkval
.operand
= GETOPERAND(query
);
94 result
= ltree_execute(GETQUERY(query
),
99 PG_FREE_IF_COPY(val
, 0);
100 PG_FREE_IF_COPY(query
, 1);
101 PG_RETURN_BOOL(result
);
105 ltxtq_rexec(PG_FUNCTION_ARGS
)
107 PG_RETURN_DATUM(DirectFunctionCall2(ltxtq_exec
,