truncating redo log file instead of removing it
[csql.git] / src / storage / PredicateImpl.cxx
blobe2b42754c70584597d1784b22ffe7b32f91d5d65
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 if (op == OpLike)
102 char *c = (char *) opnd;
103 while (*c != '\0')
105 if (*c == '_') *c = '?';
106 else if(*c == '%') *c = '*';
107 c++;
110 compOp = op;
111 operand = opnd;
112 operandPtr = NULL;
113 lhs = rhs = NULL;
114 parent = NULL;
115 logicalOp = OpInvalidLogicalOp;
116 comp2Op = OpInvalidComparisionOp;
117 operand2 =NULL;
118 operand2Ptr = NULL;
120 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op,bool nullFlag)
122 strcpy(fldName1, fName1);
123 compOp = op;
124 isNull = nullFlag;
125 lhs = rhs = NULL;
126 operandPtr = NULL;
127 operand = NULL;
128 logicalOp = OpInvalidLogicalOp;
129 comp2Op = OpInvalidComparisionOp;
130 operand2 =NULL;
131 operand2Ptr = NULL;
134 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd)
136 strcpy(fldName1, fName1);
137 compOp = op;
138 operand = NULL;
139 operandPtr = opnd;
140 lhs = rhs = NULL;
141 parent = NULL;
142 logicalOp = OpInvalidLogicalOp;
143 comp2Op = OpInvalidComparisionOp;
144 operand2 =NULL;
145 operand2Ptr = NULL;
147 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd, AggType aType)
149 strcpy(fldName1, fName1);
150 compOp = op;
151 operand = NULL;
152 operandPtr = opnd;
153 lhs = rhs = NULL;
154 parent = NULL;
155 aggType = aType;
156 logicalOp = OpInvalidLogicalOp;
157 comp2Op = OpInvalidComparisionOp;
158 operand2 =NULL;
159 operand2Ptr = NULL;
162 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd,
163 ComparisionOp op2, void **opnd2)
165 strcpy(fldName1, fName1);
166 compOp = op;
167 operand = NULL;
168 operandPtr = opnd;
169 lhs = rhs = NULL;
170 parent = NULL;
171 logicalOp = OpInvalidLogicalOp;
173 comp2Op = op2;
174 operand2=NULL;
175 operand2Ptr = opnd2;
178 void PredicateImpl::setParent(PredicateImpl *pImpl)
180 //if (parent != NULL) printf("Parent already set\n");
181 parent = pImpl;
182 return;
184 void PredicateImpl::setTerm(Predicate *p1, LogicalOp op, Predicate *p2 )
186 if (p2 == NULL && op != OpNot || op == OpNot && p2 != NULL)
188 //TODO::printError
189 printError(ErrBadArg, "Wrong argument passed\n");
190 return;
192 lhs = (PredicateImpl*)p1;
193 rhs = (PredicateImpl*)p2;
194 logicalOp = op;
195 compOp = OpInvalidComparisionOp;
196 if (lhs != NULL) lhs->setParent(this);
197 if (rhs != NULL) rhs->setParent(this);
198 return;
201 void PredicateImpl::setTable(Table *tbl)
203 if (NULL != lhs)
204 lhs->setTable(tbl);
205 if (NULL != rhs)
206 rhs->setTable(tbl);
207 table = tbl;
209 void PredicateImpl::setIfNoLeftRight()
211 if (NULL != lhs)
212 lhs->setIfNoLeftRight();
213 if (NULL != rhs)
214 rhs->setIfNoLeftRight();
215 if(NULL == lhs && NULL == rhs) isNoLeftRight=true;
216 return;
219 void PredicateImpl::setTuple(void *tpl)
221 if (isNoLeftRight) {
222 tuple=tpl;
223 return;
225 if (NULL != lhs)
226 lhs->setTuple(tpl);
227 if (NULL != rhs)
228 rhs->setTuple(tpl);
229 tuple = tpl;
231 void PredicateImpl::setProjectionList(List *lst)
233 if (NULL != lhs)
234 lhs->setProjectionList(lst);
235 if (NULL != rhs)
236 rhs->setProjectionList(lst);
237 projList = lst;
238 isBindBufSet = false;
240 bool PredicateImpl::isSingleTerm()
242 if (NULL == lhs && NULL == rhs && comp2Op == OpInvalidComparisionOp)
243 return true;
244 return false;
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; }
260 comp2Op = compOp;
261 compOp = op;
262 operand = buf;
263 operandPtr = NULL;
265 comp2Op = op;
266 operand2 = buf;
268 return true;
270 return false;
272 bool PredicateImpl::isIsNullInvolved()
274 bool lhsResult = true, rhsResult = true;
275 if (NULL != lhs)
277 lhsResult = lhs->isIsNullInvolved();
279 if (NULL != rhs)
281 rhsResult = rhs->isIsNullInvolved();
283 if (NULL != lhs)
285 if (lhsResult || rhsResult) return true;
286 if(compOp == isNull) return true;
288 return false;
290 bool PredicateImpl::isNotOrInvolved()
292 bool lhsResult = true, rhsResult = true;
293 if (NULL != lhs)
295 lhsResult = lhs->isNotOrInvolved();
297 if (NULL != rhs)
299 rhsResult = rhs->isNotOrInvolved();
301 if (NULL != lhs)
303 //Means it involves only Logical operator
304 switch(logicalOp)
306 case OpAnd:
307 if (lhsResult || rhsResult) return true; else return false;
308 break;
309 case OpOr:
310 return true;
311 break;
312 case OpNot:
313 default:
314 return true;
315 break;
318 return false;
321 DbRetVal PredicateImpl::evaluateLogical(bool &result)
323 bool rhsResult = false, lhsResult=false;
324 DbRetVal retCode =OK;
325 result = false;
326 if (NULL != lhs)
328 retCode = lhs->evaluate(lhsResult);
329 if (retCode != OK) return ErrInvalidExpr;
330 }else lhsResult = true;
331 if (NULL != rhs)
333 retCode = rhs->evaluate(rhsResult);
334 if (retCode != OK) return ErrInvalidExpr;
335 } else rhsResult = true;
336 if (NULL != lhs)
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);
348 return OK;
351 DbRetVal PredicateImpl::evaluateForHaving(bool &result, AggTableImpl *aImpl, void *aggElement)
353 bool rhsResult = false, lhsResult=false;
354 DbRetVal retCode =OK;
355 result = false;
356 if (NULL != lhs)
358 retCode = lhs->evaluateForHaving(lhsResult, aImpl, aggElement);
359 if (retCode != OK) return ErrInvalidExpr;
360 }else lhsResult = true;
361 if (NULL != rhs)
363 retCode = rhs->evaluateForHaving(rhsResult, aImpl, aggElement);
364 if (retCode != OK) return ErrInvalidExpr;
365 } else rhsResult = true;
366 if (NULL != lhs)
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);
376 return OK;
379 void *val1 = NULL, *val2 =NULL;
380 int offset = aImpl->getAggOffset(fldName1, aggType);
381 val1 = (void*)((char*)aggElement + offset);
382 if (!isBindBufSet) {
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) {
387 type = typeDouble;
388 length = sizeof(double);
389 } else if (aggType == AGG_COUNT) {
390 type = typeInt;
391 length = sizeof(int);
392 } else {
393 type = info->type;
394 length = info->length;
396 delete info;
397 isBindBufSet = true;
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) {
408 double dVal2 = 0;
409 AllDataType::convertToDouble(&dVal2, val2, type);
410 result = AllDataType::compareVal(val1, &dVal2, compOp, typeDouble, length);
412 else if (aggType == AGG_COUNT) {
413 int dVal2 = 0;
414 AllDataType::convertToInt(&dVal2, val2, type);
415 result = AllDataType::compareVal(val1, &dVal2, compOp, typeInt, length);
417 else
418 result = AllDataType::compareVal(val1, val2, compOp, type, length);
419 return OK;
422 DbRetVal PredicateImpl::evaluateLogicalForTable(bool &result, char *tuple)
424 bool rhsResult = false, lhsResult=false;
425 DbRetVal retCode =OK;
426 result = false;
427 if (NULL != lhs)
429 lhs->evaluateForTable(lhsResult, tuple);
430 }else lhsResult = true;
431 if (NULL != rhs)
433 rhs->evaluateForTable(rhsResult, tuple);
434 } else rhsResult = true;
435 if (NULL != lhs)
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);
447 return OK;
449 void PredicateImpl::evaluateForTable(bool &result, char *tuple)
451 if (!isNoLeftRight) {
452 bool rhsResult = false;
453 if (NULL != rhs)
455 rhs->evaluateForTable(rhsResult, tuple);
456 if(rhsResult == false && OpAnd == logicalOp) {//do early return
457 return;
459 } else rhsResult = true;
460 bool lhsResult = false;
461 if (NULL != lhs)
463 lhs->evaluateForTable(lhsResult, tuple);
464 }else lhsResult = true;
465 if (NULL != lhs)
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);
476 return ;
479 //Table null check of condition
480 if (isNullable) {
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) )
487 result = true;
488 else
489 result = false;
490 return;
492 if(isValueNull)
494 result=false;
495 return;
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;
502 if (!isBindBufSet) {
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)
517 if(offset2 != -1)
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;
535 isBindBufSet = true;
537 result = true;
538 if(val3) {
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;
543 if (isPushedDown) {
544 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,
552 return;
554 void* PredicateImpl::getValIfPointLookupOnInt(int &offset)
555 { //perf opt
556 if (NULL != lhs && NULL != rhs) return NULL;
557 if(typeInt != type || comp2Op !=OpInvalidComparisionOp) return NULL;
558 if (compOp != OpEquals) return NULL;
559 offset = offset1;
560 void *val =NULL;
561 if(operand == NULL && operandPtr != NULL)
563 val = *(void**)operandPtr;
564 } else if(operand != NULL && operandPtr == NULL)
566 val = (void*) operand;
568 return val;
570 void* PredicateImpl::getVal1IfBetweenOnInt(int &offset)
571 { //perf opt
572 if (NULL != lhs && NULL != rhs) return NULL;
573 if(typeInt != type) return NULL;
574 if (compOp != OpGreaterThanEquals ||
575 comp2Op !=OpLessThanEquals) return NULL;
576 offset = offset1;
577 void *val =NULL;
578 if(operand == NULL && operandPtr != NULL)
580 val = *(void**)operandPtr;
581 } else if(operand != NULL && operandPtr == NULL)
583 val = (void*) operand;
585 return val;
587 void* PredicateImpl::getVal2IfBetweenOnInt(int &offset)
588 { //perf opt
589 if (NULL != lhs && NULL != rhs) return NULL;
590 if(typeInt != type) return NULL;
591 if (compOp != OpGreaterThanEquals ||
592 comp2Op !=OpLessThanEquals) return NULL;
593 offset = offset1;
594 void *val =NULL;
595 if(operand2 == NULL && operand2Ptr != NULL)
597 val = *(void**)operand2Ptr;
598 } else if(operand2 != NULL && operand2Ptr == NULL)
600 val = (void*) operand2;
602 return val;
604 DbRetVal PredicateImpl::evaluate(bool &result)
606 if (!isNoLeftRight) {
607 bool rhsResult = false, lhsResult=false;
608 DbRetVal retCode =OK;
609 result = false;
610 if (NULL != lhs)
612 retCode = lhs->evaluate(lhsResult);
613 if (retCode < OK) return ErrInvalidExpr;
614 }else lhsResult = true;
615 if (NULL != rhs)
617 retCode = rhs->evaluate(rhsResult);
618 if (retCode < OK) return ErrInvalidExpr;
619 } else rhsResult = true;
620 if (NULL != lhs)
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);
632 return OK;
635 //Means it is relational expression
636 //first operand is always field identifier
637 //get the value in the tuple
638 if (projList) {
639 if (dontEvaluate) {result= true; return OK; }
640 if (!isBindBufSet)
642 //for join node evaluation
643 ListIterator fIter = projList->getIterator();
644 JoinProjFieldInfo *def;
645 //char *val1, *val2;
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;
653 type = def->type;
654 length = def->length;
655 break;
657 }else{
658 printError(ErrNotExists, "Field not binded %s.%s\n",
659 def->tableName, def->fieldName);
660 return ErrNotExists;
663 if (operand == NULL && operandPtr == NULL)
665 char fieldName2[IDENTIFIER_LENGTH];
666 memset(fieldName2, 0, IDENTIFIER_LENGTH);
667 Table::getFieldNameAlone(fldName2, fieldName2);
668 if (fieldName2) {
669 fIter.reset();
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;
677 break;
679 }else{
680 printError(ErrNotExists, "Field not binded %s.%s\n",
681 def->tableName, def->fieldName);
682 return ErrNotExists;
687 else if(operand != NULL && operandPtr == NULL)
689 val2 = (char*) operand;
691 else if(operand == NULL && operandPtr != NULL)
693 val2 = *(char**)operandPtr;
695 isBindBufSet = true;
697 JoinTableImpl *jTable = (JoinTableImpl*) table;
698 if (jTable->isFldNullInt(fldName1) || jTable->isFldNullInt(fldName2))
700 result=false;
701 return ErrNullValues;
703 result = AllDataType::compareVal(val1, val2, compOp, type,
704 length);
705 return OK;
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;
713 if (!isBindBufSet) {
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)
722 if(offset2 != -1)
723 val2 = ((char*)tuple) + offset2;
725 else if(operand != NULL && operandPtr == NULL)
727 val2 = (char*) operand;
729 isBindBufSet = true;
731 result = AllDataType::compareVal(val1, val2, compOp, type,length);
732 return OK;
735 void PredicateImpl::solveForProjList(Table *tab)
737 if (NULL != lhs)
739 lhs->solveForProjList(tab);
741 if (NULL != rhs)
743 rhs->solveForProjList(tab);
745 table = tab;
746 if (NULL != lhs) return ;
747 bool isExist1=false;
748 bool isExist2=false;
749 if (projList)
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))
758 isExist1=true;
760 if (!isExist2 && 0 == strcmp(fldName2, def->tabFieldName) )
762 isExist2=true;
765 if (!isExist1)
767 tab->bindFld(fldName1, NULL);
769 if (!isExist2 && strcmp(fldName2, "")!=0)
771 tab->bindFld(fldName2, NULL);
776 void PredicateImpl::setOffsetAndType()
778 if (NULL != lhs)
780 lhs->setOffsetAndType();
782 if (NULL != rhs)
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;
794 if(fieldName1){
795 FieldInfo *info = new FieldInfo();
796 tImpl->getFieldInfo(fieldName1, info);
797 offset1 = tImpl->getFieldOffset(fieldName1);
798 fldPos = tImpl->getFldPos(fieldName1);
799 type = info->type;
800 length = info->length;
801 isNullable = true;
802 if (info->isNull || info->isPrimary ||
803 info->isDefault || info->isAutoIncrement)
804 isNullable = false;
805 //printf("isNullable is set to %d\n", isNullable);
806 delete info;
809 if(fieldName2){
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;
820 if (NULL != lhs)
822 lhsResult = lhs->pointLookupInvolved(fname);
824 if (NULL != rhs)
826 rhsResult = rhs->pointLookupInvolved(fname);
828 if (NULL != lhs)
830 //Means it involves only Logical operator
831 switch(logicalOp)
833 case OpAnd:
834 //return lhsResult;
835 if (lhsResult || rhsResult) return true; else return false;
836 break;
837 case OpOr:
838 return false;
839 break;
840 case OpNot:
841 default:
842 return false;
843 break;
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))
856 return true;
859 return false;
862 bool PredicateImpl::isBetweenInvolved(const char *fname)
864 bool rhsResult, lhsResult;
865 if (NULL != lhs)
867 lhsResult = lhs->isBetweenInvolved(fname);
869 if (NULL != rhs)
871 rhsResult = rhs->isBetweenInvolved(fname);
873 if (NULL != lhs)
875 switch(logicalOp)
877 case OpAnd:
878 if (lhsResult && rhsResult) return true; else return false;
879 break;
880 default:
881 return false;
882 break;
885 char fieldName1[IDENTIFIER_LENGTH];
886 Table::getFieldNameAlone(fldName1, fieldName1);
887 if ( OpGreaterThan == compOp || OpGreaterThanEquals == compOp)
889 if(0 == strcmp(fieldName1, fname))
891 return true;
894 return false;
897 bool PredicateImpl::rangeQueryInvolved(const char *fname)
899 bool rhsResult, lhsResult;
900 if (NULL != lhs)
902 lhsResult = lhs->rangeQueryInvolved(fname);
904 if (NULL != rhs)
906 rhsResult = rhs->rangeQueryInvolved(fname);
908 if (NULL != lhs)
910 switch(logicalOp)
912 case OpAnd:
913 if (lhsResult || rhsResult) return true; else return false;
914 break;
915 case OpOr:
916 return false;
917 break;
918 case OpNot:
919 default:
920 return false;
921 break;
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))
935 return true;
938 return false;
941 void* PredicateImpl::opAndValPtrForIndexField(const char *fname, bool isUnique,ComparisionOp &op)
943 ComparisionOp lhsOp= OpInvalidComparisionOp, rhsOp= OpInvalidComparisionOp;
944 void *lhsRet=NULL, *rhsRet=NULL;
945 if (NULL != lhs)
947 lhsRet = lhs->opAndValPtrForIndexField(fname, isUnique, lhsOp);
949 if (NULL != rhs)
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;}
955 if (NULL != lhs)
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))
966 op = compOp;
967 if (isUnique && compOp != OpLessThan &&
968 compOp != OpLessThanEquals) isPushedDown = true;
969 if (operand) return operand; else return *(void**)operandPtr;
971 op = OpInvalidComparisionOp;
972 return NULL;
976 //called only in case of hash index scan
977 void* PredicateImpl::valPtrForIndexField(const char *fname, bool isUnique)
979 void *lhsRet=NULL, *rhsRet=NULL;
980 if (NULL != lhs)
982 lhsRet = lhs->valPtrForIndexField(fname, isUnique);
983 if ( lhsRet != NULL) return lhsRet;
985 if (NULL != rhs)
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;
1002 return NULL;
1004 ComparisionOp PredicateImpl::opForIndexField(const char *fname)
1006 ComparisionOp lhsRet= OpInvalidComparisionOp, rhsRet= OpInvalidComparisionOp;
1007 if (NULL != lhs)
1009 lhsRet = lhs->opForIndexField(fname);
1010 if ( lhsRet != OpInvalidComparisionOp) return lhsRet;
1013 if (NULL != rhs)
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))
1022 return compOp;
1024 return OpInvalidComparisionOp;
1026 PredicateImpl* PredicateImpl::getTablePredicate()
1028 PredicateImpl *lhsRet = NULL, *rhsRet = NULL;
1029 if (NULL != lhs)
1031 lhsRet = lhs->getTablePredicate();
1032 if ( lhsRet != NULL) return lhsRet;
1034 if (NULL != rhs)
1036 rhsRet = rhs->getTablePredicate();
1037 if ( rhsRet != NULL) return rhsRet;
1039 if (operand || operandPtr )
1041 //printf("PRABA::getTablePredicate returning %s %d\n", fldName1, compOp);
1042 if (parent)
1044 if (this == parent->lhs) {
1045 parent->lhs = NULL;
1047 else {
1048 parent->rhs = NULL;
1050 parent = NULL;
1052 return this;
1054 return NULL;
1056 PredicateImpl* PredicateImpl::getJoinPredicate()
1058 PredicateImpl *lhsRet = NULL, *rhsRet = NULL;
1059 if (NULL != lhs)
1061 lhsRet = lhs->getJoinPredicate();
1062 if ( lhsRet != NULL) return lhsRet;
1064 if (NULL != rhs)
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);
1072 if (parent)
1074 if (this == parent->lhs)
1075 parent->lhs = NULL;
1076 else
1077 parent->rhs = NULL;
1078 parent = NULL;
1080 return this;
1082 return NULL;
1084 void PredicateImpl::removeIfNotNecessary()
1086 if (NULL != lhs)
1088 lhs->removeIfNotNecessary();
1090 if (NULL != rhs)
1092 rhs->removeIfNotNecessary();
1094 if (logicalOp != OpAnd) return;
1095 if (NULL == lhs && NULL == rhs)
1097 if (NULL == parent)
1099 return;
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
1104 //delete this;
1105 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1106 //current object is deleted. do not any code here
1107 return;
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
1113 if (NULL == parent)
1115 return;
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
1120 //delete this;
1121 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1122 //current object is deleted. do not any code here
1123 return;
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
1129 if (NULL == parent)
1131 return;
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
1136 //delete this;
1137 //WARNINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1138 //current object is deleted. do not any code here
1139 return;
1141 return;
1143 bool PredicateImpl::isDummyPredicate()
1145 if (NULL == lhs && NULL == rhs && NULL == parent
1146 && NULL == operand && NULL == operandPtr &&
1147 (0 == strcmp(fldName1, "")) && (0==strcmp(fldName2, "")))
1148 return true;
1149 else
1150 return false;
1152 PredicateImpl* PredicateImpl::getIfOneSidedPredicate()
1154 if (logicalOp != OpAnd) return NULL;
1155 if (NULL == lhs && NULL !=rhs)
1157 return rhs;
1159 if (NULL != lhs && NULL ==rhs)
1161 return lhs;
1163 return NULL;