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"
17 #include <TableImpl.h>
19 SelStatement::SelStatement()
28 bindFieldValues
= NULL
;
30 isPointReturned
= false;
31 handleAggWithTbl
=false;
34 SelStatement::~SelStatement()
37 if (table
) { table
->close(); table
= NULL
; }
48 free(bindFieldValues
);
49 bindFieldValues
= NULL
;
53 DbRetVal
SelStatement::getParamFldInfo(int paramNo
, FieldInfo
*&info
)
55 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
56 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
59 printError(ErrSysFatal
, "condition value is null. Should never happen");
62 table
->getFieldNameAlone(cValue
->fName
,info
->fldName
);
63 info
->type
= cValue
->type
;
64 info
->length
= cValue
->length
;
65 info
->isNull
= cValue
->isNullable
;
68 DbRetVal
SelStatement::execute(int &rowsAffected
)
71 //copy param values to binded buffer
72 ConditionValue
*value
;
73 for (int i
= 0; i
< totalParams
; i
++)
75 value
= (ConditionValue
*) params
[i
];
76 if (paramValues
[i
] == NULL
)
79 //printError(ErrBadCall, "param values not set");
82 AllDataType::copyVal(value
->value
, paramValues
[i
], value
->type
, value
->length
);
85 rv
= table
->execute();
86 //table->printPlan(0);
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
;
98 DbRetVal
SelStatement::setShortParam(int paramNo
, short value
)
100 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
101 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
104 printError(ErrSysFatal
, "field value is null. Should never happen");
107 *(short*)cValue
->value
= value
;
111 DbRetVal
SelStatement::setIntParam(int paramNo
, int value
)
113 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
114 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
117 printError(ErrSysFatal
, "condition value is null. Should never happen");
120 *(int*)cValue
->value
= value
;
123 DbRetVal
SelStatement::setLongParam(int paramNo
, long value
)
125 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
126 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
129 printError(ErrSysFatal
, "condition value is null. Should never happen");
132 *(long*)cValue
->value
= value
;
136 DbRetVal
SelStatement::setLongLongParam(int paramNo
, long long value
)
138 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
139 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
142 printError(ErrSysFatal
, "condition value is null. Should never happen");
145 *(long long*)cValue
->value
= value
;
148 DbRetVal
SelStatement::setByteIntParam(int paramNo
, ByteInt value
)
150 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
151 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
154 printError(ErrSysFatal
, "condition value is null. Should never happen");
157 *(ByteInt
*)cValue
->value
= value
;
160 DbRetVal
SelStatement::setFloatParam(int paramNo
, float value
)
162 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
163 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
166 printError(ErrSysFatal
, "condition value is null. Should never happen");
169 *(float*)cValue
->value
= value
;
172 DbRetVal
SelStatement::setDoubleParam(int paramNo
, double value
)
174 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
175 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
178 printError(ErrSysFatal
, "condition value is null. Should never happen");
181 *(double*)cValue
->value
= value
;
184 DbRetVal
SelStatement::setStringParam(int paramNo
, char *value
)
186 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
187 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
190 printError(ErrSysFatal
, "condition value is null. Should never happen");
193 strcpy((char*)cValue
->value
, value
);
196 DbRetVal
SelStatement::setDateParam(int paramNo
, Date value
)
198 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
199 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
202 printError(ErrSysFatal
, "condition value is null. Should never happen");
205 *(Date
*)cValue
->value
= value
;
208 DbRetVal
SelStatement::setTimeParam(int paramNo
, Time value
)
210 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
211 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
214 printError(ErrSysFatal
, "condition value is null. Should never happen");
217 *(Time
*)cValue
->value
= value
;
220 DbRetVal
SelStatement::setTimeStampParam(int paramNo
, TimeStamp value
)
222 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
223 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
226 printError(ErrSysFatal
, "condition value is null. Should never happen");
229 *(TimeStamp
*)cValue
->value
= value
;
233 DbRetVal
SelStatement::setBinaryParam(int paramNo
, void *value
)
235 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
236 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
239 printError(ErrSysFatal
, "condition value is null. Should never happen");
242 AllDataType::convertToBinary(cValue
->value
,value
,typeString
,cValue
->length
);
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
;
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
);
269 printError(ErrNotExists
,
270 "Unable to open the table:Table not exists");
276 jHdl
= new JoinTableImpl();
277 jHdl
->setTable(prevHdl
, tHdl
);
283 if (joinInvolved
) table
= jHdl
; else table
= tHdl
;
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();
295 bool isSingleTableNoGrp
= false;
296 if(parsedData
->getTableNameList().size() == 1 &&
297 parsedData
->getGroupFieldNameList().size() == 0)
299 isSingleTableNoGrp
= true;
301 AggTableImpl
*aggTable
= NULL
;
302 while (iter
.hasElement())
304 name
= (FieldName
*)iter
.nextElement();
307 dbMgr
->closeTable(table
);
310 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
313 bool isBindFld
=false;
314 if ('*' == name
->fldName
[0] && name
->aType
== AGG_UNKNOWN
)
319 dbMgr
->closeTable(table
);
324 if (parsedData
->getGroupFieldNameList().size()!= 0
325 && !isSingleTableNoGrp
)
328 aggTable
= new AggTableImpl();
329 aggTable
->setTable(table
);
331 //as soon as it encounters *, it breaks the loop negleting other field names
332 //as they all are deleted during resolveStar method.
335 if ('*' == name
->fldName
[0] && name
->aType
!= AGG_COUNT
) {return ErrSyntaxError
;}
336 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
337 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
339 dbMgr
->closeTable(table
);
342 printError(ErrSyntaxError
, "Field %s does not exist in table",
344 return ErrSyntaxError
;
346 FieldValue
*newVal
= new FieldValue();
347 strcpy(newVal
->fldName
,name
->fldName
);
348 newVal
->parsedString
= NULL
;
350 newVal
->type
= fInfo
->type
;
351 newVal
->length
= fInfo
->length
;
352 newVal
->isNullable
= fInfo
->isNull
;
353 FieldName
*bFldName
=NULL
;
354 ListIterator it
= bindFldList
.getIterator();
355 while (it
.hasElement())
357 bFldName
= (FieldName
*)it
.nextElement();
358 if(0==strcmp(bFldName
->fldName
,name
->fldName
) &&
359 name
->aType
== AGG_UNKNOWN
)
361 newVal
->value
=table
->getBindFldAddr(name
->fldName
);
362 newVal
->isAllocVal
=false;
368 if(newVal
->type
== typeBinary
)
369 newVal
->value
= AllDataType::alloc(fInfo
->type
,
371 else newVal
->value
= AllDataType::alloc(fInfo
->type
,
373 newVal
->isAllocVal
=true;
375 if (name
->aType
==AGG_UNKNOWN
&&
376 parsedData
->getGroupFieldNameList().size()== 0)
377 table
->bindFld(name
->fldName
, newVal
->value
);
378 else if (!isSingleTableNoGrp
)
381 aggTable
= new AggTableImpl();
382 aggTable
->setTable(table
);
384 aggTable
->bindFld(name
->fldName
, name
->aType
, newVal
->value
);
386 if (name
->aType
!=AGG_UNKNOWN
&& isSingleTableNoGrp
)
387 handleAggWithTbl
= true;
388 parsedData
->insertFieldValue(newVal
);
390 if (!isBindFld
) bindFldList
.append(name
);
393 rv
= setBindFieldAndValues();
397 dbMgr
->closeTable(table
);
402 table
->setCondition(parsedData
->getCondition());
404 rv
= resolveForCondition();
408 //TODO::free memory allocated for params
409 table
->setCondition(NULL
);
410 dbMgr
->closeTable(table
);
414 rv
= resolveGroupFld(aggTable
);
418 //TODO::free memory allocated for params
421 table
->setCondition(NULL
);
422 dbMgr
->closeTable(table
);
430 DbRetVal
SelStatement::resolveGroupFld(AggTableImpl
*aggTable
)
435 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
436 FieldName
*name
= NULL
;
438 FieldInfo
*fInfo
= new FieldInfo();
439 if (giter
.hasElement())
441 name
= (FieldName
*)giter
.nextElement();
442 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
443 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
445 dbMgr
->closeTable(table
);
449 printError(ErrSyntaxError
, "Field %s does not exist in table",
451 return ErrSyntaxError
;
453 FieldValue
*newVal
= new FieldValue();
454 strcpy(newVal
->fldName
,name
->fldName
);
455 newVal
->parsedString
= NULL
;
457 newVal
->type
= fInfo
->type
;
458 newVal
->isNullable
= fInfo
->isNull
;
459 newVal
->length
= fInfo
->length
;
460 if (newVal
->type
== typeBinary
)
461 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
462 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
463 newVal
->isAllocVal
=true;
464 parsedData
->insertFieldValue(newVal
);
465 aggTable
->setGroup(name
->fldName
, newVal
->value
);
468 if (giter
.hasElement())
471 printError(ErrSyntaxError
, "Only one field allowed in group\n");
472 return ErrSyntaxError
;
477 DbRetVal
SelStatement::resolveStar()
480 parsedData
->clearFieldNameList();
482 List fNameList
= table
->getFieldNameList();
483 ListIterator fNameIter
= fNameList
.getIterator();
484 FieldValue
*newVal
= NULL
;
485 //fNameList.resetIter(); //do not remove this.
486 FieldInfo
*fInfo
= new FieldInfo();
487 for (int i
= 0; i
< fNameList
.size() ; i
++)
489 char *fName
= ((Identifier
*)(fNameIter
.nextElement()))->name
;
490 rv
= table
->getFieldInfo(fName
, fInfo
);
491 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
495 printError(ErrSysFatal
, "Should never happen.");
498 newVal
= new FieldValue();
499 strcpy(newVal
->fldName
,fName
);
500 newVal
->parsedString
= NULL
;
502 newVal
->type
= fInfo
->type
;
503 newVal
->length
= fInfo
->length
;
504 // for binary datatype input buffer size should be 2 times the length
505 if(newVal
->type
== typeBinary
)
506 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
507 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
508 newVal
->isAllocVal
=true;
509 parsedData
->insertFieldValue(newVal
);
510 parsedData
->insertField(fName
);
511 table
->bindFld(fName
, newVal
->value
);
514 while (fNameIter
.hasElement())
515 delete (Identifier
*) fNameIter
.nextElement();
521 DbRetVal
SelStatement::setBindFieldAndValues()
523 totalFields
= parsedData
->getFieldNameList().size();
524 bindFields
= (FieldValue
**) malloc ( totalFields
* sizeof(FieldValue
*));
525 bindFieldValues
= (char**) malloc( totalFields
* sizeof(char*));
526 memset(bindFields
, 0, totalFields
* sizeof(FieldValue
*));
527 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
528 ListIterator valIter
= parsedData
->getFieldValueList().getIterator();
530 FieldValue
*value
= NULL
;
532 while(valIter
.hasElement())
534 value
= (FieldValue
*) valIter
.nextElement();
537 free(bindFields
); bindFields
= NULL
;
538 free(bindFieldValues
); bindFieldValues
= NULL
;
539 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
542 bindFields
[colNo
++ ] = value
;
548 DbRetVal
SelStatement::resolveForCondition()
550 //get the fieldname list and validate field names
551 ListIterator iter
= parsedData
->getConditionValueList().getIterator();
553 ConditionValue
*value
;
554 FieldInfo
*fInfo
= new FieldInfo();
557 while (iter
.hasElement())
559 value
= (ConditionValue
*) iter
.nextElement();
563 printError(ErrSysFatal
, "Should never happen.");
566 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
567 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
570 printError(ErrSyntaxError
, "Field %s does not exist in table",
572 return ErrSyntaxError
;
574 value
->type
= fInfo
->type
;
575 value
->length
= fInfo
->length
;
576 value
->isNullable
= fInfo
->isNull
;
577 value
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
578 //table->bindFld(name->fldName, value->value);
579 if (value
->parsedString
== NULL
)
582 printError(ErrSyntaxError
, "Condition value should not be NULL");
583 return ErrSyntaxError
;
585 if (value
->parsedString
[0] == '?')
587 if(!value
->opLike
) // checks if 'LIKE' operator is used
588 value
->paramNo
= paramPos
++;
590 if (!value
->paramNo
) {
591 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
592 AllDataType::strToValue(value
->value
, value
->parsedString
, fInfo
->type
, fInfo
->length
);
596 totalParams
= paramPos
-1;
597 if (0 == totalParams
) return OK
;
598 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
599 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
600 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
601 memset(paramValues
, 0, totalParams
* sizeof(char*));
603 while(iter
.hasElement())
605 value
= (ConditionValue
*) iter
.nextElement();
608 free(params
); params
= NULL
;
609 free(paramValues
); paramValues
= NULL
;
610 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
613 params
[value
->paramNo
-1 ] = value
;
617 void* SelStatement::handleSingleTableAggWithoutGroup()
619 if (isPointReturned
) return NULL
;
620 TableImpl
*tblImpl
= (TableImpl
*)table
;
621 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
625 FieldValue
*fVal
= NULL
;
626 while (iter
.hasElement())
628 name
= (FieldName
*) iter
.nextElement();
629 fVal
= bindFields
[i
];
631 //rv = tblImpl->fetchAgg(name, (int) name->aType, fVal->value);
632 rv
= tblImpl
->fetchAgg(name
->fldName
, name
->aType
, fVal
->value
);
633 if (OK
!= rv
) return NULL
;
635 tblImpl
->closeScan();
638 isPointReturned
= true;
641 void* SelStatement::fetch()
645 return handleSingleTableAggWithoutGroup();
647 void *tuple
= table
->fetch();
648 if (NULL
== tuple
) return NULL
;
649 //copy values to binded buffer
651 for (int i
= 0; i
< totalFields
; i
++)
653 value
= bindFields
[i
];
654 if (bindFieldValues
[i
] == NULL
)
656 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
659 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
664 void* SelStatement::fetch(DbRetVal
&rv
)
668 return handleSingleTableAggWithoutGroup();
670 void *tuple
= table
->fetch(rv
);
671 if (NULL
== tuple
) return NULL
;
672 //copy values to binded buffer
674 for (int i
= 0; i
< totalFields
; i
++)
676 value
= bindFields
[i
];
677 if (bindFieldValues
[i
] == NULL
)
679 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
682 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
687 DbRetVal
SelStatement::close()
689 isPointReturned
= false;
690 if (table
) return table
->closeScan();
694 void* SelStatement::getParamValuePtr( int pos
)
696 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
697 return ( (void*) p
->value
);
700 char* SelStatement::getFieldName ( int pos
)
702 //TODO::if not yet prepared return error
703 //TODO::check the upper limit for projpos
704 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
706 while (iter
.hasElement())
708 if (position
== pos
) {
709 FieldName
*name
= (FieldName
*) iter
.nextElement();
712 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
715 return name
->fldName
;
722 DataType
SelStatement::getFieldType( int pos
)
724 FieldValue
*v
= bindFields
[pos
];
725 return ( (DataType
) v
->type
);
728 int SelStatement::getFieldLength( int pos
)
730 FieldValue
*v
= bindFields
[pos
];
731 return ( (int) v
->type
);
734 void* SelStatement::fetchAndPrint(bool SQL
)
739 tuple
= handleSingleTableAggWithoutGroup();
741 tuple
= table
->fetch();
743 if (NULL
== tuple
) return NULL
;
748 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
751 for (int i
= 0; i
< totalFields
; i
++)
753 value
= bindFields
[i
];
754 nullValueSet
= table
->isFldNull(value
->fldName
);
762 else printf("NULL\t");
786 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
800 if (SQL
) printf(");\n");
804 void* SelStatement::next()
808 return handleSingleTableAggWithoutGroup();
810 return( table
->fetch() );
814 void* SelStatement::getFieldValuePtr( int pos
)
816 FieldValue
*v
= bindFields
[pos
];
817 return ( (void*) v
->value
);
820 int SelStatement::noOfProjFields()
825 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
827 //TODO::if not yet prepared return error
828 //TODO::check the upper limit for projpos
829 //TODO::validate if projpos is less than size of the list
830 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
831 FieldName
*name
= NULL
;
834 while (iter
.hasElement())
836 name
= (FieldName
*)iter
.nextElement();
839 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
842 if (position
== (projpos
-1)) break;
846 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
849 //get back the qualified name(tablename.fldname)
850 char qualName
[IDENTIFIER_LENGTH
];
851 strcpy(qualName
, name
->fldName
);
855 sprintf(fInfo
->fldName
, "COUNT(%s)", qualName
);
858 sprintf(fInfo
->fldName
, "MIN(%s)", qualName
);
861 sprintf(fInfo
->fldName
, "MAX(%s)", qualName
);
864 sprintf(fInfo
->fldName
, "SUM(%s)", qualName
);
867 sprintf(fInfo
->fldName
, "AVG(%s)", qualName
);
870 strcpy(fInfo
->fldName
, qualName
);
876 int SelStatement::getFldPos(char *name
)
878 return table
->getFldPos(name
);