1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
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. *
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. *
15 ***************************************************************************/
18 #include<CatalogTables.h>
21 #include<PredicateImpl.h>
24 #include<JoinTableImpl.h>
26 DbRetVal
PredicateImpl::evaluateLogical(bool &result
)
28 bool rhsResult
= false, lhsResult
=false;
33 retCode
= lhs
->evaluate(lhsResult
);
34 if (retCode
!= OK
) return ErrInvalidExpr
;
35 }else lhsResult
= true;
38 retCode
= rhs
->evaluate(rhsResult
);
39 if (retCode
!= OK
) return ErrInvalidExpr
;
40 } else rhsResult
= true;
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
);
56 DbRetVal
PredicateImpl::evaluateForHaving(bool &result
, AggTableImpl
*aImpl
, void *aggElement
)
58 bool rhsResult
= false, lhsResult
=false;
63 retCode
= lhs
->evaluateForHaving(lhsResult
, aImpl
, aggElement
);
64 if (retCode
!= OK
) return ErrInvalidExpr
;
65 }else lhsResult
= true;
68 retCode
= rhs
->evaluateForHaving(rhsResult
, aImpl
, aggElement
);
69 if (retCode
!= OK
) return ErrInvalidExpr
;
70 } else rhsResult
= true;
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
);
84 void *val1
= NULL
, *val2
=NULL
;
85 int offset
= aImpl
->getAggOffset(fldName1
, aggType
);
86 val1
= (void*)((char*)aggElement
+ offset
);
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
) {
93 length
= sizeof(double);
94 } else if (aggType
== AGG_COUNT
) {
99 length
= info
->length
;
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
) {
114 AllDataType::convertToDouble(&dVal2
, val2
, type
);
115 result
= AllDataType::compareVal(val1
, &dVal2
, compOp
, typeDouble
, length
);
117 else if (aggType
== AGG_COUNT
) {
119 AllDataType::convertToInt(&dVal2
, val2
, type
);
120 result
= AllDataType::compareVal(val1
, &dVal2
, compOp
, typeInt
, length
);
123 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
, length
);
127 DbRetVal
PredicateImpl::evaluateLogicalForTable(bool &result
, char *tuple
)
129 bool rhsResult
= false, lhsResult
=false;
130 DbRetVal retCode
=OK
;
134 lhs
->evaluateForTable(lhsResult
, tuple
);
135 }else lhsResult
= true;
138 rhs
->evaluateForTable(rhsResult
, tuple
);
139 } else rhsResult
= true;
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
);
155 void PredicateImpl::evaluateForTable(bool &result
, char *tuple
)
157 if (!isNoLeftRight
) {
158 bool rhsResult
= false;
161 rhs
->evaluateForTable(rhsResult
, tuple
);
162 if(rhsResult
== false && OpAnd
== logicalOp
) {//do early return
166 } else rhsResult
= true;
167 bool lhsResult
= false;
170 lhs
->evaluateForTable(lhsResult
, tuple
);
171 }else lhsResult
= true;
174 //Means it involves only Logical operator
175 if (OpAnd
== logicalOp
) {
176 if (lhsResult
&& rhsResult
) result
= true;
177 }else if (OpOr
== logicalOp
) {
178 if (lhsResult
|| rhsResult
) result
= true;
179 }else if (OpNot
== logicalOp
){
180 if (lhsResult
) result
= false; else result
= true;
182 printDebug(DM_Predicate
, "result is %d", result
);
186 //Table null check of condition
190 TableImpl
*tImpl
= (TableImpl
*) table
;
192 lExp
->setTable(tImpl
);
193 lExp
->setTuple(tuple
);
194 val
= lExp
->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(lExp
->getFunctionType()));
197 rExp
->setTable(tImpl
);
198 rExp
->setTuple(tuple
);
199 rval
= rExp
->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(rExp
->getFunctionType()));
202 result
= AllDataType::compareVal(val
, rval
, compOp
, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp
->getFunctionType()),length
);
203 }else if( val
&& operandPtr
!=NULL
){
204 val2
= *(char**)operandPtr
;
205 result
= AllDataType::compareVal(val
, val2
, compOp
, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp
->getFunctionType()),length
);
206 }else if(val
&& (offset2
!= -1 && operand
== NULL
&& operandPtr
== NULL
)){
207 val2
= tuple
+ offset2
;
208 result
= AllDataType::compareVal(val
, val2
, compOp
, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp
->getFunctionType()),length
);
216 TableImpl
*tImpl
= (TableImpl
*) table
;
217 tImpl
->setCurTuple(tuple
);
218 bool isValueNull
= table
->isFldNull(fldPos
);
219 if(compOp
== OpIsNull
)
221 if( (isValueNull
&& isNull
) || (!isValueNull
&& !isNull
) )
233 //the below code works only for single table
234 val1
= tuple
+ offset1
;
235 if(offset2
!= -1 && operand
== NULL
&& operandPtr
== NULL
)
236 val2
= tuple
+ offset2
;
238 //Assumes that fldName2 data type is also same for expr f1 <f2
239 //Note:Perf: Do not change the order below
240 if(operand
== NULL
&& operandPtr
!= NULL
)
242 val2
= *(char**)operandPtr
;
243 if (compOp
== OpLike
) {
244 char *c
= (char *)val2
;
245 //OPT:If LIKE has only %, then no need to evaluate
246 if (*c
== '%' && *(c
+1) == '\0') {result
=true; return;}
247 Util::changeWildcardChar(val2
);
250 } else if (operand
== NULL
&& operandPtr
== NULL
)
253 val2
= tuple
+ offset2
;
254 } else if(operand
!= NULL
&& operandPtr
== NULL
)
256 val2
= (char*) operand
;
257 if (compOp
== OpLike
) {
258 char *c
= (char *)val2
;
259 if (*c
== '%' && *(c
+1) == '\0') {result
=true; return;}
260 Util::changeWildcardChar(val2
);
263 if(operand2
== NULL
&& operand2Ptr
!= NULL
)
265 val3
= *(char**)operand2Ptr
;
266 } else if(operand2
!= NULL
&& operand2Ptr
== NULL
)
268 val3
= (char*) operand2
;
274 //printf(" val1 %d val3 %d\n", *(int*)val1, *(int*)val3);
275 result
= AllDataType::compareVal(val1
, val3
, comp2Op
, type
,length
);
276 if(result
==false) return;
281 //printf(" val1 %d val2 %d\n", *(int*)val1, *(int*)val2);
282 if (type
!= typeVarchar
)
283 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,length
);
285 result
= AllDataType::compareVal((void *) *(long *) val1
, val2
,
286 compOp
, type
,length
);
290 DbRetVal
PredicateImpl::evaluate(bool &result
)
292 if (!isNoLeftRight
) {
293 bool rhsResult
= false, lhsResult
=false;
294 DbRetVal retCode
=OK
;
298 retCode
= lhs
->evaluate(lhsResult
);
299 if (retCode
< OK
) return ErrInvalidExpr
;
300 }else lhsResult
= true;
303 retCode
= rhs
->evaluate(rhsResult
);
304 if (retCode
< OK
) return ErrInvalidExpr
;
305 } else rhsResult
= true;
308 //Means it involves only Logical operator
309 if (OpAnd
== logicalOp
) {
310 if (lhsResult
&& rhsResult
) result
= true;
311 }else if (OpOr
== logicalOp
) {
312 if (lhsResult
|| rhsResult
) result
= true;
313 }else if (OpNot
== logicalOp
){
314 if (lhsResult
) result
= false; else result
= true;
315 if ( ErrNullValues
== retCode
) result
= false;
317 printDebug(DM_Predicate
, "result is %d", result
);
321 //Means it is relational expression
322 //first operand is always field identifier
323 //get the value in the tuple
325 if (dontEvaluate
) {result
= true; return OK
; }
328 //for join node evaluation
329 ListIterator fIter
= projList
->getIterator();
330 JoinProjFieldInfo
*def
;
332 while (fIter
.hasElement())
334 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
335 if (NULL
!= def
->bindBuf
) {
336 if (0 == strcmp(fldName1
, def
->tabFieldName
))
338 val1
= (char*)def
->bindBuf
;
340 length
= def
->length
;
344 printError(ErrNotExists
, "Field not binded %s.%s\n",
345 def
->tableName
, def
->fieldName
);
349 if (operand
== NULL
&& operandPtr
== NULL
)
351 char fieldName2
[IDENTIFIER_LENGTH
];
352 memset(fieldName2
, 0, IDENTIFIER_LENGTH
);
353 Table::getFieldNameAlone(fldName2
, fieldName2
);
356 while (fIter
.hasElement())
358 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
359 if (NULL
!= def
->bindBuf
) {
360 if (0 == strcmp(fldName2
, def
->tabFieldName
))
362 val2
= (char*)def
->bindBuf
;
366 printError(ErrNotExists
, "Field not binded %s.%s\n",
367 def
->tableName
, def
->fieldName
);
373 else if(operand
!= NULL
&& operandPtr
== NULL
)
375 val2
= (char*) operand
;
377 else if(operand
== NULL
&& operandPtr
!= NULL
)
379 val2
= *(char**)operandPtr
;
383 JoinTableImpl
*jTable
= (JoinTableImpl
*) table
;
384 if (jTable
->isFldNullInt(fldName1
) || jTable
->isFldNullInt(fldName2
))
387 return ErrNullValues
;
389 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,
394 printf("FATAL::wrong method call\n");
395 //the below code works only for single table
396 val1
= (char*)tuple
+ offset1
;
397 if(offset2
!= -1 && operand
== NULL
&& operandPtr
== NULL
)
398 val2
= ((char*)tuple
) + offset2
;
400 //Assumes that fldName2 data type is also same for expr f1 <f2
401 //Note:Perf: Do not change the order below
402 if(operand
== NULL
&& operandPtr
!= NULL
)
404 val2
= *(char**)operandPtr
;
406 else if (operand
== NULL
&& operandPtr
== NULL
)
409 val2
= ((char*)tuple
) + offset2
;
411 else if(operand
!= NULL
&& operandPtr
== NULL
)
413 val2
= (char*) operand
;
417 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,length
);