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 isMixPrjList
= false;
341 bool isAggFld
= false;
342 bool isNotAggFld
= false;
343 bool isSingleTableNoGrp
= false;
344 bool isGroupFld
= false;
345 if(parsedData
->getTableNameList().size() == 1 &&
346 parsedData
->getGroupFieldNameList().size() == 0)
348 isSingleTableNoGrp
= true;
350 AggTableImpl
*aggTable
= NULL
;
351 while (iter
.hasElement())
353 name
= (FieldName
*)iter
.nextElement();
356 dbMgr
->closeTable(table
);
359 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
362 bool isBindFld
=false;
363 if ('*' == name
->fldName
[0] && name
->aType
== AGG_UNKNOWN
)
368 dbMgr
->closeTable(table
);
373 if (parsedData
->getGroupFieldNameList().size()!= 0
374 && !isSingleTableNoGrp
)
377 aggTable
= new AggTableImpl();
378 aggTable
->setTable(table
);
380 //as soon as it encounters *, it breaks the loop negleting other field names
381 //as they all are deleted during resolveStar method.
384 if ('*' == name
->fldName
[0] && name
->aType
!= AGG_COUNT
) {
385 return ErrSyntaxError
;
387 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
388 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
390 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
391 else dbMgr
->closeTable(table
);
394 printError(ErrSyntaxError
, "Field %s does not exist in table",
396 return ErrSyntaxError
;
398 FieldValue
*newVal
= new FieldValue();
399 strcpy(newVal
->fldName
,name
->fldName
);
400 newVal
->parsedString
= NULL
;
402 newVal
->aType
= name
->aType
;
404 if (newVal
->aType
!= AGG_UNKNOWN
) isAggFld
= true;
405 else isNotAggFld
= true;
406 if (isAggFld
&& isNotAggFld
) isMixPrjList
= true;
408 newVal
->isInResSet
= true;
409 newVal
->offset
= fInfo
->offset
;
410 newVal
->isPrimary
= fInfo
->isPrimary
;
411 newVal
->isUnique
= fInfo
->isUnique
;
412 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
413 newVal
->isDefault
= fInfo
->isDefault
;
414 if (newVal
->isDefault
)
415 strcpy(newVal
->defValBuf
, fInfo
->defaultValueBuf
);
416 else newVal
->defValBuf
[0]='\0';
418 if (name
->aType
== AGG_COUNT
) {
419 newVal
->type
= typeInt
;
420 newVal
->length
= sizeof(int);
422 else if (name
->aType
== AGG_AVG
) {
423 newVal
->type
= typeDouble
;
424 newVal
->length
= sizeof(double);
425 if (!AllDataType::isValidFieldForAvg(fInfo
->type
)) {
426 printError(ErrBadArg
, "Illegal operation for field %s",
428 dbMgr
->closeTable(table
);
429 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
436 newVal
->type
= fInfo
->type
;
437 newVal
->length
= fInfo
->length
;
439 newVal
->isNullable
= fInfo
->isNull
;
440 FieldName
*bFldName
=NULL
;
441 ListIterator it
= bindFldList
.getIterator();
442 while (it
.hasElement())
444 bFldName
= (FieldName
*)it
.nextElement();
445 if(0==strcmp(bFldName
->fldName
,name
->fldName
) &&
446 name
->aType
== AGG_UNKNOWN
)
448 newVal
->value
=table
->getBindFldAddr(name
->fldName
);
449 newVal
->isAllocVal
=false;
455 if ( name
->aType
== AGG_UNKNOWN
||
456 (name
->aType
!= AGG_COUNT
&&
457 name
->aType
!= AGG_AVG
) ) {
458 if(newVal
->type
== typeBinary
)
459 newVal
->value
= AllDataType::alloc(fInfo
->type
,
461 else newVal
->value
= AllDataType::alloc(fInfo
->type
,
464 if (name
->aType
== AGG_AVG
) {
465 newVal
->value
= AllDataType::alloc(typeDouble
,
467 memset(newVal
->value
, 0, sizeof(double));
469 else if (name
->aType
== AGG_COUNT
) {
470 newVal
->value
= AllDataType::alloc(typeInt
,
472 memset(newVal
->value
, 0, sizeof(int));
476 newVal
->isAllocVal
=true;
478 if (name
->aType
==AGG_UNKNOWN
&&
479 parsedData
->getGroupFieldNameList().size()== 0) {
480 rv
= table
->bindFld(name
->fldName
, newVal
->value
);
482 if (newVal
->isAllocVal
) free(newVal
->value
);
488 else if (!isSingleTableNoGrp
)
491 aggTable
= new AggTableImpl();
492 aggTable
->setTable(table
);
494 rv
= aggTable
->bindFld(name
->fldName
, name
->aType
, newVal
->value
);
496 if (newVal
->isAllocVal
) free(newVal
->value
);
497 delete newVal
; delete fInfo
; delete aggTable
;
498 aggTable
= NULL
; table
= NULL
;
502 if (name
->aType
!=AGG_UNKNOWN
&& isSingleTableNoGrp
)
503 handleAggWithTbl
= true;
504 parsedData
->insertFieldValue(newVal
);
506 if (!isBindFld
) bindFldList
.append(name
);
510 //Check if the having list is present in projection list or not.
511 //If not present bind here not to be printed in fetchAndPrint later.
512 ListIterator hiter
= parsedData
->getHavingFieldNameList().getIterator();
513 while (hiter
.hasElement()) {
514 FieldName
*fnm
= (FieldName
*) hiter
.nextElement();
515 rv
= table
->getFieldInfo(fnm
->fldName
, fInfo
);
516 if (!isInProjectionList(fnm
->fldName
, fnm
->aType
)) {
517 FieldValue
*newVal
= new FieldValue();
518 strcpy(newVal
->fldName
,fnm
->fldName
);
519 newVal
->parsedString
= NULL
;
521 newVal
->aType
= fnm
->aType
;
522 newVal
->isInResSet
= false;
523 newVal
->isNullable
= fInfo
->isNull
;
524 newVal
->offset
= fInfo
->offset
;
525 newVal
->isPrimary
= fInfo
->isPrimary
;
526 newVal
->isUnique
= fInfo
->isUnique
;
527 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
528 if (fnm
->aType
== AGG_AVG
) {
529 newVal
->value
= AllDataType::alloc(typeDouble
, sizeof(double));
530 memset(newVal
->value
, 0, sizeof(double));
531 } else if (fnm
->aType
== AGG_COUNT
) {
532 newVal
->value
= AllDataType::alloc(typeInt
, sizeof(int));
533 memset(newVal
->value
, 0, sizeof(int));
535 newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
536 memset(newVal
->value
, 0, fInfo
->length
);
538 newVal
->isAllocVal
= true;
539 parsedData
->insertFieldValue(newVal
);
540 aggTable
->bindFld(fnm
->fldName
, fnm
->aType
, newVal
->value
);
544 rv
= setBindFieldAndValues();
548 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
549 else dbMgr
->closeTable(table
);
554 table
->setCondition(parsedData
->getCondition());
556 rv
= resolveForCondition();
560 //TODO::free memory allocated for params
561 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
563 table
->setCondition(NULL
);
564 dbMgr
->closeTable(table
);
569 if (NULL
== parsedData
->getCondition()) parsedData
->setCacheWorthy(false);
570 rv
= resolveGroupFld(aggTable
, isGroupFld
);
574 //TODO::free memory allocated for params
575 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
578 table
->setCondition(NULL
);
579 dbMgr
->closeTable(table
);
584 if (isMixPrjList
&& ! isGroupFld
) {
585 printError(ErrSyntax
, "Group By Field required.");
587 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
590 table
->setCondition(NULL
);
591 dbMgr
->closeTable(table
);
597 rv
= resolveOrderByFld();
605 rv
= resolveDistinct();
607 if(parsedData
->getExplain()) isExplain
= true;
612 DbRetVal
SelStatement::resolveDistinct()
614 if (!parsedData
->getDistinct()) {
617 OrderTableImpl
*orderTable
= new OrderTableImpl();
618 orderTable
->setTable(table
);
619 orderTable
->setProjList(parsedData
->getFieldValueList());
620 orderTable
->setOrderByList(parsedData
->getFieldValueList());
621 orderTable
->setDistinct();
623 handleAggWithTbl
= false;
628 DbRetVal
SelStatement::resolveOrderByFld()
630 if (0 == parsedData
->getOrderFieldNameList().size()) {
633 OrderTableImpl
*orderTable
= new OrderTableImpl();
634 orderTable
->setTable(table
);
635 orderTable
->setProjList(parsedData
->getFieldValueList());
636 ListIterator giter
= parsedData
->getOrderFieldNameList().getIterator();
637 FieldName
*name
= NULL
;
639 FieldInfo
*fInfo
= new FieldInfo();
640 while (giter
.hasElement())
642 name
= (FieldName
*)giter
.nextElement();
643 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
644 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
647 printError(ErrSyntaxError
, "Field %s does not exist in table",
649 return ErrSyntaxError
;
651 /*FieldValue *newVal = new FieldValue();
652 strcpy(newVal->fldName,name->fldName);
653 newVal->parsedString = NULL;
655 newVal->type = fInfo->type;
656 newVal->isNullable = fInfo->isNull;
657 newVal->length = fInfo->length;
658 if (newVal->type == typeBinary)
659 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
660 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
661 newVal->isAllocVal=true;
662 parsedData->insertFieldValue(newVal);
664 if (name
->aType
== AGG_UNKNOWN
) orderTable
->setOrderBy(name
->fldName
);
665 else orderTable
->setOrderBy(name
->fldName
, true); //descending
669 handleAggWithTbl
= false;
673 DbRetVal
SelStatement::resolveGroupFld(AggTableImpl
*aggTable
, bool &isGrpFld
)
675 if (!aggTable
) return OK
;
677 //check whether all non aggregate projections are from group list
678 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
679 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
680 FieldName
*name
= NULL
;
681 while (iter
.hasElement())
683 name
= (FieldName
*) iter
.nextElement();
684 if (name
->aType
== AGG_UNKNOWN
&& !isGroupFld(name
->fldName
) ) {
685 printError(ErrSyntaxError
,
686 "Non aggregate projection contains non group field: %s",
688 return ErrSyntaxError
;
693 FieldInfo
*fInfo
= new FieldInfo();
694 while (giter
.hasElement())
696 name
= (FieldName
*)giter
.nextElement();
697 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
698 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
701 printError(ErrSyntaxError
, "Field %s does not exist in table",
703 return ErrSyntaxError
;
705 FieldValue
*newVal
= new FieldValue();
706 strcpy(newVal
->fldName
,name
->fldName
);
707 newVal
->parsedString
= NULL
;
709 newVal
->type
= fInfo
->type
;
710 newVal
->isNullable
= fInfo
->isNull
;
711 newVal
->length
= fInfo
->length
;
712 newVal
->offset
= fInfo
->offset
;
713 newVal
->isPrimary
= fInfo
->isPrimary
;
714 newVal
->isUnique
= fInfo
->isUnique
;
715 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
716 if (newVal
->type
== typeBinary
)
717 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
718 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
719 newVal
->isAllocVal
=true;
720 parsedData
->insertFieldValue(newVal
);
721 aggTable
->setGroup(name
->fldName
, newVal
->value
);
724 aggTable
->setCondition(parsedData
->getHavingCondition());
725 /*if (giter.hasElement())
727 printError(ErrSyntaxError, "Only one field allowed in group\n");
728 return ErrSyntaxError;
735 DbRetVal
SelStatement::resolveStar()
738 parsedData
->clearFieldNameList();
739 FieldValue
*newVal
= NULL
;
740 List fNameList
= table
->getFieldNameList();
741 ListIterator fNameIter
= fNameList
.getIterator();
742 //fNameList.resetIter(); //do not remove this.
743 FieldInfo
*fInfo
= new FieldInfo();
744 for (int i
= 0; i
< fNameList
.size() ; i
++)
746 char *fName
= ((Identifier
*)(fNameIter
.nextElement()))->name
;
747 rv
= table
->getFieldInfo(fName
, fInfo
);
748 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
752 printError(ErrSysFatal
, "Should never happen.");
755 newVal
= new FieldValue();
756 strcpy(newVal
->fldName
,fName
);
757 newVal
->parsedString
= NULL
;
759 newVal
->type
= fInfo
->type
;
760 newVal
->length
= fInfo
->length
;
761 newVal
->offset
= fInfo
->offset
;
762 newVal
->isPrimary
= fInfo
->isPrimary
;
763 newVal
->isUnique
= fInfo
->isUnique
;
764 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
766 // for binary datatype input buffer size should be 2 times the length
767 if(newVal
->type
== typeBinary
)
768 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
769 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
770 newVal
->isAllocVal
=true;
771 newVal
->isInResSet
= true;
772 parsedData
->insertFieldValue(newVal
);
773 parsedData
->insertField(fName
);
774 rv
= table
->bindFld(fName
, newVal
->value
);
781 while (fNameIter
.hasElement())
782 delete (Identifier
*) fNameIter
.nextElement();
788 DbRetVal
SelStatement::setBindFieldAndValues()
790 totalFields
= parsedData
->getFieldNameList().size();
791 bindFields
= (FieldValue
**) malloc ( totalFields
* sizeof(FieldValue
*));
792 bindFieldValues
= (char**) malloc( totalFields
* sizeof(char*));
793 memset(bindFields
, 0, totalFields
* sizeof(FieldValue
*));
794 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
795 ListIterator valIter
= parsedData
->getFieldValueList().getIterator();
797 FieldValue
*value
= NULL
;
798 //The second condition colNo < totalFields is important for projection list
799 //might not contain the binded having field.
800 while(valIter
.hasElement() && colNo
< totalFields
)
802 value
= (FieldValue
*) valIter
.nextElement();
805 free(bindFields
); bindFields
= NULL
;
806 free(bindFieldValues
); bindFieldValues
= NULL
;
807 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
810 bindFields
[colNo
++] = value
;
816 DbRetVal
SelStatement::resolveForCondition()
818 //get the fieldname list and validate field names
819 ListIterator iter
= parsedData
->getConditionValueList().getIterator();
821 ConditionValue
*value
;
822 FieldInfo
*fInfo
= new FieldInfo();
825 while (iter
.hasElement())
827 value
= (ConditionValue
*) iter
.nextElement();
831 printError(ErrSysFatal
, "Should never happen.");
834 if(!value
->isFunctionInvolve
){
835 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
836 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
839 printError(ErrSyntaxError
, "Field %s does not exist in table",
841 return ErrSyntaxError
;
843 if (value
->aType
== AGG_AVG
) {
844 value
->type
= typeDouble
;
845 value
->length
= sizeof(double);
846 } else if (value
->aType
== AGG_COUNT
) {
847 value
->type
= typeInt
;
848 value
->length
= sizeof(int);
850 value
->type
= fInfo
->type
;
851 value
->length
= fInfo
->length
;
853 value
->isNullable
= fInfo
->isNull
;
855 value
->type
= AllDataType::getCsqlTypeFromFunctionTypeForComparision(parsedData
->getFunctionType());
857 value
->value
= AllDataType::alloc(value
->type
, value
->length
);
858 //table->bindFld(name->fldName, value->value);
859 if(value
->paramNo
==1) continue;//For Predecate t1.f1=t2.f1
860 if (value
->parsedString
== NULL
)
863 printError(ErrSyntaxError
, "Condition value should not be NULL");
864 return ErrSyntaxError
;
866 if (value
->parsedString
[0] == '?')
868 value
->paramNo
= paramPos
++;
870 if (!value
->paramNo
) {
872 if (value
->type
== typeDate
|| value
->type
== typeTime
||
873 value
->type
== typeTimeStamp
)
874 parsedData
->setCacheWorthy(false);
875 if((value
->type
== typeInt
) || (value
->type
==typeShort
) ||
876 (value
->type
==typeByteInt
) || (value
->type
==typeLongLong
) ||
877 (value
->type
==typeLong
)) {
878 int len
=strlen(value
->parsedString
);
879 for(int n
=0;n
<len
;n
++){
880 int p
=value
->parsedString
[n
];
881 if(!(p
>=48 && p
<=57 || p
==45)) {
888 // Here for binary dataType it is not strcpy'd bcos internally
889 // memcmp is done for predicates like f2 = 'abcd' where f2 is binary
890 rv
= AllDataType::strToValue(value
->value
, value
->parsedString
, value
->type
, value
->length
);
898 totalParams
= paramPos
-1;
899 if (0 == totalParams
) return OK
;
900 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
901 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
902 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
903 memset(paramValues
, 0, totalParams
* sizeof(char*));
905 while(iter
.hasElement())
907 value
= (ConditionValue
*) iter
.nextElement();
910 free(params
); params
= NULL
;
911 free(paramValues
); paramValues
= NULL
;
912 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
915 if (value
->paramNo
) params
[value
->paramNo
- 1] = value
;
919 bool SelStatement::isGroupFld(char *fieldName
)
921 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
922 FieldName
*name
= NULL
;
923 while (giter
.hasElement())
925 name
= (FieldName
*) giter
.nextElement();
926 if (0 == strcmp(name
->fldName
, fieldName
)) return true;
931 void* SelStatement::handleSingleTableAggWithoutGroup()
933 if (isPointReturned
) return NULL
;
934 TableImpl
*tblImpl
= (TableImpl
*)table
;
935 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
939 FieldValue
*fVal
= NULL
;
941 while (iter
.hasElement())
943 name
= (FieldName
*) iter
.nextElement();
944 fVal
= bindFields
[i
];
946 rv
= tblImpl
->fetchAgg(name
->fldName
, name
->aType
, fVal
->value
, noRec
);
947 if (OK
!= rv
) return NULL
;
949 tblImpl
->closeScan();
952 isPointReturned
= true;
953 if(noRec
&& name
->aType
!= AGG_COUNT
) return NULL
;
956 void* SelStatement::fetch()
961 tuple
= handleSingleTableAggWithoutGroup();
962 if (NULL
== tuple
) return NULL
;
964 if (isOffsetReached
) {
965 if (!isRecLimitReached
) {
966 tuple
= table
->fetch();
967 if (NULL
!= tuple
) numRecords
++;
968 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
973 while(recordOffset
<= parsedData
->getOffset()) {
974 tuple
= table
->fetch();
975 if (NULL
== tuple
) break;
978 isOffsetReached
= true;
979 if (NULL
!= tuple
) numRecords
++;
980 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
983 if (NULL
== tuple
) return NULL
;
985 //copy values to binded buffer
987 for (int i
= 0; i
< totalFields
; i
++)
989 value
= bindFields
[i
];
990 if (bindFieldValues
[i
] == NULL
)
992 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
995 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
1000 void* SelStatement::fetch(DbRetVal
&rv
)
1003 if(handleAggWithTbl
)
1005 tuple
= handleSingleTableAggWithoutGroup();
1006 if (NULL
== tuple
) return NULL
;
1008 if (isOffsetReached
) {
1009 if (!isRecLimitReached
) {
1010 tuple
= table
->fetch(rv
);
1011 if (NULL
!= tuple
) numRecords
++;
1012 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1015 int recordOffset
=0;
1016 while(recordOffset
<= parsedData
->getOffset()) {
1017 tuple
= table
->fetch(rv
);
1018 if (NULL
== tuple
) break;
1021 isOffsetReached
= true;
1022 if (NULL
!= tuple
) numRecords
++;
1023 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1026 if (NULL
== tuple
) return NULL
;
1027 //copy values to binded buffer
1029 for (int i
= 0; i
< totalFields
; i
++)
1031 value
= bindFields
[i
];
1032 if (bindFieldValues
[i
] == NULL
)
1034 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
1037 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
1042 DbRetVal
SelStatement::close()
1044 isPointReturned
= false;
1046 if (table
) return table
->closeScan();
1050 void* SelStatement::getParamValuePtr( int pos
)
1052 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
1053 return ( (void*) p
->value
);
1056 char* SelStatement::getFieldName ( int pos
)
1058 //TODO::if not yet prepared return error
1059 //TODO::check the upper limit for projpos
1060 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1062 while (iter
.hasElement())
1064 FieldName
*name
= (FieldName
*) iter
.nextElement();
1065 if (position
== pos
) {
1068 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
1071 return name
->fldName
;
1078 DataType
SelStatement::getFieldType( int pos
)
1080 FieldValue
*v
= bindFields
[pos
];
1081 return ( (DataType
) v
->type
);
1084 int SelStatement::getFieldLength( int pos
)
1086 FieldValue
*v
= bindFields
[pos
];
1087 return ( (int) v
->type
);
1090 void* SelStatement::fetchAndPrint(bool SQL
)
1093 if(handleAggWithTbl
)
1095 tuple
= handleSingleTableAggWithoutGroup();
1097 if (isOffsetReached
) {
1098 if (!isRecLimitReached
) {
1099 tuple
= table
->fetch();
1100 if (NULL
!= tuple
) numRecords
++;
1101 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1105 int recordOffset
=0;
1106 while(recordOffset
<= parsedData
->getOffset()) {
1107 tuple
= table
->fetch();
1108 if (NULL
== tuple
) break;
1111 isOffsetReached
= true;
1112 if (NULL
!= tuple
) numRecords
++;
1113 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1116 if (NULL
== tuple
) return NULL
;
1121 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
1124 for (int i
= 0; i
< totalFields
; i
++)
1126 value
= bindFields
[i
];
1127 if (!value
->isInResSet
) continue;
1128 nullValueSet
= table
->isFldNull(value
->fldName
);
1136 else if (value
->aType
!= AGG_COUNT
) printf("NULL\t");
1163 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
1175 } else printf("\t");
1178 if (SQL
) printf(");\n");
1182 void* SelStatement::next()
1184 if(handleAggWithTbl
)
1186 return handleSingleTableAggWithoutGroup();
1188 return( table
->fetch() );
1192 void* SelStatement::getFieldValuePtr( int pos
)
1194 FieldValue
*v
= bindFields
[pos
];
1195 if (NULL
== v
) return v
;
1196 return ( (void*) v
->value
);
1199 void* SelStatement::getFieldValuePtr( char *name
)
1202 char fName
[IDENTIFIER_LENGTH
];
1203 for (int i
= 0; i
< totalFields
; i
++)
1205 value
= bindFields
[i
];
1206 table
->getFieldNameAlone(value
->fldName
,fName
);
1207 if (strcmp(fName
,name
)==0)
1209 return ( (void*) value
->value
);
1215 void SelStatement::getProjFieldType(int *data
)
1218 for (int i
= 0; i
< totalFields
; i
++)
1220 value
= bindFields
[i
];
1221 data
[i
+1] = value
->type
;
1225 int SelStatement::noOfProjFields()
1230 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
1234 //TODO::if not yet prepared return error
1235 //TODO::check the upper limit for projpos
1236 if (projpos
< 0 || projpos
>totalFields
) return ErrBadArg
;
1237 FieldValue
*value
= bindFields
[projpos
-1];
1238 fInfo
->type
= value
->type
;
1239 fInfo
->length
= value
->length
;
1240 fInfo
->isNull
= value
->isNullable
;
1241 fInfo
->aType
= value
->aType
;
1242 fInfo
->offset
= value
->offset
;
1243 fInfo
->isPrimary
= value
->isPrimary
;
1244 fInfo
->isUnique
= value
->isUnique
;
1245 fInfo
->isAutoIncrement
= value
->isAutoIncrement
;
1246 fInfo
->isDefault
= value
->isDefault
;
1247 if (fInfo
->aType
== AGG_UNKNOWN
) {
1248 strcpy(fInfo
->fldName
, value
->fldName
);
1249 if (fInfo
->isDefault
) strcpy(fInfo
->defaultValueBuf
, value
->defValBuf
);
1252 switch(fInfo
->aType
)
1255 sprintf(fInfo
->fldName
, "COUNT(%s)", value
->fldName
);
1256 fInfo
->type
= typeInt
;
1257 fInfo
->length
= sizeof(int);
1260 sprintf(fInfo
->fldName
, "MIN(%s)", value
->fldName
);
1263 sprintf(fInfo
->fldName
, "MAX(%s)", value
->fldName
);
1266 sprintf(fInfo
->fldName
, "SUM(%s)", value
->fldName
);
1269 sprintf(fInfo
->fldName
, "AVG(%s)", value
->fldName
);
1270 fInfo
->type
= typeDouble
;
1271 fInfo
->length
= sizeof(double);
1274 strcpy(fInfo
->fldName
, value
->fldName
);
1279 int SelStatement::getFldPos(char *name
)
1281 return table
->getFldPos(name
);
1284 bool SelStatement::isInProjectionList(char *name
, AggType aType
)
1286 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1287 FieldName
*fldName
= NULL
;
1288 while (iter
.hasElement()) {
1289 fldName
= (FieldName
*) iter
.nextElement();
1290 if ((strcmp(fldName
->fldName
, name
)==0) && fldName
->aType
== aType
) {