Fix for Bugs: 1962820/22/24
[csql.git] / src / sql / SelStatement.cxx
blob7b497feddf02d9738effefad866269f873b34155
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::setBindField(int colNo, void *value)
230 if (colNo <=0) return ErrBadArg;
231 //TODO: check the upper limit
232 //if (colNo > table->getFieldNameList().size()) return ErrBadArg;
233 if (NULL == value) return ErrBadArg;
234 bindFieldValues[colNo -1] = (char*) value;
235 return OK;
238 DbRetVal SelStatement::resolve()
240 if (dbMgr == NULL) return ErrNoConnection;
241 //check whether the table exists
242 table = dbMgr->openTable(parsedData->getTableName());
243 if (table == NULL)
245 printError(ErrNotExists, "Unable to open the table:Table not exists");
246 return ErrNotExists;
248 //get the fieldname list and validate field names
249 ListIterator iter = parsedData->getFieldNameList().getIterator();
250 FieldName *name = NULL;
251 FieldInfo *fInfo = new FieldInfo();
252 DbRetVal rv = OK;
253 while (iter.hasElement())
255 name = (FieldName*)iter.nextElement();
256 if (NULL == name)
258 dbMgr->closeTable(table);
259 table = NULL;
260 delete fInfo;
261 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
262 return ErrSysFatal;
264 if ('*' == name->fldName[0])
266 iter.reset();
267 while (iter.hasElement())
268 delete (FieldName *) iter.nextElement();
269 rv = resolveStar();
270 if (rv != OK)
272 dbMgr->closeTable(table);
273 table = NULL;
274 delete fInfo;
275 return rv;
277 //as soon as it encounters *, it breaks the loop negleting other field names
278 //as they all are deleted during resolveStar method.
279 break;
280 } else {
281 rv = table->getFieldInfo(name->fldName, fInfo);
282 if (ErrNotFound == rv)
284 dbMgr->closeTable(table);
285 table = NULL;
286 delete fInfo;
287 printError(ErrSyntaxError, "Field %s does not exist in table",
288 name->fldName);
289 return ErrSyntaxError;
291 FieldValue *newVal = new FieldValue();
292 newVal->parsedString = NULL;
293 newVal->paramNo = 0;
294 newVal->type = fInfo->type;
295 newVal->length = fInfo->length;
296 newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
297 parsedData->insertFieldValue(newVal);
298 table->bindFld(name->fldName, newVal->value);
301 delete fInfo;
303 rv = setBindFieldAndValues();
304 if (rv != OK)
306 dbMgr->closeTable(table);
307 table = NULL;
308 return rv;
311 table->setCondition(parsedData->getCondition());
313 rv = resolveForCondition();
314 if (rv != OK)
316 //TODO::free memory allocated for params
317 table->setCondition(NULL);
318 dbMgr->closeTable(table);
319 table = NULL;
321 return rv;
323 DbRetVal SelStatement::resolveStar()
325 DbRetVal rv = OK;
326 parsedData->clearFieldNameList();
327 List fNameList = table->getFieldNameList();
328 ListIterator fNameIter = fNameList.getIterator();
329 FieldValue *newVal = NULL;
330 //fNameList.resetIter(); //do not remove this.
331 FieldInfo *fInfo = new FieldInfo();
332 for (int i = 0; i < fNameList.size() ; i++)
334 char *fName = ((Identifier*)(fNameIter.nextElement()))->name;
335 rv = table->getFieldInfo(fName, fInfo);
336 if (ErrNotFound == rv)
338 delete fInfo;
339 fNameList.reset();
340 printError(ErrSysFatal, "Should never happen.");
341 return ErrSysFatal;
343 newVal = new FieldValue();
344 newVal->parsedString = NULL;
345 newVal->paramNo = 0;
346 newVal->type = fInfo->type;
347 newVal->length = fInfo->length;
348 newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
349 parsedData->insertFieldValue(newVal);
350 parsedData->insertField(fName);
351 table->bindFld(fName, newVal->value);
353 fNameIter.reset();
354 while (fNameIter.hasElement())
355 delete (Identifier *) fNameIter.nextElement();
356 fNameList.reset();
357 delete fInfo;
358 return OK;
361 DbRetVal SelStatement::setBindFieldAndValues()
363 totalFields = parsedData->getFieldNameList().size();
364 bindFields = (FieldValue**) malloc ( totalFields * sizeof(FieldValue*));
365 bindFieldValues = (char**) malloc( totalFields * sizeof(char*));
366 memset(bindFields, 0, totalFields * sizeof(FieldValue*));
367 memset(bindFieldValues, 0, totalFields * sizeof(char*));
368 ListIterator valIter = parsedData->getFieldValueList().getIterator();
369 int colNo =0;
370 FieldValue *value = NULL;
371 valIter.reset();
372 while(valIter.hasElement())
374 value = (FieldValue*) valIter.nextElement();
375 if (value == NULL)
377 free(bindFields); bindFields = NULL;
378 free(bindFieldValues); bindFieldValues = NULL;
379 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
380 return ErrSysFatal;
382 bindFields[colNo++ ] = value;
384 return OK;
388 DbRetVal SelStatement::resolveForCondition()
390 //get the fieldname list and validate field names
391 ListIterator iter = parsedData->getConditionValueList().getIterator();
393 ConditionValue *value;
394 FieldInfo *fInfo = new FieldInfo();
395 int paramPos =1;
396 DbRetVal rv = OK;
397 while (iter.hasElement())
399 value = (ConditionValue*) iter.nextElement();
400 if (NULL == value)
402 delete fInfo;
403 printError(ErrSysFatal, "Should never happen.");
404 return ErrSysFatal;
406 rv = table->getFieldInfo(value->fName, fInfo);
407 if (ErrNotFound == rv)
409 delete fInfo;
410 printError(ErrSyntaxError, "Field %s does not exist in table",
411 value->fName);
412 return ErrSyntaxError;
414 value->type = fInfo->type;
415 value->length = fInfo->length;
416 value->value = AllDataType::alloc(fInfo->type, fInfo->length);
417 //table->bindFld(name->fldName, value->value);
418 if (value->parsedString == NULL)
420 delete fInfo;
421 printError(ErrSyntaxError, "Condition value should not be NULL");
422 return ErrSyntaxError;
424 if (value->parsedString[0] == '?')
426 value->paramNo = paramPos++;
428 if (!value->paramNo)
429 AllDataType::strToValue(value->value, value->parsedString, fInfo->type);
431 delete fInfo;
432 totalParams = paramPos -1;
433 if (0 == totalParams) return OK;
434 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
435 paramValues = (char**) malloc( totalParams * sizeof(char*));
436 memset(params, 0, totalParams * sizeof(FieldValue*));
437 memset(paramValues, 0, totalParams * sizeof(char*));
438 iter.reset();
439 while(iter.hasElement())
441 value = (ConditionValue*) iter.nextElement();
442 if (value == NULL)
444 free(params); params = NULL;
445 free(paramValues); paramValues = NULL;
446 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
447 return ErrSysFatal;
449 params[value->paramNo -1 ] = value;
451 return OK;
454 void* SelStatement::fetch()
456 void *tuple = table->fetch();
457 if (NULL == tuple) return NULL;
458 //copy values to binded buffer
459 FieldValue *value;
460 for (int i = 0; i < totalFields; i++)
462 value = bindFields[i];
463 if (bindFieldValues[i] == NULL)
465 printError(ErrBadCall, "Fields are not binded properly. Should never happen");
466 return NULL;
468 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
470 return tuple;
473 void* SelStatement::fetch(DbRetVal &rv)
475 void *tuple = table->fetch(rv);
476 if (NULL == tuple) return NULL;
477 //copy values to binded buffer
478 FieldValue *value;
479 for (int i = 0; i < totalFields; i++)
481 value = bindFields[i];
482 if (bindFieldValues[i] == NULL)
484 printError(ErrBadCall, "Fields are not binded properly. Should never happen");
485 return NULL;
487 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
489 return tuple;
492 DbRetVal SelStatement::close()
494 return table->close();
496 void* SelStatement::getParamValuePtr( int pos )
498 ConditionValue *p = (ConditionValue*) params [pos-1];
499 return ( (void*) p->value );
502 char* SelStatement::getFieldName ( int pos )
504 //TODO::if not yet prepared return error
505 //TODO::check the upper limit for projpos
506 ListIterator iter = parsedData->getFieldNameList().getIterator();
507 int position =0;
508 while (iter.hasElement())
510 if (position == pos) {
511 FieldName *name = (FieldName*) iter.nextElement();
512 if (NULL == name)
514 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
515 return (char*) 0;
517 return name->fldName;
519 position++;
521 return (char*) 0;
524 DataType SelStatement::getFieldType( int pos )
526 FieldValue *v = bindFields[pos];
527 return ( (DataType) v->type );
530 int SelStatement::getFieldLength( int pos )
532 FieldValue *v = bindFields[pos];
533 return ( (int) v->type );
536 void* SelStatement::fetchAndPrint(bool SQL)
538 void *tuple = table->fetch();
539 if (NULL == tuple) return NULL;
540 FieldValue *value;
541 bool nullValueSet;
542 char stmt[128];
543 if (SQL) {
544 sprintf(stmt, "INSERT INTO %s VALUES(", table->getName());
545 printf("%s", stmt);
547 for (int i = 0; i < totalFields; i++)
549 value = bindFields[i];
550 nullValueSet = table->isFldNull(i+1);
551 if (nullValueSet)
552 if (SQL) {
553 if (i==0)
554 printf("NULL");
555 else
556 printf(", NULL");
558 else printf("NULL\t");
559 else {
560 if (SQL) {
561 switch(value->type)
563 case typeString:
564 case typeDate:
565 case typeTime:
566 case typeTimeStamp:
568 if (i==0)
569 printf(" '");
570 else
571 printf(", '");
572 break;
574 default:
576 if (i!=0)
577 printf(",");
581 AllDataType::printVal(value->value, value->type, value->length);
582 if (SQL) {
583 switch(value->type)
585 case typeString:
586 case typeDate:
587 case typeTime:
588 case typeTimeStamp:
589 printf("'");
591 } else printf("\t");
594 if (SQL) printf(");\n");
595 return tuple;
598 void* SelStatement::next()
600 return( table->fetch() );
603 void* SelStatement::getFieldValuePtr( int pos )
605 FieldValue *v = bindFields[pos];
606 return ( (void*) v->value );
609 int SelStatement::noOfProjFields()
611 return totalFields;
614 DbRetVal SelStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
616 //TODO::if not yet prepared return error
617 //TODO::check the upper limit for projpos
618 ListIterator iter = parsedData->getFieldNameList().getIterator();
619 FieldName *name = NULL;
620 DbRetVal rv = OK;
621 int position =0;
622 while (iter.hasElement())
624 name = (FieldName*)iter.nextElement();
625 if (NULL == name)
627 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
628 return ErrSysFatal;
630 if (position == projpos) break;
631 position++;
634 rv = table->getFieldInfo(name->fldName, fInfo);