*** empty log message ***
[csql.git] / src / storage / PredicateImpl.cxx
blob0aafc2e3294fe8d760d25d77b7398efdb29fd6a1
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 compOp = op;
101 operand = opnd;
102 operandPtr = NULL;
103 lhs = rhs = NULL;
104 parent = NULL;
105 logicalOp = OpInvalidLogicalOp;
106 comp2Op = OpInvalidComparisionOp;
107 operand2 =NULL;
108 operand2Ptr = NULL;
110 void PredicateImpl::setTerm(Expression *exp, ComparisionOp op, void **opnd)
112 compOp = op;
113 lhs = rhs = NULL;
114 operandPtr = opnd;
115 operand = NULL;
116 logicalOp = OpInvalidLogicalOp;
117 comp2Op = OpInvalidComparisionOp;
118 operand2 =NULL;
119 operand2Ptr = NULL;
120 lExp = exp;
122 void PredicateImpl::setTerm(Expression *exp1, ComparisionOp op, Expression *exp2)
124 compOp = op;
125 lhs = rhs = NULL;
126 operandPtr = NULL;
127 operand = NULL;
128 logicalOp = OpInvalidLogicalOp;
129 comp2Op = OpInvalidComparisionOp;
130 operand2 =NULL;
131 operand2Ptr = NULL;
132 lExp = exp1;
133 rExp = exp2;
135 void PredicateImpl::setTerm(Expression *exp, ComparisionOp op, const char *fName2 )
137 strcpy(fldName2, fName2);
138 compOp = op;
139 operand = NULL;
140 operandPtr = NULL;
141 lhs = rhs = NULL;
142 parent = NULL;
143 logicalOp = OpInvalidLogicalOp;
144 comp2Op = OpInvalidComparisionOp;
145 operand2 =NULL;
146 operand2Ptr = NULL;
147 lExp = exp;
148 return;
151 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op,bool nullFlag)
153 strcpy(fldName1, fName1);
154 compOp = op;
155 isNull = nullFlag;
156 lhs = rhs = NULL;
157 operandPtr = NULL;
158 operand = NULL;
159 logicalOp = OpInvalidLogicalOp;
160 comp2Op = OpInvalidComparisionOp;
161 operand2 =NULL;
162 operand2Ptr = NULL;
165 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd)
167 strcpy(fldName1, fName1);
168 compOp = op;
169 operand = NULL;
170 operandPtr = opnd;
171 lhs = rhs = NULL;
172 parent = NULL;
173 logicalOp = OpInvalidLogicalOp;
174 comp2Op = OpInvalidComparisionOp;
175 operand2 =NULL;
176 operand2Ptr = NULL;
178 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd, AggType aType)
180 strcpy(fldName1, fName1);
181 compOp = op;
182 operand = NULL;
183 operandPtr = opnd;
184 lhs = rhs = NULL;
185 parent = NULL;
186 aggType = aType;
187 logicalOp = OpInvalidLogicalOp;
188 comp2Op = OpInvalidComparisionOp;
189 operand2 =NULL;
190 operand2Ptr = NULL;
193 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd,
194 ComparisionOp op2, void **opnd2)
196 strcpy(fldName1, fName1);
197 compOp = op;
198 operand = NULL;
199 operandPtr = opnd;
200 lhs = rhs = NULL;
201 parent = NULL;
202 logicalOp = OpInvalidLogicalOp;
204 comp2Op = op2;
205 operand2=NULL;
206 operand2Ptr = opnd2;
209 void PredicateImpl::setParent(PredicateImpl *pImpl)
211 //if (parent != NULL) printf("Parent already set\n");
212 parent = pImpl;
213 return;
215 void PredicateImpl::setTerm(Predicate *p1, LogicalOp op, Predicate *p2 )
217 if (p2 == NULL && op != OpNot || op == OpNot && p2 != NULL)
219 //TODO::printError
220 printError(ErrBadArg, "Wrong argument passed\n");
221 return;
223 lhs = (PredicateImpl*)p1;
224 rhs = (PredicateImpl*)p2;
225 logicalOp = op;
226 compOp = OpInvalidComparisionOp;
227 if (lhs != NULL) lhs->setParent(this);
228 if (rhs != NULL) rhs->setParent(this);
229 return;
232 void PredicateImpl::setTable(Table *tbl)
234 if (NULL != lhs)
235 lhs->setTable(tbl);
236 if (NULL != rhs)
237 rhs->setTable(tbl);
238 table = tbl;
240 void PredicateImpl::setIfNoLeftRight()
242 if (NULL != lhs)
243 lhs->setIfNoLeftRight();
244 if (NULL != rhs)
245 rhs->setIfNoLeftRight();
246 if(NULL == lhs && NULL == rhs) isNoLeftRight=true;
247 return;
250 void PredicateImpl::setTuple(void *tpl)
252 if (isNoLeftRight) {
253 tuple=tpl;
254 return;
256 if (NULL != lhs)
257 lhs->setTuple(tpl);
258 if (NULL != rhs)
259 rhs->setTuple(tpl);
260 tuple = tpl;
262 void PredicateImpl::setProjectionList(List *lst)
264 if (NULL != lhs)
265 lhs->setProjectionList(lst);
266 if (NULL != rhs)
267 rhs->setProjectionList(lst);
268 projList = lst;
269 isBindBufSet = false;
271 bool PredicateImpl::isSingleTerm()
273 if (NULL == lhs && NULL == rhs && comp2Op == OpInvalidComparisionOp)
274 return true;
275 return false;
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; }
291 comp2Op = compOp;
292 compOp = op;
293 operand = buf;
294 operandPtr = NULL;
296 comp2Op = op;
297 operand2 = buf;
299 return true;
301 return false;
303 bool PredicateImpl::isIsNullInvolved()
305 bool lhsResult = true, rhsResult = true;
306 if (NULL != lhs)
308 lhsResult = lhs->isIsNullInvolved();
310 if (NULL != rhs)
312 rhsResult = rhs->isIsNullInvolved();
314 if (NULL != lhs)
316 if (lhsResult || rhsResult) return true;
317 if(compOp == isNull) return true;
319 return false;
321 bool PredicateImpl::isNotOrInvolved()
323 bool lhsResult = true, rhsResult = true;
324 if (NULL != lhs)
326 lhsResult = lhs->isNotOrInvolved();
328 if (NULL != rhs)
330 rhsResult = rhs->isNotOrInvolved();
332 if (NULL != lhs)
334 //Means it involves only Logical operator
335 switch(logicalOp)
337 case OpAnd:
338 if (lhsResult || rhsResult) return true; else return false;
339 break;
340 case OpOr:
341 return true;
342 break;
343 case OpNot:
344 default:
345 return true;
346 break;
349 return false;
352 DbRetVal PredicateImpl::evaluateLogical(bool &result)
354 bool rhsResult = false, lhsResult=false;
355 DbRetVal retCode =OK;
356 result = false;
357 if (NULL != lhs)
359 retCode = lhs->evaluate(lhsResult);
360 if (retCode != OK) return ErrInvalidExpr;
361 }else lhsResult = true;
362 if (NULL != rhs)
364 retCode = rhs->evaluate(rhsResult);
365 if (retCode != OK) return ErrInvalidExpr;
366 } else rhsResult = true;
367 if (NULL != lhs)
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);
379 return OK;
382 DbRetVal PredicateImpl::evaluateForHaving(bool &result, AggTableImpl *aImpl, void *aggElement)
384 bool rhsResult = false, lhsResult=false;
385 DbRetVal retCode =OK;
386 result = false;
387 if (NULL != lhs)
389 retCode = lhs->evaluateForHaving(lhsResult, aImpl, aggElement);
390 if (retCode != OK) return ErrInvalidExpr;
391 }else lhsResult = true;
392 if (NULL != rhs)
394 retCode = rhs->evaluateForHaving(rhsResult, aImpl, aggElement);
395 if (retCode != OK) return ErrInvalidExpr;
396 } else rhsResult = true;
397 if (NULL != lhs)
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);
407 return OK;
410 void *val1 = NULL, *val2 =NULL;
411 int offset = aImpl->getAggOffset(fldName1, aggType);
412 val1 = (void*)((char*)aggElement + offset);
413 if (!isBindBufSet) {
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) {
418 type = typeDouble;
419 length = sizeof(double);
420 } else if (aggType == AGG_COUNT) {
421 type = typeInt;
422 length = sizeof(int);
423 } else {
424 type = info->type;
425 length = info->length;
427 delete info;
428 isBindBufSet = true;
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) {
439 double dVal2 = 0;
440 AllDataType::convertToDouble(&dVal2, val2, type);
441 result = AllDataType::compareVal(val1, &dVal2, compOp, typeDouble, length);
443 else if (aggType == AGG_COUNT) {
444 int dVal2 = 0;
445 AllDataType::convertToInt(&dVal2, val2, type);
446 result = AllDataType::compareVal(val1, &dVal2, compOp, typeInt, length);
448 else
449 result = AllDataType::compareVal(val1, val2, compOp, type, length);
450 return OK;
453 DbRetVal PredicateImpl::evaluateLogicalForTable(bool &result, char *tuple)
455 bool rhsResult = false, lhsResult=false;
456 DbRetVal retCode =OK;
457 result = false;
458 if (NULL != lhs)
460 lhs->evaluateForTable(lhsResult, tuple);
461 }else lhsResult = true;
462 if (NULL != rhs)
464 rhs->evaluateForTable(rhsResult, tuple);
465 } else rhsResult = true;
466 if (NULL != lhs)
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);
478 return OK;
480 void PredicateImpl::evaluateForTable(bool &result, char *tuple)
482 if (!isNoLeftRight) {
483 bool rhsResult = false;
484 if (NULL != rhs)
486 rhs->evaluateForTable(rhsResult, tuple);
487 if(rhsResult == false && OpAnd == logicalOp) {//do early return
488 return;
490 } else rhsResult = true;
491 bool lhsResult = false;
492 if (NULL != lhs)
494 lhs->evaluateForTable(lhsResult, tuple);
495 }else lhsResult = true;
496 if (NULL != lhs)
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);
507 return ;
510 //Table null check of condition
511 if(lExp || rExp){
512 void* val=NULL;
513 void* rval = NULL;
514 TableImpl *tImpl = (TableImpl*) table;
515 if(lExp){
516 lExp->setTable(tImpl);
517 lExp->setTuple(tuple);
518 val = lExp->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(lExp->getFunctionType()));
520 if(rExp) {
521 rExp->setTable(tImpl);
522 rExp->setTuple(tuple);
523 rval = rExp->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(rExp->getFunctionType()));
525 if( val && rval){
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);
533 }else{
534 result =false;
537 return;
539 if (isNullable) {
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) )
546 result = true;
547 else
548 result = false;
549 return;
551 if(isValueNull)
553 result=false;
554 return;
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;
561 if (!isBindBufSet) {
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)
576 if(offset2 != -1)
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;
594 isBindBufSet = true;
596 result = true;
597 if(val3) {
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;
602 if (isPushedDown) {
603 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,
611 return;
613 void* PredicateImpl::getValIfPointLookupOnInt(int &offset)
614 { //perf opt
615 if (NULL != lhs && NULL != rhs) return NULL;
616 if(typeInt != type || comp2Op !=OpInvalidComparisionOp) return NULL;
617 if (compOp != OpEquals) return NULL;
618 offset = offset1;
619 void *val =NULL;
620 if(operand == NULL && operandPtr != NULL)
622 val = *(void**)operandPtr;
623 } else if(operand != NULL && operandPtr == NULL)
625 val = (void*) operand;
627 return val;
629 void* PredicateImpl::getVal1IfBetweenOnInt(int &offset)
630 { //perf opt
631 if (NULL != lhs && NULL != rhs) return NULL;
632 if(typeInt != type) return NULL;
633 if (compOp != OpGreaterThanEquals ||
634 comp2Op !=OpLessThanEquals) return NULL;
635 offset = offset1;
636 void *val =NULL;
637 if(operand == NULL && operandPtr != NULL)
639 val = *(void**)operandPtr;
640 } else if(operand != NULL && operandPtr == NULL)
642 val = (void*) operand;
644 return val;
646 void* PredicateImpl::getVal2IfBetweenOnInt(int &offset)
647 { //perf opt
648 if (NULL != lhs && NULL != rhs) return NULL;
649 if(typeInt != type) return NULL;
650 if (compOp != OpGreaterThanEquals ||
651 comp2Op !=OpLessThanEquals) return NULL;
652 offset = offset1;
653 void *val =NULL;
654 if(operand2 == NULL && operand2Ptr != NULL)
656 val = *(void**)operand2Ptr;
657 } else if(operand2 != NULL && operand2Ptr == NULL)
659 val = (void*) operand2;
661 return val;
663 DbRetVal PredicateImpl::evaluate(bool &result)
665 if (!isNoLeftRight) {
666 bool rhsResult = false, lhsResult=false;
667 DbRetVal retCode =OK;
668 result = false;
669 if (NULL != lhs)
671 retCode = lhs->evaluate(lhsResult);
672 if (retCode < OK) return ErrInvalidExpr;
673 }else lhsResult = true;
674 if (NULL != rhs)
676 retCode = rhs->evaluate(rhsResult);
677 if (retCode < OK) return ErrInvalidExpr;
678 } else rhsResult = true;
679 if (NULL != lhs)
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);
691 return OK;
694 //Means it is relational expression
695 //first operand is always field identifier
696 //get the value in the tuple
697 if (projList) {
698 if (dontEvaluate) {result= true; return OK; }
699 if (!isBindBufSet)
701 //for join node evaluation
702 ListIterator fIter = projList->getIterator();
703 JoinProjFieldInfo *def;
704 //char *val1, *val2;
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;
712 type = def->type;
713 length = def->length;
714 break;
716 }else{
717 printError(ErrNotExists, "Field not binded %s.%s\n",
718 def->tableName, def->fieldName);
719 return ErrNotExists;
722 if (operand == NULL && operandPtr == NULL)
724 char fieldName2[IDENTIFIER_LENGTH];
725 memset(fieldName2, 0, IDENTIFIER_LENGTH);
726 Table::getFieldNameAlone(fldName2, fieldName2);
727 if (fieldName2) {
728 fIter.reset();
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;
736 break;
738 }else{
739 printError(ErrNotExists, "Field not binded %s.%s\n",
740 def->tableName, def->fieldName);
741 return ErrNotExists;
746 else if(operand != NULL && operandPtr == NULL)
748 val2 = (char*) operand;
750 else if(operand == NULL && operandPtr != NULL)
752 val2 = *(char**)operandPtr;
754 isBindBufSet = true;
756 JoinTableImpl *jTable = (JoinTableImpl*) table;
757 if (jTable->isFldNullInt(fldName1) || jTable->isFldNullInt(fldName2))
759 result=false;
760 return ErrNullValues;
762 result = AllDataType::compareVal(val1, val2, compOp, type,
763 length);
764 return OK;
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;
772 if (!isBindBufSet) {
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)
781 if(offset2 != -1)
782 val2 = ((char*)tuple) + offset2;
784 else if(operand != NULL && operandPtr == NULL)
786 val2 = (char*) operand;
788 isBindBufSet = true;
790 result = AllDataType::compareVal(val1, val2, compOp, type,length);
791 return OK;
794 void PredicateImpl::solveForProjList(Table *tab)
796 if (NULL != lhs)
798 lhs->solveForProjList(tab);
800 if (NULL != rhs)
802 rhs->solveForProjList(tab);
804 table = tab;
805 if (NULL != lhs) return ;
806 bool isExist1=false;
807 bool isExist2=false;
808 if (projList)
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))
817 isExist1=true;
819 if (!isExist2 && 0 == strcmp(fldName2, def->tabFieldName) )
821 isExist2=true;
824 if (!isExist1)
826 tab->bindFld(fldName1, NULL);
828 if (!isExist2 && strcmp(fldName2, "")!=0)
830 tab->bindFld(fldName2, NULL);
835 void PredicateImpl::setOffsetAndType()
837 if (NULL != lhs)
839 lhs->setOffsetAndType();
841 if (NULL != rhs)
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;
853 if(fieldName1){
854 FieldInfo *info = new FieldInfo();
855 tImpl->getFieldInfo(fieldName1, info);
856 offset1 = tImpl->getFieldOffset(fieldName1);
857 fldPos = tImpl->getFldPos(fieldName1);
858 type = info->type;
859 length = info->length;
860 isNullable = true;
861 if (info->isNull || info->isPrimary || info->isAutoIncrement)
862 isNullable = false;
863 //printf("isNullable is set to %d\n", isNullable);
864 delete info;
867 if(fieldName2){
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;
878 if (NULL != lhs)
880 lhsResult = lhs->pointLookupInvolved(fname);
882 if (NULL != rhs)
884 rhsResult = rhs->pointLookupInvolved(fname);
886 if (NULL != lhs)
888 //Means it involves only Logical operator
889 switch(logicalOp)
891 case OpAnd:
892 //return lhsResult;
893 if (lhsResult || rhsResult) return true; else return false;
894 break;
895 case OpOr:
896 return false;
897 break;
898 case OpNot:
899 default:
900 return false;
901 break;
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))
914 return true;
917 return false;
920 bool PredicateImpl::isBetweenInvolved(const char *fname)
922 bool rhsResult, lhsResult;
923 if (NULL != lhs)
925 lhsResult = lhs->isBetweenInvolved(fname);
927 if (NULL != rhs)
929 rhsResult = rhs->isBetweenInvolved(fname);
931 if (NULL != lhs)
933 switch(logicalOp)
935 case OpAnd:
936 if (lhsResult && rhsResult) return true; else return false;
937 break;
938 default:
939 return false;
940 break;
943 char fieldName1[IDENTIFIER_LENGTH];
944 Table::getFieldNameAlone(fldName1, fieldName1);
945 if ( OpGreaterThan == compOp || OpGreaterThanEquals == compOp)
947 if(0 == strcmp(fieldName1, fname))
949 return true;
952 return false;
955 bool PredicateImpl::rangeQueryInvolved(const char *fname)
957 bool rhsResult, lhsResult;
958 if (NULL != lhs)
960 lhsResult = lhs->rangeQueryInvolved(fname);
962 if (NULL != rhs)
964 rhsResult = rhs->rangeQueryInvolved(fname);
966 if (NULL != lhs)
968 switch(logicalOp)
970 case OpAnd:
971 if (lhsResult || rhsResult) return true; else return false;
972 break;
973 case OpOr:
974 return false;
975 break;
976 case OpNot:
977 default:
978 return false;
979 break;
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))
993 return true;
996 return false;
999 void* PredicateImpl::opAndValPtrForIndexField(const char *fname, bool isUnique,ComparisionOp &op)
1001 ComparisionOp lhsOp= OpInvalidComparisionOp, rhsOp= OpInvalidComparisionOp;
1002 void *lhsRet=NULL, *rhsRet=NULL;
1003 if (NULL != lhs)
1005 lhsRet = lhs->opAndValPtrForIndexField(fname, isUnique, lhsOp);
1007 if (NULL != rhs)
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;}
1013 if (NULL != lhs)
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))
1024 op = compOp;
1025 if (isUnique && compOp != OpLessThan &&
1026 compOp != OpLessThanEquals) isPushedDown = true;
1027 if (operand) return operand; else return *(void**)operandPtr;
1029 op = OpInvalidComparisionOp;
1030 return NULL;
1034 //called only in case of hash index scan
1035 void* PredicateImpl::valPtrForIndexField(const char *fname, bool isUnique)
1037 void *lhsRet=NULL, *rhsRet=NULL;
1038 if (NULL != lhs)
1040 lhsRet = lhs->valPtrForIndexField(fname, isUnique);
1041 if ( lhsRet != NULL) return lhsRet;
1043 if (NULL != rhs)
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;
1060 return NULL;
1062 ComparisionOp PredicateImpl::opForIndexField(const char *fname)
1064 ComparisionOp lhsRet= OpInvalidComparisionOp, rhsRet= OpInvalidComparisionOp;
1065 if (NULL != lhs)
1067 lhsRet = lhs->opForIndexField(fname);
1068 if ( lhsRet != OpInvalidComparisionOp) return lhsRet;
1071 if (NULL != rhs)
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))
1080 return compOp;
1082 return OpInvalidComparisionOp;
1084 PredicateImpl* PredicateImpl::getTablePredicate()
1086 PredicateImpl *lhsRet = NULL, *rhsRet = NULL;
1087 if (NULL != lhs)
1089 lhsRet = lhs->getTablePredicate();
1090 if ( lhsRet != NULL) return lhsRet;
1092 if (NULL != rhs)
1094 rhsRet = rhs->getTablePredicate();
1095 if ( rhsRet != NULL) return rhsRet;
1097 if (operand || operandPtr )
1099 //printf("PRABA::getTablePredicate returning %s %d\n", fldName1, compOp);
1100 if (parent)
1102 if (this == parent->lhs) {
1103 parent->lhs = NULL;
1105 else {
1106 parent->rhs = NULL;
1108 parent = NULL;
1110 return this;
1112 return NULL;
1114 PredicateImpl* PredicateImpl::getJoinPredicate()
1116 PredicateImpl *lhsRet = NULL, *rhsRet = NULL;
1117 if (NULL != lhs)
1119 lhsRet = lhs->getJoinPredicate();
1120 if ( lhsRet != NULL) return lhsRet;
1122 if (NULL != rhs)
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);
1130 if (parent)
1132 if (this == parent->lhs)
1133 parent->lhs = NULL;
1134 else
1135 parent->rhs = NULL;
1136 parent = NULL;
1138 return this;
1140 return NULL;
1142 void PredicateImpl::removeIfNotNecessary()
1144 if (NULL != lhs)
1146 lhs->removeIfNotNecessary();
1148 if (NULL != rhs)
1150 rhs->removeIfNotNecessary();
1152 if (logicalOp != OpAnd) return;
1153 if (NULL == lhs && NULL == rhs)
1155 if (NULL == parent)
1157 return;
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
1162 //delete this;
1163 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1164 //current object is deleted. do not any code here
1165 return;
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
1171 if (NULL == parent)
1173 return;
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
1178 //delete this;
1179 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1180 //current object is deleted. do not any code here
1181 return;
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
1187 if (NULL == parent)
1189 return;
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
1194 //delete this;
1195 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1196 //current object is deleted. do not any code here
1197 return;
1199 return;
1201 bool PredicateImpl::isDummyPredicate()
1203 if (NULL == lhs && NULL == rhs && NULL == parent
1204 && NULL == operand && NULL == operandPtr &&
1205 (0 == strcmp(fldName1, "")) && (0==strcmp(fldName2, "")))
1206 return true;
1207 else
1208 return false;
1210 PredicateImpl* PredicateImpl::getIfOneSidedPredicate()
1212 if (logicalOp != OpAnd) return NULL;
1213 if (NULL == lhs && NULL !=rhs)
1215 return rhs;
1217 if (NULL != lhs && NULL ==rhs)
1219 return lhs;
1221 return NULL;