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 ***************************************************************************/
17 #include <Statement.h>
18 #include <TableImpl.h>
19 #include <OrderTableImpl.h>
21 SelStatement::SelStatement()
30 bindFieldValues
= NULL
;
32 isPointReturned
= false;
33 handleAggWithTbl
=false;
35 isOffsetReached
= false;
36 isRecLimitReached
= false;
41 SelStatement::~SelStatement()
44 if (table
) { table
->close(); table
= NULL
; }
55 free(bindFieldValues
);
56 bindFieldValues
= NULL
;
60 DbRetVal
SelStatement::getParamFldInfo(int paramNo
, FieldInfo
*&info
)
62 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
63 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
66 printError(ErrSysFatal
, "condition value is null. Should never happen");
69 table
->getFieldNameAlone(cValue
->fName
,info
->fldName
);
70 info
->type
= cValue
->type
;
71 info
->length
= cValue
->length
;
72 info
->isNull
= cValue
->isNullable
;
75 DbRetVal
SelStatement::execute(int &rowsAffected
)
78 //copy param values to binded buffer
79 ConditionValue
*value
;
80 for (int i
= 0; i
< totalParams
; i
++)
82 value
= (ConditionValue
*) params
[i
];
83 if (paramValues
[i
] == NULL
)
86 //printError(ErrBadCall, "param values not set");
89 AllDataType::copyVal(value
->value
, paramValues
[i
], value
->type
, value
->length
);
91 //table->printPlan(0);
92 //printf("Execute Called\n");
93 rv
= table
->execute();
95 isOffsetReached
= false;
96 isRecLimitReached
= false;
98 if (isExplain
) table
->printPlan(0);
102 DbRetVal
SelStatement::setParam(int paramNo
, void *value
)
104 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
105 if (NULL
== value
) return ErrBadArg
;
106 paramValues
[paramNo
-1] = (char*) value
;
110 DbRetVal
SelStatement::setShortParam(int paramNo
, short value
)
112 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
113 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
116 printError(ErrSysFatal
, "field value is null. Should never happen");
119 *(short*)cValue
->value
= value
;
123 DbRetVal
SelStatement::setIntParam(int paramNo
, int 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 *(int*)cValue
->value
= value
;
135 DbRetVal
SelStatement::setLongParam(int paramNo
, 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*)cValue
->value
= value
;
148 DbRetVal
SelStatement::setLongLongParam(int paramNo
, long long 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 *(long long*)cValue
->value
= value
;
160 DbRetVal
SelStatement::setByteIntParam(int paramNo
, ByteInt 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 *(ByteInt
*)cValue
->value
= value
;
172 DbRetVal
SelStatement::setFloatParam(int paramNo
, float 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 *(float*)cValue
->value
= value
;
184 DbRetVal
SelStatement::setDoubleParam(int paramNo
, double 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 *(double*)cValue
->value
= value
;
196 DbRetVal
SelStatement::setStringParam(int paramNo
, char *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 strcpy((char*)cValue
->value
, value
);
208 DbRetVal
SelStatement::setDateParam(int paramNo
, Date 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 *(Date
*)cValue
->value
= value
;
220 DbRetVal
SelStatement::setTimeParam(int paramNo
, Time 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 *(Time
*)cValue
->value
= value
;
232 DbRetVal
SelStatement::setTimeStampParam(int paramNo
, TimeStamp 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 *(TimeStamp
*)cValue
->value
= value
;
245 DbRetVal
SelStatement::setBinaryParam(int paramNo
, void *value
, int length
)
247 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
248 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
251 printError(ErrSysFatal
, "condition value is null. Should never happen");
254 AllDataType::convertToBinary(cValue
->value
,value
,typeString
,cValue
->length
);
258 DbRetVal
SelStatement::setBindField(int colNo
, void *value
)
260 if (colNo
<=0) return ErrBadArg
;
261 //TODO: check the upper limit
262 //if (colNo > table->getFieldNameList().size()) return ErrBadArg;
263 if (NULL
== value
) return ErrBadArg
;
264 bindFieldValues
[colNo
-1] = (char*) value
;
267 bool SelStatement::isTableAlreadyPresent(char *tblName
, char *aliasName
)
269 ListIterator titer
= parsedData
->getTableNameList().getIterator();
271 while (titer
.hasElement())
273 TableName
*t
= (TableName
*)titer
.nextElement();
274 if (strcmp(t
->tblName
, tblName
) ==0 &&
275 strcmp(t
->aliasName
, aliasName
) ==0) count
++;
277 if (count
== 1) return false;
280 DbRetVal
SelStatement::openTables()
282 if (dbMgr
== NULL
) return ErrNoConnection
;
283 JoinTableImpl
*jHdl
= NULL
;
284 Table
*tHdl
= NULL
, *prevHdl
= NULL
;
286 //check whether all the table exists
287 ListIterator titer
= parsedData
->getTableNameList().getIterator();
288 ListIterator jiter
= parsedData
->getJoinTypeList().getIterator();
289 while (titer
.hasElement())
291 TableName
*t
= (TableName
*)titer
.nextElement();
292 parsedData
->setTableName(t
->tblName
);
293 if (isTableAlreadyPresent(t
->tblName
, t
->aliasName
)) {
294 printError(ErrSyntaxError
,
295 "Referencing same table again %s", t
->tblName
);
296 if (prevHdl
) delete prevHdl
;
297 return ErrSyntaxError
;
299 tHdl
= dbMgr
->openTable(t
->tblName
);
302 printError(ErrNotExists
,
303 "Unable to open the table:Table not exists");
304 if (prevHdl
) delete prevHdl
;
307 TableImpl
*tImpl
= (TableImpl
*) tHdl
;
308 tImpl
->setAliasName(t
->aliasName
);
312 jHdl
= new JoinTableImpl();
313 jHdl
->setTable(prevHdl
, tHdl
);
314 JoinTypeNode
*node
= (JoinTypeNode
*) jiter
.nextElement();
316 printError(ErrSyntaxError
,
317 "Join Type and number of tables do not match");
319 return ErrSyntaxError
;
321 jHdl
->setJoinType(node
->jType
);
328 if (isJoin
) table
= jHdl
; else table
= tHdl
;
331 DbRetVal
SelStatement::resolve()
333 DbRetVal rv
= openTables();
334 if (rv
!= OK
) return rv
;
335 //get the fieldname list and validate field names
336 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
337 FieldName
*name
= NULL
;
338 FieldInfo
*fInfo
= new FieldInfo();
340 bool isSingleTableNoGrp
= false;
341 if(parsedData
->getTableNameList().size() == 1 &&
342 parsedData
->getGroupFieldNameList().size() == 0)
344 isSingleTableNoGrp
= true;
346 AggTableImpl
*aggTable
= NULL
;
347 while (iter
.hasElement())
349 name
= (FieldName
*)iter
.nextElement();
352 dbMgr
->closeTable(table
);
355 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
358 bool isBindFld
=false;
359 if ('*' == name
->fldName
[0] && name
->aType
== AGG_UNKNOWN
)
364 dbMgr
->closeTable(table
);
369 if (parsedData
->getGroupFieldNameList().size()!= 0
370 && !isSingleTableNoGrp
)
373 aggTable
= new AggTableImpl();
374 aggTable
->setTable(table
);
376 //as soon as it encounters *, it breaks the loop negleting other field names
377 //as they all are deleted during resolveStar method.
380 if ('*' == name
->fldName
[0] && name
->aType
!= AGG_COUNT
) {return ErrSyntaxError
;}
381 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
382 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
384 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
385 else dbMgr
->closeTable(table
);
388 printError(ErrSyntaxError
, "Field %s does not exist in table",
390 return ErrSyntaxError
;
392 FieldValue
*newVal
= new FieldValue();
393 strcpy(newVal
->fldName
,name
->fldName
);
394 newVal
->parsedString
= NULL
;
396 newVal
->aType
= name
->aType
;
397 newVal
->isInResSet
= true;
398 newVal
->offset
= fInfo
->offset
;
399 newVal
->isPrimary
= fInfo
->isPrimary
;
400 newVal
->isUnique
= fInfo
->isUnique
;
401 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
402 newVal
->isDefault
= fInfo
->isDefault
;
403 if (newVal
->isDefault
)
404 strcpy(newVal
->defValBuf
, fInfo
->defaultValueBuf
);
405 else newVal
->defValBuf
[0] ='\0';
406 if (name
->aType
== AGG_COUNT
) {
407 newVal
->type
= typeInt
;
408 newVal
->length
= sizeof(int);
410 else if (name
->aType
== AGG_AVG
) {
411 newVal
->type
= typeDouble
;
412 newVal
->length
= sizeof(double);
413 if (!AllDataType::isValidFieldForAvg(fInfo
->type
)) {
414 printError(ErrBadArg
, "Illegal operation for field %s",
416 dbMgr
->closeTable(table
);
417 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
424 newVal
->type
= fInfo
->type
;
425 newVal
->length
= fInfo
->length
;
427 newVal
->isNullable
= fInfo
->isNull
;
428 FieldName
*bFldName
=NULL
;
429 ListIterator it
= bindFldList
.getIterator();
430 while (it
.hasElement())
432 bFldName
= (FieldName
*)it
.nextElement();
433 if(0==strcmp(bFldName
->fldName
,name
->fldName
) &&
434 name
->aType
== AGG_UNKNOWN
)
436 newVal
->value
=table
->getBindFldAddr(name
->fldName
);
437 newVal
->isAllocVal
=false;
443 if ( name
->aType
== AGG_UNKNOWN
||
444 (name
->aType
!= AGG_COUNT
&&
445 name
->aType
!= AGG_AVG
) ) {
446 if(newVal
->type
== typeBinary
)
447 newVal
->value
= AllDataType::alloc(fInfo
->type
,
449 else newVal
->value
= AllDataType::alloc(fInfo
->type
,
452 if (name
->aType
== AGG_AVG
) {
453 newVal
->value
= AllDataType::alloc(typeDouble
,
455 memset(newVal
->value
, 0, sizeof(double));
457 else if (name
->aType
== AGG_COUNT
) {
458 newVal
->value
= AllDataType::alloc(typeInt
,
460 memset(newVal
->value
, 0, sizeof(int));
464 newVal
->isAllocVal
=true;
466 if (name
->aType
==AGG_UNKNOWN
&&
467 parsedData
->getGroupFieldNameList().size()== 0) {
468 rv
= table
->bindFld(name
->fldName
, newVal
->value
);
470 if (newVal
->isAllocVal
) free(newVal
->value
);
476 else if (!isSingleTableNoGrp
)
479 aggTable
= new AggTableImpl();
480 aggTable
->setTable(table
);
482 rv
= aggTable
->bindFld(name
->fldName
, name
->aType
, newVal
->value
);
484 if (newVal
->isAllocVal
) free(newVal
->value
);
485 delete newVal
; delete fInfo
; delete aggTable
;
486 aggTable
= NULL
; table
= NULL
;
490 if (name
->aType
!=AGG_UNKNOWN
&& isSingleTableNoGrp
)
491 handleAggWithTbl
= true;
492 parsedData
->insertFieldValue(newVal
);
494 if (!isBindFld
) bindFldList
.append(name
);
498 //Check if the having list is present in projection list or not.
499 //If not present bind here not to be printed in fetchAndPrint later.
500 ListIterator hiter
= parsedData
->getHavingFieldNameList().getIterator();
501 while (hiter
.hasElement()) {
502 FieldName
*fnm
= (FieldName
*) hiter
.nextElement();
503 rv
= table
->getFieldInfo(fnm
->fldName
, fInfo
);
504 if (!isInProjectionList(fnm
->fldName
, fnm
->aType
)) {
505 FieldValue
*newVal
= new FieldValue();
506 strcpy(newVal
->fldName
,fnm
->fldName
);
507 newVal
->parsedString
= NULL
;
509 newVal
->aType
= fnm
->aType
;
510 newVal
->isInResSet
= false;
511 newVal
->isNullable
= fInfo
->isNull
;
512 newVal
->offset
= fInfo
->offset
;
513 newVal
->isPrimary
= fInfo
->isPrimary
;
514 newVal
->isUnique
= fInfo
->isUnique
;
515 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
516 if (fnm
->aType
== AGG_AVG
) {
517 newVal
->value
= AllDataType::alloc(typeDouble
, sizeof(double));
518 memset(newVal
->value
, 0, sizeof(double));
519 } else if (fnm
->aType
== AGG_COUNT
) {
520 newVal
->value
= AllDataType::alloc(typeInt
, sizeof(int));
521 memset(newVal
->value
, 0, sizeof(int));
523 newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
524 memset(newVal
->value
, 0, fInfo
->length
);
526 newVal
->isAllocVal
= true;
527 parsedData
->insertFieldValue(newVal
);
528 aggTable
->bindFld(fnm
->fldName
, fnm
->aType
, newVal
->value
);
532 rv
= setBindFieldAndValues();
536 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
537 else dbMgr
->closeTable(table
);
542 table
->setCondition(parsedData
->getCondition());
544 rv
= resolveForCondition();
548 //TODO::free memory allocated for params
549 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
551 table
->setCondition(NULL
);
552 dbMgr
->closeTable(table
);
557 rv
= resolveGroupFld(aggTable
);
561 //TODO::free memory allocated for params
562 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
565 table
->setCondition(NULL
);
566 dbMgr
->closeTable(table
);
572 rv
= resolveOrderByFld();
580 rv
= resolveDistinct();
582 if(parsedData
->getExplain()) isExplain
= true;
585 DbRetVal
SelStatement::resolveDistinct()
587 if (!parsedData
->getDistinct()) {
590 OrderTableImpl
*orderTable
= new OrderTableImpl();
591 orderTable
->setTable(table
);
592 orderTable
->setProjList(parsedData
->getFieldValueList());
593 orderTable
->setOrderByList(parsedData
->getFieldValueList());
594 orderTable
->setDistinct();
596 handleAggWithTbl
= false;
601 DbRetVal
SelStatement::resolveOrderByFld()
603 if (0 == parsedData
->getOrderFieldNameList().size()) {
606 OrderTableImpl
*orderTable
= new OrderTableImpl();
607 orderTable
->setTable(table
);
608 orderTable
->setProjList(parsedData
->getFieldValueList());
609 ListIterator giter
= parsedData
->getOrderFieldNameList().getIterator();
610 FieldName
*name
= NULL
;
612 FieldInfo
*fInfo
= new FieldInfo();
613 while (giter
.hasElement())
615 name
= (FieldName
*)giter
.nextElement();
616 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
617 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
620 printError(ErrSyntaxError
, "Field %s does not exist in table",
622 return ErrSyntaxError
;
624 /*FieldValue *newVal = new FieldValue();
625 strcpy(newVal->fldName,name->fldName);
626 newVal->parsedString = NULL;
628 newVal->type = fInfo->type;
629 newVal->isNullable = fInfo->isNull;
630 newVal->length = fInfo->length;
631 if (newVal->type == typeBinary)
632 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
633 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
634 newVal->isAllocVal=true;
635 parsedData->insertFieldValue(newVal);
637 if (name
->aType
== AGG_UNKNOWN
) orderTable
->setOrderBy(name
->fldName
);
638 else orderTable
->setOrderBy(name
->fldName
, true); //descending
642 handleAggWithTbl
= false;
646 DbRetVal
SelStatement::resolveGroupFld(AggTableImpl
*aggTable
)
648 if (!aggTable
) return OK
;
650 //check whether all non aggregate projections are from group list
651 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
652 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
653 FieldName
*name
= NULL
;
654 while (iter
.hasElement())
656 name
= (FieldName
*) iter
.nextElement();
657 if (name
->aType
== AGG_UNKNOWN
&& !isGroupFld(name
->fldName
) ) {
658 printError(ErrSyntaxError
, "Non aggregate projection contains non group field: %s", name
->fldName
);
659 return ErrSyntaxError
;
664 FieldInfo
*fInfo
= new FieldInfo();
665 while (giter
.hasElement())
667 name
= (FieldName
*)giter
.nextElement();
668 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
669 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
672 printError(ErrSyntaxError
, "Field %s does not exist in table",
674 return ErrSyntaxError
;
676 FieldValue
*newVal
= new FieldValue();
677 strcpy(newVal
->fldName
,name
->fldName
);
678 newVal
->parsedString
= NULL
;
680 newVal
->type
= fInfo
->type
;
681 newVal
->isNullable
= fInfo
->isNull
;
682 newVal
->length
= fInfo
->length
;
683 newVal
->offset
= fInfo
->offset
;
684 newVal
->isPrimary
= fInfo
->isPrimary
;
685 newVal
->isUnique
= fInfo
->isUnique
;
686 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
687 if (newVal
->type
== typeBinary
)
688 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
689 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
690 newVal
->isAllocVal
=true;
691 parsedData
->insertFieldValue(newVal
);
692 aggTable
->setGroup(name
->fldName
, newVal
->value
);
695 aggTable
->setCondition(parsedData
->getHavingCondition());
696 /*if (giter.hasElement())
698 printError(ErrSyntaxError, "Only one field allowed in group\n");
699 return ErrSyntaxError;
705 DbRetVal
SelStatement::resolveStar()
708 parsedData
->clearFieldNameList();
709 FieldValue
*newVal
= NULL
;
710 List fNameList
= table
->getFieldNameList();
711 ListIterator fNameIter
= fNameList
.getIterator();
712 //fNameList.resetIter(); //do not remove this.
713 FieldInfo
*fInfo
= new FieldInfo();
714 for (int i
= 0; i
< fNameList
.size() ; i
++)
716 char *fName
= ((Identifier
*)(fNameIter
.nextElement()))->name
;
717 rv
= table
->getFieldInfo(fName
, fInfo
);
718 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
722 printError(ErrSysFatal
, "Should never happen.");
725 newVal
= new FieldValue();
726 strcpy(newVal
->fldName
,fName
);
727 newVal
->parsedString
= NULL
;
729 newVal
->type
= fInfo
->type
;
730 newVal
->length
= fInfo
->length
;
731 newVal
->offset
= fInfo
->offset
;
732 newVal
->isPrimary
= fInfo
->isPrimary
;
733 newVal
->isUnique
= fInfo
->isUnique
;
734 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
736 // for binary datatype input buffer size should be 2 times the length
737 if(newVal
->type
== typeBinary
)
738 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
739 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
740 newVal
->isAllocVal
=true;
741 newVal
->isInResSet
= true;
742 parsedData
->insertFieldValue(newVal
);
743 parsedData
->insertField(fName
);
744 rv
= table
->bindFld(fName
, newVal
->value
);
751 while (fNameIter
.hasElement())
752 delete (Identifier
*) fNameIter
.nextElement();
758 DbRetVal
SelStatement::setBindFieldAndValues()
760 totalFields
= parsedData
->getFieldNameList().size();
761 bindFields
= (FieldValue
**) malloc ( totalFields
* sizeof(FieldValue
*));
762 bindFieldValues
= (char**) malloc( totalFields
* sizeof(char*));
763 memset(bindFields
, 0, totalFields
* sizeof(FieldValue
*));
764 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
765 ListIterator valIter
= parsedData
->getFieldValueList().getIterator();
767 FieldValue
*value
= NULL
;
768 //The second condition colNo < totalFields is important for projection list
769 //might not contain the binded having field.
770 while(valIter
.hasElement() && colNo
< totalFields
)
772 value
= (FieldValue
*) valIter
.nextElement();
775 free(bindFields
); bindFields
= NULL
;
776 free(bindFieldValues
); bindFieldValues
= NULL
;
777 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
780 bindFields
[colNo
++] = value
;
786 DbRetVal
SelStatement::resolveForCondition()
788 //get the fieldname list and validate field names
789 ListIterator iter
= parsedData
->getConditionValueList().getIterator();
791 ConditionValue
*value
;
792 FieldInfo
*fInfo
= new FieldInfo();
795 while (iter
.hasElement())
797 value
= (ConditionValue
*) iter
.nextElement();
801 printError(ErrSysFatal
, "Should never happen.");
804 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
805 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
808 printError(ErrSyntaxError
, "Field %s does not exist in table",
810 return ErrSyntaxError
;
812 if (value
->aType
== AGG_AVG
) {
813 value
->type
= typeDouble
;
814 value
->length
= sizeof(double);
815 } else if (value
->aType
== AGG_COUNT
) {
816 value
->type
= typeInt
;
817 value
->length
= sizeof(int);
819 value
->type
= fInfo
->type
;
820 value
->length
= fInfo
->length
;
822 value
->isNullable
= fInfo
->isNull
;
823 value
->value
= AllDataType::alloc(value
->type
, value
->length
);
824 //table->bindFld(name->fldName, value->value);
825 if(value
->paramNo
==1) continue;//For Predecate t1.f1=t2.f1
826 if (value
->parsedString
== NULL
)
829 printError(ErrSyntaxError
, "Condition value should not be NULL");
830 return ErrSyntaxError
;
832 if (value
->parsedString
[0] == '?')
834 //if(!value->opLike) // checks if 'LIKE' operator is used
835 value
->paramNo
= paramPos
++;
837 if (!value
->paramNo
) {
839 if((value
->type
== typeInt
) || (value
->type
==typeShort
) || (value
->type
==typeByteInt
) || (value
->type
==typeLongLong
) || (value
->type
==typeLong
)){
840 int len
=strlen(value
->parsedString
);
841 for(int n
=0;n
<len
;n
++){
842 int p
=value
->parsedString
[n
];
843 if(!(p
>=48 && p
<=57 || p
==45))
848 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
849 AllDataType::strToValue(value
->value
, value
->parsedString
, value
->type
, value
->length
);
853 totalParams
= paramPos
-1;
854 if (0 == totalParams
) return OK
;
855 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
856 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
857 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
858 memset(paramValues
, 0, totalParams
* sizeof(char*));
860 while(iter
.hasElement())
862 value
= (ConditionValue
*) iter
.nextElement();
865 free(params
); params
= NULL
;
866 free(paramValues
); paramValues
= NULL
;
867 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
870 params
[value
->paramNo
-1 ] = value
;
874 bool SelStatement::isGroupFld(char *fieldName
)
876 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
877 FieldName
*name
= NULL
;
878 while (giter
.hasElement())
880 name
= (FieldName
*) giter
.nextElement();
881 if (0 == strcmp(name
->fldName
, fieldName
)) return true;
886 void* SelStatement::handleSingleTableAggWithoutGroup()
888 if (isPointReturned
) return NULL
;
889 TableImpl
*tblImpl
= (TableImpl
*)table
;
890 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
894 FieldValue
*fVal
= NULL
;
896 while (iter
.hasElement())
898 name
= (FieldName
*) iter
.nextElement();
899 fVal
= bindFields
[i
];
901 rv
= tblImpl
->fetchAgg(name
->fldName
, name
->aType
, fVal
->value
, noRec
);
902 if (OK
!= rv
) return NULL
;
904 tblImpl
->closeScan();
907 isPointReturned
= true;
908 if(noRec
&& name
->aType
!= AGG_COUNT
) return NULL
;
911 void* SelStatement::fetch()
916 tuple
= handleSingleTableAggWithoutGroup();
917 if (NULL
== tuple
) return NULL
;
919 if (isOffsetReached
) {
920 if (!isRecLimitReached
) {
921 tuple
= table
->fetch();
922 if (NULL
!= tuple
) numRecords
++;
923 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
928 while(recordOffset
<= parsedData
->getOffset()) {
929 tuple
= table
->fetch();
930 if (NULL
== tuple
) break;
933 isOffsetReached
= true;
934 if (NULL
!= tuple
) numRecords
++;
935 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
938 if (NULL
== tuple
) return NULL
;
940 //copy values to binded buffer
942 for (int i
= 0; i
< totalFields
; i
++)
944 value
= bindFields
[i
];
945 if (bindFieldValues
[i
] == NULL
)
947 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
950 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
955 void* SelStatement::fetch(DbRetVal
&rv
)
960 tuple
= handleSingleTableAggWithoutGroup();
961 if (NULL
== tuple
) return NULL
;
963 if (isOffsetReached
) {
964 if (!isRecLimitReached
) {
965 tuple
= table
->fetch(rv
);
966 if (NULL
!= tuple
) numRecords
++;
967 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
971 while(recordOffset
<= parsedData
->getOffset()) {
972 tuple
= table
->fetch(rv
);
973 if (NULL
== tuple
) break;
976 isOffsetReached
= true;
977 if (NULL
!= tuple
) numRecords
++;
978 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
981 if (NULL
== tuple
) return NULL
;
982 //copy values to binded buffer
984 for (int i
= 0; i
< totalFields
; i
++)
986 value
= bindFields
[i
];
987 if (bindFieldValues
[i
] == NULL
)
989 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
992 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
997 DbRetVal
SelStatement::close()
999 isPointReturned
= false;
1000 if (table
) return table
->closeScan();
1004 void* SelStatement::getParamValuePtr( int pos
)
1006 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
1007 return ( (void*) p
->value
);
1010 char* SelStatement::getFieldName ( int pos
)
1012 //TODO::if not yet prepared return error
1013 //TODO::check the upper limit for projpos
1014 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1016 while (iter
.hasElement())
1018 FieldName
*name
= (FieldName
*) iter
.nextElement();
1019 if (position
== pos
) {
1022 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
1025 return name
->fldName
;
1032 DataType
SelStatement::getFieldType( int pos
)
1034 FieldValue
*v
= bindFields
[pos
];
1035 return ( (DataType
) v
->type
);
1038 int SelStatement::getFieldLength( int pos
)
1040 FieldValue
*v
= bindFields
[pos
];
1041 return ( (int) v
->type
);
1044 void* SelStatement::fetchAndPrint(bool SQL
)
1047 if(handleAggWithTbl
)
1049 tuple
= handleSingleTableAggWithoutGroup();
1051 if (isOffsetReached
) {
1052 if (!isRecLimitReached
) {
1053 tuple
= table
->fetch();
1054 if (NULL
!= tuple
) numRecords
++;
1055 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1059 int recordOffset
=0;
1060 while(recordOffset
<= parsedData
->getOffset()) {
1061 tuple
= table
->fetch();
1062 if (NULL
== tuple
) break;
1065 isOffsetReached
= true;
1066 if (NULL
!= tuple
) numRecords
++;
1067 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1070 if (NULL
== tuple
) return NULL
;
1075 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
1078 for (int i
= 0; i
< totalFields
; i
++)
1080 value
= bindFields
[i
];
1081 if (!value
->isInResSet
) continue;
1082 nullValueSet
= table
->isFldNull(value
->fldName
);
1090 else if (value
->aType
!= AGG_COUNT
) printf("NULL\t");
1116 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
1127 } else printf("\t");
1130 if (SQL
) printf(");\n");
1134 void* SelStatement::next()
1136 if(handleAggWithTbl
)
1138 return handleSingleTableAggWithoutGroup();
1140 return( table
->fetch() );
1144 void* SelStatement::getFieldValuePtr( int pos
)
1146 FieldValue
*v
= bindFields
[pos
];
1147 return ( (void*) v
->value
);
1150 void* SelStatement::getFieldValuePtr( char *name
)
1153 char fName
[IDENTIFIER_LENGTH
];
1154 for (int i
= 0; i
< totalFields
; i
++)
1156 value
= bindFields
[i
];
1157 table
->getFieldNameAlone(value
->fldName
,fName
);
1158 if (strcmp(fName
,name
)==0)
1160 return ( (void*) value
->value
);
1166 void SelStatement::getProjFieldType(int *data
)
1169 for (int i
= 0; i
< totalFields
; i
++)
1171 value
= bindFields
[i
];
1172 data
[i
+1] = value
->type
;
1176 int SelStatement::noOfProjFields()
1181 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
1185 //TODO::if not yet prepared return error
1186 //TODO::check the upper limit for projpos
1187 if (projpos
< 0 || projpos
>totalFields
) return ErrBadArg
;
1188 FieldValue
*value
= bindFields
[projpos
-1];
1189 fInfo
->type
= value
->type
;
1190 fInfo
->length
= value
->length
;
1191 fInfo
->isNull
= value
->isNullable
;
1192 fInfo
->aType
= value
->aType
;
1193 fInfo
->offset
= value
->offset
;
1194 fInfo
->isPrimary
= value
->isPrimary
;
1195 fInfo
->isUnique
= value
->isUnique
;
1196 fInfo
->isAutoIncrement
= value
->isAutoIncrement
;
1197 fInfo
->isDefault
= value
->isDefault
;
1198 if (fInfo
->aType
== AGG_UNKNOWN
) {
1199 strcpy(fInfo
->fldName
, value
->fldName
);
1200 if (fInfo
->isDefault
) strcpy(fInfo
->defaultValueBuf
, value
->defValBuf
);
1203 switch(fInfo
->aType
)
1206 sprintf(fInfo
->fldName
, "COUNT(%s)", value
->fldName
);
1207 fInfo
->type
= typeInt
;
1208 fInfo
->length
= sizeof(int);
1211 sprintf(fInfo
->fldName
, "MIN(%s)", value
->fldName
);
1214 sprintf(fInfo
->fldName
, "MAX(%s)", value
->fldName
);
1217 sprintf(fInfo
->fldName
, "SUM(%s)", value
->fldName
);
1220 sprintf(fInfo
->fldName
, "AVG(%s)", value
->fldName
);
1221 fInfo
->type
= typeDouble
;
1222 fInfo
->length
= sizeof(double);
1225 strcpy(fInfo
->fldName
, value
->fldName
);
1230 int SelStatement::getFldPos(char *name
)
1232 return table
->getFldPos(name
);
1235 bool SelStatement::isInProjectionList(char *name
, AggType aType
)
1237 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1238 FieldName
*fldName
= NULL
;
1239 while (iter
.hasElement()) {
1240 fldName
= (FieldName
*) iter
.nextElement();
1241 if ((strcmp(fldName
->fldName
, name
)==0) && fldName
->aType
== aType
) {