code reorg
[csql.git] / src / storage / PredicateEvalImpl.cxx
blobbcf7bd5f44e23b816f351917f113be77a92ad49d
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<JoinTableImpl.h>
25 #include<Util.h>
26 DbRetVal PredicateImpl::evaluateLogical(bool &result)
28 bool rhsResult = false, lhsResult=false;
29 DbRetVal retCode =OK;
30 result = false;
31 if (NULL != lhs)
33 retCode = lhs->evaluate(lhsResult);
34 if (retCode != OK) return ErrInvalidExpr;
35 }else lhsResult = true;
36 if (NULL != rhs)
38 retCode = rhs->evaluate(rhsResult);
39 if (retCode != OK) return ErrInvalidExpr;
40 } else rhsResult = true;
41 if (NULL != lhs)
43 //Means it involves only Logical operator
44 if (OpAnd == logicalOp) {
45 if (lhsResult && rhsResult) result = true;
46 }else if (OpOr == logicalOp) {
47 if (lhsResult || rhsResult) result = true;
48 }else if (OpNot == logicalOp){
49 if (lhsResult) result = false; else result = true;
51 printDebug(DM_Predicate, "result is %d", result);
53 return OK;
56 DbRetVal PredicateImpl::evaluateForHaving(bool &result, AggTableImpl *aImpl, void *aggElement)
58 bool rhsResult = false, lhsResult=false;
59 DbRetVal retCode =OK;
60 result = false;
61 if (NULL != lhs)
63 retCode = lhs->evaluateForHaving(lhsResult, aImpl, aggElement);
64 if (retCode != OK) return ErrInvalidExpr;
65 }else lhsResult = true;
66 if (NULL != rhs)
68 retCode = rhs->evaluateForHaving(rhsResult, aImpl, aggElement);
69 if (retCode != OK) return ErrInvalidExpr;
70 } else rhsResult = true;
71 if (NULL != lhs)
73 if (OpAnd == logicalOp) {
74 if (lhsResult && rhsResult) result = true;
75 }else if (OpOr == logicalOp) {
76 if (lhsResult || rhsResult) result = true;
77 }else if (OpNot == logicalOp){
78 if (lhsResult) result = false; else result = true;
80 printDebug(DM_Predicate, "result is %d", result);
81 return OK;
84 void *val1 = NULL, *val2 =NULL;
85 int offset = aImpl->getAggOffset(fldName1, aggType);
86 val1 = (void*)((char*)aggElement + offset);
87 if (!isBindBufSet) {
88 //sets the type and length when it is called first time
89 FieldInfo *info = new FieldInfo();
90 DbRetVal rv = aImpl->getFieldInfo(fldName1, info);
91 if (aggType == AGG_AVG) {
92 type = typeDouble;
93 length = sizeof(double);
94 } else if (aggType == AGG_COUNT) {
95 type = typeInt;
96 length = sizeof(int);
97 } else {
98 type = info->type;
99 length = info->length;
101 delete info;
102 isBindBufSet = true;
104 if(operand != NULL && operandPtr == NULL)
106 val2 = (char*) operand;
108 else if(operand == NULL && operandPtr != NULL)
110 val2 = *(char**)operandPtr;
112 if (aggType == AGG_AVG) {
113 double dVal2 = 0;
114 AllDataType::convertToDouble(&dVal2, val2, type);
115 result = AllDataType::compareVal(val1, &dVal2, compOp, typeDouble, length);
117 else if (aggType == AGG_COUNT) {
118 int dVal2 = 0;
119 AllDataType::convertToInt(&dVal2, val2, type);
120 result = AllDataType::compareVal(val1, &dVal2, compOp, typeInt, length);
122 else
123 result = AllDataType::compareVal(val1, val2, compOp, type, length);
124 return OK;
127 DbRetVal PredicateImpl::evaluateLogicalForTable(bool &result, char *tuple)
129 bool rhsResult = false, lhsResult=false;
130 DbRetVal retCode =OK;
131 result = false;
132 if (NULL != lhs)
134 lhs->evaluateForTable(lhsResult, tuple);
135 }else lhsResult = true;
136 if (NULL != rhs)
138 rhs->evaluateForTable(rhsResult, tuple);
139 } else rhsResult = true;
140 if (NULL != lhs)
142 //Means it involves only Logical operator
143 if (OpAnd == logicalOp) {
144 if (lhsResult && rhsResult) result = true;
145 }else if (OpOr == logicalOp) {
146 if (lhsResult || rhsResult) result = true;
147 }else if (OpNot == logicalOp){
148 if (lhsResult) result = false; else result = true;
150 printDebug(DM_Predicate, "result is %d", result);
152 return OK;
154 void PredicateImpl::evaluateForTable(bool &result, char *tuple)
156 if (!isNoLeftRight) {
157 bool rhsResult = false;
158 if (NULL != rhs)
160 rhs->evaluateForTable(rhsResult, tuple);
161 if(rhsResult == false && OpAnd == logicalOp) {//do early return
162 result = false;
163 return;
165 } else rhsResult = true;
166 bool lhsResult = false;
167 if (NULL != lhs)
169 lhs->evaluateForTable(lhsResult, tuple);
170 }else lhsResult = true;
171 if (NULL != lhs)
173 //Means it involves only Logical operator
174 if (OpAnd == logicalOp) {
175 if (lhsResult && rhsResult) result = true;
176 }else if (OpOr == logicalOp) {
177 if (lhsResult || rhsResult) result = true;
178 }else if (OpNot == logicalOp){
179 if (lhsResult) result = false; else result = true;
181 printDebug(DM_Predicate, "result is %d", result);
182 return ;
185 //Table null check of condition
186 if(lExp || rExp){
187 void* val=NULL;
188 void* rval = NULL;
189 TableImpl *tImpl = (TableImpl*) table;
190 if(lExp){
191 lExp->setTable(tImpl);
192 lExp->setTuple(tuple);
193 val = lExp->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(lExp->getFunctionType()));
195 if(rExp) {
196 rExp->setTable(tImpl);
197 rExp->setTuple(tuple);
198 rval = rExp->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(rExp->getFunctionType()));
200 if( val && rval){
201 result = AllDataType::compareVal(val, rval, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
202 }else if( val && operandPtr!=NULL){
203 val2 = *(char**)operandPtr;
204 result = AllDataType::compareVal(val, val2, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
205 }else if(val && (offset2 != -1 && operand == NULL && operandPtr == NULL)){
206 val2 = tuple + offset2;
207 result = AllDataType::compareVal(val, val2, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
208 }else{
209 result =false;
212 return;
214 if (isNullable) {
215 TableImpl *tImpl = (TableImpl*) table;
216 tImpl->setCurTuple(tuple);
217 bool isValueNull = table->isFldNull(fldPos);
218 if(compOp == OpIsNull)
220 if( (isValueNull && isNull) || (!isValueNull && !isNull) )
221 result = true;
222 else
223 result = false;
224 return;
226 if(isValueNull)
228 result=false;
229 return;
232 //the below code works only for single table
233 val1= tuple + offset1;
234 if(offset2 != -1 && operand == NULL && operandPtr == NULL)
235 val2 = tuple + offset2;
236 if (!isBindBufSet) {
237 //Assumes that fldName2 data type is also same for expr f1 <f2
238 //Note:Perf: Do not change the order below
239 if(operand == NULL && operandPtr != NULL)
241 val2 = *(char**)operandPtr;
242 if (compOp == OpLike) {
243 char *c = (char *)val2;
244 //OPT:If LIKE has only %, then no need to evaluate
245 if (*c == '%' && *(c+1) == '\0') {result=true; return;}
246 Util::changeWildcardChar(val2);
249 } else if (operand == NULL && operandPtr == NULL)
251 if(offset2 != -1)
252 val2 = tuple + offset2;
253 } else if(operand != NULL && operandPtr == NULL)
255 val2 = (char*) operand;
256 if (compOp == OpLike) {
257 char *c = (char *)val2;
258 if (*c == '%' && *(c+1) == '\0') {result=true; return;}
259 Util::changeWildcardChar(val2);
262 if(operand2 == NULL && operand2Ptr != NULL)
264 val3 = *(char**)operand2Ptr;
265 } else if(operand2 != NULL && operand2Ptr == NULL)
267 val3 = (char*) operand2;
269 isBindBufSet = true;
271 result = true;
272 if(val3) {
273 //printf(" val1 %d val3 %d\n", *(int*)val1, *(int*)val3);
274 result = AllDataType::compareVal(val1, val3, comp2Op, type,length);
275 if(result==false) return;
277 if (isPushedDown) {
278 return;
280 //printf(" val1 %d val2 %d\n", *(int*)val1, *(int*)val2);
281 if (type != typeVarchar)
282 result = AllDataType::compareVal(val1, val2, compOp, type,length);
283 else
284 result = AllDataType::compareVal((void *) *(long *) val1, val2,
285 compOp, type,length);
286 return;
289 DbRetVal PredicateImpl::evaluate(bool &result)
291 if (!isNoLeftRight) {
292 bool rhsResult = false, lhsResult=false;
293 DbRetVal retCode =OK;
294 result = false;
295 if (NULL != lhs)
297 retCode = lhs->evaluate(lhsResult);
298 if (retCode < OK) return ErrInvalidExpr;
299 }else lhsResult = true;
300 if (NULL != rhs)
302 retCode = rhs->evaluate(rhsResult);
303 if (retCode < OK) return ErrInvalidExpr;
304 } else rhsResult = true;
305 if (NULL != lhs)
307 //Means it involves only Logical operator
308 if (OpAnd == logicalOp) {
309 if (lhsResult && rhsResult) result = true;
310 }else if (OpOr == logicalOp) {
311 if (lhsResult || rhsResult) result = true;
312 }else if (OpNot == logicalOp){
313 if (lhsResult) result = false; else result = true;
314 if ( ErrNullValues == retCode) result = false;
316 printDebug(DM_Predicate, "result is %d", result);
317 return OK;
320 //Means it is relational expression
321 //first operand is always field identifier
322 //get the value in the tuple
323 if (projList) {
324 if (dontEvaluate) {result= true; return OK; }
325 if (!isBindBufSet)
327 //for join node evaluation
328 ListIterator fIter = projList->getIterator();
329 JoinProjFieldInfo *def;
330 //char *val1, *val2;
331 while (fIter.hasElement())
333 def = (JoinProjFieldInfo*) fIter.nextElement();
334 if (NULL != def->bindBuf) {
335 if (0 == strcmp(fldName1, def->tabFieldName))
337 val1 = (char*)def->bindBuf;
338 type = def->type;
339 length = def->length;
340 break;
342 }else{
343 printError(ErrNotExists, "Field not binded %s.%s\n",
344 def->tableName, def->fieldName);
345 return ErrNotExists;
348 if (operand == NULL && operandPtr == NULL)
350 char fieldName2[IDENTIFIER_LENGTH];
351 memset(fieldName2, 0, IDENTIFIER_LENGTH);
352 Table::getFieldNameAlone(fldName2, fieldName2);
353 if (fieldName2) {
354 fIter.reset();
355 while (fIter.hasElement())
357 def = (JoinProjFieldInfo*) fIter.nextElement();
358 if (NULL != def->bindBuf) {
359 if (0 == strcmp(fldName2, def->tabFieldName))
361 val2 = (char*)def->bindBuf;
362 break;
364 }else{
365 printError(ErrNotExists, "Field not binded %s.%s\n",
366 def->tableName, def->fieldName);
367 return ErrNotExists;
372 else if(operand != NULL && operandPtr == NULL)
374 val2 = (char*) operand;
376 else if(operand == NULL && operandPtr != NULL)
378 val2 = *(char**)operandPtr;
380 isBindBufSet = true;
382 JoinTableImpl *jTable = (JoinTableImpl*) table;
383 if (jTable->isFldNullInt(fldName1) || jTable->isFldNullInt(fldName2))
385 result=false;
386 return ErrNullValues;
388 result = AllDataType::compareVal(val1, val2, compOp, type,
389 length);
390 return OK;
393 printf("PRABA::wrong method call\n");
394 //the below code works only for single table
395 val1= (char*)tuple + offset1;
396 if(offset2 != -1 && operand == NULL && operandPtr == NULL)
397 val2 = ((char*)tuple) + offset2;
398 if (!isBindBufSet) {
399 //Assumes that fldName2 data type is also same for expr f1 <f2
400 //Note:Perf: Do not change the order below
401 if(operand == NULL && operandPtr != NULL)
403 val2 = *(char**)operandPtr;
405 else if (operand == NULL && operandPtr == NULL)
407 if(offset2 != -1)
408 val2 = ((char*)tuple) + offset2;
410 else if(operand != NULL && operandPtr == NULL)
412 val2 = (char*) operand;
414 isBindBufSet = true;
416 result = AllDataType::compareVal(val1, val2, compOp, type,length);
417 return OK;