doc: Fix section of functions age(xid) and mxid_age(xid)
[pgsql.git] / contrib / ltree / ltxtquery_op.c
blob002102c9c75b69466d79852448ad488a2905890a
1 /*
2 * txtquery operations with ltree
3 * Teodor Sigaev <teodor@stack.net>
4 * contrib/ltree/ltxtquery_op.c
5 */
6 #include "postgres.h"
8 #include <ctype.h>
10 #include "ltree.h"
11 #include "miscadmin.h"
13 PG_FUNCTION_INFO_V1(ltxtq_exec);
14 PG_FUNCTION_INFO_V1(ltxtq_rexec);
17 * check for boolean condition
19 bool
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 */
23 check_stack_depth();
25 if (curitem->type == VAL)
26 return (*chkcond) (checkval, curitem);
27 else if (curitem->val == (int32) '!')
29 return calcnot ?
30 ((ltree_execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true)
31 : 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);
37 else
38 return false;
40 else
41 { /* |-operator */
42 if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
43 return true;
44 else
45 return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
49 typedef struct
51 ltree *node;
52 char *operand;
53 } CHKVAL;
55 static bool
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;
64 while (tlen > 0)
66 if (val->flag & LVAR_SUBLEXEME)
68 if (compare_subnode(level, op, val->length, cmpptr, (val->flag & LVAR_ANYEND)))
69 return true;
71 else if ((val->length == level->len ||
72 (level->len > val->length && (val->flag & LVAR_ANYEND))) &&
73 (*cmpptr) (op, level->name, val->length) == 0)
74 return true;
76 tlen--;
77 level = LEVEL_NEXT(level);
80 return false;
83 Datum
84 ltxtq_exec(PG_FUNCTION_ARGS)
86 ltree *val = PG_GETARG_LTREE_P(0);
87 ltxtquery *query = PG_GETARG_LTXTQUERY_P(1);
88 CHKVAL chkval;
89 bool result;
91 chkval.node = val;
92 chkval.operand = GETOPERAND(query);
94 result = ltree_execute(GETQUERY(query),
95 &chkval,
96 true,
97 checkcondition_str);
99 PG_FREE_IF_COPY(val, 0);
100 PG_FREE_IF_COPY(query, 1);
101 PG_RETURN_BOOL(result);
104 Datum
105 ltxtq_rexec(PG_FUNCTION_ARGS)
107 PG_RETURN_DATUM(DirectFunctionCall2(ltxtq_exec,
108 PG_GETARG_DATUM(1),
109 PG_GETARG_DATUM(0)