PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
ltxtquery_op.c
Go to the documentation of this file.
1 /*
2  * txtquery operations with ltree
3  * Teodor Sigaev <teodor@stack.net>
4  * contrib/ltree/ltxtquery_op.c
5  */
6 #include "postgres.h"
7 
8 #include <ctype.h>
9 
10 #include "ltree.h"
11 #include "miscadmin.h"
12 
15 
16 /*
17  * check for boolean condition
18  */
19 bool
20 ltree_execute(ITEM *curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM *val))
21 {
22  /* since this function recurses, it could be driven to stack overflow */
24 
25  if (curitem->type == VAL)
26  return (*chkcond) (checkval, curitem);
27  else if (curitem->val == (int32) '!')
28  {
29  return (calcnot) ?
30  ((ltree_execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true)
31  : true;
32  }
33  else if (curitem->val == (int32) '&')
34  {
35  if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
36  return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
37  else
38  return false;
39  }
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);
46  }
47 }
48 
49 typedef struct
50 {
52  char *operand;
53 } CHKVAL;
54 
55 static bool
56 checkcondition_str(void *checkval, ITEM *val)
57 {
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);
62 
63  cmpptr = (val->flag & LVAR_INCASE) ? ltree_strncasecmp : strncmp;
64  while (tlen > 0)
65  {
66  if (val->flag & LVAR_SUBLEXEME)
67  {
68  if (compare_subnode(level, op, val->length, cmpptr, (val->flag & LVAR_ANYEND)))
69  return true;
70  }
71  else if (
72  (
73  val->length == level->len ||
74  (level->len > val->length && (val->flag & LVAR_ANYEND))
75  ) &&
76  (*cmpptr) (op, level->name, val->length) == 0)
77  return true;
78 
79  tlen--;
80  level = LEVEL_NEXT(level);
81  }
82 
83  return false;
84 }
85 
86 Datum
88 {
90  ltxtquery *query = PG_GETARG_LTXTQUERY(1);
91  CHKVAL chkval;
92  bool result;
93 
94  chkval.node = val;
95  chkval.operand = GETOPERAND(query);
96 
97  result = ltree_execute(
98  GETQUERY(query),
99  &chkval,
100  true,
102  );
103 
104  PG_FREE_IF_COPY(val, 0);
105  PG_FREE_IF_COPY(query, 1);
106  PG_RETURN_BOOL(result);
107 }
108 
109 Datum
111 {
113  PG_GETARG_DATUM(1),
114  PG_GETARG_DATUM(0)
115  ));
116 }
Definition: _int.h:125
int ltree_strncasecmp(const char *a, const char *b, size_t s)
Definition: lquery_op.c:91
bool compare_subnode(ltree_level *t, char *qn, int len, int(*cmpptr)(const char *, const char *, size_t), bool anyend)
Definition: lquery_op.c:53
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: ltree.h:13
#define LVAR_INCASE
Definition: ltree.h:44
uint16 len
Definition: ltree.h:12
#define PG_GETARG_LTXTQUERY(x)
Definition: ltree.h:172
#define LVAR_ANYEND
Definition: ltree.h:43
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:225
uint8 length
Definition: ltree.h:98
return result
Definition: formatting.c:1618
uint8 flag
Definition: ltree.h:96
#define GETQUERY(x)
Definition: _int.h:142
signed int int32
Definition: c.h:256
#define GETOPERAND(x)
Definition: ltree.h:118
int16 type
Definition: _int.h:127
#define PG_GETARG_LTREE(x)
Definition: ltree.h:168
static bool checkcondition_str(void *checkval, ITEM *val)
Definition: ltxtquery_op.c:56
char * operand
Definition: ltxtquery_op.c:52
void check_stack_depth(void)
Definition: postgres.c:3098
int32 val
Definition: _int.h:129
#define LEVEL_NEXT(x)
Definition: ltree.h:17
Datum ltxtq_exec(PG_FUNCTION_ARGS)
Definition: ltxtquery_op.c:87
Definition: ltree.h:19
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:311
uintptr_t Datum
Definition: postgres.h:372
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:305
int16 left
Definition: _int.h:128
#define VAL
Definition: _int.h:147
#define LVAR_SUBLEXEME
Definition: ltree.h:45
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:217
Datum ltxtq_rexec(PG_FUNCTION_ARGS)
Definition: ltxtquery_op.c:110
ltree * node
Definition: ltxtquery_op.c:51
PG_FUNCTION_INFO_V1(ltxtq_exec)
#define LTREE_FIRST(x)
Definition: ltree.h:27
#define PG_FUNCTION_ARGS
Definition: fmgr.h:150
long val
Definition: informix.c:689
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:578
uint16 distance
Definition: ltree.h:99
bool ltree_execute(ITEM *curitem, void *checkval, bool calcnot, bool(*chkcond)(void *checkval, ITEM *val))
Definition: ltxtquery_op.c:20