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(const char* fName1
, ComparisionOp op
,bool nullFlag
)
122 strcpy(fldName1
, fName1
);
128 logicalOp
= OpInvalidLogicalOp
;
129 comp2Op
= OpInvalidComparisionOp
;
134 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
)
136 strcpy(fldName1
, fName1
);
142 logicalOp
= OpInvalidLogicalOp
;
143 comp2Op
= OpInvalidComparisionOp
;
147 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
, AggType aType
)
149 strcpy(fldName1
, fName1
);
156 logicalOp
= OpInvalidLogicalOp
;
157 comp2Op
= OpInvalidComparisionOp
;
162 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
,
163 ComparisionOp op2
, void **opnd2
)
165 strcpy(fldName1
, fName1
);
171 logicalOp
= OpInvalidLogicalOp
;
178 void PredicateImpl::setParent(PredicateImpl
*pImpl
)
180 //if (parent != NULL) printf("Parent already set\n");
184 void PredicateImpl::setTerm(Predicate
*p1
, LogicalOp op
, Predicate
*p2
)
186 if (p2
== NULL
&& op
!= OpNot
|| op
== OpNot
&& p2
!= NULL
)
189 printError(ErrBadArg
, "Wrong argument passed\n");
192 lhs
= (PredicateImpl
*)p1
;
193 rhs
= (PredicateImpl
*)p2
;
195 compOp
= OpInvalidComparisionOp
;
196 if (lhs
!= NULL
) lhs
->setParent(this);
197 if (rhs
!= NULL
) rhs
->setParent(this);
201 void PredicateImpl::setTable(Table
*tbl
)
209 void PredicateImpl::setIfNoLeftRight()
212 lhs
->setIfNoLeftRight();
214 rhs
->setIfNoLeftRight();
215 if(NULL
== lhs
&& NULL
== rhs
) isNoLeftRight
=true;
219 void PredicateImpl::setTuple(void *tpl
)
231 void PredicateImpl::setProjectionList(List
*lst
)
234 lhs
->setProjectionList(lst
);
236 rhs
->setProjectionList(lst
);
238 isBindBufSet
= false;
240 bool PredicateImpl::isSingleTerm()
242 if (NULL
== lhs
&& NULL
== rhs
&& comp2Op
== OpInvalidComparisionOp
)
247 bool PredicateImpl::appendIfSameFld(char *fName
, ComparisionOp op
, void *buf
)
249 char fieldName1
[IDENTIFIER_LENGTH
];
250 Table::getFieldNameAlone(fldName1
, fieldName1
);
251 if (strcmp(fName
,fieldName1
) == 0)
253 printDebug(DM_Predicate
, "Field name matched");
255 //switching so that in case of joins, first other conditions are
256 //evaluated first and then matching tuples for join is evaluated
257 //otherwise it may give wrong result set
258 if (operand) {operand2 = operand; operand2Ptr = NULL; }
259 if (operandPtr) {operand2Ptr = operandPtr; operand2 = NULL; }
272 bool PredicateImpl::isIsNullInvolved()
274 bool lhsResult
= true, rhsResult
= true;
277 lhsResult
= lhs
->isIsNullInvolved();
281 rhsResult
= rhs
->isIsNullInvolved();
285 if (lhsResult
|| rhsResult
) return true;
286 if(compOp
== isNull
) return true;
290 bool PredicateImpl::isNotOrInvolved()
292 bool lhsResult
= true, rhsResult
= true;
295 lhsResult
= lhs
->isNotOrInvolved();
299 rhsResult
= rhs
->isNotOrInvolved();
303 //Means it involves only Logical operator
307 if (lhsResult
|| rhsResult
) return true; else return false;
321 DbRetVal
PredicateImpl::evaluateLogical(bool &result
)
323 bool rhsResult
= false, lhsResult
=false;
324 DbRetVal retCode
=OK
;
328 retCode
= lhs
->evaluate(lhsResult
);
329 if (retCode
!= OK
) return ErrInvalidExpr
;
330 }else lhsResult
= true;
333 retCode
= rhs
->evaluate(rhsResult
);
334 if (retCode
!= OK
) return ErrInvalidExpr
;
335 } else rhsResult
= true;
338 //Means it involves only Logical operator
339 if (OpAnd
== logicalOp
) {
340 if (lhsResult
&& rhsResult
) result
= true;
341 }else if (OpOr
== logicalOp
) {
342 if (lhsResult
|| rhsResult
) result
= true;
343 }else if (OpNot
== logicalOp
){
344 if (lhsResult
) result
= false; else result
= true;
346 printDebug(DM_Predicate
, "result is %d", result
);
351 DbRetVal
PredicateImpl::evaluateForHaving(bool &result
, AggTableImpl
*aImpl
, void *aggElement
)
353 bool rhsResult
= false, lhsResult
=false;
354 DbRetVal retCode
=OK
;
358 retCode
= lhs
->evaluateForHaving(lhsResult
, aImpl
, aggElement
);
359 if (retCode
!= OK
) return ErrInvalidExpr
;
360 }else lhsResult
= true;
363 retCode
= rhs
->evaluateForHaving(rhsResult
, aImpl
, aggElement
);
364 if (retCode
!= OK
) return ErrInvalidExpr
;
365 } else rhsResult
= true;
368 if (OpAnd
== logicalOp
) {
369 if (lhsResult
&& rhsResult
) result
= true;
370 }else if (OpOr
== logicalOp
) {
371 if (lhsResult
|| rhsResult
) result
= true;
372 }else if (OpNot
== logicalOp
){
373 if (lhsResult
) result
= false; else result
= true;
375 printDebug(DM_Predicate
, "result is %d", result
);
379 void *val1
= NULL
, *val2
=NULL
;
380 int offset
= aImpl
->getAggOffset(fldName1
, aggType
);
381 val1
= (void*)((char*)aggElement
+ offset
);
383 //sets the type and length when it is called first time
384 FieldInfo
*info
= new FieldInfo();
385 DbRetVal rv
= aImpl
->getFieldInfo(fldName1
, info
);
386 if (aggType
== AGG_AVG
) {
388 length
= sizeof(double);
389 } else if (aggType
== AGG_COUNT
) {
391 length
= sizeof(int);
394 length
= info
->length
;
399 if(operand
!= NULL
&& operandPtr
== NULL
)
401 val2
= (char*) operand
;
403 else if(operand
== NULL
&& operandPtr
!= NULL
)
405 val2
= *(char**)operandPtr
;
407 if (aggType
== AGG_AVG
) {
409 AllDataType::convertToDouble(&dVal2
, val2
, type
);
410 result
= AllDataType::compareVal(val1
, &dVal2
, compOp
, typeDouble
, length
);
412 else if (aggType
== AGG_COUNT
) {
414 AllDataType::convertToInt(&dVal2
, val2
, type
);
415 result
= AllDataType::compareVal(val1
, &dVal2
, compOp
, typeInt
, length
);
418 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
, length
);
422 DbRetVal
PredicateImpl::evaluateLogicalForTable(bool &result
, char *tuple
)
424 bool rhsResult
= false, lhsResult
=false;
425 DbRetVal retCode
=OK
;
429 lhs
->evaluateForTable(lhsResult
, tuple
);
430 }else lhsResult
= true;
433 rhs
->evaluateForTable(rhsResult
, tuple
);
434 } else rhsResult
= true;
437 //Means it involves only Logical operator
438 if (OpAnd
== logicalOp
) {
439 if (lhsResult
&& rhsResult
) result
= true;
440 }else if (OpOr
== logicalOp
) {
441 if (lhsResult
|| rhsResult
) result
= true;
442 }else if (OpNot
== logicalOp
){
443 if (lhsResult
) result
= false; else result
= true;
445 printDebug(DM_Predicate
, "result is %d", result
);
449 void PredicateImpl::evaluateForTable(bool &result
, char *tuple
)
451 if (!isNoLeftRight
) {
452 bool rhsResult
= false;
455 rhs
->evaluateForTable(rhsResult
, tuple
);
456 if(rhsResult
== false && OpAnd
== logicalOp
) {//do early return
459 } else rhsResult
= true;
460 bool lhsResult
= false;
463 lhs
->evaluateForTable(lhsResult
, tuple
);
464 }else lhsResult
= true;
467 //Means it involves only Logical operator
468 if (OpAnd
== logicalOp
) {
469 if (lhsResult
&& rhsResult
) result
= true;
470 }else if (OpOr
== logicalOp
) {
471 if (lhsResult
|| rhsResult
) result
= true;
472 }else if (OpNot
== logicalOp
){
473 if (lhsResult
) result
= false; else result
= true;
475 printDebug(DM_Predicate
, "result is %d", result
);
479 //Table null check of condition
481 TableImpl
*tImpl
= (TableImpl
*) table
;
482 tImpl
->setCurTuple(tuple
);
483 bool isValueNull
= table
->isFldNull(fldPos
);
484 if(compOp
== OpIsNull
)
486 if( (isValueNull
&& isNull
) || (!isValueNull
&& !isNull
) )
498 //the below code works only for single table
499 val1
= tuple
+ offset1
;
500 if(offset2
!= -1 && operand
== NULL
&& operandPtr
== NULL
)
501 val2
= tuple
+ offset2
;
503 //Assumes that fldName2 data type is also same for expr f1 <f2
504 //Note:Perf: Do not change the order below
505 if(operand
== NULL
&& operandPtr
!= NULL
)
507 val2
= *(char**)operandPtr
;
508 if (compOp
== OpLike
) {
509 char *c
= (char *)val2
;
510 //OPT:If LIKE has only %, then no need to evaluate
511 if (*c
== '%' && *(c
+1) == '\0') {result
=true; return;}
512 Util::changeWildcardChar(val2
);
515 } else if (operand
== NULL
&& operandPtr
== NULL
)
518 val2
= tuple
+ offset2
;
519 } else if(operand
!= NULL
&& operandPtr
== NULL
)
521 val2
= (char*) operand
;
522 if (compOp
== OpLike
) {
523 char *c
= (char *)val2
;
524 if (*c
== '%' && *(c
+1) == '\0') {result
=true; return;}
525 Util::changeWildcardChar(val2
);
528 if(operand2
== NULL
&& operand2Ptr
!= NULL
)
530 val3
= *(char**)operand2Ptr
;
531 } else if(operand2
!= NULL
&& operand2Ptr
== NULL
)
533 val3
= (char*) operand2
;
539 //printf(" val1 %d val3 %d\n", *(int*)val1, *(int*)val3);
540 result
= AllDataType::compareVal(val1
, val3
, comp2Op
, type
,length
);
541 if(result
==false) return;
546 //printf(" val1 %d val2 %d\n", *(int*)val1, *(int*)val2);
547 if (type
!= typeVarchar
)
548 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,length
);
549 else result
= AllDataType::compareVal((void *) *(long *) val1
, val2
,
550 compOp
, type
,length
);
551 //if (!result && val3) AllDataType::copyVal(val3,
554 void* PredicateImpl::getValIfPointLookupOnInt(int &offset
)
556 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
557 if(typeInt
!= type
|| comp2Op
!=OpInvalidComparisionOp
) return NULL
;
558 if (compOp
!= OpEquals
) return NULL
;
561 if(operand
== NULL
&& operandPtr
!= NULL
)
563 val
= *(void**)operandPtr
;
564 } else if(operand
!= NULL
&& operandPtr
== NULL
)
566 val
= (void*) operand
;
570 void* PredicateImpl::getVal1IfBetweenOnInt(int &offset
)
572 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
573 if(typeInt
!= type
) return NULL
;
574 if (compOp
!= OpGreaterThanEquals
||
575 comp2Op
!=OpLessThanEquals
) return NULL
;
578 if(operand
== NULL
&& operandPtr
!= NULL
)
580 val
= *(void**)operandPtr
;
581 } else if(operand
!= NULL
&& operandPtr
== NULL
)
583 val
= (void*) operand
;
587 void* PredicateImpl::getVal2IfBetweenOnInt(int &offset
)
589 if (NULL
!= lhs
&& NULL
!= rhs
) return NULL
;
590 if(typeInt
!= type
) return NULL
;
591 if (compOp
!= OpGreaterThanEquals
||
592 comp2Op
!=OpLessThanEquals
) return NULL
;
595 if(operand2
== NULL
&& operand2Ptr
!= NULL
)
597 val
= *(void**)operand2Ptr
;
598 } else if(operand2
!= NULL
&& operand2Ptr
== NULL
)
600 val
= (void*) operand2
;
604 DbRetVal
PredicateImpl::evaluate(bool &result
)
606 if (!isNoLeftRight
) {
607 bool rhsResult
= false, lhsResult
=false;
608 DbRetVal retCode
=OK
;
612 retCode
= lhs
->evaluate(lhsResult
);
613 if (retCode
< OK
) return ErrInvalidExpr
;
614 }else lhsResult
= true;
617 retCode
= rhs
->evaluate(rhsResult
);
618 if (retCode
< OK
) return ErrInvalidExpr
;
619 } else rhsResult
= true;
622 //Means it involves only Logical operator
623 if (OpAnd
== logicalOp
) {
624 if (lhsResult
&& rhsResult
) result
= true;
625 }else if (OpOr
== logicalOp
) {
626 if (lhsResult
|| rhsResult
) result
= true;
627 }else if (OpNot
== logicalOp
){
628 if (lhsResult
) result
= false; else result
= true;
629 if ( ErrNullValues
== retCode
) result
= false;
631 printDebug(DM_Predicate
, "result is %d", result
);
635 //Means it is relational expression
636 //first operand is always field identifier
637 //get the value in the tuple
639 if (dontEvaluate
) {result
= true; return OK
; }
642 //for join node evaluation
643 ListIterator fIter
= projList
->getIterator();
644 JoinProjFieldInfo
*def
;
646 while (fIter
.hasElement())
648 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
649 if (NULL
!= def
->bindBuf
) {
650 if (0 == strcmp(fldName1
, def
->tabFieldName
))
652 val1
= (char*)def
->bindBuf
;
654 length
= def
->length
;
658 printError(ErrNotExists
, "Field not binded %s.%s\n",
659 def
->tableName
, def
->fieldName
);
663 if (operand
== NULL
&& operandPtr
== NULL
)
665 char fieldName2
[IDENTIFIER_LENGTH
];
666 memset(fieldName2
, 0, IDENTIFIER_LENGTH
);
667 Table::getFieldNameAlone(fldName2
, fieldName2
);
670 while (fIter
.hasElement())
672 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
673 if (NULL
!= def
->bindBuf
) {
674 if (0 == strcmp(fldName2
, def
->tabFieldName
))
676 val2
= (char*)def
->bindBuf
;
680 printError(ErrNotExists
, "Field not binded %s.%s\n",
681 def
->tableName
, def
->fieldName
);
687 else if(operand
!= NULL
&& operandPtr
== NULL
)
689 val2
= (char*) operand
;
691 else if(operand
== NULL
&& operandPtr
!= NULL
)
693 val2
= *(char**)operandPtr
;
697 JoinTableImpl
*jTable
= (JoinTableImpl
*) table
;
698 if (jTable
->isFldNullInt(fldName1
) || jTable
->isFldNullInt(fldName2
))
701 return ErrNullValues
;
703 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,
708 printf("PRABA::wrong method call\n");
709 //the below code works only for single table
710 val1
= (char*)tuple
+ offset1
;
711 if(offset2
!= -1 && operand
== NULL
&& operandPtr
== NULL
)
712 val2
= ((char*)tuple
) + offset2
;
714 //Assumes that fldName2 data type is also same for expr f1 <f2
715 //Note:Perf: Do not change the order below
716 if(operand
== NULL
&& operandPtr
!= NULL
)
718 val2
= *(char**)operandPtr
;
720 else if (operand
== NULL
&& operandPtr
== NULL
)
723 val2
= ((char*)tuple
) + offset2
;
725 else if(operand
!= NULL
&& operandPtr
== NULL
)
727 val2
= (char*) operand
;
731 result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,length
);
735 void PredicateImpl::solveForProjList(Table
*tab
)
739 lhs
->solveForProjList(tab
);
743 rhs
->solveForProjList(tab
);
746 if (NULL
!= lhs
) return ;
751 ListIterator fIter
= projList
->getIterator();
752 JoinProjFieldInfo
*def
;
753 while (fIter
.hasElement())
755 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
756 if (!isExist1
&& 0 == strcmp(fldName1
, def
->tabFieldName
))
760 if (!isExist2
&& 0 == strcmp(fldName2
, def
->tabFieldName
) )
767 tab
->bindFld(fldName1
, NULL
);
769 if (!isExist2
&& strcmp(fldName2
, "")!=0)
771 tab
->bindFld(fldName2
, NULL
);
776 void PredicateImpl::setOffsetAndType()
780 lhs
->setOffsetAndType();
784 rhs
->setOffsetAndType();
786 char fieldName1
[IDENTIFIER_LENGTH
];
787 char fieldName2
[IDENTIFIER_LENGTH
];
788 memset(fieldName1
, 0, IDENTIFIER_LENGTH
);
789 memset(fieldName2
, 0, IDENTIFIER_LENGTH
);
790 Table::getFieldNameAlone(fldName1
, fieldName1
);
791 Table::getFieldNameAlone(fldName2
, fieldName2
);
792 //this function is called only from TableImpl
793 TableImpl
*tImpl
= (TableImpl
*) table
;
795 FieldInfo
*info
= new FieldInfo();
796 tImpl
->getFieldInfo(fieldName1
, info
);
797 offset1
= tImpl
->getFieldOffset(fieldName1
);
798 fldPos
= tImpl
->getFldPos(fieldName1
);
800 length
= info
->length
;
802 if (info
->isNull
|| info
->isPrimary
||
803 info
->isDefault
|| info
->isAutoIncrement
)
805 //printf("isNullable is set to %d\n", isNullable);
810 offset2
= tImpl
->getFieldOffset(fieldName2
);
811 if(typeUnknown
== type
)
812 type
= tImpl
->getFieldType(fieldName2
);
817 bool PredicateImpl::pointLookupInvolved(const char *fname
)
819 bool rhsResult
, lhsResult
;
822 lhsResult
= lhs
->pointLookupInvolved(fname
);
826 rhsResult
= rhs
->pointLookupInvolved(fname
);
830 //Means it involves only Logical operator
835 if (lhsResult
|| rhsResult
) return true; else return false;
846 //Means it is relational expression
847 //first operand is always field identifier
848 char fieldName1
[IDENTIFIER_LENGTH
];
849 Table::getFieldNameAlone(fldName1
, fieldName1
);
850 if (OpEquals
== compOp
)
852 //for expressions f1 == f2 use full scan, so return false
853 if(NULL
== operand
&& NULL
== operandPtr
) return false;
854 if(0 == strcmp(fieldName1
, fname
))
862 bool PredicateImpl::isBetweenInvolved(const char *fname
)
864 bool rhsResult
, lhsResult
;
867 lhsResult
= lhs
->isBetweenInvolved(fname
);
871 rhsResult
= rhs
->isBetweenInvolved(fname
);
878 if (lhsResult
&& rhsResult
) return true; else return false;
885 char fieldName1
[IDENTIFIER_LENGTH
];
886 Table::getFieldNameAlone(fldName1
, fieldName1
);
887 if ( OpGreaterThan
== compOp
|| OpGreaterThanEquals
== compOp
)
889 if(0 == strcmp(fieldName1
, fname
))
897 bool PredicateImpl::rangeQueryInvolved(const char *fname
)
899 bool rhsResult
, lhsResult
;
902 lhsResult
= lhs
->rangeQueryInvolved(fname
);
906 rhsResult
= rhs
->rangeQueryInvolved(fname
);
913 if (lhsResult
|| rhsResult
) return true; else return false;
924 //Means it is relational expression
925 //first operand is always field identifier
926 char fieldName1
[IDENTIFIER_LENGTH
];
927 Table::getFieldNameAlone(fldName1
, fieldName1
);
928 if (OpLessThan
== compOp
|| OpLessThanEquals
== compOp
||
929 OpGreaterThan
== compOp
|| OpGreaterThanEquals
== compOp
)
931 //for expressions f1 == f2 use full scan, so return false
932 if(NULL
== operand
&& NULL
== operandPtr
) return false;
933 if(0 == strcmp(fieldName1
, fname
))
941 void* PredicateImpl::opAndValPtrForIndexField(const char *fname
, bool isUnique
,ComparisionOp
&op
)
943 ComparisionOp lhsOp
= OpInvalidComparisionOp
, rhsOp
= OpInvalidComparisionOp
;
944 void *lhsRet
=NULL
, *rhsRet
=NULL
;
947 lhsRet
= lhs
->opAndValPtrForIndexField(fname
, isUnique
, lhsOp
);
951 rhsRet
= rhs
->opAndValPtrForIndexField(fname
, isUnique
,rhsOp
);
953 if (lhsRet
&& lhsOp
== OpEquals
) { op
= lhsOp
; return lhsRet
;}
954 if (rhsRet
&& rhsOp
== OpEquals
) { op
= rhsOp
; return rhsRet
;}
957 if( lhsRet
) { op
= lhsOp
; return lhsRet
; }
958 if( rhsRet
) { op
= rhsOp
; return rhsRet
; }
960 char fieldName1
[IDENTIFIER_LENGTH
];
961 Table::getFieldNameAlone(fldName1
, fieldName1
);
962 //Means it is relational expression
963 //first operand is always field identifier
964 if(0 == strcmp(fieldName1
, fname
))
967 if (isUnique
&& compOp
!= OpLessThan
&&
968 compOp
!= OpLessThanEquals
) isPushedDown
= true;
969 if (operand
) return operand
; else return *(void**)operandPtr
;
971 op
= OpInvalidComparisionOp
;
976 //called only in case of hash index scan
977 void* PredicateImpl::valPtrForIndexField(const char *fname
, bool isUnique
)
979 void *lhsRet
=NULL
, *rhsRet
=NULL
;
982 lhsRet
= lhs
->valPtrForIndexField(fname
, isUnique
);
983 if ( lhsRet
!= NULL
) return lhsRet
;
987 rhsRet
= rhs
->valPtrForIndexField(fname
, isUnique
);
988 if ( rhsRet
!= NULL
) return rhsRet
;
990 char fieldName1
[IDENTIFIER_LENGTH
];
991 Table::getFieldNameAlone(fldName1
, fieldName1
);
992 //Means it is relational expression
993 //first operand is always field identifier
994 if (OpEquals
== compOp
)
996 if(0 == strcmp(fieldName1
, fname
))
998 if (isUnique
) isPushedDown
= true;
999 if (operand
) return operand
; else return *(void**)operandPtr
;
1004 ComparisionOp
PredicateImpl::opForIndexField(const char *fname
)
1006 ComparisionOp lhsRet
= OpInvalidComparisionOp
, rhsRet
= OpInvalidComparisionOp
;
1009 lhsRet
= lhs
->opForIndexField(fname
);
1010 if ( lhsRet
!= OpInvalidComparisionOp
) return lhsRet
;
1015 rhsRet
= rhs
->opForIndexField(fname
);
1016 if ( rhsRet
!= OpInvalidComparisionOp
) return rhsRet
;
1018 char fieldName1
[IDENTIFIER_LENGTH
];
1019 Table::getFieldNameAlone(fldName1
, fieldName1
);
1020 if(0 == strcmp(fieldName1
, fname
))
1024 return OpInvalidComparisionOp
;
1026 PredicateImpl
* PredicateImpl::getTablePredicate()
1028 PredicateImpl
*lhsRet
= NULL
, *rhsRet
= NULL
;
1031 lhsRet
= lhs
->getTablePredicate();
1032 if ( lhsRet
!= NULL
) return lhsRet
;
1036 rhsRet
= rhs
->getTablePredicate();
1037 if ( rhsRet
!= NULL
) return rhsRet
;
1039 if (operand
|| operandPtr
)
1041 //printf("PRABA::getTablePredicate returning %s %d\n", fldName1, compOp);
1044 if (this == parent
->lhs
) {
1056 PredicateImpl
* PredicateImpl::getJoinPredicate()
1058 PredicateImpl
*lhsRet
= NULL
, *rhsRet
= NULL
;
1061 lhsRet
= lhs
->getJoinPredicate();
1062 if ( lhsRet
!= NULL
) return lhsRet
;
1066 rhsRet
= rhs
->getJoinPredicate();
1067 if ( rhsRet
!= NULL
) return rhsRet
;
1069 if (0 != strcmp(fldName2
, ""))
1071 //printf("PRABA::getJoinPredicate returning %s %s\n", fldName1, fldName2);
1074 if (this == parent
->lhs
)
1084 void PredicateImpl::removeIfNotNecessary()
1088 lhs
->removeIfNotNecessary();
1092 rhs
->removeIfNotNecessary();
1094 if (logicalOp
!= OpAnd
) return;
1095 if (NULL
== lhs
&& NULL
== rhs
)
1101 if (this == parent
->rhs
) parent
->rhs
= NULL
;
1102 else if (this == parent
->lhs
) parent
->lhs
= NULL
;
1103 //TODO::PRABA::fix the leak below. if uncommented dumps core
1105 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1106 //current object is deleted. do not any code here
1109 else if (NULL
== lhs
)
1111 //left side of the node is empty means we can remove this AND node
1112 //and place it as left or right of my parent where i am currently placed
1117 if (this == parent
->rhs
) parent
->rhs
=this->rhs
;
1118 else if (this == parent
->lhs
) parent
->lhs
= this->rhs
;
1119 //TODO::PRABA::fix the leak below. if uncommented dumps core
1121 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1122 //current object is deleted. do not any code here
1125 else if (NULL
== rhs
)
1127 //right side of the node is empty means we can remove this AND node
1128 //and place it as left or right of my parent where i am currently placed
1133 if (this == parent
->rhs
) parent
->rhs
=this->lhs
;
1134 else if (this == parent
->lhs
) parent
->lhs
= this->lhs
;
1135 //TODO::PRABA::fix the leak below. if uncommented dumps core
1137 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1138 //current object is deleted. do not any code here
1143 bool PredicateImpl::isDummyPredicate()
1145 if (NULL
== lhs
&& NULL
== rhs
&& NULL
== parent
1146 && NULL
== operand
&& NULL
== operandPtr
&&
1147 (0 == strcmp(fldName1
, "")) && (0==strcmp(fldName2
, "")))
1152 PredicateImpl
* PredicateImpl::getIfOneSidedPredicate()
1154 if (logicalOp
!= OpAnd
) return NULL
;
1155 if (NULL
== lhs
&& NULL
!=rhs
)
1159 if (NULL
!= lhs
&& NULL
==rhs
)