statement caching modifications and cache stmt display
[csql.git] / src / storage / PredicateImpl.cxx
blob65550ba04b702caf25a283ea3f039b682f56434f
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 static char aggNames[][10] =
28 "MIN", "MAX", "SUM", "AVG", "COUNT", ""
31 PredicateImpl::~PredicateImpl()
33 // if (lhs) {delete lhs; lhs = NULL; }
34 // if (rhs) { delete rhs; rhs = NULL; }
36 void PredicateImpl::print(int space)
38 char spaceBuf[IDENTIFIER_LENGTH];
39 memset(spaceBuf, 32, IDENTIFIER_LENGTH);
40 spaceBuf[space] = '\0';
42 printf("%s <PREDICATE>\n", spaceBuf);
43 if (0 != strcmp(fldName1, "")) {
44 if (aggType == AGG_UNKNOWN)
45 printf("%s <FieldName1> %s </FieldName1>\n", spaceBuf, fldName1);
46 else
47 printf("%s <FieldName1> %s(%s) </FieldName1>\n", spaceBuf,
48 aggNames[aggType-1], fldName1);
50 if (0 != strcmp(fldName2, ""))
51 printf("%s <FieldName2> %s </FieldName2>\n", spaceBuf, fldName2);
52 if (compOp != OpInvalidComparisionOp)
53 printf("%s <CompOp> %s </CompOp>\n", spaceBuf, CompOpNames[compOp]);
54 if (logicalOp != OpInvalidLogicalOp)
55 printf("%s <LogOp> %s </LogOp>\n", spaceBuf, LogOpNames[logicalOp]);
56 if (operand) printf("%s <Operand> VALUE </Operand>\n", spaceBuf);
57 if (operandPtr) printf("%s <OperandPtr> VALUE </OperandPtr>\n", spaceBuf);
58 if (comp2Op != OpInvalidComparisionOp)
59 printf("%s <Comp2Op> %s </Comp2Op>\n", spaceBuf, CompOpNames[comp2Op]);
60 if (operand2) printf("%s <Operand2> VALUE </Operand2>\n", spaceBuf);
61 if (operand2Ptr) printf("%s <Operand2Ptr> VALUE </Operand2Ptr>\n", spaceBuf);
62 //TEMP
63 //printf("<ISPUSHEDDOWN> %d </ISPUSHEDDOWN>\n", isPushedDown);
65 if (lhs) {
66 printf("%s <PRED-LEFT>\n", spaceBuf);
67 lhs->print(space+2);
68 printf("%s </PRED-LEFT>\n", spaceBuf);
70 if (rhs)
72 printf("%s <PRED-RIGHT>\n", spaceBuf);
73 rhs->print(space+2);
74 printf("%s </PRED-RIGHT>\n", spaceBuf);
76 printf("%s </PREDICATE>\n", spaceBuf);
80 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op,
81 const char *fName2)
83 strcpy(fldName1, fName1);
84 strcpy(fldName2, fName2);
85 compOp = op;
86 operand = NULL;
87 operandPtr = NULL;
88 lhs = rhs = NULL;
89 parent = NULL;
90 logicalOp = OpInvalidLogicalOp;
91 comp2Op = OpInvalidComparisionOp;
92 operand2 =NULL;
93 operand2Ptr = NULL;
96 //Operand should be of the same type of the field.This is must
97 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void *opnd)
99 strcpy(fldName1, fName1);
100 if (op == OpLike)
102 char *c = (char *) opnd;
103 while (*c != '\0')
105 if (*c == '_') *c = '?';
106 else if(*c == '%') *c = '*';
107 c++;
110 compOp = op;
111 operand = opnd;
112 operandPtr = NULL;
113 lhs = rhs = NULL;
114 parent = NULL;
115 logicalOp = OpInvalidLogicalOp;
116 comp2Op = OpInvalidComparisionOp;
117 operand2 =NULL;
118 operand2Ptr = NULL;
120 void PredicateImpl::setTerm(Expression *exp, ComparisionOp op, void **opnd)
122 compOp = op;
123 lhs = rhs = NULL;
124 operandPtr = opnd;
125 operand = NULL;
126 logicalOp = OpInvalidLogicalOp;
127 comp2Op = OpInvalidComparisionOp;
128 operand2 =NULL;
129 operand2Ptr = NULL;
130 lExp = exp;
132 void PredicateImpl::setTerm(Expression *exp1, ComparisionOp op, Expression *exp2)
134 compOp = op;
135 lhs = rhs = NULL;
136 operandPtr = NULL;
137 operand = NULL;
138 logicalOp = OpInvalidLogicalOp;
139 comp2Op = OpInvalidComparisionOp;
140 operand2 =NULL;
141 operand2Ptr = NULL;
142 lExp = exp1;
143 rExp = exp2;
145 void PredicateImpl::setTerm(Expression *exp, ComparisionOp op, const char *fName2 )
147 strcpy(fldName2, fName2);
148 compOp = op;
149 operand = NULL;
150 operandPtr = NULL;
151 lhs = rhs = NULL;
152 parent = NULL;
153 logicalOp = OpInvalidLogicalOp;
154 comp2Op = OpInvalidComparisionOp;
155 operand2 =NULL;
156 operand2Ptr = NULL;
157 lExp = exp;
158 return;
161 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op,bool nullFlag)
163 strcpy(fldName1, fName1);
164 compOp = op;
165 isNull = nullFlag;
166 lhs = rhs = NULL;
167 operandPtr = NULL;
168 operand = NULL;
169 logicalOp = OpInvalidLogicalOp;
170 comp2Op = OpInvalidComparisionOp;
171 operand2 =NULL;
172 operand2Ptr = NULL;
175 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd)
177 strcpy(fldName1, fName1);
178 compOp = op;
179 operand = NULL;
180 operandPtr = opnd;
181 lhs = rhs = NULL;
182 parent = NULL;
183 logicalOp = OpInvalidLogicalOp;
184 comp2Op = OpInvalidComparisionOp;
185 operand2 =NULL;
186 operand2Ptr = NULL;
188 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd, AggType aType)
190 strcpy(fldName1, fName1);
191 compOp = op;
192 operand = NULL;
193 operandPtr = opnd;
194 lhs = rhs = NULL;
195 parent = NULL;
196 aggType = aType;
197 logicalOp = OpInvalidLogicalOp;
198 comp2Op = OpInvalidComparisionOp;
199 operand2 =NULL;
200 operand2Ptr = NULL;
203 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd,
204 ComparisionOp op2, void **opnd2)
206 strcpy(fldName1, fName1);
207 compOp = op;
208 operand = NULL;
209 operandPtr = opnd;
210 lhs = rhs = NULL;
211 parent = NULL;
212 logicalOp = OpInvalidLogicalOp;
214 comp2Op = op2;
215 operand2=NULL;
216 operand2Ptr = opnd2;
219 void PredicateImpl::setParent(PredicateImpl *pImpl)
221 //if (parent != NULL) printf("Parent already set\n");
222 parent = pImpl;
223 return;
225 void PredicateImpl::setTerm(Predicate *p1, LogicalOp op, Predicate *p2 )
227 if (p2 == NULL && op != OpNot || op == OpNot && p2 != NULL)
229 //TODO::printError
230 printError(ErrBadArg, "Wrong argument passed\n");
231 return;
233 lhs = (PredicateImpl*)p1;
234 rhs = (PredicateImpl*)p2;
235 logicalOp = op;
236 compOp = OpInvalidComparisionOp;
237 if (lhs != NULL) lhs->setParent(this);
238 if (rhs != NULL) rhs->setParent(this);
239 return;
242 void PredicateImpl::setTable(Table *tbl)
244 if (NULL != lhs)
245 lhs->setTable(tbl);
246 if (NULL != rhs)
247 rhs->setTable(tbl);
248 table = tbl;
250 void PredicateImpl::setIfNoLeftRight()
252 if (NULL != lhs)
253 lhs->setIfNoLeftRight();
254 if (NULL != rhs)
255 rhs->setIfNoLeftRight();
256 if(NULL == lhs && NULL == rhs) isNoLeftRight=true;
257 return;
260 void PredicateImpl::setTuple(void *tpl)
262 if (isNoLeftRight) {
263 tuple=tpl;
264 return;
266 if (NULL != lhs)
267 lhs->setTuple(tpl);
268 if (NULL != rhs)
269 rhs->setTuple(tpl);
270 tuple = tpl;
272 void PredicateImpl::setProjectionList(List *lst)
274 if (NULL != lhs)
275 lhs->setProjectionList(lst);
276 if (NULL != rhs)
277 rhs->setProjectionList(lst);
278 projList = lst;
279 isBindBufSet = false;
281 bool PredicateImpl::isSingleTerm()
283 if (NULL == lhs && NULL == rhs && comp2Op == OpInvalidComparisionOp)
284 return true;
285 return false;
288 bool PredicateImpl::appendIfSameFld(char *fName, ComparisionOp op, void *buf)
290 char fieldName1[IDENTIFIER_LENGTH];
291 Table::getFieldNameAlone(fldName1, fieldName1);
292 if (strcmp(fName,fieldName1) == 0)
294 printDebug(DM_Predicate, "Field name matched");
296 //switching so that in case of joins, first other conditions are
297 //evaluated first and then matching tuples for join is evaluated
298 //otherwise it may give wrong result set
299 if (operand) {operand2 = operand; operand2Ptr = NULL; }
300 if (operandPtr) {operand2Ptr = operandPtr; operand2 = NULL; }
301 comp2Op = compOp;
302 compOp = op;
303 operand = buf;
304 operandPtr = NULL;
306 comp2Op = op;
307 operand2 = buf;
309 return true;
311 return false;
313 bool PredicateImpl::isIsNullInvolved()
315 bool lhsResult = true, rhsResult = true;
316 if (NULL != lhs)
318 lhsResult = lhs->isIsNullInvolved();
320 if (NULL != rhs)
322 rhsResult = rhs->isIsNullInvolved();
324 if (NULL != lhs)
326 if (lhsResult || rhsResult) return true;
327 if(compOp == isNull) return true;
329 return false;
331 bool PredicateImpl::isNotOrInvolved()
333 bool lhsResult = true, rhsResult = true;
334 if (NULL != lhs)
336 lhsResult = lhs->isNotOrInvolved();
338 if (NULL != rhs)
340 rhsResult = rhs->isNotOrInvolved();
342 if (NULL != lhs)
344 //Means it involves only Logical operator
345 switch(logicalOp)
347 case OpAnd:
348 if (lhsResult || rhsResult) return true; else return false;
349 break;
350 case OpOr:
351 return true;
352 break;
353 case OpNot:
354 default:
355 return true;
356 break;
359 return false;
362 DbRetVal PredicateImpl::evaluateLogical(bool &result)
364 bool rhsResult = false, lhsResult=false;
365 DbRetVal retCode =OK;
366 result = false;
367 if (NULL != lhs)
369 retCode = lhs->evaluate(lhsResult);
370 if (retCode != OK) return ErrInvalidExpr;
371 }else lhsResult = true;
372 if (NULL != rhs)
374 retCode = rhs->evaluate(rhsResult);
375 if (retCode != OK) return ErrInvalidExpr;
376 } else rhsResult = true;
377 if (NULL != lhs)
379 //Means it involves only Logical operator
380 if (OpAnd == logicalOp) {
381 if (lhsResult && rhsResult) result = true;
382 }else if (OpOr == logicalOp) {
383 if (lhsResult || rhsResult) result = true;
384 }else if (OpNot == logicalOp){
385 if (lhsResult) result = false; else result = true;
387 printDebug(DM_Predicate, "result is %d", result);
389 return OK;
392 DbRetVal PredicateImpl::evaluateForHaving(bool &result, AggTableImpl *aImpl, void *aggElement)
394 bool rhsResult = false, lhsResult=false;
395 DbRetVal retCode =OK;
396 result = false;
397 if (NULL != lhs)
399 retCode = lhs->evaluateForHaving(lhsResult, aImpl, aggElement);
400 if (retCode != OK) return ErrInvalidExpr;
401 }else lhsResult = true;
402 if (NULL != rhs)
404 retCode = rhs->evaluateForHaving(rhsResult, aImpl, aggElement);
405 if (retCode != OK) return ErrInvalidExpr;
406 } else rhsResult = true;
407 if (NULL != lhs)
409 if (OpAnd == logicalOp) {
410 if (lhsResult && rhsResult) result = true;
411 }else if (OpOr == logicalOp) {
412 if (lhsResult || rhsResult) result = true;
413 }else if (OpNot == logicalOp){
414 if (lhsResult) result = false; else result = true;
416 printDebug(DM_Predicate, "result is %d", result);
417 return OK;
420 void *val1 = NULL, *val2 =NULL;
421 int offset = aImpl->getAggOffset(fldName1, aggType);
422 val1 = (void*)((char*)aggElement + offset);
423 if (!isBindBufSet) {
424 //sets the type and length when it is called first time
425 FieldInfo *info = new FieldInfo();
426 DbRetVal rv = aImpl->getFieldInfo(fldName1, info);
427 if (aggType == AGG_AVG) {
428 type = typeDouble;
429 length = sizeof(double);
430 } else if (aggType == AGG_COUNT) {
431 type = typeInt;
432 length = sizeof(int);
433 } else {
434 type = info->type;
435 length = info->length;
437 delete info;
438 isBindBufSet = true;
440 if(operand != NULL && operandPtr == NULL)
442 val2 = (char*) operand;
444 else if(operand == NULL && operandPtr != NULL)
446 val2 = *(char**)operandPtr;
448 if (aggType == AGG_AVG) {
449 double dVal2 = 0;
450 AllDataType::convertToDouble(&dVal2, val2, type);
451 result = AllDataType::compareVal(val1, &dVal2, compOp, typeDouble, length);
453 else if (aggType == AGG_COUNT) {
454 int dVal2 = 0;
455 AllDataType::convertToInt(&dVal2, val2, type);
456 result = AllDataType::compareVal(val1, &dVal2, compOp, typeInt, length);
458 else
459 result = AllDataType::compareVal(val1, val2, compOp, type, length);
460 return OK;
463 DbRetVal PredicateImpl::evaluateLogicalForTable(bool &result, char *tuple)
465 bool rhsResult = false, lhsResult=false;
466 DbRetVal retCode =OK;
467 result = false;
468 if (NULL != lhs)
470 lhs->evaluateForTable(lhsResult, tuple);
471 }else lhsResult = true;
472 if (NULL != rhs)
474 rhs->evaluateForTable(rhsResult, tuple);
475 } else rhsResult = true;
476 if (NULL != lhs)
478 //Means it involves only Logical operator
479 if (OpAnd == logicalOp) {
480 if (lhsResult && rhsResult) result = true;
481 }else if (OpOr == logicalOp) {
482 if (lhsResult || rhsResult) result = true;
483 }else if (OpNot == logicalOp){
484 if (lhsResult) result = false; else result = true;
486 printDebug(DM_Predicate, "result is %d", result);
488 return OK;
490 void PredicateImpl::evaluateForTable(bool &result, char *tuple)
492 if (!isNoLeftRight) {
493 bool rhsResult = false;
494 if (NULL != rhs)
496 rhs->evaluateForTable(rhsResult, tuple);
497 if(rhsResult == false && OpAnd == logicalOp) {//do early return
498 return;
500 } else rhsResult = true;
501 bool lhsResult = false;
502 if (NULL != lhs)
504 lhs->evaluateForTable(lhsResult, tuple);
505 }else lhsResult = true;
506 if (NULL != lhs)
508 //Means it involves only Logical operator
509 if (OpAnd == logicalOp) {
510 if (lhsResult && rhsResult) result = true;
511 }else if (OpOr == logicalOp) {
512 if (lhsResult || rhsResult) result = true;
513 }else if (OpNot == logicalOp){
514 if (lhsResult) result = false; else result = true;
516 printDebug(DM_Predicate, "result is %d", result);
517 return ;
520 //Table null check of condition
521 if(lExp || rExp){
522 void* val=NULL;
523 void* rval = NULL;
524 TableImpl *tImpl = (TableImpl*) table;
525 if(lExp){
526 lExp->setTable(tImpl);
527 lExp->setTuple(tuple);
528 val = lExp->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(lExp->getFunctionType()));
530 if(rExp) {
531 rExp->setTable(tImpl);
532 rExp->setTuple(tuple);
533 rval = rExp->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(rExp->getFunctionType()));
535 if( val && rval){
536 result = AllDataType::compareVal(val, rval, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
537 }else if( val && operandPtr!=NULL){
538 val2 = *(char**)operandPtr;
539 result = AllDataType::compareVal(val, val2, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
540 }else if(val && (offset2 != -1 && operand == NULL && operandPtr == NULL)){
541 val2 = tuple + offset2;
542 result = AllDataType::compareVal(val, val2, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
543 }else{
544 result =false;
547 return;
549 if (isNullable) {
550 TableImpl *tImpl = (TableImpl*) table;
551 tImpl->setCurTuple(tuple);
552 bool isValueNull = table->isFldNull(fldPos);
553 if(compOp == OpIsNull)
555 if( (isValueNull && isNull) || (!isValueNull && !isNull) )
556 result = true;
557 else
558 result = false;
559 return;
561 if(isValueNull)
563 result=false;
564 return;
567 //the below code works only for single table
568 val1= tuple + offset1;
569 if(offset2 != -1 && operand == NULL && operandPtr == NULL)
570 val2 = tuple + offset2;
571 if (!isBindBufSet) {
572 //Assumes that fldName2 data type is also same for expr f1 <f2
573 //Note:Perf: Do not change the order below
574 if(operand == NULL && operandPtr != NULL)
576 val2 = *(char**)operandPtr;
577 if (compOp == OpLike) {
578 char *c = (char *)val2;
579 //OPT:If LIKE has only %, then no need to evaluate
580 if (*c == '%' && *(c+1) == '\0') {result=true; return;}
581 Util::changeWildcardChar(val2);
584 } else if (operand == NULL && operandPtr == NULL)
586 if(offset2 != -1)
587 val2 = tuple + offset2;
588 } else if(operand != NULL && operandPtr == NULL)
590 val2 = (char*) operand;
591 if (compOp == OpLike) {
592 char *c = (char *)val2;
593 if (*c == '%' && *(c+1) == '\0') {result=true; return;}
594 Util::changeWildcardChar(val2);
597 if(operand2 == NULL && operand2Ptr != NULL)
599 val3 = *(char**)operand2Ptr;
600 } else if(operand2 != NULL && operand2Ptr == NULL)
602 val3 = (char*) operand2;
604 isBindBufSet = true;
606 result = true;
607 if(val3) {
608 //printf(" val1 %d val3 %d\n", *(int*)val1, *(int*)val3);
609 result = AllDataType::compareVal(val1, val3, comp2Op, type,length);
610 if(result==false) return;
612 if (isPushedDown) {
613 return;
615 //printf(" val1 %d val2 %d\n", *(int*)val1, *(int*)val2);
616 if (type != typeVarchar)
617 result = AllDataType::compareVal(val1, val2, compOp, type,length);
618 else result = AllDataType::compareVal((void *) *(long *) val1, val2,
619 compOp, type,length);
620 //if (!result && val3) AllDataType::copyVal(val3,
621 return;
623 void* PredicateImpl::getValIfPointLookupOnInt(int &offset)
624 { //perf opt
625 if (NULL != lhs && NULL != rhs) return NULL;
626 if(typeInt != type || comp2Op !=OpInvalidComparisionOp) return NULL;
627 if (compOp != OpEquals) return NULL;
628 offset = offset1;
629 void *val =NULL;
630 if(operand == NULL && operandPtr != NULL)
632 val = *(void**)operandPtr;
633 } else if(operand != NULL && operandPtr == NULL)
635 val = (void*) operand;
637 return val;
639 void* PredicateImpl::getVal1IfBetweenOnInt(int &offset)
640 { //perf opt
641 if (NULL != lhs && NULL != rhs) return NULL;
642 if(typeInt != type) return NULL;
643 if (compOp != OpGreaterThanEquals ||
644 comp2Op !=OpLessThanEquals) return NULL;
645 offset = offset1;
646 void *val =NULL;
647 if(operand == NULL && operandPtr != NULL)
649 val = *(void**)operandPtr;
650 } else if(operand != NULL && operandPtr == NULL)
652 val = (void*) operand;
654 return val;
656 void* PredicateImpl::getVal2IfBetweenOnInt(int &offset)
657 { //perf opt
658 if (NULL != lhs && NULL != rhs) return NULL;
659 if(typeInt != type) return NULL;
660 if (compOp != OpGreaterThanEquals ||
661 comp2Op !=OpLessThanEquals) return NULL;
662 offset = offset1;
663 void *val =NULL;
664 if(operand2 == NULL && operand2Ptr != NULL)
666 val = *(void**)operand2Ptr;
667 } else if(operand2 != NULL && operand2Ptr == NULL)
669 val = (void*) operand2;
671 return val;
673 DbRetVal PredicateImpl::evaluate(bool &result)
675 if (!isNoLeftRight) {
676 bool rhsResult = false, lhsResult=false;
677 DbRetVal retCode =OK;
678 result = false;
679 if (NULL != lhs)
681 retCode = lhs->evaluate(lhsResult);
682 if (retCode < OK) return ErrInvalidExpr;
683 }else lhsResult = true;
684 if (NULL != rhs)
686 retCode = rhs->evaluate(rhsResult);
687 if (retCode < OK) return ErrInvalidExpr;
688 } else rhsResult = true;
689 if (NULL != lhs)
691 //Means it involves only Logical operator
692 if (OpAnd == logicalOp) {
693 if (lhsResult && rhsResult) result = true;
694 }else if (OpOr == logicalOp) {
695 if (lhsResult || rhsResult) result = true;
696 }else if (OpNot == logicalOp){
697 if (lhsResult) result = false; else result = true;
698 if ( ErrNullValues == retCode) result = false;
700 printDebug(DM_Predicate, "result is %d", result);
701 return OK;
704 //Means it is relational expression
705 //first operand is always field identifier
706 //get the value in the tuple
707 if (projList) {
708 if (dontEvaluate) {result= true; return OK; }
709 if (!isBindBufSet)
711 //for join node evaluation
712 ListIterator fIter = projList->getIterator();
713 JoinProjFieldInfo *def;
714 //char *val1, *val2;
715 while (fIter.hasElement())
717 def = (JoinProjFieldInfo*) fIter.nextElement();
718 if (NULL != def->bindBuf) {
719 if (0 == strcmp(fldName1, def->tabFieldName))
721 val1 = (char*)def->bindBuf;
722 type = def->type;
723 length = def->length;
724 break;
726 }else{
727 printError(ErrNotExists, "Field not binded %s.%s\n",
728 def->tableName, def->fieldName);
729 return ErrNotExists;
732 if (operand == NULL && operandPtr == NULL)
734 char fieldName2[IDENTIFIER_LENGTH];
735 memset(fieldName2, 0, IDENTIFIER_LENGTH);
736 Table::getFieldNameAlone(fldName2, fieldName2);
737 if (fieldName2) {
738 fIter.reset();
739 while (fIter.hasElement())
741 def = (JoinProjFieldInfo*) fIter.nextElement();
742 if (NULL != def->bindBuf) {
743 if (0 == strcmp(fldName2, def->tabFieldName))
745 val2 = (char*)def->bindBuf;
746 break;
748 }else{
749 printError(ErrNotExists, "Field not binded %s.%s\n",
750 def->tableName, def->fieldName);
751 return ErrNotExists;
756 else if(operand != NULL && operandPtr == NULL)
758 val2 = (char*) operand;
760 else if(operand == NULL && operandPtr != NULL)
762 val2 = *(char**)operandPtr;
764 isBindBufSet = true;
766 JoinTableImpl *jTable = (JoinTableImpl*) table;
767 if (jTable->isFldNullInt(fldName1) || jTable->isFldNullInt(fldName2))
769 result=false;
770 return ErrNullValues;
772 result = AllDataType::compareVal(val1, val2, compOp, type,
773 length);
774 return OK;
777 printf("PRABA::wrong method call\n");
778 //the below code works only for single table
779 val1= (char*)tuple + offset1;
780 if(offset2 != -1 && operand == NULL && operandPtr == NULL)
781 val2 = ((char*)tuple) + offset2;
782 if (!isBindBufSet) {
783 //Assumes that fldName2 data type is also same for expr f1 <f2
784 //Note:Perf: Do not change the order below
785 if(operand == NULL && operandPtr != NULL)
787 val2 = *(char**)operandPtr;
789 else if (operand == NULL && operandPtr == NULL)
791 if(offset2 != -1)
792 val2 = ((char*)tuple) + offset2;
794 else if(operand != NULL && operandPtr == NULL)
796 val2 = (char*) operand;
798 isBindBufSet = true;
800 result = AllDataType::compareVal(val1, val2, compOp, type,length);
801 return OK;
804 void PredicateImpl::solveForProjList(Table *tab)
806 if (NULL != lhs)
808 lhs->solveForProjList(tab);
810 if (NULL != rhs)
812 rhs->solveForProjList(tab);
814 table = tab;
815 if (NULL != lhs) return ;
816 bool isExist1=false;
817 bool isExist2=false;
818 if (projList)
820 ListIterator fIter = projList->getIterator();
821 JoinProjFieldInfo *def;
822 while (fIter.hasElement())
824 def = (JoinProjFieldInfo*) fIter.nextElement();
825 if (!isExist1 && 0 == strcmp(fldName1, def->tabFieldName))
827 isExist1=true;
829 if (!isExist2 && 0 == strcmp(fldName2, def->tabFieldName) )
831 isExist2=true;
834 if (!isExist1)
836 tab->bindFld(fldName1, NULL);
838 if (!isExist2 && strcmp(fldName2, "")!=0)
840 tab->bindFld(fldName2, NULL);
845 void PredicateImpl::setOffsetAndType()
847 if (NULL != lhs)
849 lhs->setOffsetAndType();
851 if (NULL != rhs)
853 rhs->setOffsetAndType();
855 char fieldName1[IDENTIFIER_LENGTH];
856 char fieldName2[IDENTIFIER_LENGTH];
857 memset(fieldName1, 0, IDENTIFIER_LENGTH);
858 memset(fieldName2, 0, IDENTIFIER_LENGTH);
859 Table::getFieldNameAlone(fldName1, fieldName1);
860 Table::getFieldNameAlone(fldName2, fieldName2);
861 //this function is called only from TableImpl
862 TableImpl *tImpl = (TableImpl*) table;
863 if(fieldName1){
864 FieldInfo *info = new FieldInfo();
865 tImpl->getFieldInfo(fieldName1, info);
866 offset1 = tImpl->getFieldOffset(fieldName1);
867 fldPos = tImpl->getFldPos(fieldName1);
868 type = info->type;
869 length = info->length;
870 isNullable = true;
871 if (info->isNull || info->isPrimary || info->isAutoIncrement)
872 isNullable = false;
873 //printf("isNullable is set to %d\n", isNullable);
874 delete info;
877 if(fieldName2){
878 offset2 = tImpl->getFieldOffset(fieldName2);
879 if(typeUnknown == type)
880 type = tImpl->getFieldType(fieldName2);
885 bool PredicateImpl::pointLookupInvolved(const char *fname)
887 bool rhsResult, lhsResult;
888 if (NULL != lhs)
890 lhsResult = lhs->pointLookupInvolved(fname);
892 if (NULL != rhs)
894 rhsResult = rhs->pointLookupInvolved(fname);
896 if (NULL != lhs)
898 //Means it involves only Logical operator
899 switch(logicalOp)
901 case OpAnd:
902 //return lhsResult;
903 if (lhsResult || rhsResult) return true; else return false;
904 break;
905 case OpOr:
906 return false;
907 break;
908 case OpNot:
909 default:
910 return false;
911 break;
914 //Means it is relational expression
915 //first operand is always field identifier
916 char fieldName1[IDENTIFIER_LENGTH];
917 Table::getFieldNameAlone(fldName1, fieldName1);
918 if (OpEquals == compOp)
920 //for expressions f1 == f2 use full scan, so return false
921 if(NULL == operand && NULL == operandPtr) return false;
922 if(0 == strcmp(fieldName1, fname))
924 return true;
927 return false;
930 bool PredicateImpl::isBetweenInvolved(const char *fname)
932 bool rhsResult, lhsResult;
933 if (NULL != lhs)
935 lhsResult = lhs->isBetweenInvolved(fname);
937 if (NULL != rhs)
939 rhsResult = rhs->isBetweenInvolved(fname);
941 if (NULL != lhs)
943 switch(logicalOp)
945 case OpAnd:
946 if (lhsResult && rhsResult) return true; else return false;
947 break;
948 default:
949 return false;
950 break;
953 char fieldName1[IDENTIFIER_LENGTH];
954 Table::getFieldNameAlone(fldName1, fieldName1);
955 if ( OpGreaterThan == compOp || OpGreaterThanEquals == compOp)
957 if(0 == strcmp(fieldName1, fname))
959 return true;
962 return false;
965 bool PredicateImpl::rangeQueryInvolved(const char *fname)
967 bool rhsResult, lhsResult;
968 if (NULL != lhs)
970 lhsResult = lhs->rangeQueryInvolved(fname);
972 if (NULL != rhs)
974 rhsResult = rhs->rangeQueryInvolved(fname);
976 if (NULL != lhs)
978 switch(logicalOp)
980 case OpAnd:
981 if (lhsResult || rhsResult) return true; else return false;
982 break;
983 case OpOr:
984 return false;
985 break;
986 case OpNot:
987 default:
988 return false;
989 break;
992 //Means it is relational expression
993 //first operand is always field identifier
994 char fieldName1[IDENTIFIER_LENGTH];
995 Table::getFieldNameAlone(fldName1, fieldName1);
996 if (OpLessThan == compOp || OpLessThanEquals == compOp ||
997 OpGreaterThan == compOp || OpGreaterThanEquals == compOp)
999 //for expressions f1 == f2 use full scan, so return false
1000 if(NULL == operand && NULL == operandPtr) return false;
1001 if(0 == strcmp(fieldName1, fname))
1003 return true;
1006 return false;
1009 void* PredicateImpl::opAndValPtrForIndexField(const char *fname, bool isUnique,ComparisionOp &op)
1011 ComparisionOp lhsOp= OpInvalidComparisionOp, rhsOp= OpInvalidComparisionOp;
1012 void *lhsRet=NULL, *rhsRet=NULL;
1013 if (NULL != lhs)
1015 lhsRet = lhs->opAndValPtrForIndexField(fname, isUnique, lhsOp);
1017 if (NULL != rhs)
1019 rhsRet = rhs->opAndValPtrForIndexField(fname, isUnique,rhsOp);
1021 if (lhsRet && lhsOp == OpEquals) { op = lhsOp; return lhsRet;}
1022 if (rhsRet && rhsOp == OpEquals) { op = rhsOp; return rhsRet;}
1023 if (NULL != lhs)
1025 if( lhsRet) { op = lhsOp; return lhsRet; }
1026 if( rhsRet) { op = rhsOp; return rhsRet; }
1028 char fieldName1[IDENTIFIER_LENGTH];
1029 Table::getFieldNameAlone(fldName1, fieldName1);
1030 //Means it is relational expression
1031 //first operand is always field identifier
1032 if(0 == strcmp(fieldName1, fname))
1034 op = compOp;
1035 if (isUnique && compOp != OpLessThan &&
1036 compOp != OpLessThanEquals) isPushedDown = true;
1037 if (operand) return operand; else return *(void**)operandPtr;
1039 op = OpInvalidComparisionOp;
1040 return NULL;
1044 //called only in case of hash index scan
1045 void* PredicateImpl::valPtrForIndexField(const char *fname, bool isUnique)
1047 void *lhsRet=NULL, *rhsRet=NULL;
1048 if (NULL != lhs)
1050 lhsRet = lhs->valPtrForIndexField(fname, isUnique);
1051 if ( lhsRet != NULL) return lhsRet;
1053 if (NULL != rhs)
1055 rhsRet = rhs->valPtrForIndexField(fname, isUnique);
1056 if ( rhsRet != NULL) return rhsRet;
1058 char fieldName1[IDENTIFIER_LENGTH];
1059 Table::getFieldNameAlone(fldName1, fieldName1);
1060 //Means it is relational expression
1061 //first operand is always field identifier
1062 if (OpEquals == compOp)
1064 if(0 == strcmp(fieldName1, fname))
1066 if (isUnique) isPushedDown = true;
1067 if (operand) return operand; else return *(void**)operandPtr;
1070 return NULL;
1072 ComparisionOp PredicateImpl::opForIndexField(const char *fname)
1074 ComparisionOp lhsRet= OpInvalidComparisionOp, rhsRet= OpInvalidComparisionOp;
1075 if (NULL != lhs)
1077 lhsRet = lhs->opForIndexField(fname);
1078 if ( lhsRet != OpInvalidComparisionOp) return lhsRet;
1081 if (NULL != rhs)
1083 rhsRet = rhs->opForIndexField(fname);
1084 if ( rhsRet != OpInvalidComparisionOp) return rhsRet;
1086 char fieldName1[IDENTIFIER_LENGTH];
1087 Table::getFieldNameAlone(fldName1, fieldName1);
1088 if(0 == strcmp(fieldName1, fname))
1090 return compOp;
1092 return OpInvalidComparisionOp;
1094 PredicateImpl* PredicateImpl::getTablePredicate()
1096 PredicateImpl *lhsRet = NULL, *rhsRet = NULL;
1097 if (NULL != lhs)
1099 lhsRet = lhs->getTablePredicate();
1100 if ( lhsRet != NULL) return lhsRet;
1102 if (NULL != rhs)
1104 rhsRet = rhs->getTablePredicate();
1105 if ( rhsRet != NULL) return rhsRet;
1107 if (operand || operandPtr )
1109 //printf("PRABA::getTablePredicate returning %s %d\n", fldName1, compOp);
1110 if (parent)
1112 if (this == parent->lhs) {
1113 parent->lhs = NULL;
1115 else {
1116 parent->rhs = NULL;
1118 parent = NULL;
1120 return this;
1122 return NULL;
1124 PredicateImpl* PredicateImpl::getJoinPredicate()
1126 PredicateImpl *lhsRet = NULL, *rhsRet = NULL;
1127 if (NULL != lhs)
1129 lhsRet = lhs->getJoinPredicate();
1130 if ( lhsRet != NULL) return lhsRet;
1132 if (NULL != rhs)
1134 rhsRet = rhs->getJoinPredicate();
1135 if ( rhsRet != NULL) return rhsRet;
1137 if (0 != strcmp(fldName2, ""))
1139 //printf("PRABA::getJoinPredicate returning %s %s\n", fldName1, fldName2);
1140 if (parent)
1142 if (this == parent->lhs)
1143 parent->lhs = NULL;
1144 else
1145 parent->rhs = NULL;
1146 parent = NULL;
1148 return this;
1150 return NULL;
1152 void PredicateImpl::removeIfNotNecessary()
1154 if (NULL != lhs)
1156 lhs->removeIfNotNecessary();
1158 if (NULL != rhs)
1160 rhs->removeIfNotNecessary();
1162 if (logicalOp != OpAnd) return;
1163 if (NULL == lhs && NULL == rhs)
1165 if (NULL == parent)
1167 return;
1169 if (this == parent->rhs) parent->rhs = NULL;
1170 else if (this == parent->lhs) parent->lhs = NULL;
1171 //TODO::PRABA::fix the leak below. if uncommented dumps core
1172 //delete this;
1173 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1174 //current object is deleted. do not any code here
1175 return;
1177 else if (NULL == lhs )
1179 //left side of the node is empty means we can remove this AND node
1180 //and place it as left or right of my parent where i am currently placed
1181 if (NULL == parent)
1183 return;
1185 if (this == parent->rhs) parent->rhs=this->rhs;
1186 else if (this == parent->lhs) parent->lhs = this->rhs;
1187 //TODO::PRABA::fix the leak below. if uncommented dumps core
1188 //delete this;
1189 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1190 //current object is deleted. do not any code here
1191 return;
1193 else if (NULL == rhs )
1195 //right side of the node is empty means we can remove this AND node
1196 //and place it as left or right of my parent where i am currently placed
1197 if (NULL == parent)
1199 return;
1201 if (this == parent->rhs) parent->rhs=this->lhs;
1202 else if (this == parent->lhs) parent->lhs = this->lhs;
1203 //TODO::PRABA::fix the leak below. if uncommented dumps core
1204 //delete this;
1205 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1206 //current object is deleted. do not any code here
1207 return;
1209 return;
1211 bool PredicateImpl::isDummyPredicate()
1213 if (NULL == lhs && NULL == rhs && NULL == parent
1214 && NULL == operand && NULL == operandPtr &&
1215 (0 == strcmp(fldName1, "")) && (0==strcmp(fldName2, "")))
1216 return true;
1217 else
1218 return false;
1220 PredicateImpl* PredicateImpl::getIfOneSidedPredicate()
1222 if (logicalOp != OpAnd) return NULL;
1223 if (NULL == lhs && NULL !=rhs)
1225 return rhs;
1227 if (NULL != lhs && NULL ==rhs)
1229 return lhs;
1231 return NULL;