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);
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];
60 printError(ErrSysFatal
, "condition value is null. Should never happen");
63 table
->getFieldNameAlone(cValue
->fName
,info
->fldName
);
64 info
->type
= cValue
->type
;
65 info
->length
= cValue
->length
;
66 info
->isNull
= cValue
->isNullable
;
69 DbRetVal
SelStatement::execute(int &rowsAffected
)
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
)
80 //printError(ErrBadCall, "param values not set");
83 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 AggTableImpl
*aggTable
= NULL
;
296 while (iter
.hasElement())
298 name
= (FieldName
*)iter
.nextElement();
301 dbMgr
->closeTable(table
);
304 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
307 bool isBindFld
=false;
308 if ('*' == name
->fldName
[0] && name
->aType
== AGG_UNKNOWN
)
313 dbMgr
->closeTable(table
);
318 if (parsedData
->getGroupFieldNameList().size()!= 0)
321 aggTable
= new AggTableImpl();
322 aggTable
->setTable(table
);
324 //as soon as it encounters *, it breaks the loop negleting other field names
325 //as they all are deleted during resolveStar method.
328 if ('*' == name
->fldName
[0] && name
->aType
!= AGG_COUNT
) {return ErrSyntaxError
;}
329 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
330 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
332 dbMgr
->closeTable(table
);
335 printError(ErrSyntaxError
, "Field %s does not exist in table",
337 return ErrSyntaxError
;
339 FieldValue
*newVal
= new FieldValue();
340 strcpy(newVal
->fldName
,name
->fldName
);
341 newVal
->parsedString
= NULL
;
343 newVal
->type
= fInfo
->type
;
344 newVal
->length
= fInfo
->length
;
345 newVal
->isNullable
= fInfo
->isNull
;
346 FieldName
*bFldName
=NULL
;
347 ListIterator it
= bindFldList
.getIterator();
348 while (it
.hasElement())
350 bFldName
= (FieldName
*)it
.nextElement();
351 if(0==strcmp(bFldName
->fldName
,name
->fldName
))
353 newVal
->value
=table
->getBindFldAddr(name
->fldName
);
354 newVal
->isAllocVal
=false;
360 if(newVal
->type
== typeBinary
)
361 newVal
->value
= AllDataType::alloc(fInfo
->type
,
363 else newVal
->value
= AllDataType::alloc(fInfo
->type
,
365 newVal
->isAllocVal
=true;
367 if (name
->aType
==AGG_UNKNOWN
&&
368 parsedData
->getGroupFieldNameList().size()== 0)
369 table
->bindFld(name
->fldName
, newVal
->value
);
372 aggTable
= new AggTableImpl();
373 aggTable
->setTable(table
);
375 aggTable
->bindFld(name
->fldName
, name
->aType
, newVal
->value
);
377 parsedData
->insertFieldValue(newVal
);
379 if (!isBindFld
) bindFldList
.append(name
);
382 rv
= setBindFieldAndValues();
386 dbMgr
->closeTable(table
);
391 table
->setCondition(parsedData
->getCondition());
393 rv
= resolveForCondition();
397 //TODO::free memory allocated for params
398 table
->setCondition(NULL
);
399 dbMgr
->closeTable(table
);
403 rv
= resolveGroupFld(aggTable
);
407 //TODO::free memory allocated for params
410 table
->setCondition(NULL
);
411 dbMgr
->closeTable(table
);
419 DbRetVal
SelStatement::resolveGroupFld(AggTableImpl
*aggTable
)
421 if (!aggTable
) return OK
;
422 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
423 FieldName
*name
= NULL
;
425 FieldInfo
*fInfo
= new FieldInfo();
426 if (giter
.hasElement())
428 name
= (FieldName
*)giter
.nextElement();
429 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
430 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
432 dbMgr
->closeTable(table
);
436 printError(ErrSyntaxError
, "Field %s does not exist in table",
438 return ErrSyntaxError
;
440 FieldValue
*newVal
= new FieldValue();
441 strcpy(newVal
->fldName
,name
->fldName
);
442 newVal
->parsedString
= NULL
;
444 newVal
->type
= fInfo
->type
;
445 newVal
->isNullable
= fInfo
->isNull
;
446 newVal
->length
= fInfo
->length
;
447 if (newVal
->type
== typeBinary
)
448 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
449 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
450 newVal
->isAllocVal
=true;
451 parsedData
->insertFieldValue(newVal
);
452 aggTable
->setGroup(name
->fldName
, newVal
->value
);
455 if (giter
.hasElement())
458 printError(ErrSyntaxError
, "Only one field allowed in group\n");
459 return ErrSyntaxError
;
464 DbRetVal
SelStatement::resolveStar()
467 parsedData
->clearFieldNameList();
469 List fNameList
= table
->getFieldNameList();
470 ListIterator fNameIter
= fNameList
.getIterator();
471 FieldValue
*newVal
= NULL
;
472 //fNameList.resetIter(); //do not remove this.
473 FieldInfo
*fInfo
= new FieldInfo();
474 for (int i
= 0; i
< fNameList
.size() ; i
++)
476 char *fName
= ((Identifier
*)(fNameIter
.nextElement()))->name
;
477 rv
= table
->getFieldInfo(fName
, fInfo
);
478 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
482 printError(ErrSysFatal
, "Should never happen.");
485 newVal
= new FieldValue();
486 strcpy(newVal
->fldName
,fName
);
487 newVal
->parsedString
= NULL
;
489 newVal
->type
= fInfo
->type
;
490 newVal
->length
= fInfo
->length
;
491 // for binary datatype input buffer size should be 2 times the length
492 if(newVal
->type
== typeBinary
)
493 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
494 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
495 newVal
->isAllocVal
=true;
496 parsedData
->insertFieldValue(newVal
);
497 parsedData
->insertField(fName
);
498 table
->bindFld(fName
, newVal
->value
);
501 while (fNameIter
.hasElement())
502 delete (Identifier
*) fNameIter
.nextElement();
508 DbRetVal
SelStatement::setBindFieldAndValues()
510 totalFields
= parsedData
->getFieldNameList().size();
511 bindFields
= (FieldValue
**) malloc ( totalFields
* sizeof(FieldValue
*));
512 bindFieldValues
= (char**) malloc( totalFields
* sizeof(char*));
513 memset(bindFields
, 0, totalFields
* sizeof(FieldValue
*));
514 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
515 ListIterator valIter
= parsedData
->getFieldValueList().getIterator();
517 FieldValue
*value
= NULL
;
519 while(valIter
.hasElement())
521 value
= (FieldValue
*) valIter
.nextElement();
524 free(bindFields
); bindFields
= NULL
;
525 free(bindFieldValues
); bindFieldValues
= NULL
;
526 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
529 bindFields
[colNo
++ ] = value
;
535 DbRetVal
SelStatement::resolveForCondition()
537 //get the fieldname list and validate field names
538 ListIterator iter
= parsedData
->getConditionValueList().getIterator();
540 ConditionValue
*value
;
541 FieldInfo
*fInfo
= new FieldInfo();
544 while (iter
.hasElement())
546 value
= (ConditionValue
*) iter
.nextElement();
550 printError(ErrSysFatal
, "Should never happen.");
553 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
554 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
557 printError(ErrSyntaxError
, "Field %s does not exist in table",
559 return ErrSyntaxError
;
561 value
->type
= fInfo
->type
;
562 value
->length
= fInfo
->length
;
563 value
->isNullable
= fInfo
->isNull
;
564 value
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
565 //table->bindFld(name->fldName, value->value);
566 if (value
->parsedString
== NULL
)
569 printError(ErrSyntaxError
, "Condition value should not be NULL");
570 return ErrSyntaxError
;
572 if (value
->parsedString
[0] == '?')
574 if(!value
->opLike
) // checks if 'LIKE' operator is used
575 value
->paramNo
= paramPos
++;
577 if (!value
->paramNo
) {
578 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
579 AllDataType::strToValue(value
->value
, value
->parsedString
, fInfo
->type
, fInfo
->length
);
583 totalParams
= paramPos
-1;
584 if (0 == totalParams
) return OK
;
585 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
586 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
587 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
588 memset(paramValues
, 0, totalParams
* sizeof(char*));
590 while(iter
.hasElement())
592 value
= (ConditionValue
*) iter
.nextElement();
595 free(params
); params
= NULL
;
596 free(paramValues
); paramValues
= NULL
;
597 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
600 params
[value
->paramNo
-1 ] = value
;
605 void* SelStatement::fetch()
607 void *tuple
= table
->fetch();
608 if (NULL
== tuple
) return NULL
;
609 //copy values to binded buffer
611 for (int i
= 0; i
< totalFields
; i
++)
613 value
= bindFields
[i
];
614 if (bindFieldValues
[i
] == NULL
)
616 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
619 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
624 void* SelStatement::fetch(DbRetVal
&rv
)
626 void *tuple
= table
->fetch(rv
);
627 if (NULL
== tuple
) return NULL
;
628 //copy values to binded buffer
630 for (int i
= 0; i
< totalFields
; i
++)
632 value
= bindFields
[i
];
633 if (bindFieldValues
[i
] == NULL
)
635 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
638 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
643 DbRetVal
SelStatement::close()
645 return table
->closeScan();
648 DbRetVal
SelStatement::freeScan()
650 if (table
) return table
->close();
654 void* SelStatement::getParamValuePtr( int pos
)
656 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
657 return ( (void*) p
->value
);
660 char* SelStatement::getFieldName ( int pos
)
662 //TODO::if not yet prepared return error
663 //TODO::check the upper limit for projpos
664 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
666 while (iter
.hasElement())
668 if (position
== pos
) {
669 FieldName
*name
= (FieldName
*) iter
.nextElement();
672 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
675 return name
->fldName
;
682 DataType
SelStatement::getFieldType( int pos
)
684 FieldValue
*v
= bindFields
[pos
];
685 return ( (DataType
) v
->type
);
688 int SelStatement::getFieldLength( int pos
)
690 FieldValue
*v
= bindFields
[pos
];
691 return ( (int) v
->type
);
694 void* SelStatement::fetchAndPrint(bool SQL
)
696 void *tuple
= table
->fetch();
697 if (NULL
== tuple
) return NULL
;
702 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
705 for (int i
= 0; i
< totalFields
; i
++)
707 value
= bindFields
[i
];
708 nullValueSet
= table
->isFldNull(value
->fldName
);
716 else printf("NULL\t");
740 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
754 if (SQL
) printf(");\n");
758 void* SelStatement::next()
760 return( table
->fetch() );
764 void* SelStatement::getFieldValuePtr( int pos
)
766 FieldValue
*v
= bindFields
[pos
];
767 return ( (void*) v
->value
);
770 int SelStatement::noOfProjFields()
775 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
777 //TODO::if not yet prepared return error
778 //TODO::check the upper limit for projpos
779 //TODO::validate if projpos is less than size of the list
780 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
781 FieldName
*name
= NULL
;
784 while (iter
.hasElement())
786 name
= (FieldName
*)iter
.nextElement();
789 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
792 if (position
== (projpos
-1)) break;
796 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
799 //get back the qualified name(tablename.fldname)
800 char qualName
[IDENTIFIER_LENGTH
];
801 strcpy(qualName
, name
->fldName
);
805 sprintf(fInfo
->fldName
, "COUNT(%s)", qualName
);
808 sprintf(fInfo
->fldName
, "MIN(%s)", qualName
);
811 sprintf(fInfo
->fldName
, "MAX(%s)", qualName
);
814 sprintf(fInfo
->fldName
, "SUM(%s)", qualName
);
817 sprintf(fInfo
->fldName
, "AVG(%s)", qualName
);
820 strcpy(fInfo
->fldName
, qualName
);
826 int SelStatement::getFldPos(char *name
)
828 return table
->getFldPos(name
);