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()
36 if (table
) { table
->close(); table
= 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];
58 printError(ErrSysFatal
, "condition value is null. Should never happen");
61 table
->getFieldNameAlone(cValue
->fName
,info
->fldName
);
62 info
->type
= cValue
->type
;
63 info
->length
= cValue
->length
;
64 info
->isNull
= cValue
->isNullable
;
67 DbRetVal
SelStatement::execute(int &rowsAffected
)
70 //copy param values to binded buffer
71 ConditionValue
*value
;
72 for (int i
= 0; i
< totalParams
; i
++)
74 value
= (ConditionValue
*) params
[i
];
75 if (paramValues
[i
] == NULL
)
78 //printError(ErrBadCall, "param values not set");
81 AllDataType::copyVal(value
->value
, paramValues
[i
], value
->type
, value
->length
);
84 rv
= table
->execute();
85 //table->printPlan(0);
89 DbRetVal
SelStatement::setParam(int paramNo
, void *value
)
91 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
92 if (NULL
== value
) return ErrBadArg
;
93 paramValues
[paramNo
-1] = (char*) value
;
97 DbRetVal
SelStatement::setShortParam(int paramNo
, short value
)
99 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
100 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
103 printError(ErrSysFatal
, "field value is null. Should never happen");
106 *(short*)cValue
->value
= value
;
110 DbRetVal
SelStatement::setIntParam(int paramNo
, int value
)
112 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
113 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
116 printError(ErrSysFatal
, "condition value is null. Should never happen");
119 *(int*)cValue
->value
= value
;
122 DbRetVal
SelStatement::setLongParam(int paramNo
, long value
)
124 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
125 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
128 printError(ErrSysFatal
, "condition value is null. Should never happen");
131 *(long*)cValue
->value
= value
;
135 DbRetVal
SelStatement::setLongLongParam(int paramNo
, long long value
)
137 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
138 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
141 printError(ErrSysFatal
, "condition value is null. Should never happen");
144 *(long long*)cValue
->value
= value
;
147 DbRetVal
SelStatement::setByteIntParam(int paramNo
, ByteInt value
)
149 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
150 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
153 printError(ErrSysFatal
, "condition value is null. Should never happen");
156 *(ByteInt
*)cValue
->value
= value
;
159 DbRetVal
SelStatement::setFloatParam(int paramNo
, float value
)
161 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
162 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
165 printError(ErrSysFatal
, "condition value is null. Should never happen");
168 *(float*)cValue
->value
= value
;
171 DbRetVal
SelStatement::setDoubleParam(int paramNo
, double value
)
173 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
174 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
177 printError(ErrSysFatal
, "condition value is null. Should never happen");
180 *(double*)cValue
->value
= value
;
183 DbRetVal
SelStatement::setStringParam(int paramNo
, char *value
)
185 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
186 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
189 printError(ErrSysFatal
, "condition value is null. Should never happen");
192 strcpy((char*)cValue
->value
, value
);
195 DbRetVal
SelStatement::setDateParam(int paramNo
, Date value
)
197 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
198 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
201 printError(ErrSysFatal
, "condition value is null. Should never happen");
204 *(Date
*)cValue
->value
= value
;
207 DbRetVal
SelStatement::setTimeParam(int paramNo
, Time value
)
209 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
210 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
213 printError(ErrSysFatal
, "condition value is null. Should never happen");
216 *(Time
*)cValue
->value
= value
;
219 DbRetVal
SelStatement::setTimeStampParam(int paramNo
, TimeStamp value
)
221 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
222 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
225 printError(ErrSysFatal
, "condition value is null. Should never happen");
228 *(TimeStamp
*)cValue
->value
= value
;
232 DbRetVal
SelStatement::setBinaryParam(int paramNo
, void *value
)
234 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
235 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
238 printError(ErrSysFatal
, "condition value is null. Should never happen");
241 AllDataType::convertToBinary(cValue
->value
,value
,typeString
,cValue
->length
);
245 DbRetVal
SelStatement::setBindField(int colNo
, void *value
)
247 if (colNo
<=0) return ErrBadArg
;
248 //TODO: check the upper limit
249 //if (colNo > table->getFieldNameList().size()) return ErrBadArg;
250 if (NULL
== value
) return ErrBadArg
;
251 bindFieldValues
[colNo
-1] = (char*) value
;
254 DbRetVal
SelStatement::openTables()
256 if (dbMgr
== NULL
) return ErrNoConnection
;
257 JoinTableImpl
*jHdl
= NULL
;
258 Table
*tHdl
= NULL
, *prevHdl
= NULL
;
259 bool joinInvolved
= false;
260 //check whether all the table exists
261 ListIterator titer
= parsedData
->getTableNameList().getIterator();
262 while (titer
.hasElement())
264 TableName
*t
= (TableName
*)titer
.nextElement();
265 tHdl
= dbMgr
->openTable(t
->tblName
);
268 printError(ErrNotExists
,
269 "Unable to open the table:Table not exists");
275 jHdl
= new JoinTableImpl();
276 jHdl
->setTable(prevHdl
, tHdl
);
282 if (joinInvolved
) table
= jHdl
; else table
= tHdl
;
285 DbRetVal
SelStatement::resolve()
287 DbRetVal rv
= openTables();
288 if (rv
!= OK
) return rv
;
289 //get the fieldname list and validate field names
290 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
291 FieldName
*name
= NULL
;
292 FieldInfo
*fInfo
= new FieldInfo();
294 bool isSingleTableNoGrp
= false;
295 if(parsedData
->getTableNameList().size() == 1 &&
296 parsedData
->getGroupFieldNameList().size() == 0)
298 isSingleTableNoGrp
= true;
300 AggTableImpl
*aggTable
= NULL
;
301 while (iter
.hasElement())
303 name
= (FieldName
*)iter
.nextElement();
306 dbMgr
->closeTable(table
);
309 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
312 bool isBindFld
=false;
313 if ('*' == name
->fldName
[0] && name
->aType
== AGG_UNKNOWN
)
318 dbMgr
->closeTable(table
);
323 if (parsedData
->getGroupFieldNameList().size()!= 0
324 && !isSingleTableNoGrp
)
327 aggTable
= new AggTableImpl();
328 aggTable
->setTable(table
);
330 //as soon as it encounters *, it breaks the loop negleting other field names
331 //as they all are deleted during resolveStar method.
334 if ('*' == name
->fldName
[0] && name
->aType
!= AGG_COUNT
) {return ErrSyntaxError
;}
335 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
336 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
338 dbMgr
->closeTable(table
);
341 printError(ErrSyntaxError
, "Field %s does not exist in table",
343 return ErrSyntaxError
;
345 FieldValue
*newVal
= new FieldValue();
346 strcpy(newVal
->fldName
,name
->fldName
);
347 newVal
->parsedString
= NULL
;
349 newVal
->type
= fInfo
->type
;
350 newVal
->length
= fInfo
->length
;
351 newVal
->isNullable
= fInfo
->isNull
;
352 FieldName
*bFldName
=NULL
;
353 ListIterator it
= bindFldList
.getIterator();
354 while (it
.hasElement())
356 bFldName
= (FieldName
*)it
.nextElement();
357 if(0==strcmp(bFldName
->fldName
,name
->fldName
) &&
358 name
->aType
== AGG_UNKNOWN
)
360 newVal
->value
=table
->getBindFldAddr(name
->fldName
);
361 newVal
->isAllocVal
=false;
367 if(newVal
->type
== typeBinary
)
368 newVal
->value
= AllDataType::alloc(fInfo
->type
,
370 else newVal
->value
= AllDataType::alloc(fInfo
->type
,
372 newVal
->isAllocVal
=true;
374 if (name
->aType
==AGG_UNKNOWN
&&
375 parsedData
->getGroupFieldNameList().size()== 0)
376 table
->bindFld(name
->fldName
, newVal
->value
);
377 else if (!isSingleTableNoGrp
)
380 aggTable
= new AggTableImpl();
381 aggTable
->setTable(table
);
383 aggTable
->bindFld(name
->fldName
, name
->aType
, newVal
->value
);
385 if (name
->aType
!=AGG_UNKNOWN
&& isSingleTableNoGrp
)
386 handleAggWithTbl
= true;
387 parsedData
->insertFieldValue(newVal
);
389 if (!isBindFld
) bindFldList
.append(name
);
392 rv
= setBindFieldAndValues();
396 dbMgr
->closeTable(table
);
401 table
->setCondition(parsedData
->getCondition());
403 rv
= resolveForCondition();
407 //TODO::free memory allocated for params
408 table
->setCondition(NULL
);
409 dbMgr
->closeTable(table
);
413 rv
= resolveGroupFld(aggTable
);
417 //TODO::free memory allocated for params
420 table
->setCondition(NULL
);
421 dbMgr
->closeTable(table
);
429 DbRetVal
SelStatement::resolveGroupFld(AggTableImpl
*aggTable
)
434 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
435 FieldName
*name
= NULL
;
437 FieldInfo
*fInfo
= new FieldInfo();
438 if (giter
.hasElement())
440 name
= (FieldName
*)giter
.nextElement();
441 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
442 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
444 dbMgr
->closeTable(table
);
448 printError(ErrSyntaxError
, "Field %s does not exist in table",
450 return ErrSyntaxError
;
452 FieldValue
*newVal
= new FieldValue();
453 strcpy(newVal
->fldName
,name
->fldName
);
454 newVal
->parsedString
= NULL
;
456 newVal
->type
= fInfo
->type
;
457 newVal
->isNullable
= fInfo
->isNull
;
458 newVal
->length
= fInfo
->length
;
459 if (newVal
->type
== typeBinary
)
460 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
461 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
462 newVal
->isAllocVal
=true;
463 parsedData
->insertFieldValue(newVal
);
464 aggTable
->setGroup(name
->fldName
, newVal
->value
);
467 if (giter
.hasElement())
470 printError(ErrSyntaxError
, "Only one field allowed in group\n");
471 return ErrSyntaxError
;
476 DbRetVal
SelStatement::resolveStar()
479 parsedData
->clearFieldNameList();
481 List fNameList
= table
->getFieldNameList();
482 ListIterator fNameIter
= fNameList
.getIterator();
483 FieldValue
*newVal
= NULL
;
484 //fNameList.resetIter(); //do not remove this.
485 FieldInfo
*fInfo
= new FieldInfo();
486 for (int i
= 0; i
< fNameList
.size() ; i
++)
488 char *fName
= ((Identifier
*)(fNameIter
.nextElement()))->name
;
489 rv
= table
->getFieldInfo(fName
, fInfo
);
490 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
494 printError(ErrSysFatal
, "Should never happen.");
497 newVal
= new FieldValue();
498 strcpy(newVal
->fldName
,fName
);
499 newVal
->parsedString
= NULL
;
501 newVal
->type
= fInfo
->type
;
502 newVal
->length
= fInfo
->length
;
503 // for binary datatype input buffer size should be 2 times the length
504 if(newVal
->type
== typeBinary
)
505 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
506 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
507 newVal
->isAllocVal
=true;
508 parsedData
->insertFieldValue(newVal
);
509 parsedData
->insertField(fName
);
510 table
->bindFld(fName
, newVal
->value
);
513 while (fNameIter
.hasElement())
514 delete (Identifier
*) fNameIter
.nextElement();
520 DbRetVal
SelStatement::setBindFieldAndValues()
522 totalFields
= parsedData
->getFieldNameList().size();
523 bindFields
= (FieldValue
**) malloc ( totalFields
* sizeof(FieldValue
*));
524 bindFieldValues
= (char**) malloc( totalFields
* sizeof(char*));
525 memset(bindFields
, 0, totalFields
* sizeof(FieldValue
*));
526 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
527 ListIterator valIter
= parsedData
->getFieldValueList().getIterator();
529 FieldValue
*value
= NULL
;
531 while(valIter
.hasElement())
533 value
= (FieldValue
*) valIter
.nextElement();
536 free(bindFields
); bindFields
= NULL
;
537 free(bindFieldValues
); bindFieldValues
= NULL
;
538 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
541 bindFields
[colNo
++ ] = value
;
547 DbRetVal
SelStatement::resolveForCondition()
549 //get the fieldname list and validate field names
550 ListIterator iter
= parsedData
->getConditionValueList().getIterator();
552 ConditionValue
*value
;
553 FieldInfo
*fInfo
= new FieldInfo();
556 while (iter
.hasElement())
558 value
= (ConditionValue
*) iter
.nextElement();
562 printError(ErrSysFatal
, "Should never happen.");
565 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
566 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
569 printError(ErrSyntaxError
, "Field %s does not exist in table",
571 return ErrSyntaxError
;
573 value
->type
= fInfo
->type
;
574 value
->length
= fInfo
->length
;
575 value
->isNullable
= fInfo
->isNull
;
576 value
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
577 //table->bindFld(name->fldName, value->value);
578 if (value
->parsedString
== NULL
)
581 printError(ErrSyntaxError
, "Condition value should not be NULL");
582 return ErrSyntaxError
;
584 if (value
->parsedString
[0] == '?')
586 if(!value
->opLike
) // checks if 'LIKE' operator is used
587 value
->paramNo
= paramPos
++;
589 if (!value
->paramNo
) {
590 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
591 AllDataType::strToValue(value
->value
, value
->parsedString
, fInfo
->type
, fInfo
->length
);
595 totalParams
= paramPos
-1;
596 if (0 == totalParams
) return OK
;
597 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
598 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
599 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
600 memset(paramValues
, 0, totalParams
* sizeof(char*));
602 while(iter
.hasElement())
604 value
= (ConditionValue
*) iter
.nextElement();
607 free(params
); params
= NULL
;
608 free(paramValues
); paramValues
= NULL
;
609 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
612 params
[value
->paramNo
-1 ] = value
;
616 void* SelStatement::handleSingleTableAggWithoutGroup()
618 if (isPointReturned
) return NULL
;
619 TableImpl
*tblImpl
= (TableImpl
*)table
;
620 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
624 FieldValue
*fVal
= NULL
;
625 while (iter
.hasElement())
627 name
= (FieldName
*) iter
.nextElement();
628 fVal
= bindFields
[i
];
630 //rv = tblImpl->fetchAgg(name, (int) name->aType, fVal->value);
631 rv
= tblImpl
->fetchAgg(name
->fldName
, name
->aType
, fVal
->value
);
632 if (OK
!= rv
) return NULL
;
634 tblImpl
->closeScan();
637 isPointReturned
= true;
640 void* SelStatement::fetch()
644 return handleSingleTableAggWithoutGroup();
646 void *tuple
= table
->fetch();
647 if (NULL
== tuple
) return NULL
;
648 //copy values to binded buffer
650 for (int i
= 0; i
< totalFields
; i
++)
652 value
= bindFields
[i
];
653 if (bindFieldValues
[i
] == NULL
)
655 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
658 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
663 void* SelStatement::fetch(DbRetVal
&rv
)
667 return handleSingleTableAggWithoutGroup();
669 void *tuple
= table
->fetch(rv
);
670 if (NULL
== tuple
) return NULL
;
671 //copy values to binded buffer
673 for (int i
= 0; i
< totalFields
; i
++)
675 value
= bindFields
[i
];
676 if (bindFieldValues
[i
] == NULL
)
678 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
681 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
686 DbRetVal
SelStatement::close()
688 isPointReturned
= false;
689 return table
->closeScan();
692 DbRetVal
SelStatement::freeScan()
694 if (table
) return table
->close();
698 void* SelStatement::getParamValuePtr( int pos
)
700 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
701 return ( (void*) p
->value
);
704 char* SelStatement::getFieldName ( int pos
)
706 //TODO::if not yet prepared return error
707 //TODO::check the upper limit for projpos
708 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
710 while (iter
.hasElement())
712 if (position
== pos
) {
713 FieldName
*name
= (FieldName
*) iter
.nextElement();
716 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
719 return name
->fldName
;
726 DataType
SelStatement::getFieldType( int pos
)
728 FieldValue
*v
= bindFields
[pos
];
729 return ( (DataType
) v
->type
);
732 int SelStatement::getFieldLength( int pos
)
734 FieldValue
*v
= bindFields
[pos
];
735 return ( (int) v
->type
);
738 void* SelStatement::fetchAndPrint(bool SQL
)
743 tuple
= handleSingleTableAggWithoutGroup();
745 tuple
= table
->fetch();
747 if (NULL
== tuple
) return NULL
;
752 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
755 for (int i
= 0; i
< totalFields
; i
++)
757 value
= bindFields
[i
];
758 nullValueSet
= table
->isFldNull(value
->fldName
);
766 else printf("NULL\t");
790 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
804 if (SQL
) printf(");\n");
808 void* SelStatement::next()
812 return handleSingleTableAggWithoutGroup();
814 return( table
->fetch() );
818 void* SelStatement::getFieldValuePtr( int pos
)
820 FieldValue
*v
= bindFields
[pos
];
821 return ( (void*) v
->value
);
824 int SelStatement::noOfProjFields()
829 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
831 //TODO::if not yet prepared return error
832 //TODO::check the upper limit for projpos
833 //TODO::validate if projpos is less than size of the list
834 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
835 FieldName
*name
= NULL
;
838 while (iter
.hasElement())
840 name
= (FieldName
*)iter
.nextElement();
843 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
846 if (position
== (projpos
-1)) break;
850 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
853 //get back the qualified name(tablename.fldname)
854 char qualName
[IDENTIFIER_LENGTH
];
855 strcpy(qualName
, name
->fldName
);
859 sprintf(fInfo
->fldName
, "COUNT(%s)", qualName
);
862 sprintf(fInfo
->fldName
, "MIN(%s)", qualName
);
865 sprintf(fInfo
->fldName
, "MAX(%s)", qualName
);
868 sprintf(fInfo
->fldName
, "SUM(%s)", qualName
);
871 sprintf(fInfo
->fldName
, "AVG(%s)", qualName
);
874 strcpy(fInfo
->fldName
, qualName
);
880 int SelStatement::getFldPos(char *name
)
882 return table
->getFldPos(name
);