1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
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. *
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. *
15 ***************************************************************************/
16 #include "Statement.h"
18 SelStatement::SelStatement()
27 bindFieldValues
= NULL
;
31 SelStatement::~SelStatement()
34 table
->setCondition(NULL
);
35 if (dbMgr
) dbMgr
->closeTable(table
);
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];
58 printError(ErrSysFatal
, "condition value is null. Should never happen");
61 info
->type
= cValue
->type
;
62 info
->length
= cValue
->length
;
65 DbRetVal
SelStatement::execute(int &rowsAffected
)
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
)
76 //printError(ErrBadCall, "param values not set");
79 AllDataType::copyVal(value
->value
, paramValues
[i
], value
->type
, value
->length
);
81 rv
= table
->execute();
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
;
93 DbRetVal
SelStatement::setShortParam(int paramNo
, short value
)
95 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
96 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
99 printError(ErrSysFatal
, "field value is null. Should never happen");
102 *(short*)cValue
->value
= value
;
106 DbRetVal
SelStatement::setIntParam(int paramNo
, int value
)
108 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
109 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
112 printError(ErrSysFatal
, "condition value is null. Should never happen");
115 *(int*)cValue
->value
= value
;
118 DbRetVal
SelStatement::setLongParam(int paramNo
, long value
)
120 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
121 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
124 printError(ErrSysFatal
, "condition value is null. Should never happen");
127 *(long*)cValue
->value
= value
;
131 DbRetVal
SelStatement::setLongLongParam(int paramNo
, long long value
)
133 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
134 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
137 printError(ErrSysFatal
, "condition value is null. Should never happen");
140 *(long long*)cValue
->value
= value
;
143 DbRetVal
SelStatement::setByteIntParam(int paramNo
, ByteInt value
)
145 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
146 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
149 printError(ErrSysFatal
, "condition value is null. Should never happen");
152 *(ByteInt
*)cValue
->value
= value
;
155 DbRetVal
SelStatement::setFloatParam(int paramNo
, float value
)
157 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
158 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
161 printError(ErrSysFatal
, "condition value is null. Should never happen");
164 *(float*)cValue
->value
= value
;
167 DbRetVal
SelStatement::setDoubleParam(int paramNo
, double value
)
169 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
170 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
173 printError(ErrSysFatal
, "condition value is null. Should never happen");
176 *(double*)cValue
->value
= value
;
179 DbRetVal
SelStatement::setStringParam(int paramNo
, char *value
)
181 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
182 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
185 printError(ErrSysFatal
, "condition value is null. Should never happen");
188 strcpy((char*)cValue
->value
, value
);
191 DbRetVal
SelStatement::setDateParam(int paramNo
, Date value
)
193 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
194 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
197 printError(ErrSysFatal
, "condition value is null. Should never happen");
200 *(Date
*)cValue
->value
= value
;
203 DbRetVal
SelStatement::setTimeParam(int paramNo
, Time value
)
205 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
206 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
209 printError(ErrSysFatal
, "condition value is null. Should never happen");
212 *(Time
*)cValue
->value
= value
;
215 DbRetVal
SelStatement::setTimeStampParam(int paramNo
, TimeStamp value
)
217 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
218 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
221 printError(ErrSysFatal
, "condition value is null. Should never happen");
224 *(TimeStamp
*)cValue
->value
= value
;
228 DbRetVal
SelStatement::setBinaryParam(int paramNo
, void *value
)
230 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
231 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
234 printError(ErrSysFatal
, "condition value is null. Should never happen");
237 memcpy(cValue
->value
, value
, 2 * cValue
->length
);
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
;
251 DbRetVal
SelStatement::resolve()
253 if (dbMgr
== NULL
) return ErrNoConnection
;
254 //check whether the table exists
255 table
= dbMgr
->openTable(parsedData
->getTableName());
258 printError(ErrNotExists
, "Unable to open the table:Table not exists");
261 List fNameList
= table
->getFieldNameList();
262 ListIterator fNameIter
= fNameList
.getIterator();
263 Identifier
*elem
= NULL
;
264 if (fNameIter
.hasElement())
265 elem
= (Identifier
*) fNameIter
.nextElement();
268 printError(ErrNotExists
, "No fields present in the table %s", parsedData
->getTableName());
272 //get the fieldname list and validate field names
273 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
274 FieldName
*name
= NULL
;
275 FieldInfo
*fInfo
= new FieldInfo();
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
);
287 bool isGroupFldInProjection
= false;
288 while (iter
.hasElement())
290 name
= (FieldName
*)iter
.nextElement();
293 dbMgr
->closeTable(table
);
296 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
299 if ('*' == name
->fldName
[0] && name
->aType
!= AGG_COUNT
)
302 while (iter
.hasElement())
303 delete (FieldName
*) iter
.nextElement();
307 dbMgr
->closeTable(table
);
312 //as soon as it encounters *, it breaks the loop negleting other field names
313 //as they all are deleted during resolveStar method.
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
);
323 printError(ErrSyntaxError
, "Field %s does not exist in table",
325 return ErrSyntaxError
;
327 FieldValue
*newVal
= new FieldValue();
328 newVal
->parsedString
= NULL
;
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
);
342 FieldName
*groupFldName
= NULL
;
343 ListIterator giter
= parsedData
->getGroupFieldNameList().
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");
357 dbMgr
->closeTable(table
);
364 aggTable
= new AggTableImpl();
365 aggTable
->setTable(table
);
368 aggTable
->bindFld(name
->fldName
, name
->aType
, newVal
->value
);
373 rv
= setBindFieldAndValues();
377 dbMgr
->closeTable(table
);
382 table
->setCondition(parsedData
->getCondition());
384 rv
= resolveForCondition();
388 //TODO::free memory allocated for params
389 table
->setCondition(NULL
);
390 dbMgr
->closeTable(table
);
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
);
405 printError(ErrSyntaxError
, "Field %s does not exist in table",
407 return ErrSyntaxError
;
409 FieldValue
*newVal
= new FieldValue();
410 newVal
->parsedString
= NULL
;
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
);
428 DbRetVal
SelStatement::resolveStar()
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
)
445 printError(ErrSysFatal
, "Should never happen.");
448 newVal
= new FieldValue();
449 newVal
->parsedString
= NULL
;
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
);
462 while (fNameIter
.hasElement())
463 delete (Identifier
*) fNameIter
.nextElement();
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();
478 FieldValue
*value
= NULL
;
480 while(valIter
.hasElement())
482 value
= (FieldValue
*) valIter
.nextElement();
485 free(bindFields
); bindFields
= NULL
;
486 free(bindFieldValues
); bindFieldValues
= NULL
;
487 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
490 bindFields
[colNo
++ ] = value
;
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();
505 while (iter
.hasElement())
507 value
= (ConditionValue
*) iter
.nextElement();
511 printError(ErrSysFatal
, "Should never happen.");
514 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
515 if (ErrNotFound
== rv
)
518 printError(ErrSyntaxError
, "Field %s does not exist in table",
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
)
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
);
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*));
550 while(iter
.hasElement())
552 value
= (ConditionValue
*) iter
.nextElement();
555 free(params
); params
= NULL
;
556 free(paramValues
); paramValues
= NULL
;
557 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
560 params
[value
->paramNo
-1 ] = value
;
565 void* SelStatement::fetch()
567 void *tuple
= table
->fetch();
568 if (NULL
== tuple
) return NULL
;
569 //copy values to binded buffer
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");
579 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
584 void* SelStatement::fetch(DbRetVal
&rv
)
586 void *tuple
= table
->fetch(rv
);
587 if (NULL
== tuple
) return NULL
;
588 //copy values to binded buffer
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");
598 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
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();
619 while (iter
.hasElement())
621 if (position
== pos
) {
622 FieldName
*name
= (FieldName
*) iter
.nextElement();
625 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
628 return name
->fldName
;
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
;
655 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
658 for (int i
= 0; i
< totalFields
; i
++)
660 value
= bindFields
[i
];
661 nullValueSet
= table
->isFldNull(i
+1);
669 else printf("NULL\t");
693 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
707 if (SQL
) printf(");\n");
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()
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
;
735 while (iter
.hasElement())
737 name
= (FieldName
*)iter
.nextElement();
740 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
743 if (position
== projpos
) break;
747 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);