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 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
);
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
);
63 //printf("<ISPUSHEDDOWN> %d </ISPUSHEDDOWN>\n", isPushedDown);
66 printf("%s <PRED-LEFT>\n", spaceBuf
);
68 printf("%s </PRED-LEFT>\n", spaceBuf
);
72 printf("%s <PRED-RIGHT>\n", spaceBuf
);
74 printf("%s </PRED-RIGHT>\n", spaceBuf
);
76 printf("%s </PREDICATE>\n", spaceBuf
);
80 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
,
83 strcpy(fldName1
, fName1
);
84 strcpy(fldName2
, fName2
);
90 logicalOp
= OpInvalidLogicalOp
;
91 comp2Op
= OpInvalidComparisionOp
;
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
);
105 logicalOp
= OpInvalidLogicalOp
;
106 comp2Op
= OpInvalidComparisionOp
;
110 void PredicateImpl::setTerm(Expression
*exp
, ComparisionOp op
, void **opnd
)
116 logicalOp
= OpInvalidLogicalOp
;
117 comp2Op
= OpInvalidComparisionOp
;
122 void PredicateImpl::setTerm(Expression
*exp1
, ComparisionOp op
, Expression
*exp2
)
128 logicalOp
= OpInvalidLogicalOp
;
129 comp2Op
= OpInvalidComparisionOp
;
135 void PredicateImpl::setTerm(Expression
*exp
, ComparisionOp op
, const char *fName2
)
137 strcpy(fldName2
, fName2
);
143 logicalOp
= OpInvalidLogicalOp
;
144 comp2Op
= OpInvalidComparisionOp
;
151 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
,bool nullFlag
)
153 strcpy(fldName1
, fName1
);
159 logicalOp
= OpInvalidLogicalOp
;
160 comp2Op
= OpInvalidComparisionOp
;
165 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
)
167 strcpy(fldName1
, fName1
);
173 logicalOp
= OpInvalidLogicalOp
;
174 comp2Op
= OpInvalidComparisionOp
;
178 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
, AggType aType
)
180 strcpy(fldName1
, fName1
);
187 logicalOp
= OpInvalidLogicalOp
;
188 comp2Op
= OpInvalidComparisionOp
;
193 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
,
194 ComparisionOp op2
, void **opnd2
)
196 strcpy(fldName1
, fName1
);
202 logicalOp
= OpInvalidLogicalOp
;
209 void PredicateImpl::setParent(PredicateImpl
*pImpl
)
211 //if (parent != NULL) printf("Parent already set\n");
215 void PredicateImpl::setTerm(Predicate
*p1
, LogicalOp op
, Predicate
*p2
)
217 if (p2
== NULL
&& op
!= OpNot
|| op
== OpNot
&& p2
!= NULL
)
220 printError(ErrBadArg
, "Wrong argument passed\n");
223 lhs
= (PredicateImpl
*)p1
;
224 rhs
= (PredicateImpl
*)p2
;
226 compOp
= OpInvalidComparisionOp
;
227 if (lhs
!= NULL
) lhs
->setParent(this);
228 if (rhs
!= NULL
) rhs
->setParent(this);
232 void PredicateImpl::setTable(Table
*tbl
)
240 void PredicateImpl::setIfNoLeftRight()
243 lhs
->setIfNoLeftRight();
245 rhs
->setIfNoLeftRight();
246 if(NULL
== lhs
&& NULL
== rhs
) isNoLeftRight
=true;
250 void PredicateImpl::setTuple(void *tpl
)
262 void PredicateImpl::setProjectionList(List
*lst
)
265 lhs
->setProjectionList(lst
);
267 rhs
->setProjectionList(lst
);
269 isBindBufSet
= false;
271 bool PredicateImpl::isSingleTerm()
273 if (NULL
== lhs
&& NULL
== rhs
&& comp2Op
== OpInvalidComparisionOp
)
278 bool PredicateImpl::appendIfSameFld(char *fName
, ComparisionOp op
, void *buf
)
280 char fieldName1
[IDENTIFIER_LENGTH
];
281 Table::getFieldNameAlone(fldName1
, fieldName1
);
282 if (strcmp(fName
,fieldName1
) == 0)
284 printDebug(DM_Predicate
, "Field name matched");
286 //switching so that in case of joins, first other conditions are
287 //evaluated first and then matching tuples for join is evaluated
288 //otherwise it may give wrong result set
289 if (operand) {operand2 = operand; operand2Ptr = NULL; }
290 if (operandPtr) {operand2Ptr = operandPtr; operand2 = NULL; }
303 bool PredicateImpl::isIsNullInvolved()
305 bool lhsResult
= true, rhsResult
= true;
308 lhsResult
= lhs
->isIsNullInvolved();
312 rhsResult
= rhs
->isIsNullInvolved();
316 if (lhsResult
|| rhsResult
) return true;
317 if(compOp
== isNull
) return true;
321 bool PredicateImpl::isNotOrInvolved()
323 bool lhsResult
= true, rhsResult
= true;
326 lhsResult
= lhs
->isNotOrInvolved();
330 rhsResult
= rhs
->isNotOrInvolved();
334 //Means it involves only Logical operator
338 if (lhsResult
|| rhsResult
) return true; else return false;
352 DbRetVal
PredicateImpl::evaluateLogical(bool &result
)
354 bool rhsResult
= false, lhsResult
=false;
355 DbRetVal retCode
=OK
;
359 retCode
= lhs
->evaluate(lhsResult
);
360 if (retCode
!= OK
) return ErrInvalidExpr
;
361 }else lhsResult
= true;
364 retCode
= rhs
->evaluate(rhsResult
);
365 if (retCode
!= OK
) return ErrInvalidExpr
;
366 } else rhsResult
= true;
369 //Means it involves only Logical operator
370 if (OpAnd
== logicalOp
) {
371 if (lhsResult
&& rhsResult
) result
= true;
372 }else if (OpOr
== logicalOp
) {
373 if (lhsResult
|| rhsResult
) result
= true;
374 }else if (OpNot
== logicalOp
){
375 if (lhsResult
) result
= false; else result
= true;
377 printDebug(DM_Predicate
, "result is %d", result
);
382 DbRetVal
PredicateImpl::evaluateForHaving(bool &result
, AggTableImpl
*aImpl
, void *aggElement
)
384 bool rhsResult
= false, lhsResult
=false;
385 DbRetVal retCode
=OK
;
389 retCode
= lhs
->evaluateForHaving(lhsResult
, aImpl
, aggElement
);
390 if (retCode
!= OK
) return ErrInvalidExpr
;
391 }else lhsResult
= true;
394 retCode
= rhs
->evaluateForHaving(rhsResult
, aImpl
, aggElement
);
395 if (retCode
!= OK
) return ErrInvalidExpr
;
396 } else rhsResult
= true;
399 if (OpAnd
== logicalOp
) {
400 if (lhsResult
&& rhsResult
) result
= true;
401 }else if (OpOr
== logicalOp
) {
402 if (lhsResult
|| rhsResult
) result
= true;
403 }else if (OpNot
== logicalOp
){
404 if (lhsResult
) result
= false; else result
= true;
406 printDebug(DM_Predicate
, "result is %d", result
);
410 void *val1
= NULL
, *val2
=NULL
;
411 int offset
= aImpl
->getAggOffset(fldName1
, aggType
);
412 val1
= (void*)((char*)aggElement
+ offset
);
414 //sets the type and length when it is called first time
415 FieldInfo
*info
= new FieldInfo();
416 DbRetVal rv
= aImpl
->getFieldInfo(fldName1
, info
);
417 if (aggType
== AGG_AVG
) {
419 length
= sizeof(double);
420 } else if (aggType
== AGG_COUNT
) {
422 length
= sizeof(int);
425 length
= info
->length
;
430 if(operand
!= NULL
&& operandPtr
== NULL
)
432 val2
= (char*) operand
;
434 else if(operand
== NULL
&& operandPtr
!= NULL
)
436 val2
= *(char**)operandPtr
;
438 if (aggType
== AGG_AVG
) {
440 AllDataType::convertToDouble(&dVal2
, val2
, type
);
441 result
= AllDataType::compareVal(val1
, &dVal2
, compOp
, typeDouble
, length
);
443 else if (aggType
== AGG_COUNT
) {
445 AllDataType::convertToInt(&dVal2
, val2
, type
);
446 result
= AllDataType::compareVal(val1
, &dVal2
, compOp
, typeInt
, length
);
449 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
, length
);
453 DbRetVal
PredicateImpl::evaluateLogicalForTable(bool &result
, char *tuple
)
455 bool rhsResult
= false, lhsResult
=false;
456 DbRetVal retCode
=OK
;
460 lhs
->evaluateForTable(lhsResult
, tuple
);
461 }else lhsResult
= true;
464 rhs
->evaluateForTable(rhsResult
, tuple
);
465 } else rhsResult
= true;
468 //Means it involves only Logical operator
469 if (OpAnd
== logicalOp
) {
470 if (lhsResult
&& rhsResult
) result
= true;
471 }else if (OpOr
== logicalOp
) {
472 if (lhsResult
|| rhsResult
) result
= true;
473 }else if (OpNot
== logicalOp
){
474 if (lhsResult
) result
= false; else result
= true;
476 printDebug(DM_Predicate
, "result is %d", result
);
480 void PredicateImpl::evaluateForTable(bool &result
, char *tuple
)
482 if (!isNoLeftRight
) {
483 bool rhsResult
= false;
486 rhs
->evaluateForTable(rhsResult
, tuple
);
487 if(rhsResult
== false && OpAnd
== logicalOp
) {//do early return
490 } else rhsResult
= true;
491 bool lhsResult
= false;
494 lhs
->evaluateForTable(lhsResult
, tuple
);
495 }else lhsResult
= true;
498 //Means it involves only Logical operator
499 if (OpAnd
== logicalOp
) {
500 if (lhsResult
&& rhsResult
) result
= true;
501 }else if (OpOr
== logicalOp
) {
502 if (lhsResult
|| rhsResult
) result
= true;
503 }else if (OpNot
== logicalOp
){
504 if (lhsResult
) result
= false; else result
= true;
506 printDebug(DM_Predicate
, "result is %d", result
);
510 //Table null check of condition
514 TableImpl
*tImpl
= (TableImpl
*) table
;
516 lExp
->setTable(tImpl
);
517 lExp
->setTuple(tuple
);
518 val
= lExp
->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(lExp
->getFunctionType()));
521 rExp
->setTable(tImpl
);
522 rExp
->setTuple(tuple
);
523 rval
= rExp
->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(rExp
->getFunctionType()));
526 result
= AllDataType::compareVal(val
, rval
, compOp
, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp
->getFunctionType()),length
);
527 }else if( val
&& operandPtr
!=NULL
){
528 val2
= *(char**)operandPtr
;
529 result
= AllDataType::compareVal(val
, val2
, compOp
, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp
->getFunctionType()),length
);
530 }else if(val
&& (offset2
!= -1 && operand
== NULL
&& operandPtr
== NULL
)){
531 val2
= tuple
+ offset2
;
532 result
= AllDataType::compareVal(val
, val2
, compOp
, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp
->getFunctionType()),length
);
540 TableImpl
*tImpl
= (TableImpl
*) table
;
541 tImpl
->setCurTuple(tuple
);
542 bool isValueNull
= table
->isFldNull(fldPos
);
543 if(compOp
== OpIsNull
)
545 if( (isValueNull
&& isNull
) || (!isValueNull
&& !isNull
) )
557 //the below code works only for single table
558 val1
= tuple
+ offset1
;
559 if(offset2
!= -1 && operand
== NULL
&& operandPtr
== NULL
)
560 val2
= tuple
+ offset2
;
562 //Assumes that fldName2 data type is also same for expr f1 <f2
563 //Note:Perf: Do not change the order below
564 if(operand
== NULL
&& operandPtr
!= NULL
)
566 val2
= *(char**)operandPtr
;
567 if (compOp
== OpLike
) {
568 char *c
= (char *)val2
;
569 //OPT:If LIKE has only %, then no need to evaluate
570 if (*c
== '%' && *(c
+1) == '\0') {result
=true; return;}
571 Util::changeWildcardChar(val2
);
574 } else if (operand
== NULL
&& operandPtr
== NULL
)
577 val2
= tuple
+ offset2
;
578 } else if(operand
!= NULL
&& operandPtr
== NULL
)
580 val2
= (char*) operand
;
581 if (compOp
== OpLike
) {
582 char *c
= (char *)val2
;
583 if (*c
== '%' && *(c
+1) == '\0') {result
=true; return;}
584 Util::changeWildcardChar(val2
);
587 if(operand2
== NULL
&& operand2Ptr
!= NULL
)
589 val3
= *(char**)operand2Ptr
;
590 } else if(operand2
!= NULL
&& operand2Ptr
== NULL
)
592 val3
= (char*) operand2
;
598 //printf(" val1 %d val3 %d\n", *(int*)val1, *(int*)val3);
599 result
= AllDataType::compareVal(val1
, val3
, comp2Op
, type
,length
);
600 if(result
==false) return;
605 //printf(" val1 %d val2 %d\n", *(int*)val1, *(int*)val2);
606 if (type
!= typeVarchar
)
607 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,length
);
608 else result
= AllDataType::compareVal((void *) *(long *) val1
, val2
,
609 compOp
, type
,length
);
610 //if (!result && val3) AllDataType::copyVal(val3,
613 void* PredicateImpl::getValIfPointLookupOnInt(int &offset
)
615 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
616 if(typeInt
!= type
|| comp2Op
!=OpInvalidComparisionOp
) return NULL
;
617 if (compOp
!= OpEquals
) return NULL
;
620 if(operand
== NULL
&& operandPtr
!= NULL
)
622 val
= *(void**)operandPtr
;
623 } else if(operand
!= NULL
&& operandPtr
== NULL
)
625 val
= (void*) operand
;
629 void* PredicateImpl::getVal1IfBetweenOnInt(int &offset
)
631 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
632 if(typeInt
!= type
) return NULL
;
633 if (compOp
!= OpGreaterThanEquals
||
634 comp2Op
!=OpLessThanEquals
) return NULL
;
637 if(operand
== NULL
&& operandPtr
!= NULL
)
639 val
= *(void**)operandPtr
;
640 } else if(operand
!= NULL
&& operandPtr
== NULL
)
642 val
= (void*) operand
;
646 void* PredicateImpl::getVal2IfBetweenOnInt(int &offset
)
648 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
649 if(typeInt
!= type
) return NULL
;
650 if (compOp
!= OpGreaterThanEquals
||
651 comp2Op
!=OpLessThanEquals
) return NULL
;
654 if(operand2
== NULL
&& operand2Ptr
!= NULL
)
656 val
= *(void**)operand2Ptr
;
657 } else if(operand2
!= NULL
&& operand2Ptr
== NULL
)
659 val
= (void*) operand2
;
663 DbRetVal
PredicateImpl::evaluate(bool &result
)
665 if (!isNoLeftRight
) {
666 bool rhsResult
= false, lhsResult
=false;
667 DbRetVal retCode
=OK
;
671 retCode
= lhs
->evaluate(lhsResult
);
672 if (retCode
< OK
) return ErrInvalidExpr
;
673 }else lhsResult
= true;
676 retCode
= rhs
->evaluate(rhsResult
);
677 if (retCode
< OK
) return ErrInvalidExpr
;
678 } else rhsResult
= true;
681 //Means it involves only Logical operator
682 if (OpAnd
== logicalOp
) {
683 if (lhsResult
&& rhsResult
) result
= true;
684 }else if (OpOr
== logicalOp
) {
685 if (lhsResult
|| rhsResult
) result
= true;
686 }else if (OpNot
== logicalOp
){
687 if (lhsResult
) result
= false; else result
= true;
688 if ( ErrNullValues
== retCode
) result
= false;
690 printDebug(DM_Predicate
, "result is %d", result
);
694 //Means it is relational expression
695 //first operand is always field identifier
696 //get the value in the tuple
698 if (dontEvaluate
) {result
= true; return OK
; }
701 //for join node evaluation
702 ListIterator fIter
= projList
->getIterator();
703 JoinProjFieldInfo
*def
;
705 while (fIter
.hasElement())
707 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
708 if (NULL
!= def
->bindBuf
) {
709 if (0 == strcmp(fldName1
, def
->tabFieldName
))
711 val1
= (char*)def
->bindBuf
;
713 length
= def
->length
;
717 printError(ErrNotExists
, "Field not binded %s.%s\n",
718 def
->tableName
, def
->fieldName
);
722 if (operand
== NULL
&& operandPtr
== NULL
)
724 char fieldName2
[IDENTIFIER_LENGTH
];
725 memset(fieldName2
, 0, IDENTIFIER_LENGTH
);
726 Table::getFieldNameAlone(fldName2
, fieldName2
);
729 while (fIter
.hasElement())
731 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
732 if (NULL
!= def
->bindBuf
) {
733 if (0 == strcmp(fldName2
, def
->tabFieldName
))
735 val2
= (char*)def
->bindBuf
;
739 printError(ErrNotExists
, "Field not binded %s.%s\n",
740 def
->tableName
, def
->fieldName
);
746 else if(operand
!= NULL
&& operandPtr
== NULL
)
748 val2
= (char*) operand
;
750 else if(operand
== NULL
&& operandPtr
!= NULL
)
752 val2
= *(char**)operandPtr
;
756 JoinTableImpl
*jTable
= (JoinTableImpl
*) table
;
757 if (jTable
->isFldNullInt(fldName1
) || jTable
->isFldNullInt(fldName2
))
760 return ErrNullValues
;
762 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,
767 printf("PRABA::wrong method call\n");
768 //the below code works only for single table
769 val1
= (char*)tuple
+ offset1
;
770 if(offset2
!= -1 && operand
== NULL
&& operandPtr
== NULL
)
771 val2
= ((char*)tuple
) + offset2
;
773 //Assumes that fldName2 data type is also same for expr f1 <f2
774 //Note:Perf: Do not change the order below
775 if(operand
== NULL
&& operandPtr
!= NULL
)
777 val2
= *(char**)operandPtr
;
779 else if (operand
== NULL
&& operandPtr
== NULL
)
782 val2
= ((char*)tuple
) + offset2
;
784 else if(operand
!= NULL
&& operandPtr
== NULL
)
786 val2
= (char*) operand
;
790 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,length
);
794 void PredicateImpl::solveForProjList(Table
*tab
)
798 lhs
->solveForProjList(tab
);
802 rhs
->solveForProjList(tab
);
805 if (NULL
!= lhs
) return ;
810 ListIterator fIter
= projList
->getIterator();
811 JoinProjFieldInfo
*def
;
812 while (fIter
.hasElement())
814 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
815 if (!isExist1
&& 0 == strcmp(fldName1
, def
->tabFieldName
))
819 if (!isExist2
&& 0 == strcmp(fldName2
, def
->tabFieldName
) )
826 tab
->bindFld(fldName1
, NULL
);
828 if (!isExist2
&& strcmp(fldName2
, "")!=0)
830 tab
->bindFld(fldName2
, NULL
);
835 void PredicateImpl::setOffsetAndType()
839 lhs
->setOffsetAndType();
843 rhs
->setOffsetAndType();
845 char fieldName1
[IDENTIFIER_LENGTH
];
846 char fieldName2
[IDENTIFIER_LENGTH
];
847 memset(fieldName1
, 0, IDENTIFIER_LENGTH
);
848 memset(fieldName2
, 0, IDENTIFIER_LENGTH
);
849 Table::getFieldNameAlone(fldName1
, fieldName1
);
850 Table::getFieldNameAlone(fldName2
, fieldName2
);
851 //this function is called only from TableImpl
852 TableImpl
*tImpl
= (TableImpl
*) table
;
854 FieldInfo
*info
= new FieldInfo();
855 tImpl
->getFieldInfo(fieldName1
, info
);
856 offset1
= tImpl
->getFieldOffset(fieldName1
);
857 fldPos
= tImpl
->getFldPos(fieldName1
);
859 length
= info
->length
;
861 if (info
->isNull
|| info
->isPrimary
|| info
->isAutoIncrement
)
863 //printf("isNullable is set to %d\n", isNullable);
868 offset2
= tImpl
->getFieldOffset(fieldName2
);
869 if(typeUnknown
== type
)
870 type
= tImpl
->getFieldType(fieldName2
);
875 bool PredicateImpl::pointLookupInvolved(const char *fname
)
877 bool rhsResult
, lhsResult
;
880 lhsResult
= lhs
->pointLookupInvolved(fname
);
884 rhsResult
= rhs
->pointLookupInvolved(fname
);
888 //Means it involves only Logical operator
893 if (lhsResult
|| rhsResult
) return true; else return false;
904 //Means it is relational expression
905 //first operand is always field identifier
906 char fieldName1
[IDENTIFIER_LENGTH
];
907 Table::getFieldNameAlone(fldName1
, fieldName1
);
908 if (OpEquals
== compOp
)
910 //for expressions f1 == f2 use full scan, so return false
911 if(NULL
== operand
&& NULL
== operandPtr
) return false;
912 if(0 == strcmp(fieldName1
, fname
))
920 bool PredicateImpl::isBetweenInvolved(const char *fname
)
922 bool rhsResult
, lhsResult
;
925 lhsResult
= lhs
->isBetweenInvolved(fname
);
929 rhsResult
= rhs
->isBetweenInvolved(fname
);
936 if (lhsResult
&& rhsResult
) return true; else return false;
943 char fieldName1
[IDENTIFIER_LENGTH
];
944 Table::getFieldNameAlone(fldName1
, fieldName1
);
945 if ( OpGreaterThan
== compOp
|| OpGreaterThanEquals
== compOp
)
947 if(0 == strcmp(fieldName1
, fname
))
955 bool PredicateImpl::rangeQueryInvolved(const char *fname
)
957 bool rhsResult
, lhsResult
;
960 lhsResult
= lhs
->rangeQueryInvolved(fname
);
964 rhsResult
= rhs
->rangeQueryInvolved(fname
);
971 if (lhsResult
|| rhsResult
) return true; else return false;
982 //Means it is relational expression
983 //first operand is always field identifier
984 char fieldName1
[IDENTIFIER_LENGTH
];
985 Table::getFieldNameAlone(fldName1
, fieldName1
);
986 if (OpLessThan
== compOp
|| OpLessThanEquals
== compOp
||
987 OpGreaterThan
== compOp
|| OpGreaterThanEquals
== compOp
)
989 //for expressions f1 == f2 use full scan, so return false
990 if(NULL
== operand
&& NULL
== operandPtr
) return false;
991 if(0 == strcmp(fieldName1
, fname
))
999 void* PredicateImpl::opAndValPtrForIndexField(const char *fname
, bool isUnique
,ComparisionOp
&op
)
1001 ComparisionOp lhsOp
= OpInvalidComparisionOp
, rhsOp
= OpInvalidComparisionOp
;
1002 void *lhsRet
=NULL
, *rhsRet
=NULL
;
1005 lhsRet
= lhs
->opAndValPtrForIndexField(fname
, isUnique
, lhsOp
);
1009 rhsRet
= rhs
->opAndValPtrForIndexField(fname
, isUnique
,rhsOp
);
1011 if (lhsRet
&& lhsOp
== OpEquals
) { op
= lhsOp
; return lhsRet
;}
1012 if (rhsRet
&& rhsOp
== OpEquals
) { op
= rhsOp
; return rhsRet
;}
1015 if( lhsRet
) { op
= lhsOp
; return lhsRet
; }
1016 if( rhsRet
) { op
= rhsOp
; return rhsRet
; }
1018 char fieldName1
[IDENTIFIER_LENGTH
];
1019 Table::getFieldNameAlone(fldName1
, fieldName1
);
1020 //Means it is relational expression
1021 //first operand is always field identifier
1022 if(0 == strcmp(fieldName1
, fname
))
1025 if (isUnique
&& compOp
!= OpLessThan
&&
1026 compOp
!= OpLessThanEquals
) isPushedDown
= true;
1027 if (operand
) return operand
; else return *(void**)operandPtr
;
1029 op
= OpInvalidComparisionOp
;
1034 //called only in case of hash index scan
1035 void* PredicateImpl::valPtrForIndexField(const char *fname
, bool isUnique
)
1037 void *lhsRet
=NULL
, *rhsRet
=NULL
;
1040 lhsRet
= lhs
->valPtrForIndexField(fname
, isUnique
);
1041 if ( lhsRet
!= NULL
) return lhsRet
;
1045 rhsRet
= rhs
->valPtrForIndexField(fname
, isUnique
);
1046 if ( rhsRet
!= NULL
) return rhsRet
;
1048 char fieldName1
[IDENTIFIER_LENGTH
];
1049 Table::getFieldNameAlone(fldName1
, fieldName1
);
1050 //Means it is relational expression
1051 //first operand is always field identifier
1052 if (OpEquals
== compOp
)
1054 if(0 == strcmp(fieldName1
, fname
))
1056 if (isUnique
) isPushedDown
= true;
1057 if (operand
) return operand
; else return *(void**)operandPtr
;
1062 ComparisionOp
PredicateImpl::opForIndexField(const char *fname
)
1064 ComparisionOp lhsRet
= OpInvalidComparisionOp
, rhsRet
= OpInvalidComparisionOp
;
1067 lhsRet
= lhs
->opForIndexField(fname
);
1068 if ( lhsRet
!= OpInvalidComparisionOp
) return lhsRet
;
1073 rhsRet
= rhs
->opForIndexField(fname
);
1074 if ( rhsRet
!= OpInvalidComparisionOp
) return rhsRet
;
1076 char fieldName1
[IDENTIFIER_LENGTH
];
1077 Table::getFieldNameAlone(fldName1
, fieldName1
);
1078 if(0 == strcmp(fieldName1
, fname
))
1082 return OpInvalidComparisionOp
;
1084 PredicateImpl
* PredicateImpl::getTablePredicate()
1086 PredicateImpl
*lhsRet
= NULL
, *rhsRet
= NULL
;
1089 lhsRet
= lhs
->getTablePredicate();
1090 if ( lhsRet
!= NULL
) return lhsRet
;
1094 rhsRet
= rhs
->getTablePredicate();
1095 if ( rhsRet
!= NULL
) return rhsRet
;
1097 if (operand
|| operandPtr
)
1099 //printf("PRABA::getTablePredicate returning %s %d\n", fldName1, compOp);
1102 if (this == parent
->lhs
) {
1114 PredicateImpl
* PredicateImpl::getJoinPredicate()
1116 PredicateImpl
*lhsRet
= NULL
, *rhsRet
= NULL
;
1119 lhsRet
= lhs
->getJoinPredicate();
1120 if ( lhsRet
!= NULL
) return lhsRet
;
1124 rhsRet
= rhs
->getJoinPredicate();
1125 if ( rhsRet
!= NULL
) return rhsRet
;
1127 if (0 != strcmp(fldName2
, ""))
1129 //printf("PRABA::getJoinPredicate returning %s %s\n", fldName1, fldName2);
1132 if (this == parent
->lhs
)
1142 void PredicateImpl::removeIfNotNecessary()
1146 lhs
->removeIfNotNecessary();
1150 rhs
->removeIfNotNecessary();
1152 if (logicalOp
!= OpAnd
) return;
1153 if (NULL
== lhs
&& NULL
== rhs
)
1159 if (this == parent
->rhs
) parent
->rhs
= NULL
;
1160 else if (this == parent
->lhs
) parent
->lhs
= NULL
;
1161 //TODO::PRABA::fix the leak below. if uncommented dumps core
1163 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1164 //current object is deleted. do not any code here
1167 else if (NULL
== lhs
)
1169 //left side of the node is empty means we can remove this AND node
1170 //and place it as left or right of my parent where i am currently placed
1175 if (this == parent
->rhs
) parent
->rhs
=this->rhs
;
1176 else if (this == parent
->lhs
) parent
->lhs
= this->rhs
;
1177 //TODO::PRABA::fix the leak below. if uncommented dumps core
1179 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1180 //current object is deleted. do not any code here
1183 else if (NULL
== rhs
)
1185 //right side of the node is empty means we can remove this AND node
1186 //and place it as left or right of my parent where i am currently placed
1191 if (this == parent
->rhs
) parent
->rhs
=this->lhs
;
1192 else if (this == parent
->lhs
) parent
->lhs
= this->lhs
;
1193 //TODO::PRABA::fix the leak below. if uncommented dumps core
1195 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1196 //current object is deleted. do not any code here
1201 bool PredicateImpl::isDummyPredicate()
1203 if (NULL
== lhs
&& NULL
== rhs
&& NULL
== parent
1204 && NULL
== operand
&& NULL
== operandPtr
&&
1205 (0 == strcmp(fldName1
, "")) && (0==strcmp(fldName2
, "")))
1210 PredicateImpl
* PredicateImpl::getIfOneSidedPredicate()
1212 if (logicalOp
!= OpAnd
) return NULL
;
1213 if (NULL
== lhs
&& NULL
!=rhs
)
1217 if (NULL
!= lhs
&& NULL
==rhs
)