Renamed server directory to storage directory in src
[csql.git] / src / storage / PredicateImpl.cxx
blob94fe3983ed05ef99d71a45a019e44cd64f6eabd0
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 void PredicateImpl::print()
27 printf("FieldName1 %s, FieldName2 %s", fldName1, fldName2);
28 printf("CompOp %d, operand %x operandPtr%x", compOp, operand);
29 printf("lhs %x, rhs %x", lhs, rhs);
33 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op,
34 const char *fName2)
36 strcpy(fldName1, fName1);
37 strcpy(fldName2, fName2);
38 compOp = op;
39 operand = NULL;
40 operandPtr = NULL;
41 lhs = rhs = NULL;
42 logicalOp = OpInvalidLogicalOp;
45 //Operand should be of the same type of the field.This is must
46 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void *opnd)
48 strcpy(fldName1, fName1);
49 if (op == OpLike) {
50 char *c = (char *) opnd;
51 while (*c != '\0') {
52 if (*c == '_') *c = '?';
53 else if(*c == '%') *c = '*';
54 c++;
57 compOp = op;
58 operand = opnd;
59 operandPtr = NULL;
60 lhs = rhs = NULL;
61 logicalOp = OpInvalidLogicalOp;
64 void PredicateImpl::setTerm(const char* fName1, ComparisionOp op, void **opnd)
66 strcpy(fldName1, fName1);
67 compOp = op;
68 operand = NULL;
69 operandPtr = opnd;
70 lhs = rhs = NULL;
71 logicalOp = OpInvalidLogicalOp;
75 void PredicateImpl::setTerm(Predicate *p1, LogicalOp op, Predicate *p2 )
77 if (p2 == NULL && op != OpNot || op == OpNot && p2 != NULL)
79 //TODO::printError
80 return;
82 lhs = (PredicateImpl*)p1;
83 rhs = (PredicateImpl*)p2;
84 logicalOp = op;
85 compOp = OpInvalidComparisionOp;
88 void PredicateImpl::setTable(Table *tbl)
90 if (NULL != lhs)
91 lhs->setTable((TableImpl*)tbl);
92 if (NULL != rhs)
93 rhs->setTable((TableImpl*)tbl);
94 table = (TableImpl*)tbl;
97 void PredicateImpl::setTuple(void *tpl)
99 if (NULL != lhs)
100 lhs->setTuple(tpl);
101 if (NULL != rhs)
102 rhs->setTuple(tpl);
103 tuple = tpl;
105 bool PredicateImpl::isSingleTerm()
107 if (NULL == lhs && NULL == rhs) return true; else false;
111 bool PredicateImpl::isNotOrInvolved()
113 bool lhsResult = true, rhsResult = true;
114 if (NULL != lhs)
116 lhsResult = lhs->isNotOrInvolved();
118 if (NULL != rhs)
120 rhsResult = rhs->isNotOrInvolved();
122 if (NULL != lhs)
124 //Means it involves only Logical operator
125 switch(logicalOp)
127 case OpAnd:
128 if (lhsResult || rhsResult) return true; else return false;
129 break;
130 case OpOr:
131 return true;
132 break;
133 case OpNot:
134 default:
135 return true;
136 break;
139 return false;
142 DbRetVal PredicateImpl::evaluate(bool &result)
144 bool rhsResult = false, lhsResult=false;
145 printDebug(DM_Predicate, "Evaluate start logical:%d compOp:%d", logicalOp, compOp);
146 DbRetVal retCode =OK;
147 result = false;
148 if (NULL != lhs)
150 retCode = lhs->evaluate(lhsResult);
151 printDebug(DM_Predicate, "LHS result %d retcode: %d", lhsResult, retCode);
152 if (retCode != OK) return ErrInvalidExpr;
154 if (NULL != rhs)
156 retCode = rhs->evaluate(rhsResult);
157 printDebug(DM_Predicate, "RHS result %d retcode:%d", rhsResult, retCode);
158 if (retCode != OK) return ErrInvalidExpr;
160 if (NULL != lhs)
162 //Means it involves only Logical operator
163 printDebug(DM_Predicate,"Evalute operator %d lhsResult %d : rhsResult %d", logicalOp, lhsResult, rhsResult );
164 switch(logicalOp)
166 case OpAnd:
167 if (lhsResult && rhsResult) result = true;
168 break;
169 case OpOr:
170 if (lhsResult || rhsResult) result = true;
171 break;
172 case OpNot:
173 if (lhsResult) result = false; else result = true;
174 break;
175 default:
176 return ErrInvalidExpr;
179 printDebug(DM_Predicate, "result is %d", result);
180 return OK;
182 printDebug(DM_Predicate, "Evaluating comparision predicate op:%d", compOp);
183 //Means it is relational expression
184 //first operand is always field identifier
185 //get the value in the tuple
186 int offset1, offset2;
187 offset1 = table->getFieldOffset(fldName1);
188 //TODO::do not call getFieldXXX many times, instead get it using getFieldInfo
189 char *val1, *val2 ;
190 //Assumes that fldName2 data type is also same for expr f1 <f2
191 DataType srcType = table->getFieldType(fldName1);
192 val1 = ((char*) tuple) + offset1;
193 if (operand == NULL && operandPtr == NULL)
195 if (fldName2) {
196 offset2 = table->getFieldOffset(fldName2);
197 val2 = ((char*)tuple) + offset2;
200 else if(operand != NULL && operandPtr == NULL)
202 val2 = (char*) operand;
204 else if(operand == NULL && operandPtr != NULL)
206 val2 = *(char**)operandPtr;
208 int ret = 0;
209 printDebug(DM_Predicate, " fldname :%s ", fldName1);
210 if (compOp == OpLike) result = ! fnmatch(val2, val1, 0);
211 else result = AllDataType::compareVal(val1, val2, compOp, srcType,
212 table->getFieldLength(fldName1));
213 return OK;
216 bool PredicateImpl::pointLookupInvolved(const char *fname)
218 bool rhsResult, lhsResult;
219 if (NULL != lhs)
221 lhsResult = lhs->pointLookupInvolved(fname);
223 if (NULL != rhs)
225 rhsResult = rhs->pointLookupInvolved(fname);
227 if (NULL != lhs)
229 //Means it involves only Logical operator
230 switch(logicalOp)
232 case OpAnd:
233 //return lhsResult;
234 if (lhsResult || rhsResult) return true; else return false;
235 break;
236 case OpOr:
237 return false;
238 break;
239 case OpNot:
240 default:
241 return false;
242 break;
245 //Means it is relational expression
246 //first operand is always field identifier
247 if (OpEquals == compOp)
249 //for expressions f1 == f2 use full scan, so return false
250 if(NULL == operand && NULL == operandPtr) return false;
251 if(0 == strcmp(fldName1, fname))
253 return true;
256 return false;
259 void* PredicateImpl::valPtrForIndexField(const char *fname)
261 void *lhsRet, *rhsRet;
262 if (NULL != lhs)
264 lhsRet = lhs->valPtrForIndexField(fname);
266 if (NULL != rhs)
268 rhsRet = rhs->valPtrForIndexField(fname);
270 if (NULL != lhs)
272 //Means it involves only Logical operator
273 if ( lhsRet != NULL) return lhsRet;
274 if ( rhsRet != NULL) return rhsRet;
276 //Means it is relational expression
277 //first operand is always field identifier
278 if (OpEquals == compOp)
280 if(0 == strcmp(fldName1, fname))
282 if (operand) return operand; else return *(void**)operandPtr;
285 return NULL;