Fixing failures in Join and systest failures because of predicate reset
[csql.git] / src / sql / SelStatement.cxx
blobcb3ffe6be4958b37c2e4852f2fc31b6dc8fc7f82
1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.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 "Statement.h"
18 SelStatement::SelStatement()
20 parsedData = NULL;
21 dbMgr = NULL;
22 table = NULL;
23 params = NULL;
24 paramValues = NULL;
25 totalParams = 0;
26 bindFields = NULL;
27 bindFieldValues = NULL;
28 totalFields = 0;
31 SelStatement::~SelStatement()
33 if (table) {
34 table->setCondition(NULL);
35 //if (dbMgr) dbMgr->closeTable(table);
36 table->close();
37 delete table;
39 if (totalParams) {
40 free(params);
41 params = NULL;
42 free(paramValues);
43 paramValues = NULL;
45 if (totalFields)
47 free(bindFields);
48 bindFields = NULL;
49 free(bindFieldValues);
50 bindFieldValues = NULL;
54 DbRetVal SelStatement::getParamFldInfo(int paramNo, FieldInfo *&info)
56 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
57 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
58 if (NULL == cValue)
60 printError(ErrSysFatal, "condition value is null. Should never happen");
61 return ErrSysFatal;
63 table->getFieldNameAlone(cValue->fName,info->fldName);
64 info->type = cValue->type;
65 info->length = cValue->length;
66 info->isNull = cValue->isNullable;
67 return OK;
69 DbRetVal SelStatement::execute(int &rowsAffected)
71 DbRetVal rv = OK;
72 //copy param values to binded buffer
73 ConditionValue *value;
74 for (int i = 0; i < totalParams; i ++)
76 value = (ConditionValue*) params[i];
77 if (paramValues[i] == NULL)
79 continue;
80 //printError(ErrBadCall, "param values not set");
81 //return ErrBadCall;
83 AllDataType::copyVal(value->value, paramValues[i], value->type, value->length);
85 rv = table->execute();
86 //table->printPlan(0);
87 return rv;
90 DbRetVal SelStatement::setParam(int paramNo, void *value)
92 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
93 if (NULL == value) return ErrBadArg;
94 paramValues[paramNo -1] = (char*) value;
95 return OK;
98 DbRetVal SelStatement::setShortParam(int paramNo, short value)
100 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
101 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
102 if (NULL == cValue)
104 printError(ErrSysFatal, "field value is null. Should never happen");
105 return ErrSysFatal;
107 *(short*)cValue->value = value;
108 return OK;
111 DbRetVal SelStatement::setIntParam(int paramNo, int value)
113 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
114 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
115 if (NULL == cValue)
117 printError(ErrSysFatal, "condition value is null. Should never happen");
118 return ErrSysFatal;
120 *(int*)cValue->value = value;
121 return OK;
123 DbRetVal SelStatement::setLongParam(int paramNo, long value)
125 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
126 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
127 if (NULL == cValue)
129 printError(ErrSysFatal, "condition value is null. Should never happen");
130 return ErrSysFatal;
132 *(long*)cValue->value = value;
133 return OK;
136 DbRetVal SelStatement::setLongLongParam(int paramNo, long long value)
138 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
139 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
140 if (NULL == cValue)
142 printError(ErrSysFatal, "condition value is null. Should never happen");
143 return ErrSysFatal;
145 *(long long*)cValue->value = value;
146 return OK;
148 DbRetVal SelStatement::setByteIntParam(int paramNo, ByteInt value)
150 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
151 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
152 if (NULL == cValue)
154 printError(ErrSysFatal, "condition value is null. Should never happen");
155 return ErrSysFatal;
157 *(ByteInt*)cValue->value = value;
158 return OK;
160 DbRetVal SelStatement::setFloatParam(int paramNo, float value)
162 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
163 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
164 if (NULL == cValue)
166 printError(ErrSysFatal, "condition value is null. Should never happen");
167 return ErrSysFatal;
169 *(float*)cValue->value = value;
170 return OK;
172 DbRetVal SelStatement::setDoubleParam(int paramNo, double value)
174 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
175 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
176 if (NULL == cValue)
178 printError(ErrSysFatal, "condition value is null. Should never happen");
179 return ErrSysFatal;
181 *(double*)cValue->value = value;
182 return OK;
184 DbRetVal SelStatement::setStringParam(int paramNo, char *value)
186 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
187 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
188 if (NULL == cValue)
190 printError(ErrSysFatal, "condition value is null. Should never happen");
191 return ErrSysFatal;
193 strcpy((char*)cValue->value, value);
194 return OK;
196 DbRetVal SelStatement::setDateParam(int paramNo, Date value)
198 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
199 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
200 if (NULL == cValue)
202 printError(ErrSysFatal, "condition value is null. Should never happen");
203 return ErrSysFatal;
205 *(Date*)cValue->value = value;
206 return OK;
208 DbRetVal SelStatement::setTimeParam(int paramNo, Time value)
210 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
211 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
212 if (NULL == cValue)
214 printError(ErrSysFatal, "condition value is null. Should never happen");
215 return ErrSysFatal;
217 *(Time*)cValue->value = value;
218 return OK;
220 DbRetVal SelStatement::setTimeStampParam(int paramNo, TimeStamp value)
222 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
223 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
224 if (NULL == cValue)
226 printError(ErrSysFatal, "condition value is null. Should never happen");
227 return ErrSysFatal;
229 *(TimeStamp*)cValue->value = value;
230 return OK;
233 DbRetVal SelStatement::setBinaryParam(int paramNo, void *value)
235 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
236 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
237 if (NULL == cValue)
239 printError(ErrSysFatal, "condition value is null. Should never happen");
240 return ErrSysFatal;
242 AllDataType::convertToBinary(cValue->value,value,typeString,cValue->length);
243 return OK;
246 DbRetVal SelStatement::setBindField(int colNo, void *value)
248 if (colNo <=0) return ErrBadArg;
249 //TODO: check the upper limit
250 //if (colNo > table->getFieldNameList().size()) return ErrBadArg;
251 if (NULL == value) return ErrBadArg;
252 bindFieldValues[colNo -1] = (char*) value;
253 return OK;
255 DbRetVal SelStatement::openTables()
257 if (dbMgr == NULL) return ErrNoConnection;
258 JoinTableImpl *jHdl = NULL;
259 Table *tHdl = NULL, *prevHdl = NULL;
260 bool joinInvolved = false;
261 //check whether all the table exists
262 ListIterator titer = parsedData->getTableNameList().getIterator();
263 while (titer.hasElement())
265 TableName *t = (TableName*)titer.nextElement();
266 tHdl = dbMgr->openTable(t->tblName);
267 if ( NULL == tHdl )
269 printError(ErrNotExists,
270 "Unable to open the table:Table not exists");
271 return ErrNotExists;
273 if (NULL != prevHdl)
275 joinInvolved = true;
276 jHdl = new JoinTableImpl();
277 jHdl->setTable(prevHdl, tHdl);
278 prevHdl = jHdl;
279 continue;
281 prevHdl = tHdl;
283 if (joinInvolved) table = jHdl; else table = tHdl;
284 return OK;
286 DbRetVal SelStatement::resolve()
288 DbRetVal rv = openTables();
289 if (rv != OK) return rv;
290 //get the fieldname list and validate field names
291 ListIterator iter = parsedData->getFieldNameList().getIterator();
292 FieldName *name = NULL;
293 FieldInfo *fInfo = new FieldInfo();
294 List bindFldList;
295 AggTableImpl *aggTable = NULL;
296 while (iter.hasElement())
298 name = (FieldName*)iter.nextElement();
299 if (NULL == name)
301 dbMgr->closeTable(table);
302 table = NULL;
303 delete fInfo;
304 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
305 return ErrSysFatal;
307 bool isBindFld=false;
308 if ('*' == name->fldName[0] && name->aType != AGG_COUNT)
310 rv = resolveStar();
311 if (rv != OK)
313 dbMgr->closeTable(table);
314 table = NULL;
315 delete fInfo;
316 return rv;
318 //as soon as it encounters *, it breaks the loop negleting other field names
319 //as they all are deleted during resolveStar method.
320 break;
321 }else {
322 if ('*' == name->fldName[0]) {return ErrSyntaxError;}
323 rv = table->getFieldInfo(name->fldName, fInfo);
324 if (ErrNotFound == rv || ErrNotExists == rv)
326 dbMgr->closeTable(table);
327 table = NULL;
328 delete fInfo;
329 printError(ErrSyntaxError, "Field %s does not exist in table",
330 name->fldName);
331 return ErrSyntaxError;
333 FieldValue *newVal = new FieldValue();
334 strcpy(newVal->fldName,name->fldName);
335 newVal->parsedString = NULL;
336 newVal->paramNo = 0;
337 newVal->type = fInfo->type;
338 newVal->length = fInfo->length;
339 newVal->isNullable = fInfo->isNull;
340 FieldName *bFldName=NULL;
341 ListIterator it = bindFldList.getIterator();
342 while (it.hasElement())
344 bFldName = (FieldName*)it.nextElement();
345 if(0==strcmp(bFldName->fldName,name->fldName))
347 newVal->value=table->getBindFldAddr(name->fldName);
348 newVal->isAllocVal=false;
349 isBindFld=true;
350 break;
353 if (!isBindFld) {
354 if(newVal->type == typeBinary)
355 newVal->value = AllDataType::alloc(fInfo->type,
356 2 * fInfo->length);
357 else newVal->value = AllDataType::alloc(fInfo->type,
358 fInfo->length);
359 newVal->isAllocVal=true;
361 if (name->aType ==AGG_UNKNOWN &&
362 parsedData->getGroupFieldNameList().size()== 0)
363 table->bindFld(name->fldName, newVal->value);
364 else {
365 if (!aggTable)
366 aggTable = new AggTableImpl();
367 aggTable->setTable(table);
368 aggTable->bindFld(name->fldName, name->aType, newVal->value);
370 parsedData->insertFieldValue(newVal);
372 if (!isBindFld) bindFldList.append(name);
374 rv = setBindFieldAndValues();
375 if (rv != OK)
377 delete fInfo;
378 dbMgr->closeTable(table);
379 table = NULL;
380 return rv;
383 table->setCondition(parsedData->getCondition());
385 rv = resolveForCondition();
386 if (rv != OK)
388 delete fInfo;
389 //TODO::free memory allocated for params
390 table->setCondition(NULL);
391 dbMgr->closeTable(table);
392 table = NULL;
393 return rv;
395 resolveGroupFld(aggTable);
396 delete fInfo;
397 return rv;
399 DbRetVal SelStatement::resolveGroupFld(AggTableImpl *aggTable)
401 if (!aggTable) return OK;
402 ListIterator giter = parsedData->getGroupFieldNameList().getIterator();
403 FieldName *name = NULL;
404 DbRetVal rv = OK;
405 FieldInfo *fInfo = new FieldInfo();
406 while (giter.hasElement())
408 name = (FieldName*)giter.nextElement();
409 rv = table->getFieldInfo(name->fldName, fInfo);
410 if (ErrNotFound == rv || ErrNotExists == rv)
412 dbMgr->closeTable(table);
413 table = NULL;
414 delete fInfo;
415 delete aggTable;
416 printError(ErrSyntaxError, "Field %s does not exist in table",
417 name->fldName);
418 return ErrSyntaxError;
420 FieldValue *newVal = new FieldValue();
421 strcpy(newVal->fldName,name->fldName);
422 newVal->parsedString = NULL;
423 newVal->paramNo = 0;
424 newVal->type = fInfo->type;
425 newVal->isNullable = fInfo->isNull;
426 newVal->length = fInfo->length;
427 if (newVal->type == typeBinary)
428 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
429 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
430 newVal->isAllocVal=true;
431 parsedData->insertFieldValue(newVal);
432 aggTable->setGroup(name->fldName, newVal->value);
434 table = aggTable;
435 return OK;
437 DbRetVal SelStatement::resolveStar()
439 DbRetVal rv = OK;
440 parsedData->clearFieldNameList();
442 List fNameList = table->getFieldNameList();
443 ListIterator fNameIter = fNameList.getIterator();
444 FieldValue *newVal = NULL;
445 //fNameList.resetIter(); //do not remove this.
446 FieldInfo *fInfo = new FieldInfo();
447 for (int i = 0; i < fNameList.size() ; i++)
449 char *fName = ((Identifier*)(fNameIter.nextElement()))->name;
450 rv = table->getFieldInfo(fName, fInfo);
451 if (ErrNotFound == rv || ErrNotExists == rv)
453 delete fInfo;
454 fNameList.reset();
455 printError(ErrSysFatal, "Should never happen.");
456 return ErrSysFatal;
458 newVal = new FieldValue();
459 strcpy(newVal->fldName,fName);
460 newVal->parsedString = NULL;
461 newVal->paramNo = 0;
462 newVal->type = fInfo->type;
463 newVal->length = fInfo->length;
464 // for binary datatype input buffer size should be 2 times the length
465 if(newVal->type == typeBinary)
466 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
467 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
468 newVal->isAllocVal=true;
469 parsedData->insertFieldValue(newVal);
470 parsedData->insertField(fName);
471 table->bindFld(fName, newVal->value);
473 fNameIter.reset();
474 while (fNameIter.hasElement())
475 delete (Identifier *) fNameIter.nextElement();
476 fNameList.reset();
477 delete fInfo;
478 return OK;
481 DbRetVal SelStatement::setBindFieldAndValues()
483 totalFields = parsedData->getFieldNameList().size();
484 bindFields = (FieldValue**) malloc ( totalFields * sizeof(FieldValue*));
485 bindFieldValues = (char**) malloc( totalFields * sizeof(char*));
486 memset(bindFields, 0, totalFields * sizeof(FieldValue*));
487 memset(bindFieldValues, 0, totalFields * sizeof(char*));
488 ListIterator valIter = parsedData->getFieldValueList().getIterator();
489 int colNo =0;
490 FieldValue *value = NULL;
491 valIter.reset();
492 while(valIter.hasElement())
494 value = (FieldValue*) valIter.nextElement();
495 if (value == NULL)
497 free(bindFields); bindFields = NULL;
498 free(bindFieldValues); bindFieldValues = NULL;
499 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
500 return ErrSysFatal;
502 bindFields[colNo++ ] = value;
504 return OK;
508 DbRetVal SelStatement::resolveForCondition()
510 //get the fieldname list and validate field names
511 ListIterator iter = parsedData->getConditionValueList().getIterator();
513 ConditionValue *value;
514 FieldInfo *fInfo = new FieldInfo();
515 int paramPos =1;
516 DbRetVal rv = OK;
517 while (iter.hasElement())
519 value = (ConditionValue*) iter.nextElement();
520 if (NULL == value)
522 delete fInfo;
523 printError(ErrSysFatal, "Should never happen.");
524 return ErrSysFatal;
526 rv = table->getFieldInfo(value->fName, fInfo);
527 if (ErrNotFound == rv || ErrNotExists == rv)
529 delete fInfo;
530 printError(ErrSyntaxError, "Field %s does not exist in table",
531 value->fName);
532 return ErrSyntaxError;
534 value->type = fInfo->type;
535 value->length = fInfo->length;
536 value->isNullable = fInfo->isNull;
537 value->value = AllDataType::alloc(fInfo->type, fInfo->length);
538 //table->bindFld(name->fldName, value->value);
539 if (value->parsedString == NULL)
541 delete fInfo;
542 printError(ErrSyntaxError, "Condition value should not be NULL");
543 return ErrSyntaxError;
545 if (value->parsedString[0] == '?')
547 if(!value->opLike) // checks if 'LIKE' operator is used
548 value->paramNo = paramPos++;
550 if (!value->paramNo) {
551 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
552 AllDataType::strToValue(value->value, value->parsedString, fInfo->type, fInfo->length);
555 delete fInfo;
556 totalParams = paramPos -1;
557 if (0 == totalParams) return OK;
558 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
559 paramValues = (char**) malloc( totalParams * sizeof(char*));
560 memset(params, 0, totalParams * sizeof(FieldValue*));
561 memset(paramValues, 0, totalParams * sizeof(char*));
562 iter.reset();
563 while(iter.hasElement())
565 value = (ConditionValue*) iter.nextElement();
566 if (value == NULL)
568 free(params); params = NULL;
569 free(paramValues); paramValues = NULL;
570 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
571 return ErrSysFatal;
573 params[value->paramNo -1 ] = value;
575 return OK;
578 void* SelStatement::fetch()
580 void *tuple = table->fetch();
581 if (NULL == tuple) return NULL;
582 //copy values to binded buffer
583 FieldValue *value;
584 for (int i = 0; i < totalFields; i++)
586 value = bindFields[i];
587 if (bindFieldValues[i] == NULL)
589 printError(ErrBadCall, "Fields are not binded properly. Should never happen");
590 return NULL;
592 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
594 return tuple;
597 void* SelStatement::fetch(DbRetVal &rv)
599 void *tuple = table->fetch(rv);
600 if (NULL == tuple) return NULL;
601 //copy values to binded buffer
602 FieldValue *value;
603 for (int i = 0; i < totalFields; i++)
605 value = bindFields[i];
606 if (bindFieldValues[i] == NULL)
608 printError(ErrBadCall, "Fields are not binded properly. Should never happen %d", i);
609 return NULL;
611 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
613 return tuple;
616 DbRetVal SelStatement::close()
618 return table->close();
620 void* SelStatement::getParamValuePtr( int pos )
622 ConditionValue *p = (ConditionValue*) params [pos-1];
623 return ( (void*) p->value );
626 char* SelStatement::getFieldName ( int pos )
628 //TODO::if not yet prepared return error
629 //TODO::check the upper limit for projpos
630 ListIterator iter = parsedData->getFieldNameList().getIterator();
631 int position =0;
632 while (iter.hasElement())
634 if (position == pos) {
635 FieldName *name = (FieldName*) iter.nextElement();
636 if (NULL == name)
638 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
639 return (char*) 0;
641 return name->fldName;
643 position++;
645 return (char*) 0;
648 DataType SelStatement::getFieldType( int pos )
650 FieldValue *v = bindFields[pos];
651 return ( (DataType) v->type );
654 int SelStatement::getFieldLength( int pos )
656 FieldValue *v = bindFields[pos];
657 return ( (int) v->type );
660 void* SelStatement::fetchAndPrint(bool SQL)
662 void *tuple = table->fetch();
663 if (NULL == tuple) return NULL;
664 FieldValue *value;
665 bool nullValueSet;
666 char stmt[128];
667 if (SQL) {
668 sprintf(stmt, "INSERT INTO %s VALUES(", table->getName());
669 printf("%s", stmt);
671 for (int i = 0; i < totalFields; i++)
673 value = bindFields[i];
674 nullValueSet = table->isFldNull(value->fldName);
675 if (nullValueSet)
676 if (SQL) {
677 if (i==0)
678 printf("NULL");
679 else
680 printf(", NULL");
682 else printf("NULL\t");
683 else {
684 if (SQL) {
685 switch(value->type)
687 case typeString:
688 case typeBinary:
689 case typeDate:
690 case typeTime:
691 case typeTimeStamp:
693 if (i==0)
694 printf(" '");
695 else
696 printf(", '");
697 break;
699 default:
701 if (i!=0)
702 printf(",");
706 AllDataType::printVal(value->value, value->type, value->length);
707 if (SQL) {
708 switch(value->type)
710 case typeString:
711 case typeBinary:
712 case typeDate:
713 case typeTime:
714 case typeTimeStamp:
715 printf("'");
717 } else printf("\t");
720 if (SQL) printf(");\n");
721 return tuple;
724 void* SelStatement::next()
726 return( table->fetch() );
730 void* SelStatement::getFieldValuePtr( int pos )
732 FieldValue *v = bindFields[pos];
733 return ( (void*) v->value );
736 int SelStatement::noOfProjFields()
738 return totalFields;
741 DbRetVal SelStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
743 //TODO::if not yet prepared return error
744 //TODO::check the upper limit for projpos
745 ListIterator iter = parsedData->getFieldNameList().getIterator();
746 FieldName *name = NULL;
747 DbRetVal rv = OK;
748 int position =0;
749 while (iter.hasElement())
751 name = (FieldName*)iter.nextElement();
752 if (NULL == name)
754 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
755 return ErrSysFatal;
757 if (position == (projpos-1)) break;
758 position++;
761 rv = table->getFieldInfo(name->fldName, fInfo);
763 int SelStatement::getFldPos(char *name)
765 return table->getFldPos(name);