autoinc and tree index predicate fix
[csql.git] / src / storage / PredicateImpl.cxx
blob87e7e7fc4e7ebe7f9136e1a55b9d4533f9e55f63
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 result = false;
489 return;
491 } else rhsResult = true;
492 bool lhsResult = false;
493 if (NULL != lhs)
495 lhs->evaluateForTable(lhsResult, tuple);
496 }else lhsResult = true;
497 if (NULL != lhs)
499 //Means it involves only Logical operator
500 if (OpAnd == logicalOp) {
501 if (lhsResult && rhsResult) result = true;
502 }else if (OpOr == logicalOp) {
503 if (lhsResult || rhsResult) result = true;
504 }else if (OpNot == logicalOp){
505 if (lhsResult) result = false; else result = true;
507 printDebug(DM_Predicate, "result is %d", result);
508 return ;
511 //Table null check of condition
512 if(lExp || rExp){
513 void* val=NULL;
514 void* rval = NULL;
515 TableImpl *tImpl = (TableImpl*) table;
516 if(lExp){
517 lExp->setTable(tImpl);
518 lExp->setTuple(tuple);
519 val = lExp->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(lExp->getFunctionType()));
521 if(rExp) {
522 rExp->setTable(tImpl);
523 rExp->setTuple(tuple);
524 rval = rExp->evaluateForFunction(AllDataType::getCsqlTypeFromFunctionType(rExp->getFunctionType()));
526 if( val && rval){
527 result = AllDataType::compareVal(val, rval, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
528 }else if( val && operandPtr!=NULL){
529 val2 = *(char**)operandPtr;
530 result = AllDataType::compareVal(val, val2, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
531 }else if(val && (offset2 != -1 && operand == NULL && operandPtr == NULL)){
532 val2 = tuple + offset2;
533 result = AllDataType::compareVal(val, val2, compOp, AllDataType::getCsqlTypeFromFunctionTypeForComparision(lExp->getFunctionType()),length);
534 }else{
535 result =false;
538 return;
540 if (isNullable) {
541 TableImpl *tImpl = (TableImpl*) table;
542 tImpl->setCurTuple(tuple);
543 bool isValueNull = table->isFldNull(fldPos);
544 if(compOp == OpIsNull)
546 if( (isValueNull && isNull) || (!isValueNull && !isNull) )
547 result = true;
548 else
549 result = false;
550 return;
552 if(isValueNull)
554 result=false;
555 return;
558 //the below code works only for single table
559 val1= tuple + offset1;
560 if(offset2 != -1 && operand == NULL && operandPtr == NULL)
561 val2 = tuple + offset2;
562 if (!isBindBufSet) {
563 //Assumes that fldName2 data type is also same for expr f1 <f2
564 //Note:Perf: Do not change the order below
565 if(operand == NULL && operandPtr != NULL)
567 val2 = *(char**)operandPtr;
568 if (compOp == OpLike) {
569 char *c = (char *)val2;
570 //OPT:If LIKE has only %, then no need to evaluate
571 if (*c == '%' && *(c+1) == '\0') {result=true; return;}
572 Util::changeWildcardChar(val2);
575 } else if (operand == NULL && operandPtr == NULL)
577 if(offset2 != -1)
578 val2 = tuple + offset2;
579 } else if(operand != NULL && operandPtr == NULL)
581 val2 = (char*) operand;
582 if (compOp == OpLike) {
583 char *c = (char *)val2;
584 if (*c == '%' && *(c+1) == '\0') {result=true; return;}
585 Util::changeWildcardChar(val2);
588 if(operand2 == NULL && operand2Ptr != NULL)
590 val3 = *(char**)operand2Ptr;
591 } else if(operand2 != NULL && operand2Ptr == NULL)
593 val3 = (char*) operand2;
595 isBindBufSet = true;
597 result = true;
598 if(val3) {
599 //printf(" val1 %d val3 %d\n", *(int*)val1, *(int*)val3);
600 result = AllDataType::compareVal(val1, val3, comp2Op, type,length);
601 if(result==false) return;
603 if (isPushedDown) {
604 return;
606 //printf(" val1 %d val2 %d\n", *(int*)val1, *(int*)val2);
607 if (type != typeVarchar)
608 result = AllDataType::compareVal(val1, val2, compOp, type,length);
609 else
610 result = AllDataType::compareVal((void *) *(long *) val1, val2,
611 compOp, type,length);
612 return;
614 void* PredicateImpl::getValIfPointLookupOnInt(int &offset)
615 { //perf opt
616 if (NULL != lhs && NULL != rhs) return NULL;
617 if(typeInt != type || comp2Op !=OpInvalidComparisionOp) return NULL;
618 if (compOp != OpEquals) return NULL;
619 offset = offset1;
620 void *val =NULL;
621 if(operand == NULL && operandPtr != NULL)
623 val = *(void**)operandPtr;
624 } else if(operand != NULL && operandPtr == NULL)
626 val = (void*) operand;
628 return val;
630 void* PredicateImpl::getVal1IfBetweenOnInt(int &offset)
631 { //perf opt
632 if (NULL != lhs && NULL != rhs) return NULL;
633 if(typeInt != type) return NULL;
634 if (compOp != OpGreaterThanEquals ||
635 comp2Op !=OpLessThanEquals) return NULL;
636 offset = offset1;
637 void *val =NULL;
638 if(operand == NULL && operandPtr != NULL)
640 val = *(void**)operandPtr;
641 } else if(operand != NULL && operandPtr == NULL)
643 val = (void*) operand;
645 return val;
647 void* PredicateImpl::getVal2IfBetweenOnInt(int &offset)
648 { //perf opt
649 if (NULL != lhs && NULL != rhs) return NULL;
650 if(typeInt != type) return NULL;
651 if (compOp != OpGreaterThanEquals ||
652 comp2Op !=OpLessThanEquals) return NULL;
653 offset = offset1;
654 void *val =NULL;
655 if(operand2 == NULL && operand2Ptr != NULL)
657 val = *(void**)operand2Ptr;
658 } else if(operand2 != NULL && operand2Ptr == NULL)
660 val = (void*) operand2;
662 return val;
664 DbRetVal PredicateImpl::evaluate(bool &result)
666 if (!isNoLeftRight) {
667 bool rhsResult = false, lhsResult=false;
668 DbRetVal retCode =OK;
669 result = false;
670 if (NULL != lhs)
672 retCode = lhs->evaluate(lhsResult);
673 if (retCode < OK) return ErrInvalidExpr;
674 }else lhsResult = true;
675 if (NULL != rhs)
677 retCode = rhs->evaluate(rhsResult);
678 if (retCode < OK) return ErrInvalidExpr;
679 } else rhsResult = true;
680 if (NULL != lhs)
682 //Means it involves only Logical operator
683 if (OpAnd == logicalOp) {
684 if (lhsResult && rhsResult) result = true;
685 }else if (OpOr == logicalOp) {
686 if (lhsResult || rhsResult) result = true;
687 }else if (OpNot == logicalOp){
688 if (lhsResult) result = false; else result = true;
689 if ( ErrNullValues == retCode) result = false;
691 printDebug(DM_Predicate, "result is %d", result);
692 return OK;
695 //Means it is relational expression
696 //first operand is always field identifier
697 //get the value in the tuple
698 if (projList) {
699 if (dontEvaluate) {result= true; return OK; }
700 if (!isBindBufSet)
702 //for join node evaluation
703 ListIterator fIter = projList->getIterator();
704 JoinProjFieldInfo *def;
705 //char *val1, *val2;
706 while (fIter.hasElement())
708 def = (JoinProjFieldInfo*) fIter.nextElement();
709 if (NULL != def->bindBuf) {
710 if (0 == strcmp(fldName1, def->tabFieldName))
712 val1 = (char*)def->bindBuf;
713 type = def->type;
714 length = def->length;
715 break;
717 }else{
718 printError(ErrNotExists, "Field not binded %s.%s\n",
719 def->tableName, def->fieldName);
720 return ErrNotExists;
723 if (operand == NULL && operandPtr == NULL)
725 char fieldName2[IDENTIFIER_LENGTH];
726 memset(fieldName2, 0, IDENTIFIER_LENGTH);
727 Table::getFieldNameAlone(fldName2, fieldName2);
728 if (fieldName2) {
729 fIter.reset();
730 while (fIter.hasElement())
732 def = (JoinProjFieldInfo*) fIter.nextElement();
733 if (NULL != def->bindBuf) {
734 if (0 == strcmp(fldName2, def->tabFieldName))
736 val2 = (char*)def->bindBuf;
737 break;
739 }else{
740 printError(ErrNotExists, "Field not binded %s.%s\n",
741 def->tableName, def->fieldName);
742 return ErrNotExists;
747 else if(operand != NULL && operandPtr == NULL)
749 val2 = (char*) operand;
751 else if(operand == NULL && operandPtr != NULL)
753 val2 = *(char**)operandPtr;
755 isBindBufSet = true;
757 JoinTableImpl *jTable = (JoinTableImpl*) table;
758 if (jTable->isFldNullInt(fldName1) || jTable->isFldNullInt(fldName2))
760 result=false;
761 return ErrNullValues;
763 result = AllDataType::compareVal(val1, val2, compOp, type,
764 length);
765 return OK;
768 printf("PRABA::wrong method call\n");
769 //the below code works only for single table
770 val1= (char*)tuple + offset1;
771 if(offset2 != -1 && operand == NULL && operandPtr == NULL)
772 val2 = ((char*)tuple) + offset2;
773 if (!isBindBufSet) {
774 //Assumes that fldName2 data type is also same for expr f1 <f2
775 //Note:Perf: Do not change the order below
776 if(operand == NULL && operandPtr != NULL)
778 val2 = *(char**)operandPtr;
780 else if (operand == NULL && operandPtr == NULL)
782 if(offset2 != -1)
783 val2 = ((char*)tuple) + offset2;
785 else if(operand != NULL && operandPtr == NULL)
787 val2 = (char*) operand;
789 isBindBufSet = true;
791 result = AllDataType::compareVal(val1, val2, compOp, type,length);
792 return OK;
795 void PredicateImpl::solveForProjList(Table *tab)
797 if (NULL != lhs)
799 lhs->solveForProjList(tab);
801 if (NULL != rhs)
803 rhs->solveForProjList(tab);
805 table = tab;
806 if (NULL != lhs) return ;
807 bool isExist1=false;
808 bool isExist2=false;
809 if (projList)
811 ListIterator fIter = projList->getIterator();
812 JoinProjFieldInfo *def;
813 while (fIter.hasElement())
815 def = (JoinProjFieldInfo*) fIter.nextElement();
816 if (!isExist1 && 0 == strcmp(fldName1, def->tabFieldName))
818 isExist1=true;
820 if (!isExist2 && 0 == strcmp(fldName2, def->tabFieldName) )
822 isExist2=true;
825 if (!isExist1)
827 tab->bindFld(fldName1, NULL);
829 if (!isExist2 && strcmp(fldName2, "")!=0)
831 tab->bindFld(fldName2, NULL);
836 void PredicateImpl::setOffsetAndType()
838 if (NULL != lhs)
840 lhs->setOffsetAndType();
842 if (NULL != rhs)
844 rhs->setOffsetAndType();
846 char fieldName1[IDENTIFIER_LENGTH];
847 char fieldName2[IDENTIFIER_LENGTH];
848 memset(fieldName1, 0, IDENTIFIER_LENGTH);
849 memset(fieldName2, 0, IDENTIFIER_LENGTH);
850 Table::getFieldNameAlone(fldName1, fieldName1);
851 Table::getFieldNameAlone(fldName2, fieldName2);
852 //this function is called only from TableImpl
853 TableImpl *tImpl = (TableImpl*) table;
854 if(fieldName1){
855 FieldInfo *info = new FieldInfo();
856 tImpl->getFieldInfo(fieldName1, info);
857 offset1 = tImpl->getFieldOffset(fieldName1);
858 fldPos = tImpl->getFldPos(fieldName1);
859 type = info->type;
860 length = info->length;
861 isNullable = true;
862 if (info->isNull || info->isPrimary || info->isAutoIncrement)
863 isNullable = false;
864 //printf("isNullable is set to %d\n", isNullable);
865 delete info;
868 if(fieldName2){
869 offset2 = tImpl->getFieldOffset(fieldName2);
870 if(typeUnknown == type)
871 type = tImpl->getFieldType(fieldName2);
876 bool PredicateImpl::pointLookupInvolved(const char *fname)
878 bool rhsResult, lhsResult;
879 if (NULL != lhs)
881 lhsResult = lhs->pointLookupInvolved(fname);
883 if (NULL != rhs)
885 rhsResult = rhs->pointLookupInvolved(fname);
887 if (NULL != lhs)
889 //Means it involves only Logical operator
890 switch(logicalOp)
892 case OpAnd:
893 //return lhsResult;
894 if (lhsResult || rhsResult) return true; else return false;
895 break;
896 case OpOr:
897 return false;
898 break;
899 case OpNot:
900 default:
901 return false;
902 break;
905 //Means it is relational expression
906 //first operand is always field identifier
907 char fieldName1[IDENTIFIER_LENGTH];
908 Table::getFieldNameAlone(fldName1, fieldName1);
909 if (OpEquals == compOp)
911 //for expressions f1 == f2 use full scan, so return false
912 if(NULL == operand && NULL == operandPtr) return false;
913 if(0 == strcmp(fieldName1, fname))
915 return true;
918 return false;
921 bool PredicateImpl::isBetweenInvolved(const char *fname)
923 bool rhsResult, lhsResult;
924 if (NULL != lhs)
926 lhsResult = lhs->isBetweenInvolved(fname);
928 if (NULL != rhs)
930 rhsResult = rhs->isBetweenInvolved(fname);
932 if (NULL != lhs)
934 switch(logicalOp)
936 case OpAnd:
937 if (lhsResult && rhsResult) return true; else return false;
938 break;
939 default:
940 return false;
941 break;
944 char fieldName1[IDENTIFIER_LENGTH];
945 Table::getFieldNameAlone(fldName1, fieldName1);
946 if ( OpGreaterThan == compOp || OpGreaterThanEquals == compOp)
948 if(0 == strcmp(fieldName1, fname))
950 return true;
953 return false;
956 bool PredicateImpl::rangeQueryInvolved(const char *fname)
958 bool rhsResult, lhsResult;
959 if (NULL != lhs)
961 lhsResult = lhs->rangeQueryInvolved(fname);
963 if (NULL != rhs)
965 rhsResult = rhs->rangeQueryInvolved(fname);
967 if (NULL != lhs)
969 switch(logicalOp)
971 case OpAnd:
972 if (lhsResult || rhsResult) return true; else return false;
973 break;
974 case OpOr:
975 return false;
976 break;
977 case OpNot:
978 default:
979 return false;
980 break;
983 //Means it is relational expression
984 //first operand is always field identifier
985 char fieldName1[IDENTIFIER_LENGTH];
986 Table::getFieldNameAlone(fldName1, fieldName1);
987 if (OpLessThan == compOp || OpLessThanEquals == compOp ||
988 OpGreaterThan == compOp || OpGreaterThanEquals == compOp)
990 //for expressions f1 == f2 use full scan, so return false
991 if(NULL == operand && NULL == operandPtr) return false;
992 if(0 == strcmp(fieldName1, fname))
994 return true;
997 return false;
1000 void* PredicateImpl::opAndValPtrForIndexField(const char *fname, bool isUnique,ComparisionOp &op)
1002 ComparisionOp lhsOp= OpInvalidComparisionOp, rhsOp= OpInvalidComparisionOp;
1003 void *lhsRet=NULL, *rhsRet=NULL;
1004 if (NULL != lhs)
1006 lhsRet = lhs->opAndValPtrForIndexField(fname, isUnique, lhsOp);
1008 if (NULL != rhs)
1010 rhsRet = rhs->opAndValPtrForIndexField(fname, isUnique,rhsOp);
1012 if (lhsRet && lhsOp == OpEquals) { op = lhsOp; return lhsRet;}
1013 if (rhsRet && rhsOp == OpEquals) { op = rhsOp; return rhsRet;}
1014 if (NULL != lhs)
1016 if( lhsRet) { op = lhsOp; return lhsRet; }
1017 if( rhsRet) { op = rhsOp; return rhsRet; }
1019 char fieldName1[IDENTIFIER_LENGTH];
1020 Table::getFieldNameAlone(fldName1, fieldName1);
1021 //Means it is relational expression
1022 //first operand is always field identifier
1023 if(0 == strcmp(fieldName1, fname))
1025 op = compOp;
1026 if (isUnique && compOp != OpLessThan &&
1027 compOp != OpLessThanEquals &&
1028 compOp != OpNotEquals ) isPushedDown = true;
1029 if (operand) return operand; else return *(void**)operandPtr;
1031 op = OpInvalidComparisionOp;
1032 return NULL;
1036 //called only in case of hash index scan
1037 void* PredicateImpl::valPtrForIndexField(const char *fname, bool isUnique)
1039 void *lhsRet=NULL, *rhsRet=NULL;
1040 if (NULL != lhs)
1042 lhsRet = lhs->valPtrForIndexField(fname, isUnique);
1043 if ( lhsRet != NULL) return lhsRet;
1045 if (NULL != rhs)
1047 rhsRet = rhs->valPtrForIndexField(fname, isUnique);
1048 if ( rhsRet != NULL) return rhsRet;
1050 char fieldName1[IDENTIFIER_LENGTH];
1051 Table::getFieldNameAlone(fldName1, fieldName1);
1052 //Means it is relational expression
1053 //first operand is always field identifier
1054 if (OpEquals == compOp)
1056 if(0 == strcmp(fieldName1, fname))
1058 if (isUnique) isPushedDown = true;
1059 if (operand) return operand; else return *(void**)operandPtr;
1062 return NULL;
1064 ComparisionOp PredicateImpl::opForIndexField(const char *fname)
1066 ComparisionOp lhsRet= OpInvalidComparisionOp, rhsRet= OpInvalidComparisionOp;
1067 if (NULL != lhs)
1069 lhsRet = lhs->opForIndexField(fname);
1070 if ( lhsRet != OpInvalidComparisionOp) return lhsRet;
1073 if (NULL != rhs)
1075 rhsRet = rhs->opForIndexField(fname);
1076 if ( rhsRet != OpInvalidComparisionOp) return rhsRet;
1078 char fieldName1[IDENTIFIER_LENGTH];
1079 Table::getFieldNameAlone(fldName1, fieldName1);
1080 if(0 == strcmp(fieldName1, fname))
1082 return compOp;
1084 return OpInvalidComparisionOp;
1086 PredicateImpl* PredicateImpl::getTablePredicate()
1088 PredicateImpl *lhsRet = NULL, *rhsRet = NULL;
1089 if (NULL != lhs)
1091 lhsRet = lhs->getTablePredicate();
1092 if ( lhsRet != NULL) return lhsRet;
1094 if (NULL != rhs)
1096 rhsRet = rhs->getTablePredicate();
1097 if ( rhsRet != NULL) return rhsRet;
1099 if (operand || operandPtr )
1101 //printf("PRABA::getTablePredicate returning %s %d\n", fldName1, compOp);
1102 if (parent)
1104 if (this == parent->lhs) {
1105 parent->lhs = NULL;
1107 else {
1108 parent->rhs = NULL;
1110 parent = NULL;
1112 return this;
1114 return NULL;
1116 PredicateImpl* PredicateImpl::getJoinPredicate()
1118 PredicateImpl *lhsRet = NULL, *rhsRet = NULL;
1119 if (NULL != lhs)
1121 lhsRet = lhs->getJoinPredicate();
1122 if ( lhsRet != NULL) return lhsRet;
1124 if (NULL != rhs)
1126 rhsRet = rhs->getJoinPredicate();
1127 if ( rhsRet != NULL) return rhsRet;
1129 if (0 != strcmp(fldName2, ""))
1131 //printf("PRABA::getJoinPredicate returning %s %s\n", fldName1, fldName2);
1132 if (parent)
1134 if (this == parent->lhs)
1135 parent->lhs = NULL;
1136 else
1137 parent->rhs = NULL;
1138 parent = NULL;
1140 return this;
1142 return NULL;
1144 void PredicateImpl::removeIfNotNecessary()
1146 if (NULL != lhs)
1148 lhs->removeIfNotNecessary();
1150 if (NULL != rhs)
1152 rhs->removeIfNotNecessary();
1154 if (logicalOp != OpAnd) return;
1155 if (NULL == lhs && NULL == rhs)
1157 if (NULL == parent)
1159 return;
1161 if (this == parent->rhs) parent->rhs = NULL;
1162 else if (this == parent->lhs) parent->lhs = NULL;
1163 //TODO::PRABA::fix the leak below. if uncommented dumps core
1164 //delete this;
1165 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1166 //current object is deleted. do not any code here
1167 return;
1169 else if (NULL == lhs )
1171 //left side of the node is empty means we can remove this AND node
1172 //and place it as left or right of my parent where i am currently placed
1173 if (NULL == parent)
1175 return;
1177 if (this == parent->rhs) parent->rhs=this->rhs;
1178 else if (this == parent->lhs) parent->lhs = this->rhs;
1179 //TODO::PRABA::fix the leak below. if uncommented dumps core
1180 //delete this;
1181 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1182 //current object is deleted. do not any code here
1183 return;
1185 else if (NULL == rhs )
1187 //right side of the node is empty means we can remove this AND node
1188 //and place it as left or right of my parent where i am currently placed
1189 if (NULL == parent)
1191 return;
1193 if (this == parent->rhs) parent->rhs=this->lhs;
1194 else if (this == parent->lhs) parent->lhs = this->lhs;
1195 //TODO::PRABA::fix the leak below. if uncommented dumps core
1196 //delete this;
1197 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1198 //current object is deleted. do not any code here
1199 return;
1201 return;
1203 bool PredicateImpl::isDummyPredicate()
1205 if (NULL == lhs && NULL == rhs && NULL == parent
1206 && NULL == operand && NULL == operandPtr &&
1207 (0 == strcmp(fldName1, "")) && (0==strcmp(fldName2, "")))
1208 return true;
1209 else
1210 return false;
1212 PredicateImpl* PredicateImpl::getIfOneSidedPredicate()
1214 if (logicalOp != OpAnd) return NULL;
1215 if (NULL == lhs && NULL !=rhs)
1217 return rhs;
1219 if (NULL != lhs && NULL ==rhs)
1221 return lhs;
1223 return NULL;