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
);
102 char *c
= (char *) opnd
;
105 if (*c
== '_') *c
= '?';
106 else if(*c
== '%') *c
= '*';
115 logicalOp
= OpInvalidLogicalOp
;
116 comp2Op
= OpInvalidComparisionOp
;
120 void PredicateImpl::setTerm(Expression
*exp
, ComparisionOp op
, void **opnd
)
126 logicalOp
= OpInvalidLogicalOp
;
127 comp2Op
= OpInvalidComparisionOp
;
132 void PredicateImpl::setTerm(Expression
*exp1
, ComparisionOp op
, Expression
*exp2
)
138 logicalOp
= OpInvalidLogicalOp
;
139 comp2Op
= OpInvalidComparisionOp
;
145 void PredicateImpl::setTerm(Expression
*exp
, ComparisionOp op
, const char *fName2
)
147 strcpy(fldName2
, fName2
);
153 logicalOp
= OpInvalidLogicalOp
;
154 comp2Op
= OpInvalidComparisionOp
;
161 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
,bool nullFlag
)
163 strcpy(fldName1
, fName1
);
169 logicalOp
= OpInvalidLogicalOp
;
170 comp2Op
= OpInvalidComparisionOp
;
175 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
)
177 strcpy(fldName1
, fName1
);
183 logicalOp
= OpInvalidLogicalOp
;
184 comp2Op
= OpInvalidComparisionOp
;
188 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
, AggType aType
)
190 strcpy(fldName1
, fName1
);
197 logicalOp
= OpInvalidLogicalOp
;
198 comp2Op
= OpInvalidComparisionOp
;
203 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
,
204 ComparisionOp op2
, void **opnd2
)
206 strcpy(fldName1
, fName1
);
212 logicalOp
= OpInvalidLogicalOp
;
219 void PredicateImpl::setParent(PredicateImpl
*pImpl
)
221 //if (parent != NULL) printf("Parent already set\n");
225 void PredicateImpl::setTerm(Predicate
*p1
, LogicalOp op
, Predicate
*p2
)
227 if (p2
== NULL
&& op
!= OpNot
|| op
== OpNot
&& p2
!= NULL
)
230 printError(ErrBadArg
, "Wrong argument passed\n");
233 lhs
= (PredicateImpl
*)p1
;
234 rhs
= (PredicateImpl
*)p2
;
236 compOp
= OpInvalidComparisionOp
;
237 if (lhs
!= NULL
) lhs
->setParent(this);
238 if (rhs
!= NULL
) rhs
->setParent(this);
242 void PredicateImpl::setTable(Table
*tbl
)
250 void PredicateImpl::setIfNoLeftRight()
253 lhs
->setIfNoLeftRight();
255 rhs
->setIfNoLeftRight();
256 if(NULL
== lhs
&& NULL
== rhs
) isNoLeftRight
=true;
260 void PredicateImpl::setTuple(void *tpl
)
272 void PredicateImpl::setProjectionList(List
*lst
)
275 lhs
->setProjectionList(lst
);
277 rhs
->setProjectionList(lst
);
279 isBindBufSet
= false;
281 bool PredicateImpl::isSingleTerm()
283 if (NULL
== lhs
&& NULL
== rhs
&& comp2Op
== OpInvalidComparisionOp
)
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; }
313 bool PredicateImpl::isIsNullInvolved()
315 bool lhsResult
= true, rhsResult
= true;
318 lhsResult
= lhs
->isIsNullInvolved();
322 rhsResult
= rhs
->isIsNullInvolved();
326 if (lhsResult
|| rhsResult
) return true;
327 if(compOp
== isNull
) return true;
331 bool PredicateImpl::isNotOrInvolved()
333 bool lhsResult
= true, rhsResult
= true;
336 lhsResult
= lhs
->isNotOrInvolved();
340 rhsResult
= rhs
->isNotOrInvolved();
344 //Means it involves only Logical operator
348 if (lhsResult
|| rhsResult
) return true; else return false;
362 DbRetVal
PredicateImpl::evaluateLogical(bool &result
)
364 bool rhsResult
= false, lhsResult
=false;
365 DbRetVal retCode
=OK
;
369 retCode
= lhs
->evaluate(lhsResult
);
370 if (retCode
!= OK
) return ErrInvalidExpr
;
371 }else lhsResult
= true;
374 retCode
= rhs
->evaluate(rhsResult
);
375 if (retCode
!= OK
) return ErrInvalidExpr
;
376 } else rhsResult
= true;
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
);
392 DbRetVal
PredicateImpl::evaluateForHaving(bool &result
, AggTableImpl
*aImpl
, void *aggElement
)
394 bool rhsResult
= false, lhsResult
=false;
395 DbRetVal retCode
=OK
;
399 retCode
= lhs
->evaluateForHaving(lhsResult
, aImpl
, aggElement
);
400 if (retCode
!= OK
) return ErrInvalidExpr
;
401 }else lhsResult
= true;
404 retCode
= rhs
->evaluateForHaving(rhsResult
, aImpl
, aggElement
);
405 if (retCode
!= OK
) return ErrInvalidExpr
;
406 } else rhsResult
= true;
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
);
420 void *val1
= NULL
, *val2
=NULL
;
421 int offset
= aImpl
->getAggOffset(fldName1
, aggType
);
422 val1
= (void*)((char*)aggElement
+ offset
);
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
) {
429 length
= sizeof(double);
430 } else if (aggType
== AGG_COUNT
) {
432 length
= sizeof(int);
435 length
= info
->length
;
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
) {
450 AllDataType::convertToDouble(&dVal2
, val2
, type
);
451 result
= AllDataType::compareVal(val1
, &dVal2
, compOp
, typeDouble
, length
);
453 else if (aggType
== AGG_COUNT
) {
455 AllDataType::convertToInt(&dVal2
, val2
, type
);
456 result
= AllDataType::compareVal(val1
, &dVal2
, compOp
, typeInt
, length
);
459 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
, length
);
463 DbRetVal
PredicateImpl::evaluateLogicalForTable(bool &result
, char *tuple
)
465 bool rhsResult
= false, lhsResult
=false;
466 DbRetVal retCode
=OK
;
470 lhs
->evaluateForTable(lhsResult
, tuple
);
471 }else lhsResult
= true;
474 rhs
->evaluateForTable(rhsResult
, tuple
);
475 } else rhsResult
= true;
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
);
490 void PredicateImpl::evaluateForTable(bool &result
, char *tuple
)
492 if (!isNoLeftRight
) {
493 bool rhsResult
= false;
496 rhs
->evaluateForTable(rhsResult
, tuple
);
497 if(rhsResult
== false && OpAnd
== logicalOp
) {//do early return
500 } else rhsResult
= true;
501 bool lhsResult
= false;
504 lhs
->evaluateForTable(lhsResult
, tuple
);
505 }else lhsResult
= true;
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
);
520 //Table null check of condition
524 TableImpl
*tImpl
= (TableImpl
*) table
;
526 lExp
->setTable(tImpl
);
527 lExp
->setTuple(tuple
);
528 val
= lExp
->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(lExp
->getFunctionType()));
531 rExp
->setTable(tImpl
);
532 rExp
->setTuple(tuple
);
533 rval
= rExp
->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(rExp
->getFunctionType()));
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
);
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
) )
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
;
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
)
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
;
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;
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,
623 void* PredicateImpl::getValIfPointLookupOnInt(int &offset
)
625 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
626 if(typeInt
!= type
|| comp2Op
!=OpInvalidComparisionOp
) return NULL
;
627 if (compOp
!= OpEquals
) return NULL
;
630 if(operand
== NULL
&& operandPtr
!= NULL
)
632 val
= *(void**)operandPtr
;
633 } else if(operand
!= NULL
&& operandPtr
== NULL
)
635 val
= (void*) operand
;
639 void* PredicateImpl::getVal1IfBetweenOnInt(int &offset
)
641 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
642 if(typeInt
!= type
) return NULL
;
643 if (compOp
!= OpGreaterThanEquals
||
644 comp2Op
!=OpLessThanEquals
) return NULL
;
647 if(operand
== NULL
&& operandPtr
!= NULL
)
649 val
= *(void**)operandPtr
;
650 } else if(operand
!= NULL
&& operandPtr
== NULL
)
652 val
= (void*) operand
;
656 void* PredicateImpl::getVal2IfBetweenOnInt(int &offset
)
658 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
659 if(typeInt
!= type
) return NULL
;
660 if (compOp
!= OpGreaterThanEquals
||
661 comp2Op
!=OpLessThanEquals
) return NULL
;
664 if(operand2
== NULL
&& operand2Ptr
!= NULL
)
666 val
= *(void**)operand2Ptr
;
667 } else if(operand2
!= NULL
&& operand2Ptr
== NULL
)
669 val
= (void*) operand2
;
673 DbRetVal
PredicateImpl::evaluate(bool &result
)
675 if (!isNoLeftRight
) {
676 bool rhsResult
= false, lhsResult
=false;
677 DbRetVal retCode
=OK
;
681 retCode
= lhs
->evaluate(lhsResult
);
682 if (retCode
< OK
) return ErrInvalidExpr
;
683 }else lhsResult
= true;
686 retCode
= rhs
->evaluate(rhsResult
);
687 if (retCode
< OK
) return ErrInvalidExpr
;
688 } else rhsResult
= true;
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
);
704 //Means it is relational expression
705 //first operand is always field identifier
706 //get the value in the tuple
708 if (dontEvaluate
) {result
= true; return OK
; }
711 //for join node evaluation
712 ListIterator fIter
= projList
->getIterator();
713 JoinProjFieldInfo
*def
;
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
;
723 length
= def
->length
;
727 printError(ErrNotExists
, "Field not binded %s.%s\n",
728 def
->tableName
, def
->fieldName
);
732 if (operand
== NULL
&& operandPtr
== NULL
)
734 char fieldName2
[IDENTIFIER_LENGTH
];
735 memset(fieldName2
, 0, IDENTIFIER_LENGTH
);
736 Table::getFieldNameAlone(fldName2
, fieldName2
);
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
;
749 printError(ErrNotExists
, "Field not binded %s.%s\n",
750 def
->tableName
, def
->fieldName
);
756 else if(operand
!= NULL
&& operandPtr
== NULL
)
758 val2
= (char*) operand
;
760 else if(operand
== NULL
&& operandPtr
!= NULL
)
762 val2
= *(char**)operandPtr
;
766 JoinTableImpl
*jTable
= (JoinTableImpl
*) table
;
767 if (jTable
->isFldNullInt(fldName1
) || jTable
->isFldNullInt(fldName2
))
770 return ErrNullValues
;
772 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,
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
;
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
)
792 val2
= ((char*)tuple
) + offset2
;
794 else if(operand
!= NULL
&& operandPtr
== NULL
)
796 val2
= (char*) operand
;
800 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,length
);
804 void PredicateImpl::solveForProjList(Table
*tab
)
808 lhs
->solveForProjList(tab
);
812 rhs
->solveForProjList(tab
);
815 if (NULL
!= lhs
) return ;
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
))
829 if (!isExist2
&& 0 == strcmp(fldName2
, def
->tabFieldName
) )
836 tab
->bindFld(fldName1
, NULL
);
838 if (!isExist2
&& strcmp(fldName2
, "")!=0)
840 tab
->bindFld(fldName2
, NULL
);
845 void PredicateImpl::setOffsetAndType()
849 lhs
->setOffsetAndType();
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
;
864 FieldInfo
*info
= new FieldInfo();
865 tImpl
->getFieldInfo(fieldName1
, info
);
866 offset1
= tImpl
->getFieldOffset(fieldName1
);
867 fldPos
= tImpl
->getFldPos(fieldName1
);
869 length
= info
->length
;
871 if (info
->isNull
|| info
->isPrimary
|| info
->isAutoIncrement
)
873 //printf("isNullable is set to %d\n", isNullable);
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
;
890 lhsResult
= lhs
->pointLookupInvolved(fname
);
894 rhsResult
= rhs
->pointLookupInvolved(fname
);
898 //Means it involves only Logical operator
903 if (lhsResult
|| rhsResult
) return true; else return false;
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
))
930 bool PredicateImpl::isBetweenInvolved(const char *fname
)
932 bool rhsResult
, lhsResult
;
935 lhsResult
= lhs
->isBetweenInvolved(fname
);
939 rhsResult
= rhs
->isBetweenInvolved(fname
);
946 if (lhsResult
&& rhsResult
) return true; else return false;
953 char fieldName1
[IDENTIFIER_LENGTH
];
954 Table::getFieldNameAlone(fldName1
, fieldName1
);
955 if ( OpGreaterThan
== compOp
|| OpGreaterThanEquals
== compOp
)
957 if(0 == strcmp(fieldName1
, fname
))
965 bool PredicateImpl::rangeQueryInvolved(const char *fname
)
967 bool rhsResult
, lhsResult
;
970 lhsResult
= lhs
->rangeQueryInvolved(fname
);
974 rhsResult
= rhs
->rangeQueryInvolved(fname
);
981 if (lhsResult
|| rhsResult
) return true; else return false;
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
))
1009 void* PredicateImpl::opAndValPtrForIndexField(const char *fname
, bool isUnique
,ComparisionOp
&op
)
1011 ComparisionOp lhsOp
= OpInvalidComparisionOp
, rhsOp
= OpInvalidComparisionOp
;
1012 void *lhsRet
=NULL
, *rhsRet
=NULL
;
1015 lhsRet
= lhs
->opAndValPtrForIndexField(fname
, isUnique
, lhsOp
);
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
;}
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
))
1035 if (isUnique
&& compOp
!= OpLessThan
&&
1036 compOp
!= OpLessThanEquals
) isPushedDown
= true;
1037 if (operand
) return operand
; else return *(void**)operandPtr
;
1039 op
= OpInvalidComparisionOp
;
1044 //called only in case of hash index scan
1045 void* PredicateImpl::valPtrForIndexField(const char *fname
, bool isUnique
)
1047 void *lhsRet
=NULL
, *rhsRet
=NULL
;
1050 lhsRet
= lhs
->valPtrForIndexField(fname
, isUnique
);
1051 if ( lhsRet
!= NULL
) return lhsRet
;
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
;
1072 ComparisionOp
PredicateImpl::opForIndexField(const char *fname
)
1074 ComparisionOp lhsRet
= OpInvalidComparisionOp
, rhsRet
= OpInvalidComparisionOp
;
1077 lhsRet
= lhs
->opForIndexField(fname
);
1078 if ( lhsRet
!= OpInvalidComparisionOp
) return lhsRet
;
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
))
1092 return OpInvalidComparisionOp
;
1094 PredicateImpl
* PredicateImpl::getTablePredicate()
1096 PredicateImpl
*lhsRet
= NULL
, *rhsRet
= NULL
;
1099 lhsRet
= lhs
->getTablePredicate();
1100 if ( lhsRet
!= NULL
) return lhsRet
;
1104 rhsRet
= rhs
->getTablePredicate();
1105 if ( rhsRet
!= NULL
) return rhsRet
;
1107 if (operand
|| operandPtr
)
1109 //printf("PRABA::getTablePredicate returning %s %d\n", fldName1, compOp);
1112 if (this == parent
->lhs
) {
1124 PredicateImpl
* PredicateImpl::getJoinPredicate()
1126 PredicateImpl
*lhsRet
= NULL
, *rhsRet
= NULL
;
1129 lhsRet
= lhs
->getJoinPredicate();
1130 if ( lhsRet
!= NULL
) return lhsRet
;
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);
1142 if (this == parent
->lhs
)
1152 void PredicateImpl::removeIfNotNecessary()
1156 lhs
->removeIfNotNecessary();
1160 rhs
->removeIfNotNecessary();
1162 if (logicalOp
!= OpAnd
) return;
1163 if (NULL
== lhs
&& NULL
== rhs
)
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
1173 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1174 //current object is deleted. do not any code here
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
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
1189 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1190 //current object is deleted. do not any code here
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
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
1205 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1206 //current object is deleted. do not any code here
1211 bool PredicateImpl::isDummyPredicate()
1213 if (NULL
== lhs
&& NULL
== rhs
&& NULL
== parent
1214 && NULL
== operand
&& NULL
== operandPtr
&&
1215 (0 == strcmp(fldName1
, "")) && (0==strcmp(fldName2
, "")))
1220 PredicateImpl
* PredicateImpl::getIfOneSidedPredicate()
1222 if (logicalOp
!= OpAnd
) return NULL
;
1223 if (NULL
== lhs
&& NULL
!=rhs
)
1227 if (NULL
!= lhs
&& NULL
==rhs
)