1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 ***************************************************************************/
18 #include<CatalogTables.h>
21 #include<PredicateImpl.h>
25 #include<JoinTableImpl.h>
27 void PredicateImpl::print()
29 printf("FieldName1 %s, FieldName2 %s", fldName1
, fldName2
);
30 printf("CompOp %d, operand %x operandPtr%x", compOp
, operand
);
31 printf("lhs %x, rhs %x", lhs
, rhs
);
35 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
,
38 strcpy(fldName1
, fName1
);
39 strcpy(fldName2
, fName2
);
44 logicalOp
= OpInvalidLogicalOp
;
47 //Operand should be of the same type of the field.This is must
48 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void *opnd
)
50 strcpy(fldName1
, fName1
);
52 char *c
= (char *) opnd
;
54 if (*c
== '_') *c
= '?';
55 else if(*c
== '%') *c
= '*';
63 logicalOp
= OpInvalidLogicalOp
;
66 void PredicateImpl::setTerm(const char* fName1
, ComparisionOp op
, void **opnd
)
68 strcpy(fldName1
, fName1
);
73 logicalOp
= OpInvalidLogicalOp
;
77 void PredicateImpl::setTerm(Predicate
*p1
, LogicalOp op
, Predicate
*p2
)
79 if (p2
== NULL
&& op
!= OpNot
|| op
== OpNot
&& p2
!= NULL
)
84 lhs
= (PredicateImpl
*)p1
;
85 rhs
= (PredicateImpl
*)p2
;
87 compOp
= OpInvalidComparisionOp
;
90 void PredicateImpl::setTable(Table
*tbl
)
93 lhs
->setTable((TableImpl
*)tbl
);
95 rhs
->setTable((TableImpl
*)tbl
);
96 table
= (TableImpl
*)tbl
;
99 void PredicateImpl::setTuple(void *tpl
)
107 void PredicateImpl::setProjectionList(List
*lst
)
110 lhs
->setProjectionList(lst
);
112 rhs
->setProjectionList(lst
);
115 bool PredicateImpl::isSingleTerm()
117 if (NULL
== lhs
&& NULL
== rhs
) return true; else false;
121 bool PredicateImpl::isNotOrInvolved()
123 bool lhsResult
= true, rhsResult
= true;
126 lhsResult
= lhs
->isNotOrInvolved();
130 rhsResult
= rhs
->isNotOrInvolved();
134 //Means it involves only Logical operator
138 if (lhsResult
|| rhsResult
) return true; else return false;
152 DbRetVal
PredicateImpl::evaluate(bool &result
)
154 bool rhsResult
= false, lhsResult
=false;
155 printDebug(DM_Predicate
, "Evaluate start logical:%d compOp:%d", logicalOp
, compOp
);
156 DbRetVal retCode
=OK
;
160 retCode
= lhs
->evaluate(lhsResult
);
161 printDebug(DM_Predicate
, "LHS result %d retcode: %d", lhsResult
, retCode
);
162 if (retCode
!= OK
) return ErrInvalidExpr
;
166 retCode
= rhs
->evaluate(rhsResult
);
167 printDebug(DM_Predicate
, "RHS result %d retcode:%d", rhsResult
, retCode
);
168 if (retCode
!= OK
) return ErrInvalidExpr
;
172 //Means it involves only Logical operator
173 printDebug(DM_Predicate
,"Evalute operator %d lhsResult %d : rhsResult %d", logicalOp
, lhsResult
, rhsResult
);
177 if (lhsResult
&& rhsResult
) result
= true;
180 if (lhsResult
|| rhsResult
) result
= true;
183 if (lhsResult
) result
= false; else result
= true;
186 return ErrInvalidExpr
;
189 printDebug(DM_Predicate
, "result is %d", result
);
192 printDebug(DM_Predicate
, "Evaluating comparision predicate op:%d", compOp
);
193 //Means it is relational expression
194 //first operand is always field identifier
195 //get the value in the tuple
196 char fieldName1
[IDENTIFIER_LENGTH
];
197 char fieldName2
[IDENTIFIER_LENGTH
];
198 memset(fieldName1
, 0, IDENTIFIER_LENGTH
);
199 memset(fieldName2
, 0, IDENTIFIER_LENGTH
);
200 Table::getFieldNameAlone(fldName1
, fieldName1
);
201 Table::getFieldNameAlone(fldName2
, fieldName2
);
204 DataType type
=typeUnknown
;
206 //for join node evaluation
207 ListIterator fIter
= projList
->getIterator();
208 JoinProjFieldInfo
*def
;
210 while (fIter
.hasElement())
212 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
213 if (NULL
!= def
->appBuf
) {
214 if (0 == strcmp(fldName1
, def
->tabFieldName
))
216 val1
= (char*)def
->bindBuf
;
218 length
= def
->length
;
222 printError(ErrNotExists
, "Field not binded %s.%s\n",
223 def
->tableName
, def
->fieldName
);
227 if (operand
== NULL
&& operandPtr
== NULL
)
231 while (fIter
.hasElement())
233 def
= (JoinProjFieldInfo
*) fIter
.nextElement();
234 if (NULL
!= def
->appBuf
) {
235 if (0 == strcmp(fldName2
, def
->tabFieldName
))
237 val2
= (char*)def
->bindBuf
;
241 printError(ErrNotExists
, "Field not binded %s.%s\n",
242 def
->tableName
, def
->fieldName
);
248 else if(operand
!= NULL
&& operandPtr
== NULL
)
250 val2
= (char*) operand
;
252 else if(operand
== NULL
&& operandPtr
!= NULL
)
254 val2
= *(char**)operandPtr
;
256 if (compOp
== OpLike
) result
= ! fnmatch(val2
, val1
, 0);
257 else result
= AllDataType::compareVal(val1
, val2
, compOp
, type
,
261 //the below code works only for single table
262 int offset1
, offset2
;
263 offset1
= table
->getFieldOffset(fieldName1
);
264 //TODO::do not call getFieldXXX many times, instead get it using getFieldInfo
266 //Assumes that fldName2 data type is also same for expr f1 <f2
267 DataType srcType
= table
->getFieldType(fieldName1
);
268 val1
= ((char*) tuple
) + offset1
;
269 if (operand
== NULL
&& operandPtr
== NULL
)
272 offset2
= table
->getFieldOffset(fieldName2
);
273 val2
= ((char*)tuple
) + offset2
;
276 else if(operand
!= NULL
&& operandPtr
== NULL
)
278 val2
= (char*) operand
;
280 else if(operand
== NULL
&& operandPtr
!= NULL
)
282 val2
= *(char**)operandPtr
;
285 printDebug(DM_Predicate
, " fldname :%s ", fieldName1
);
286 if (compOp
== OpLike
) result
= ! fnmatch(val2
, val1
, 0);
287 else result
= AllDataType::compareVal(val1
, val2
, compOp
, srcType
,
288 table
->getFieldLength(fieldName1
));
292 bool PredicateImpl::pointLookupInvolved(const char *fname
)
294 bool rhsResult
, lhsResult
;
297 lhsResult
= lhs
->pointLookupInvolved(fname
);
301 rhsResult
= rhs
->pointLookupInvolved(fname
);
305 //Means it involves only Logical operator
310 if (lhsResult
|| rhsResult
) return true; else return false;
321 //Means it is relational expression
322 //first operand is always field identifier
323 char fieldName1
[IDENTIFIER_LENGTH
];
324 Table::getFieldNameAlone(fldName1
, fieldName1
);
325 if (OpEquals
== compOp
)
327 //for expressions f1 == f2 use full scan, so return false
328 if(NULL
== operand
&& NULL
== operandPtr
) return false;
329 if(0 == strcmp(fieldName1
, fname
))
336 bool PredicateImpl::rangeQueryInvolved(const char *fname
)
338 bool rhsResult
, lhsResult
;
341 lhsResult
= lhs
->rangeQueryInvolved(fname
);
345 rhsResult
= rhs
->rangeQueryInvolved(fname
);
352 if (lhsResult
|| rhsResult
) return true; else return false;
363 //Means it is relational expression
364 //first operand is always field identifier
365 char fieldName1
[IDENTIFIER_LENGTH
];
366 Table::getFieldNameAlone(fldName1
, fieldName1
);
367 if (OpLessThan
== compOp
|| OpLessThanEquals
== compOp
||
368 OpGreaterThan
== compOp
|| OpGreaterThanEquals
== compOp
)
370 //for expressions f1 == f2 use full scan, so return false
371 if(NULL
== operand
&& NULL
== operandPtr
) return false;
372 if(0 == strcmp(fieldName1
, fname
))
381 void* PredicateImpl::valPtrForIndexField(const char *fname
)
383 void *lhsRet
, *rhsRet
;
386 lhsRet
= lhs
->valPtrForIndexField(fname
);
390 rhsRet
= rhs
->valPtrForIndexField(fname
);
394 //Means it involves only Logical operator
395 if ( lhsRet
!= NULL
) return lhsRet
;
396 if ( rhsRet
!= NULL
) return rhsRet
;
398 char fieldName1
[IDENTIFIER_LENGTH
];
399 Table::getFieldNameAlone(fldName1
, fieldName1
);
400 //Means it is relational expression
401 //first operand is always field identifier
402 //if (OpEquals == compOp)
404 if(0 == strcmp(fieldName1
, fname
))
406 if (operand
) return operand
; else return *(void**)operandPtr
;
411 ComparisionOp
PredicateImpl::opForIndexField(const char *fname
)
413 ComparisionOp lhsRet
, rhsRet
;
416 lhsRet
= lhs
->opForIndexField(fname
);
420 rhsRet
= rhs
->opForIndexField(fname
);
424 if ( lhsRet
!= NULL
) return lhsRet
;
425 if ( rhsRet
!= NULL
) return rhsRet
;
427 char fieldName1
[IDENTIFIER_LENGTH
];
428 Table::getFieldNameAlone(fldName1
, fieldName1
);
429 if(0 == strcmp(fieldName1
, fname
))
433 return OpInvalidComparisionOp
;