2 * Rewrite routines of query tree
3 * Teodor Sigaev <teodor@sigaev.ru>
10 #include "utils/builtins.h"
13 #include "query_cleanup.h"
23 * make query tree from plain view of query
28 NODE *node = (NODE *) palloc(sizeof(NODE));
31 node->right = node->left = NULL;
34 node->right = maketree(in + 1);
35 if (in->val != (int4) '!')
36 node->left = maketree(in + in->left);
49 plainnode(PLAINTREE * state, NODE * node)
51 if (state->cur == state->len)
54 state->ptr = (ITEM *) repalloc((void *) state->ptr, state->len * sizeof(ITEM));
56 memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(ITEM));
57 if (node->valnode->type == VAL)
59 else if (node->valnode->val == (int4) '!')
61 state->ptr[state->cur].left = 1;
63 plainnode(state, node->right);
67 int4 cur = state->cur;
70 plainnode(state, node->right);
71 state->ptr[cur].left = state->cur - cur;
72 plainnode(state, node->left);
78 * make plain view of tree from 'normal' view of tree
81 plaintree(NODE * root, int4 *len)
87 if (root && (root->valnode->type == VAL || root->valnode->type == OPR))
89 pl.ptr = (ITEM *) palloc(pl.len * sizeof(ITEM));
104 freetree(node->left);
106 freetree(node->right);
111 * clean tree for ! operator.
112 * It's usefull for debug, but in
113 * other case, such view is used with search in index.
114 * Operator ! always return TRUE
117 clean_NOT_intree(NODE * node)
119 if (node->valnode->type == VAL)
122 if (node->valnode->val == (int4) '!')
128 /* operator & or | */
129 if (node->valnode->val == (int4) '|')
131 if ((node->left = clean_NOT_intree(node->left)) == NULL ||
132 (node->right = clean_NOT_intree(node->right)) == NULL)
142 node->left = clean_NOT_intree(node->left);
143 node->right = clean_NOT_intree(node->right);
144 if (node->left == NULL && node->right == NULL)
149 else if (node->left == NULL)
154 else if (node->right == NULL)
165 clean_NOT_v2(ITEM * ptr, int4 *len)
167 NODE *root = maketree(ptr);
169 return plaintree(clean_NOT_intree(root), len);
173 #ifdef V_UNKNOWN /* exists in Windows headers */
183 * Clean query tree from values which is always in
187 clean_fakeval_intree(NODE * node, char *result)
189 char lresult = V_UNKNOWN,
192 if (node->valnode->type == VAL)
194 else if (node->valnode->type == VALSTOP)
202 if (node->valnode->val == (int4) '!')
204 node->right = clean_fakeval_intree(node->right, &rresult);
216 node->left = clean_fakeval_intree(node->left, &lresult);
217 node->right = clean_fakeval_intree(node->right, &rresult);
218 if (lresult == V_STOP && rresult == V_STOP)
224 else if (lresult == V_STOP)
229 else if (rresult == V_STOP)
240 clean_fakeval_v2(ITEM * ptr, int4 *len)
242 NODE *root = maketree(ptr);
243 char result = V_UNKNOWN;
246 resroot = clean_fakeval_intree(root, &result);
247 if (result != V_UNKNOWN)
249 elog(NOTICE, "query contains only stopword(s) or doesn't contain lexeme(s), ignored");
254 return plaintree(resroot, len);