corrected to accept hostname and connect to network
[csql.git] / src / storage / PredicateImpl.cxx
blobc22b9d8cf3f6394fa3a41a131d4d6298a0c5d399
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<fnmatch.h>
25 #include<JoinTableImpl.h>
26 #include<Util.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,
36 const char *fName2)
38 strcpy(fldName1, fName1);
39 strcpy(fldName2, fName2);
40 compOp = op;
41 operand = NULL;
42 operandPtr = NULL;
43 lhs = rhs = NULL;
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);
51 if (op == OpLike) {
52 char *c = (char *) opnd;
53 while (*c != '\0') {
54 if (*c == '_') *c = '?';
55 else if(*c == '%') *c = '*';
56 c++;
59 compOp = op;
60 operand = opnd;
61 operandPtr = NULL;
62 lhs = rhs = NULL;
63 logicalOp = OpInvalidLogicalOp;
66 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd)
68 strcpy(fldName1, fName1);
69 compOp = op;
70 operand = NULL;
71 operandPtr = opnd;
72 lhs = rhs = NULL;
73 logicalOp = OpInvalidLogicalOp;
77 void PredicateImpl::setTerm(Predicate *p1, LogicalOp op, Predicate *p2 )
79 if (p2 == NULL && op != OpNot || op == OpNot && p2 != NULL)
81 //TODO::printError
82 return;
84 lhs = (PredicateImpl*)p1;
85 rhs = (PredicateImpl*)p2;
86 logicalOp = op;
87 compOp = OpInvalidComparisionOp;
90 void PredicateImpl::setTable(Table *tbl)
92 if (NULL != lhs)
93 lhs->setTable((TableImpl*)tbl);
94 if (NULL != rhs)
95 rhs->setTable((TableImpl*)tbl);
96 table = (TableImpl*)tbl;
99 void PredicateImpl::setTuple(void *tpl)
101 if (NULL != lhs)
102 lhs->setTuple(tpl);
103 if (NULL != rhs)
104 rhs->setTuple(tpl);
105 tuple = tpl;
107 void PredicateImpl::setProjectionList(List *lst)
109 if (NULL != lhs)
110 lhs->setProjectionList(lst);
111 if (NULL != rhs)
112 rhs->setProjectionList(lst);
113 projList = 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;
124 if (NULL != lhs)
126 lhsResult = lhs->isNotOrInvolved();
128 if (NULL != rhs)
130 rhsResult = rhs->isNotOrInvolved();
132 if (NULL != lhs)
134 //Means it involves only Logical operator
135 switch(logicalOp)
137 case OpAnd:
138 if (lhsResult || rhsResult) return true; else return false;
139 break;
140 case OpOr:
141 return true;
142 break;
143 case OpNot:
144 default:
145 return true;
146 break;
149 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;
157 result = false;
158 if (NULL != lhs)
160 retCode = lhs->evaluate(lhsResult);
161 printDebug(DM_Predicate, "LHS result %d retcode: %d", lhsResult, retCode);
162 if (retCode != OK) return ErrInvalidExpr;
164 if (NULL != rhs)
166 retCode = rhs->evaluate(rhsResult);
167 printDebug(DM_Predicate, "RHS result %d retcode:%d", rhsResult, retCode);
168 if (retCode != OK) return ErrInvalidExpr;
170 if (NULL != lhs)
172 //Means it involves only Logical operator
173 printDebug(DM_Predicate,"Evalute operator %d lhsResult %d : rhsResult %d", logicalOp, lhsResult, rhsResult );
174 switch(logicalOp)
176 case OpAnd:
177 if (lhsResult && rhsResult) result = true;
178 break;
179 case OpOr:
180 if (lhsResult || rhsResult) result = true;
181 break;
182 case OpNot:
183 if (lhsResult) result = false; else result = true;
184 break;
185 default:
186 return ErrInvalidExpr;
189 printDebug(DM_Predicate, "result is %d", result);
190 return OK;
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);
202 if (projList)
204 DataType type=typeUnknown;
205 int length=0;
206 //for join node evaluation
207 ListIterator fIter = projList->getIterator();
208 JoinProjFieldInfo *def;
209 char *val1, *val2;
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;
217 type = def->type;
218 length = def->length;
219 break;
221 }else{
222 printError(ErrNotExists, "Field not binded %s.%s\n",
223 def->tableName, def->fieldName);
224 return ErrNotExists;
227 if (operand == NULL && operandPtr == NULL)
229 if (fieldName2) {
230 fIter.reset();
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;
238 break;
240 }else{
241 printError(ErrNotExists, "Field not binded %s.%s\n",
242 def->tableName, def->fieldName);
243 return ErrNotExists;
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,
258 length);
259 return OK;
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
265 char *val1, *val2;
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)
271 if (fieldName2) {
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;
284 int ret = 0;
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));
289 return OK;
292 bool PredicateImpl::pointLookupInvolved(const char *fname)
294 bool rhsResult, lhsResult;
295 if (NULL != lhs)
297 lhsResult = lhs->pointLookupInvolved(fname);
299 if (NULL != rhs)
301 rhsResult = rhs->pointLookupInvolved(fname);
303 if (NULL != lhs)
305 //Means it involves only Logical operator
306 switch(logicalOp)
308 case OpAnd:
309 //return lhsResult;
310 if (lhsResult || rhsResult) return true; else return false;
311 break;
312 case OpOr:
313 return false;
314 break;
315 case OpNot:
316 default:
317 return false;
318 break;
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))
331 return true;
334 return false;
336 bool PredicateImpl::rangeQueryInvolved(const char *fname)
338 bool rhsResult, lhsResult;
339 if (NULL != lhs)
341 lhsResult = lhs->rangeQueryInvolved(fname);
343 if (NULL != rhs)
345 rhsResult = rhs->rangeQueryInvolved(fname);
347 if (NULL != lhs)
349 switch(logicalOp)
351 case OpAnd:
352 if (lhsResult || rhsResult) return true; else return false;
353 break;
354 case OpOr:
355 return false;
356 break;
357 case OpNot:
358 default:
359 return false;
360 break;
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))
374 return true;
377 return false;
381 void* PredicateImpl::valPtrForIndexField(const char *fname)
383 void *lhsRet, *rhsRet;
384 if (NULL != lhs)
386 lhsRet = lhs->valPtrForIndexField(fname);
388 if (NULL != rhs)
390 rhsRet = rhs->valPtrForIndexField(fname);
392 if (NULL != lhs)
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;
409 return NULL;
411 ComparisionOp PredicateImpl::opForIndexField(const char *fname)
413 ComparisionOp lhsRet, rhsRet;
414 if (NULL != lhs)
416 lhsRet = lhs->opForIndexField(fname);
418 if (NULL != rhs)
420 rhsRet = rhs->opForIndexField(fname);
422 if (NULL != lhs)
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))
431 return compOp;
433 return OpInvalidComparisionOp;