2031095 select count(*) from t1 is not working
[csql.git] / src / sql / SelStatement.cxx
blob6f91783a1d3eca5991a38bfe4683cfdab674db36
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);
37 if (totalParams) {
38 free(params);
39 params = NULL;
40 free(paramValues);
41 paramValues = NULL;
43 if (totalFields)
45 free(bindFields);
46 bindFields = NULL;
47 free(bindFieldValues);
48 bindFieldValues = NULL;
52 DbRetVal SelStatement::getParamFldInfo(int paramNo, FieldInfo *&info)
54 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
55 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
56 if (NULL == cValue)
58 printError(ErrSysFatal, "condition value is null. Should never happen");
59 return ErrSysFatal;
61 info->type = cValue->type;
62 info->length = cValue->length;
63 return OK;
65 DbRetVal SelStatement::execute(int &rowsAffected)
67 DbRetVal rv = OK;
68 //copy param values to binded buffer
69 ConditionValue *value;
70 for (int i = 0; i < totalParams; i ++)
72 value = (ConditionValue*) params[i];
73 if (paramValues[i] == NULL)
75 continue;
76 //printError(ErrBadCall, "param values not set");
77 //return ErrBadCall;
79 AllDataType::copyVal(value->value, paramValues[i], value->type, value->length);
81 rv = table->execute();
82 return rv;
85 DbRetVal SelStatement::setParam(int paramNo, void *value)
87 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
88 if (NULL == value) return ErrBadArg;
89 paramValues[paramNo -1] = (char*) value;
90 return OK;
93 DbRetVal SelStatement::setShortParam(int paramNo, short value)
95 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
96 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
97 if (NULL == cValue)
99 printError(ErrSysFatal, "field value is null. Should never happen");
100 return ErrSysFatal;
102 *(short*)cValue->value = value;
103 return OK;
106 DbRetVal SelStatement::setIntParam(int paramNo, int value)
108 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
109 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
110 if (NULL == cValue)
112 printError(ErrSysFatal, "condition value is null. Should never happen");
113 return ErrSysFatal;
115 *(int*)cValue->value = value;
116 return OK;
118 DbRetVal SelStatement::setLongParam(int paramNo, long value)
120 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
121 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
122 if (NULL == cValue)
124 printError(ErrSysFatal, "condition value is null. Should never happen");
125 return ErrSysFatal;
127 *(long*)cValue->value = value;
128 return OK;
131 DbRetVal SelStatement::setLongLongParam(int paramNo, long long value)
133 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
134 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
135 if (NULL == cValue)
137 printError(ErrSysFatal, "condition value is null. Should never happen");
138 return ErrSysFatal;
140 *(long long*)cValue->value = value;
141 return OK;
143 DbRetVal SelStatement::setByteIntParam(int paramNo, ByteInt value)
145 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
146 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
147 if (NULL == cValue)
149 printError(ErrSysFatal, "condition value is null. Should never happen");
150 return ErrSysFatal;
152 *(ByteInt*)cValue->value = value;
153 return OK;
155 DbRetVal SelStatement::setFloatParam(int paramNo, float value)
157 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
158 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
159 if (NULL == cValue)
161 printError(ErrSysFatal, "condition value is null. Should never happen");
162 return ErrSysFatal;
164 *(float*)cValue->value = value;
165 return OK;
167 DbRetVal SelStatement::setDoubleParam(int paramNo, double value)
169 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
170 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
171 if (NULL == cValue)
173 printError(ErrSysFatal, "condition value is null. Should never happen");
174 return ErrSysFatal;
176 *(double*)cValue->value = value;
177 return OK;
179 DbRetVal SelStatement::setStringParam(int paramNo, char *value)
181 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
182 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
183 if (NULL == cValue)
185 printError(ErrSysFatal, "condition value is null. Should never happen");
186 return ErrSysFatal;
188 strcpy((char*)cValue->value, value);
189 return OK;
191 DbRetVal SelStatement::setDateParam(int paramNo, Date value)
193 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
194 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
195 if (NULL == cValue)
197 printError(ErrSysFatal, "condition value is null. Should never happen");
198 return ErrSysFatal;
200 *(Date*)cValue->value = value;
201 return OK;
203 DbRetVal SelStatement::setTimeParam(int paramNo, Time value)
205 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
206 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
207 if (NULL == cValue)
209 printError(ErrSysFatal, "condition value is null. Should never happen");
210 return ErrSysFatal;
212 *(Time*)cValue->value = value;
213 return OK;
215 DbRetVal SelStatement::setTimeStampParam(int paramNo, TimeStamp value)
217 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
218 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
219 if (NULL == cValue)
221 printError(ErrSysFatal, "condition value is null. Should never happen");
222 return ErrSysFatal;
224 *(TimeStamp*)cValue->value = value;
225 return OK;
228 DbRetVal SelStatement::setBinaryParam(int paramNo, void *value)
230 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
231 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
232 if (NULL == cValue)
234 printError(ErrSysFatal, "condition value is null. Should never happen");
235 return ErrSysFatal;
237 memcpy(cValue->value, value, 2 * cValue->length);
238 return OK;
241 DbRetVal SelStatement::setBindField(int colNo, void *value)
243 if (colNo <=0) return ErrBadArg;
244 //TODO: check the upper limit
245 //if (colNo > table->getFieldNameList().size()) return ErrBadArg;
246 if (NULL == value) return ErrBadArg;
247 bindFieldValues[colNo -1] = (char*) value;
248 return OK;
251 DbRetVal SelStatement::resolve()
253 if (dbMgr == NULL) return ErrNoConnection;
254 //check whether the table exists
255 table = dbMgr->openTable(parsedData->getTableName());
256 if (table == NULL)
258 printError(ErrNotExists, "Unable to open the table:Table not exists");
259 return ErrNotExists;
261 List fNameList = table->getFieldNameList();
262 ListIterator fNameIter = fNameList.getIterator();
263 Identifier *elem = NULL;
264 if (fNameIter.hasElement())
265 elem = (Identifier*) fNameIter.nextElement();
266 if (elem == NULL)
268 printError(ErrNotExists, "No fields present in the table %s", parsedData->getTableName());
269 return ErrNotExists;
272 //get the fieldname list and validate field names
273 ListIterator iter = parsedData->getFieldNameList().getIterator();
274 FieldName *name = NULL;
275 FieldInfo *fInfo = new FieldInfo();
276 DbRetVal rv = OK;
277 bool aggFlag = false;
278 AggTableImpl *aggTable = NULL;
279 //TODO::Projection should have only aggregates and field names in
280 // group by list only
281 int groupFieldListSize = parsedData->getGroupFieldNameList().size();
282 if (groupFieldListSize !=0) {
283 aggTable = new AggTableImpl();
284 aggTable->setTable(table);
285 aggFlag = true;
287 bool isGroupFldInProjection = false;
288 while (iter.hasElement())
290 name = (FieldName*)iter.nextElement();
291 if (NULL == name)
293 dbMgr->closeTable(table);
294 table = NULL;
295 delete fInfo;
296 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
297 return ErrSysFatal;
299 if ('*' == name->fldName[0] && name->aType != AGG_COUNT)
301 iter.reset();
302 while (iter.hasElement())
303 delete (FieldName *) iter.nextElement();
304 rv = resolveStar();
305 if (rv != OK)
307 dbMgr->closeTable(table);
308 table = NULL;
309 delete fInfo;
310 return rv;
312 //as soon as it encounters *, it breaks the loop negleting other field names
313 //as they all are deleted during resolveStar method.
314 break;
315 } else {
316 if ('*' == name->fldName[0]) strcpy(name->fldName, elem->name);
317 rv = table->getFieldInfo(name->fldName, fInfo);
318 if (ErrNotFound == rv)
320 dbMgr->closeTable(table);
321 table = NULL;
322 delete fInfo;
323 printError(ErrSyntaxError, "Field %s does not exist in table",
324 name->fldName);
325 return ErrSyntaxError;
327 FieldValue *newVal = new FieldValue();
328 newVal->parsedString = NULL;
329 newVal->paramNo = 0;
330 newVal->type = fInfo->type;
331 newVal->length = fInfo->length;
332 // for binary datatype input buffer size should be 2 times the length
333 if(newVal->type == typeBinary)
334 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
335 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
336 parsedData->insertFieldValue(newVal);
337 if (name->aType == AGG_UNKNOWN) {
338 if (groupFieldListSize == 0) {
339 table->bindFld(name->fldName, newVal->value);
340 }else {
341 //delete newVal;
342 FieldName *groupFldName = NULL;
343 ListIterator giter = parsedData->getGroupFieldNameList().
344 getIterator();
345 while (giter.hasElement())
347 groupFldName = (FieldName*)giter.nextElement();
348 if (strcmp(groupFldName->fldName, name->fldName) ==0) {
349 isGroupFldInProjection = true;
350 aggTable->setGroup(name->fldName, newVal->value);
353 if (!isGroupFldInProjection)
355 printError(ErrSyntax, "Projection should contain only group fields\n");
356 delete fInfo;
357 dbMgr->closeTable(table);
358 table = NULL;
359 return ErrSyntax;
362 } else {
363 if (!aggFlag) {
364 aggTable = new AggTableImpl();
365 aggTable->setTable(table);
366 aggFlag = true;
368 aggTable->bindFld(name->fldName, name->aType, newVal->value);
373 rv = setBindFieldAndValues();
374 if (rv != OK)
376 delete fInfo;
377 dbMgr->closeTable(table);
378 table = NULL;
379 return rv;
382 table->setCondition(parsedData->getCondition());
384 rv = resolveForCondition();
385 if (rv != OK)
387 delete fInfo;
388 //TODO::free memory allocated for params
389 table->setCondition(NULL);
390 dbMgr->closeTable(table);
391 table = NULL;
393 if(aggFlag && !isGroupFldInProjection) {
394 ListIterator giter = parsedData->getGroupFieldNameList().getIterator();
395 while (giter.hasElement())
397 name = (FieldName*)giter.nextElement();
398 rv = table->getFieldInfo(name->fldName, fInfo);
399 if (ErrNotFound == rv)
401 dbMgr->closeTable(table);
402 table = NULL;
403 delete fInfo;
404 delete aggTable;
405 printError(ErrSyntaxError, "Field %s does not exist in table",
406 name->fldName);
407 return ErrSyntaxError;
409 FieldValue *newVal = new FieldValue();
410 newVal->parsedString = NULL;
411 newVal->paramNo = 0;
412 newVal->type = fInfo->type;
413 newVal->length = fInfo->length;
414 // for binary datatype input buffer size should be 2 times the length
415 if (newVal->type == typeBinary)
416 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
417 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
418 parsedData->insertFieldValue(newVal);
419 aggTable->setGroup(name->fldName, newVal->value);
422 if (aggFlag) {
423 table = aggTable;
425 delete fInfo;
426 return rv;
428 DbRetVal SelStatement::resolveStar()
430 DbRetVal rv = OK;
431 parsedData->clearFieldNameList();
432 List fNameList = table->getFieldNameList();
433 ListIterator fNameIter = fNameList.getIterator();
434 FieldValue *newVal = NULL;
435 //fNameList.resetIter(); //do not remove this.
436 FieldInfo *fInfo = new FieldInfo();
437 for (int i = 0; i < fNameList.size() ; i++)
439 char *fName = ((Identifier*)(fNameIter.nextElement()))->name;
440 rv = table->getFieldInfo(fName, fInfo);
441 if (ErrNotFound == rv)
443 delete fInfo;
444 fNameList.reset();
445 printError(ErrSysFatal, "Should never happen.");
446 return ErrSysFatal;
448 newVal = new FieldValue();
449 newVal->parsedString = NULL;
450 newVal->paramNo = 0;
451 newVal->type = fInfo->type;
452 newVal->length = fInfo->length;
453 // for binary datatype input buffer size should be 2 times the length
454 if(newVal->type == typeBinary)
455 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
456 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
457 parsedData->insertFieldValue(newVal);
458 parsedData->insertField(fName);
459 table->bindFld(fName, newVal->value);
461 fNameIter.reset();
462 while (fNameIter.hasElement())
463 delete (Identifier *) fNameIter.nextElement();
464 fNameList.reset();
465 delete fInfo;
466 return OK;
469 DbRetVal SelStatement::setBindFieldAndValues()
471 totalFields = parsedData->getFieldNameList().size();
472 bindFields = (FieldValue**) malloc ( totalFields * sizeof(FieldValue*));
473 bindFieldValues = (char**) malloc( totalFields * sizeof(char*));
474 memset(bindFields, 0, totalFields * sizeof(FieldValue*));
475 memset(bindFieldValues, 0, totalFields * sizeof(char*));
476 ListIterator valIter = parsedData->getFieldValueList().getIterator();
477 int colNo =0;
478 FieldValue *value = NULL;
479 valIter.reset();
480 while(valIter.hasElement())
482 value = (FieldValue*) valIter.nextElement();
483 if (value == NULL)
485 free(bindFields); bindFields = NULL;
486 free(bindFieldValues); bindFieldValues = NULL;
487 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
488 return ErrSysFatal;
490 bindFields[colNo++ ] = value;
492 return OK;
496 DbRetVal SelStatement::resolveForCondition()
498 //get the fieldname list and validate field names
499 ListIterator iter = parsedData->getConditionValueList().getIterator();
501 ConditionValue *value;
502 FieldInfo *fInfo = new FieldInfo();
503 int paramPos =1;
504 DbRetVal rv = OK;
505 while (iter.hasElement())
507 value = (ConditionValue*) iter.nextElement();
508 if (NULL == value)
510 delete fInfo;
511 printError(ErrSysFatal, "Should never happen.");
512 return ErrSysFatal;
514 rv = table->getFieldInfo(value->fName, fInfo);
515 if (ErrNotFound == rv)
517 delete fInfo;
518 printError(ErrSyntaxError, "Field %s does not exist in table",
519 value->fName);
520 return ErrSyntaxError;
522 value->type = fInfo->type;
523 value->length = fInfo->length;
524 value->value = AllDataType::alloc(fInfo->type, fInfo->length);
525 //table->bindFld(name->fldName, value->value);
526 if (value->parsedString == NULL)
528 delete fInfo;
529 printError(ErrSyntaxError, "Condition value should not be NULL");
530 return ErrSyntaxError;
532 if (value->parsedString[0] == '?')
534 if(!value->opLike) // checks if 'LIKE' operator is used
535 value->paramNo = paramPos++;
537 if (!value->paramNo) {
538 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
539 AllDataType::strToValue(value->value, value->parsedString, fInfo->type, fInfo->length);
542 delete fInfo;
543 totalParams = paramPos -1;
544 if (0 == totalParams) return OK;
545 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
546 paramValues = (char**) malloc( totalParams * sizeof(char*));
547 memset(params, 0, totalParams * sizeof(FieldValue*));
548 memset(paramValues, 0, totalParams * sizeof(char*));
549 iter.reset();
550 while(iter.hasElement())
552 value = (ConditionValue*) iter.nextElement();
553 if (value == NULL)
555 free(params); params = NULL;
556 free(paramValues); paramValues = NULL;
557 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
558 return ErrSysFatal;
560 params[value->paramNo -1 ] = value;
562 return OK;
565 void* SelStatement::fetch()
567 void *tuple = table->fetch();
568 if (NULL == tuple) return NULL;
569 //copy values to binded buffer
570 FieldValue *value;
571 for (int i = 0; i < totalFields; i++)
573 value = bindFields[i];
574 if (bindFieldValues[i] == NULL)
576 printError(ErrBadCall, "Fields are not binded properly. Should never happen");
577 return NULL;
579 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
581 return tuple;
584 void* SelStatement::fetch(DbRetVal &rv)
586 void *tuple = table->fetch(rv);
587 if (NULL == tuple) return NULL;
588 //copy values to binded buffer
589 FieldValue *value;
590 for (int i = 0; i < totalFields; i++)
592 value = bindFields[i];
593 if (bindFieldValues[i] == NULL)
595 printError(ErrBadCall, "Fields are not binded properly. Should never happen");
596 return NULL;
598 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
600 return tuple;
603 DbRetVal SelStatement::close()
605 return table->close();
607 void* SelStatement::getParamValuePtr( int pos )
609 ConditionValue *p = (ConditionValue*) params [pos-1];
610 return ( (void*) p->value );
613 char* SelStatement::getFieldName ( int pos )
615 //TODO::if not yet prepared return error
616 //TODO::check the upper limit for projpos
617 ListIterator iter = parsedData->getFieldNameList().getIterator();
618 int position =0;
619 while (iter.hasElement())
621 if (position == pos) {
622 FieldName *name = (FieldName*) iter.nextElement();
623 if (NULL == name)
625 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
626 return (char*) 0;
628 return name->fldName;
630 position++;
632 return (char*) 0;
635 DataType SelStatement::getFieldType( int pos )
637 FieldValue *v = bindFields[pos];
638 return ( (DataType) v->type );
641 int SelStatement::getFieldLength( int pos )
643 FieldValue *v = bindFields[pos];
644 return ( (int) v->type );
647 void* SelStatement::fetchAndPrint(bool SQL)
649 void *tuple = table->fetch();
650 if (NULL == tuple) return NULL;
651 FieldValue *value;
652 bool nullValueSet;
653 char stmt[128];
654 if (SQL) {
655 sprintf(stmt, "INSERT INTO %s VALUES(", table->getName());
656 printf("%s", stmt);
658 for (int i = 0; i < totalFields; i++)
660 value = bindFields[i];
661 nullValueSet = table->isFldNull(i+1);
662 if (nullValueSet)
663 if (SQL) {
664 if (i==0)
665 printf("NULL");
666 else
667 printf(", NULL");
669 else printf("NULL\t");
670 else {
671 if (SQL) {
672 switch(value->type)
674 case typeString:
675 case typeBinary:
676 case typeDate:
677 case typeTime:
678 case typeTimeStamp:
680 if (i==0)
681 printf(" '");
682 else
683 printf(", '");
684 break;
686 default:
688 if (i!=0)
689 printf(",");
693 AllDataType::printVal(value->value, value->type, value->length);
694 if (SQL) {
695 switch(value->type)
697 case typeString:
698 case typeBinary:
699 case typeDate:
700 case typeTime:
701 case typeTimeStamp:
702 printf("'");
704 } else printf("\t");
707 if (SQL) printf(");\n");
708 return tuple;
711 void* SelStatement::next()
713 return( table->fetch() );
716 void* SelStatement::getFieldValuePtr( int pos )
718 FieldValue *v = bindFields[pos];
719 return ( (void*) v->value );
722 int SelStatement::noOfProjFields()
724 return totalFields;
727 DbRetVal SelStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
729 //TODO::if not yet prepared return error
730 //TODO::check the upper limit for projpos
731 ListIterator iter = parsedData->getFieldNameList().getIterator();
732 FieldName *name = NULL;
733 DbRetVal rv = OK;
734 int position =0;
735 while (iter.hasElement())
737 name = (FieldName*)iter.nextElement();
738 if (NULL == name)
740 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
741 return ErrSysFatal;
743 if (position == projpos) break;
744 position++;
747 rv = table->getFieldInfo(name->fldName, fInfo);