More sensible character_octet_length
[PostgreSQL.git] / contrib / ltree / ltxtquery_op.c
blob921cf1ad89be2dea4bba7b84f909fa9ddf04b8fd
1 /*
2 * txtquery operations with ltree
3 * Teodor Sigaev <teodor@stack.net>
4 * $PostgreSQL$
5 */
6 #include "postgres.h"
8 #include <ctype.h>
10 #include "ltree.h"
12 PG_FUNCTION_INFO_V1(ltxtq_exec);
13 PG_FUNCTION_INFO_V1(ltxtq_rexec);
16 * check for boolean condition
18 bool
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) '!')
25 return (calcnot) ?
26 ((ltree_execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true)
27 : 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);
33 else
34 return false;
36 else
37 { /* |-operator */
38 if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
39 return true;
40 else
41 return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
43 return false;
46 typedef struct
48 ltree *node;
49 char *operand;
50 } CHKVAL;
52 static bool
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;
61 while (tlen > 0)
63 if (val->flag & LVAR_SUBLEXEME)
65 if (compare_subnode(level, op, val->length, cmpptr, (val->flag & LVAR_ANYEND)))
66 return true;
68 else if (
70 val->length == level->len ||
71 (level->len > val->length && (val->flag & LVAR_ANYEND))
72 ) &&
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(0);
87 ltxtquery *query = PG_GETARG_LTXTQUERY(1);
88 CHKVAL chkval;
89 bool result;
91 chkval.node = val;
92 chkval.operand = GETOPERAND(query);
94 result = ltree_execute(
95 GETQUERY(query),
96 &chkval,
97 true,
98 checkcondition_str
101 PG_FREE_IF_COPY(val, 0);
102 PG_FREE_IF_COPY(query, 1);
103 PG_RETURN_BOOL(result);
106 Datum
107 ltxtq_rexec(PG_FUNCTION_ARGS)
109 PG_RETURN_DATUM(DirectFunctionCall2(ltxtq_exec,
110 PG_GETARG_DATUM(1),
111 PG_GETARG_DATUM(0)