2
* Rewrite routines of query tree
3
* Teodor Sigaev <teodor@stack.net>
10
#include "access/gist.h"
11
#include "access/itup.h"
12
#include "access/rtree.h"
13
#include "utils/array.h"
14
#include "utils/builtins.h"
15
#include "storage/bufpage.h"
28
* make query tree from plain view of query
33
NODE *node = (NODE *) palloc(sizeof(NODE));
36
node->right = node->left = NULL;
39
node->right = maketree(in + 1);
40
if (in->val != (int4) '!')
41
node->left = maketree(in + in->left);
54
plainnode(PLAINTREE * state, NODE * node)
56
if (state->cur == state->len)
59
state->ptr = (ITEM *) repalloc((void *) state->ptr, state->len * sizeof(ITEM));
61
memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(ITEM));
62
if (node->valnode->type == VAL)
64
else if (node->valnode->val == (int4) '!')
66
state->ptr[state->cur].left = 1;
68
plainnode(state, node->right);
72
int4 cur = state->cur;
75
plainnode(state, node->right);
76
state->ptr[cur].left = state->cur - cur;
77
plainnode(state, node->left);
83
* make plain view of tree from 'normal' view of tree
86
plaintree(NODE * root, int4 *len)
92
if (root && (root->valnode->type == VAL || root->valnode->type == OPR))
94
pl.ptr = (ITEM *) palloc(pl.len * sizeof(ITEM));
104
freetree(NODE * node)
109
freetree(node->left);
111
freetree(node->right);
116
* clean tree for ! operator.
117
* It's useful for debug, but in
118
* other case, such view is used with search in index.
119
* Operator ! always return TRUE
122
clean_NOT_intree(NODE * node)
124
if (node->valnode->type == VAL)
127
if (node->valnode->val == (int4) '!')
133
/* operator & or | */
134
if (node->valnode->val == (int4) '|')
136
if ((node->left = clean_NOT_intree(node->left)) == NULL ||
137
(node->right = clean_NOT_intree(node->right)) == NULL)
147
node->left = clean_NOT_intree(node->left);
148
node->right = clean_NOT_intree(node->right);
149
if (node->left == NULL && node->right == NULL)
154
else if (node->left == NULL)
159
else if (node->right == NULL)
170
clean_NOT(ITEM * ptr, int4 *len)
172
NODE *root = maketree(ptr);
174
return plaintree(clean_NOT_intree(root), len);
177
#ifdef V_UNKNOWN /* apparently Windows defines this :-( */
185
* Clean query tree from values which is always in
189
clean_fakeval_intree(NODE * node, char *result)
191
char lresult = V_UNKNOWN,
194
if (node->valnode->type == VAL)
196
else if (node->valnode->type == VALTRUE)
204
if (node->valnode->val == (int4) '!')
206
node->right = clean_fakeval_intree(node->right, &rresult);
209
*result = (rresult == V_TRUE) ? V_FALSE : V_TRUE;
214
else if (node->valnode->val == (int4) '|')
218
node->left = clean_fakeval_intree(node->left, &lresult);
219
node->right = clean_fakeval_intree(node->right, &rresult);
220
if (lresult == V_TRUE || rresult == V_TRUE)
226
else if (lresult == V_FALSE && rresult == V_FALSE)
232
else if (lresult == V_FALSE)
237
else if (rresult == V_FALSE)
248
node->left = clean_fakeval_intree(node->left, &lresult);
249
node->right = clean_fakeval_intree(node->right, &rresult);
250
if (lresult == V_FALSE || rresult == V_FALSE)
256
else if (lresult == V_TRUE && rresult == V_TRUE)
262
else if (lresult == V_TRUE)
267
else if (rresult == V_TRUE)
278
clean_fakeval(ITEM * ptr, int4 *len)
280
NODE *root = maketree(ptr);
281
char result = V_UNKNOWN;
284
resroot = clean_fakeval_intree(root, &result);
285
if (result != V_UNKNOWN)
287
elog(NOTICE, "query contains only stopword(s) or doesn't contain lexeme(s), ignored");
292
return plaintree(resroot, len);