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
->paramNo
==1) continue;//For Predecate t1.f1=t2.f1
580 if (value
->parsedString
== NULL
)
583 printError(ErrSyntaxError
, "Condition value should not be NULL");
584 return ErrSyntaxError
;
586 if (value
->parsedString
[0] == '?')
588 if(!value
->opLike
) // checks if 'LIKE' operator is used
589 value
->paramNo
= paramPos
++;
591 if (!value
->paramNo
) {
592 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
593 AllDataType::strToValue(value
->value
, value
->parsedString
, fInfo
->type
, fInfo
->length
);
597 totalParams
= paramPos
-1;
598 if (0 == totalParams
) return OK
;
599 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
600 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
601 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
602 memset(paramValues
, 0, totalParams
* sizeof(char*));
604 while(iter
.hasElement())
606 value
= (ConditionValue
*) iter
.nextElement();
609 free(params
); params
= NULL
;
610 free(paramValues
); paramValues
= NULL
;
611 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
614 params
[value
->paramNo
-1 ] = value
;
618 void* SelStatement::handleSingleTableAggWithoutGroup()
620 if (isPointReturned
) return NULL
;
621 TableImpl
*tblImpl
= (TableImpl
*)table
;
622 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
626 FieldValue
*fVal
= NULL
;
627 while (iter
.hasElement())
629 name
= (FieldName
*) iter
.nextElement();
630 fVal
= bindFields
[i
];
632 //rv = tblImpl->fetchAgg(name, (int) name->aType, fVal->value);
633 rv
= tblImpl
->fetchAgg(name
->fldName
, name
->aType
, fVal
->value
);
634 if (OK
!= rv
) return NULL
;
636 tblImpl
->closeScan();
639 isPointReturned
= true;
642 void* SelStatement::fetch()
646 return handleSingleTableAggWithoutGroup();
648 void *tuple
= table
->fetch();
649 if (NULL
== tuple
) return NULL
;
650 //copy values to binded buffer
652 for (int i
= 0; i
< totalFields
; i
++)
654 value
= bindFields
[i
];
655 if (bindFieldValues
[i
] == NULL
)
657 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
660 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
665 void* SelStatement::fetch(DbRetVal
&rv
)
669 return handleSingleTableAggWithoutGroup();
671 void *tuple
= table
->fetch(rv
);
672 if (NULL
== tuple
) return NULL
;
673 //copy values to binded buffer
675 for (int i
= 0; i
< totalFields
; i
++)
677 value
= bindFields
[i
];
678 if (bindFieldValues
[i
] == NULL
)
680 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
683 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
688 DbRetVal
SelStatement::close()
690 isPointReturned
= false;
691 if (table
) return table
->closeScan();
695 void* SelStatement::getParamValuePtr( int pos
)
697 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
698 return ( (void*) p
->value
);
701 char* SelStatement::getFieldName ( int pos
)
703 //TODO::if not yet prepared return error
704 //TODO::check the upper limit for projpos
705 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
707 while (iter
.hasElement())
709 if (position
== pos
) {
710 FieldName
*name
= (FieldName
*) iter
.nextElement();
713 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
716 return name
->fldName
;
723 DataType
SelStatement::getFieldType( int pos
)
725 FieldValue
*v
= bindFields
[pos
];
726 return ( (DataType
) v
->type
);
729 int SelStatement::getFieldLength( int pos
)
731 FieldValue
*v
= bindFields
[pos
];
732 return ( (int) v
->type
);
735 void* SelStatement::fetchAndPrint(bool SQL
)
740 tuple
= handleSingleTableAggWithoutGroup();
742 tuple
= table
->fetch();
744 if (NULL
== tuple
) return NULL
;
749 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
752 for (int i
= 0; i
< totalFields
; i
++)
754 value
= bindFields
[i
];
755 nullValueSet
= table
->isFldNull(value
->fldName
);
763 else printf("NULL\t");
787 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
801 if (SQL
) printf(");\n");
805 void* SelStatement::next()
809 return handleSingleTableAggWithoutGroup();
811 return( table
->fetch() );
815 void* SelStatement::getFieldValuePtr( int pos
)
817 FieldValue
*v
= bindFields
[pos
];
818 return ( (void*) v
->value
);
821 int SelStatement::noOfProjFields()
826 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
828 //TODO::if not yet prepared return error
829 //TODO::check the upper limit for projpos
830 //TODO::validate if projpos is less than size of the list
831 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
832 FieldName
*name
= NULL
;
835 while (iter
.hasElement())
837 name
= (FieldName
*)iter
.nextElement();
840 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
843 if (position
== (projpos
-1)) break;
847 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
850 //get back the qualified name(tablename.fldname)
851 char qualName
[IDENTIFIER_LENGTH
];
852 strcpy(qualName
, name
->fldName
);
856 sprintf(fInfo
->fldName
, "COUNT(%s)", qualName
);
859 sprintf(fInfo
->fldName
, "MIN(%s)", qualName
);
862 sprintf(fInfo
->fldName
, "MAX(%s)", qualName
);
865 sprintf(fInfo
->fldName
, "SUM(%s)", qualName
);
868 sprintf(fInfo
->fldName
, "AVG(%s)", qualName
);
871 strcpy(fInfo
->fldName
, qualName
);
877 int SelStatement::getFldPos(char *name
)
879 return table
->getFldPos(name
);