fix for trie index
[csql.git] / src / server / PredicateImpl.cxx
blob747c931e63d5f483a1bd6d8a9fc04fd0a253a78c
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 ***************************************************************************/
16 #include<Table.h>
17 #include<Index.h>
18 #include<CatalogTables.h>
19 #include<Lock.h>
20 #include<Debug.h>
21 #include<PredicateImpl.h>
22 #include<Table.h>
23 #include<TableImpl.h>
24 #include<fnmatch.h>
25 void PredicateImpl::print()
27 printf("FieldName1 %s, FieldName2 %s", fldName1, fldName2);
28 printf("CompOp %d, operand %x operandPtr%x", compOp, operand);
29 printf("lhs %x, rhs %x", lhs, rhs);
33 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op,
34 const char *fName2)
36 strcpy(fldName1, fName1);
37 strcpy(fldName2, fName2);
38 compOp = op;
39 operand = NULL;
40 operandPtr = NULL;
41 lhs = rhs = NULL;
42 logicalOp = OpInvalidLogicalOp;
45 //Operand should be of the same type of the field.This is must
46 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void *opnd)
48 strcpy(fldName1, fName1);
49 if (op == OpLike) {
50 char *c = (char *) opnd;
51 while (*c != '\0') {
52 if (*c == '_') *c = '?';
53 else if(*c == '%') *c = '*';
54 c++;
57 compOp = op;
58 operand = opnd;
59 operandPtr = NULL;
60 lhs = rhs = NULL;
61 logicalOp = OpInvalidLogicalOp;
64 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd)
66 strcpy(fldName1, fName1);
67 compOp = op;
68 operand = NULL;
69 operandPtr = opnd;
70 lhs = rhs = NULL;
71 logicalOp = OpInvalidLogicalOp;
75 void PredicateImpl::setTerm(Predicate *p1, LogicalOp op, Predicate *p2 )
77 if (p2 == NULL && op != OpNot || op == OpNot && p2 != NULL)
79 //TODO::printError
80 return;
82 lhs = (PredicateImpl*)p1;
83 rhs = (PredicateImpl*)p2;
84 logicalOp = op;
85 compOp = OpInvalidComparisionOp;
88 void PredicateImpl::setTable(Table *tbl)
90 if (NULL != lhs)
91 lhs->setTable((TableImpl*)tbl);
92 if (NULL != rhs)
93 rhs->setTable((TableImpl*)tbl);
94 table = (TableImpl*)tbl;
97 void PredicateImpl::setTuple(void *tpl)
99 printf("setTuple called\n");
100 if (NULL != lhs)
101 lhs->setTuple(tpl);
102 if (NULL != rhs)
103 rhs->setTuple(tpl);
104 tuple = tpl;
106 bool PredicateImpl::isSingleTerm()
108 if (NULL == lhs && NULL == rhs) return true; else false;
112 bool PredicateImpl::isNotOrInvolved()
114 bool lhsResult = true, rhsResult = true;
115 if (NULL != lhs)
117 lhsResult = lhs->isNotOrInvolved();
119 if (NULL != rhs)
121 rhsResult = rhs->isNotOrInvolved();
123 if (NULL != lhs)
125 //Means it involves only Logical operator
126 switch(logicalOp)
128 case OpAnd:
129 if (lhsResult || rhsResult) return true; else return false;
130 break;
131 case OpOr:
132 return true;
133 break;
134 case OpNot:
135 default:
136 return true;
137 break;
140 return false;
143 DbRetVal PredicateImpl::evaluate(bool &result)
145 bool rhsResult = false, lhsResult=false;
146 printDebug(DM_Predicate, "Evaluate start logical:%d compOp:%d", logicalOp, compOp);
147 DbRetVal retCode =OK;
148 result = false;
149 if (NULL != lhs)
151 retCode = lhs->evaluate(lhsResult);
152 printDebug(DM_Predicate, "LHS result %d retcode: %d", lhsResult, retCode);
153 if (retCode != OK) return ErrInvalidExpr;
155 if (NULL != rhs)
157 retCode = rhs->evaluate(rhsResult);
158 printDebug(DM_Predicate, "RHS result %d retcode:%d", rhsResult, retCode);
159 if (retCode != OK) return ErrInvalidExpr;
161 if (NULL != lhs)
163 //Means it involves only Logical operator
164 printDebug(DM_Predicate,"Evalute operator %d lhsResult %d : rhsResult %d", logicalOp, lhsResult, rhsResult );
165 switch(logicalOp)
167 case OpAnd:
168 if (lhsResult && rhsResult) result = true;
169 break;
170 case OpOr:
171 if (lhsResult || rhsResult) result = true;
172 break;
173 case OpNot:
174 if (lhsResult) result = false; else result = true;
175 break;
176 default:
177 return ErrInvalidExpr;
180 printDebug(DM_Predicate, "result is %d", result);
181 return OK;
183 printDebug(DM_Predicate, "Evaluating comparision predicate op:%d", compOp);
184 //Means it is relational expression
185 //first operand is always field identifier
186 //get the value in the tuple
187 int offset1, offset2;
188 offset1 = table->getFieldOffset(fldName1);
189 //TODO::do not call getFieldXXX many times, instead get it using getFieldInfo
190 char *val1, *val2 ;
191 //Assumes that fldName2 data type is also same for expr f1 <f2
192 DataType srcType = table->getFieldType(fldName1);
193 val1 = ((char*) tuple) + offset1;
194 if (operand == NULL && operandPtr == NULL)
196 if (fldName2) {
197 offset2 = table->getFieldOffset(fldName2);
198 val2 = ((char*)tuple) + offset2;
201 else if(operand != NULL && operandPtr == NULL)
203 val2 = (char*) operand;
205 else if(operand == NULL && operandPtr != NULL)
207 val2 = *(char**)operandPtr;
209 int ret = 0;
210 printDebug(DM_Predicate, " fldname :%s ", fldName1);
211 if (compOp == OpLike) result = ! fnmatch(val2, val1, 0);
212 else result = AllDataType::compareVal(val1, val2, compOp, srcType,
213 table->getFieldLength(fldName1));
214 return OK;
217 bool PredicateImpl::pointLookupInvolved(const char *fname)
219 bool rhsResult, lhsResult;
220 if (NULL != lhs)
222 lhsResult = lhs->pointLookupInvolved(fname);
224 if (NULL != rhs)
226 rhsResult = rhs->pointLookupInvolved(fname);
228 if (NULL != lhs)
230 //Means it involves only Logical operator
231 switch(logicalOp)
233 case OpAnd:
234 //return lhsResult;
235 if (lhsResult || rhsResult) return true; else return false;
236 break;
237 case OpOr:
238 return false;
239 break;
240 case OpNot:
241 default:
242 return false;
243 break;
246 //Means it is relational expression
247 //first operand is always field identifier
248 if (OpEquals == compOp)
250 //for expressions f1 == f2 use full scan, so return false
251 if(NULL == operand && NULL == operandPtr) return false;
252 if(0 == strcmp(fldName1, fname))
254 return true;
257 return false;
260 void* PredicateImpl::valPtrForIndexField(const char *fname)
262 void *lhsRet, *rhsRet;
263 if (NULL != lhs)
265 lhsRet = lhs->valPtrForIndexField(fname);
267 if (NULL != rhs)
269 rhsRet = rhs->valPtrForIndexField(fname);
271 if (NULL != lhs)
273 //Means it involves only Logical operator
274 if ( lhsRet != NULL) return lhsRet;
275 if ( rhsRet != NULL) return rhsRet;
277 //Means it is relational expression
278 //first operand is always field identifier
279 if (OpEquals == compOp)
281 if(0 == strcmp(fldName1, fname))
283 if (operand) return operand; else return *(void**)operandPtr;
286 return NULL;