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';
407 if (name
->aType
== AGG_COUNT
) {
408 newVal
->type
= typeInt
;
409 newVal
->length
= sizeof(int);
411 else if (name
->aType
== AGG_AVG
) {
412 newVal
->type
= typeDouble
;
413 newVal
->length
= sizeof(double);
414 if (!AllDataType::isValidFieldForAvg(fInfo
->type
)) {
415 printError(ErrBadArg
, "Illegal operation for field %s",
417 dbMgr
->closeTable(table
);
418 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
425 newVal
->type
= fInfo
->type
;
426 newVal
->length
= fInfo
->length
;
428 newVal
->isNullable
= fInfo
->isNull
;
429 FieldName
*bFldName
=NULL
;
430 ListIterator it
= bindFldList
.getIterator();
431 while (it
.hasElement())
433 bFldName
= (FieldName
*)it
.nextElement();
434 if(0==strcmp(bFldName
->fldName
,name
->fldName
) &&
435 name
->aType
== AGG_UNKNOWN
)
437 newVal
->value
=table
->getBindFldAddr(name
->fldName
);
438 newVal
->isAllocVal
=false;
444 if ( name
->aType
== AGG_UNKNOWN
||
445 (name
->aType
!= AGG_COUNT
&&
446 name
->aType
!= AGG_AVG
) ) {
447 if(newVal
->type
== typeBinary
)
448 newVal
->value
= AllDataType::alloc(fInfo
->type
,
450 else newVal
->value
= AllDataType::alloc(fInfo
->type
,
453 if (name
->aType
== AGG_AVG
) {
454 newVal
->value
= AllDataType::alloc(typeDouble
,
456 memset(newVal
->value
, 0, sizeof(double));
458 else if (name
->aType
== AGG_COUNT
) {
459 newVal
->value
= AllDataType::alloc(typeInt
,
461 memset(newVal
->value
, 0, sizeof(int));
465 newVal
->isAllocVal
=true;
467 if (name
->aType
==AGG_UNKNOWN
&&
468 parsedData
->getGroupFieldNameList().size()== 0) {
469 rv
= table
->bindFld(name
->fldName
, newVal
->value
);
471 if (newVal
->isAllocVal
) free(newVal
->value
);
477 else if (!isSingleTableNoGrp
)
480 aggTable
= new AggTableImpl();
481 aggTable
->setTable(table
);
483 rv
= aggTable
->bindFld(name
->fldName
, name
->aType
, newVal
->value
);
485 if (newVal
->isAllocVal
) free(newVal
->value
);
486 delete newVal
; delete fInfo
; delete aggTable
;
487 aggTable
= NULL
; table
= NULL
;
491 if (name
->aType
!=AGG_UNKNOWN
&& isSingleTableNoGrp
)
492 handleAggWithTbl
= true;
493 parsedData
->insertFieldValue(newVal
);
495 if (!isBindFld
) bindFldList
.append(name
);
499 //Check if the having list is present in projection list or not.
500 //If not present bind here not to be printed in fetchAndPrint later.
501 ListIterator hiter
= parsedData
->getHavingFieldNameList().getIterator();
502 while (hiter
.hasElement()) {
503 FieldName
*fnm
= (FieldName
*) hiter
.nextElement();
504 rv
= table
->getFieldInfo(fnm
->fldName
, fInfo
);
505 if (!isInProjectionList(fnm
->fldName
, fnm
->aType
)) {
506 FieldValue
*newVal
= new FieldValue();
507 strcpy(newVal
->fldName
,fnm
->fldName
);
508 newVal
->parsedString
= NULL
;
510 newVal
->aType
= fnm
->aType
;
511 newVal
->isInResSet
= false;
512 newVal
->isNullable
= fInfo
->isNull
;
513 newVal
->offset
= fInfo
->offset
;
514 newVal
->isPrimary
= fInfo
->isPrimary
;
515 newVal
->isUnique
= fInfo
->isUnique
;
516 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
517 if (fnm
->aType
== AGG_AVG
) {
518 newVal
->value
= AllDataType::alloc(typeDouble
, sizeof(double));
519 memset(newVal
->value
, 0, sizeof(double));
520 } else if (fnm
->aType
== AGG_COUNT
) {
521 newVal
->value
= AllDataType::alloc(typeInt
, sizeof(int));
522 memset(newVal
->value
, 0, sizeof(int));
524 newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
525 memset(newVal
->value
, 0, fInfo
->length
);
527 newVal
->isAllocVal
= true;
528 parsedData
->insertFieldValue(newVal
);
529 aggTable
->bindFld(fnm
->fldName
, fnm
->aType
, newVal
->value
);
533 rv
= setBindFieldAndValues();
537 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
538 else dbMgr
->closeTable(table
);
543 table
->setCondition(parsedData
->getCondition());
545 rv
= resolveForCondition();
549 //TODO::free memory allocated for params
550 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
552 table
->setCondition(NULL
);
553 dbMgr
->closeTable(table
);
558 if (NULL
== parsedData
->getCondition()) parsedData
->setCacheWorthy(false);
559 rv
= resolveGroupFld(aggTable
);
563 //TODO::free memory allocated for params
564 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
567 table
->setCondition(NULL
);
568 dbMgr
->closeTable(table
);
574 rv
= resolveOrderByFld();
582 rv
= resolveDistinct();
584 if(parsedData
->getExplain()) isExplain
= true;
587 DbRetVal
SelStatement::resolveDistinct()
589 if (!parsedData
->getDistinct()) {
592 OrderTableImpl
*orderTable
= new OrderTableImpl();
593 orderTable
->setTable(table
);
594 orderTable
->setProjList(parsedData
->getFieldValueList());
595 orderTable
->setOrderByList(parsedData
->getFieldValueList());
596 orderTable
->setDistinct();
598 handleAggWithTbl
= false;
603 DbRetVal
SelStatement::resolveOrderByFld()
605 if (0 == parsedData
->getOrderFieldNameList().size()) {
608 OrderTableImpl
*orderTable
= new OrderTableImpl();
609 orderTable
->setTable(table
);
610 orderTable
->setProjList(parsedData
->getFieldValueList());
611 ListIterator giter
= parsedData
->getOrderFieldNameList().getIterator();
612 FieldName
*name
= NULL
;
614 FieldInfo
*fInfo
= new FieldInfo();
615 while (giter
.hasElement())
617 name
= (FieldName
*)giter
.nextElement();
618 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
619 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
622 printError(ErrSyntaxError
, "Field %s does not exist in table",
624 return ErrSyntaxError
;
626 /*FieldValue *newVal = new FieldValue();
627 strcpy(newVal->fldName,name->fldName);
628 newVal->parsedString = NULL;
630 newVal->type = fInfo->type;
631 newVal->isNullable = fInfo->isNull;
632 newVal->length = fInfo->length;
633 if (newVal->type == typeBinary)
634 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
635 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
636 newVal->isAllocVal=true;
637 parsedData->insertFieldValue(newVal);
639 if (name
->aType
== AGG_UNKNOWN
) orderTable
->setOrderBy(name
->fldName
);
640 else orderTable
->setOrderBy(name
->fldName
, true); //descending
644 handleAggWithTbl
= false;
648 DbRetVal
SelStatement::resolveGroupFld(AggTableImpl
*aggTable
)
650 if (!aggTable
) return OK
;
652 //check whether all non aggregate projections are from group list
653 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
654 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
655 FieldName
*name
= NULL
;
656 while (iter
.hasElement())
658 name
= (FieldName
*) iter
.nextElement();
659 if (name
->aType
== AGG_UNKNOWN
&& !isGroupFld(name
->fldName
) ) {
660 printError(ErrSyntaxError
, "Non aggregate projection contains non group field: %s", name
->fldName
);
661 return ErrSyntaxError
;
666 FieldInfo
*fInfo
= new FieldInfo();
667 while (giter
.hasElement())
669 name
= (FieldName
*)giter
.nextElement();
670 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
671 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
674 printError(ErrSyntaxError
, "Field %s does not exist in table",
676 return ErrSyntaxError
;
678 FieldValue
*newVal
= new FieldValue();
679 strcpy(newVal
->fldName
,name
->fldName
);
680 newVal
->parsedString
= NULL
;
682 newVal
->type
= fInfo
->type
;
683 newVal
->isNullable
= fInfo
->isNull
;
684 newVal
->length
= fInfo
->length
;
685 newVal
->offset
= fInfo
->offset
;
686 newVal
->isPrimary
= fInfo
->isPrimary
;
687 newVal
->isUnique
= fInfo
->isUnique
;
688 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
689 if (newVal
->type
== typeBinary
)
690 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
691 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
692 newVal
->isAllocVal
=true;
693 parsedData
->insertFieldValue(newVal
);
694 aggTable
->setGroup(name
->fldName
, newVal
->value
);
697 aggTable
->setCondition(parsedData
->getHavingCondition());
698 /*if (giter.hasElement())
700 printError(ErrSyntaxError, "Only one field allowed in group\n");
701 return ErrSyntaxError;
707 DbRetVal
SelStatement::resolveStar()
710 parsedData
->clearFieldNameList();
711 FieldValue
*newVal
= NULL
;
712 List fNameList
= table
->getFieldNameList();
713 ListIterator fNameIter
= fNameList
.getIterator();
714 //fNameList.resetIter(); //do not remove this.
715 FieldInfo
*fInfo
= new FieldInfo();
716 for (int i
= 0; i
< fNameList
.size() ; i
++)
718 char *fName
= ((Identifier
*)(fNameIter
.nextElement()))->name
;
719 rv
= table
->getFieldInfo(fName
, fInfo
);
720 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
724 printError(ErrSysFatal
, "Should never happen.");
727 newVal
= new FieldValue();
728 strcpy(newVal
->fldName
,fName
);
729 newVal
->parsedString
= NULL
;
731 newVal
->type
= fInfo
->type
;
732 newVal
->length
= fInfo
->length
;
733 newVal
->offset
= fInfo
->offset
;
734 newVal
->isPrimary
= fInfo
->isPrimary
;
735 newVal
->isUnique
= fInfo
->isUnique
;
736 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
738 // for binary datatype input buffer size should be 2 times the length
739 if(newVal
->type
== typeBinary
)
740 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
741 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
742 newVal
->isAllocVal
=true;
743 newVal
->isInResSet
= true;
744 parsedData
->insertFieldValue(newVal
);
745 parsedData
->insertField(fName
);
746 rv
= table
->bindFld(fName
, newVal
->value
);
753 while (fNameIter
.hasElement())
754 delete (Identifier
*) fNameIter
.nextElement();
760 DbRetVal
SelStatement::setBindFieldAndValues()
762 totalFields
= parsedData
->getFieldNameList().size();
763 bindFields
= (FieldValue
**) malloc ( totalFields
* sizeof(FieldValue
*));
764 bindFieldValues
= (char**) malloc( totalFields
* sizeof(char*));
765 memset(bindFields
, 0, totalFields
* sizeof(FieldValue
*));
766 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
767 ListIterator valIter
= parsedData
->getFieldValueList().getIterator();
769 FieldValue
*value
= NULL
;
770 //The second condition colNo < totalFields is important for projection list
771 //might not contain the binded having field.
772 while(valIter
.hasElement() && colNo
< totalFields
)
774 value
= (FieldValue
*) valIter
.nextElement();
777 free(bindFields
); bindFields
= NULL
;
778 free(bindFieldValues
); bindFieldValues
= NULL
;
779 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
782 bindFields
[colNo
++] = value
;
788 DbRetVal
SelStatement::resolveForCondition()
790 //get the fieldname list and validate field names
791 ListIterator iter
= parsedData
->getConditionValueList().getIterator();
793 ConditionValue
*value
;
794 FieldInfo
*fInfo
= new FieldInfo();
797 while (iter
.hasElement())
799 value
= (ConditionValue
*) iter
.nextElement();
803 printError(ErrSysFatal
, "Should never happen.");
806 if(!value
->isFunctionInvolve
){
807 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
808 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
811 printError(ErrSyntaxError
, "Field %s does not exist in table",
813 return ErrSyntaxError
;
815 if (value
->aType
== AGG_AVG
) {
816 value
->type
= typeDouble
;
817 value
->length
= sizeof(double);
818 } else if (value
->aType
== AGG_COUNT
) {
819 value
->type
= typeInt
;
820 value
->length
= sizeof(int);
822 value
->type
= fInfo
->type
;
823 value
->length
= fInfo
->length
;
825 value
->isNullable
= fInfo
->isNull
;
827 value
->type
= AllDataType::getCsqlTypeFromFunctionTypeForComparision(parsedData
->getFunctionType());
829 value
->value
= AllDataType::alloc(value
->type
, value
->length
);
830 //table->bindFld(name->fldName, value->value);
831 if(value
->paramNo
==1) continue;//For Predecate t1.f1=t2.f1
832 if (value
->parsedString
== NULL
)
835 printError(ErrSyntaxError
, "Condition value should not be NULL");
836 return ErrSyntaxError
;
838 if (value
->parsedString
[0] == '?')
840 //if(!value->opLike) // checks if 'LIKE' operator is used
841 value
->paramNo
= paramPos
++;
843 if (!value
->paramNo
) {
845 if (value
->type
== typeDate
|| value
->type
== typeTime
||
846 value
->type
== typeTimeStamp
)
847 parsedData
->setCacheWorthy(false);
848 if((value
->type
== typeInt
) || (value
->type
==typeShort
) ||
849 (value
->type
==typeByteInt
) || (value
->type
==typeLongLong
) ||
850 (value
->type
==typeLong
)) {
851 int len
=strlen(value
->parsedString
);
852 for(int n
=0;n
<len
;n
++){
853 int p
=value
->parsedString
[n
];
854 if(!(p
>=48 && p
<=57 || p
==45)) return ErrBadArg
;
858 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
859 AllDataType::strToValue(value
->value
, value
->parsedString
, value
->type
, value
->length
);
863 totalParams
= paramPos
-1;
864 if (0 == totalParams
) return OK
;
865 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
866 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
867 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
868 memset(paramValues
, 0, totalParams
* sizeof(char*));
870 while(iter
.hasElement())
872 value
= (ConditionValue
*) iter
.nextElement();
875 free(params
); params
= NULL
;
876 free(paramValues
); paramValues
= NULL
;
877 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
880 if (value
->paramNo
) params
[value
->paramNo
- 1] = value
;
884 bool SelStatement::isGroupFld(char *fieldName
)
886 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
887 FieldName
*name
= NULL
;
888 while (giter
.hasElement())
890 name
= (FieldName
*) giter
.nextElement();
891 if (0 == strcmp(name
->fldName
, fieldName
)) return true;
896 void* SelStatement::handleSingleTableAggWithoutGroup()
898 if (isPointReturned
) return NULL
;
899 TableImpl
*tblImpl
= (TableImpl
*)table
;
900 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
904 FieldValue
*fVal
= NULL
;
906 while (iter
.hasElement())
908 name
= (FieldName
*) iter
.nextElement();
909 fVal
= bindFields
[i
];
911 rv
= tblImpl
->fetchAgg(name
->fldName
, name
->aType
, fVal
->value
, noRec
);
912 if (OK
!= rv
) return NULL
;
914 tblImpl
->closeScan();
917 isPointReturned
= true;
918 if(noRec
&& name
->aType
!= AGG_COUNT
) return NULL
;
921 void* SelStatement::fetch()
926 tuple
= handleSingleTableAggWithoutGroup();
927 if (NULL
== tuple
) return NULL
;
929 if (isOffsetReached
) {
930 if (!isRecLimitReached
) {
931 tuple
= table
->fetch();
932 if (NULL
!= tuple
) numRecords
++;
933 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
938 while(recordOffset
<= parsedData
->getOffset()) {
939 tuple
= table
->fetch();
940 if (NULL
== tuple
) break;
943 isOffsetReached
= true;
944 if (NULL
!= tuple
) numRecords
++;
945 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
948 if (NULL
== tuple
) return NULL
;
950 //copy values to binded buffer
952 for (int i
= 0; i
< totalFields
; i
++)
954 value
= bindFields
[i
];
955 if (bindFieldValues
[i
] == NULL
)
957 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
960 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
965 void* SelStatement::fetch(DbRetVal
&rv
)
970 tuple
= handleSingleTableAggWithoutGroup();
971 if (NULL
== tuple
) return NULL
;
973 if (isOffsetReached
) {
974 if (!isRecLimitReached
) {
975 tuple
= table
->fetch(rv
);
976 if (NULL
!= tuple
) numRecords
++;
977 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
981 while(recordOffset
<= parsedData
->getOffset()) {
982 tuple
= table
->fetch(rv
);
983 if (NULL
== tuple
) break;
986 isOffsetReached
= true;
987 if (NULL
!= tuple
) numRecords
++;
988 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
991 if (NULL
== tuple
) return NULL
;
992 //copy values to binded buffer
994 for (int i
= 0; i
< totalFields
; i
++)
996 value
= bindFields
[i
];
997 if (bindFieldValues
[i
] == NULL
)
999 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
1002 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
1007 DbRetVal
SelStatement::close()
1009 isPointReturned
= false;
1010 if (table
) return table
->closeScan();
1014 void* SelStatement::getParamValuePtr( int pos
)
1016 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
1017 return ( (void*) p
->value
);
1020 char* SelStatement::getFieldName ( int pos
)
1022 //TODO::if not yet prepared return error
1023 //TODO::check the upper limit for projpos
1024 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1026 while (iter
.hasElement())
1028 FieldName
*name
= (FieldName
*) iter
.nextElement();
1029 if (position
== pos
) {
1032 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
1035 return name
->fldName
;
1042 DataType
SelStatement::getFieldType( int pos
)
1044 FieldValue
*v
= bindFields
[pos
];
1045 return ( (DataType
) v
->type
);
1048 int SelStatement::getFieldLength( int pos
)
1050 FieldValue
*v
= bindFields
[pos
];
1051 return ( (int) v
->type
);
1054 void* SelStatement::fetchAndPrint(bool SQL
)
1057 if(handleAggWithTbl
)
1059 tuple
= handleSingleTableAggWithoutGroup();
1061 if (isOffsetReached
) {
1062 if (!isRecLimitReached
) {
1063 tuple
= table
->fetch();
1064 if (NULL
!= tuple
) numRecords
++;
1065 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1069 int recordOffset
=0;
1070 while(recordOffset
<= parsedData
->getOffset()) {
1071 tuple
= table
->fetch();
1072 if (NULL
== tuple
) break;
1075 isOffsetReached
= true;
1076 if (NULL
!= tuple
) numRecords
++;
1077 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1080 if (NULL
== tuple
) return NULL
;
1085 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
1088 for (int i
= 0; i
< totalFields
; i
++)
1090 value
= bindFields
[i
];
1091 if (!value
->isInResSet
) continue;
1092 nullValueSet
= table
->isFldNull(value
->fldName
);
1100 else if (value
->aType
!= AGG_COUNT
) printf("NULL\t");
1127 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
1139 } else printf("\t");
1142 if (SQL
) printf(");\n");
1146 void* SelStatement::next()
1148 if(handleAggWithTbl
)
1150 return handleSingleTableAggWithoutGroup();
1152 return( table
->fetch() );
1156 void* SelStatement::getFieldValuePtr( int pos
)
1158 FieldValue
*v
= bindFields
[pos
];
1159 return ( (void*) v
->value
);
1162 void* SelStatement::getFieldValuePtr( char *name
)
1165 char fName
[IDENTIFIER_LENGTH
];
1166 for (int i
= 0; i
< totalFields
; i
++)
1168 value
= bindFields
[i
];
1169 table
->getFieldNameAlone(value
->fldName
,fName
);
1170 if (strcmp(fName
,name
)==0)
1172 return ( (void*) value
->value
);
1178 void SelStatement::getProjFieldType(int *data
)
1181 for (int i
= 0; i
< totalFields
; i
++)
1183 value
= bindFields
[i
];
1184 data
[i
+1] = value
->type
;
1188 int SelStatement::noOfProjFields()
1193 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
1197 //TODO::if not yet prepared return error
1198 //TODO::check the upper limit for projpos
1199 if (projpos
< 0 || projpos
>totalFields
) return ErrBadArg
;
1200 FieldValue
*value
= bindFields
[projpos
-1];
1201 fInfo
->type
= value
->type
;
1202 fInfo
->length
= value
->length
;
1203 fInfo
->isNull
= value
->isNullable
;
1204 fInfo
->aType
= value
->aType
;
1205 fInfo
->offset
= value
->offset
;
1206 fInfo
->isPrimary
= value
->isPrimary
;
1207 fInfo
->isUnique
= value
->isUnique
;
1208 fInfo
->isAutoIncrement
= value
->isAutoIncrement
;
1209 fInfo
->isDefault
= value
->isDefault
;
1210 if (fInfo
->aType
== AGG_UNKNOWN
) {
1211 strcpy(fInfo
->fldName
, value
->fldName
);
1212 if (fInfo
->isDefault
) strcpy(fInfo
->defaultValueBuf
, value
->defValBuf
);
1215 switch(fInfo
->aType
)
1218 sprintf(fInfo
->fldName
, "COUNT(%s)", value
->fldName
);
1219 fInfo
->type
= typeInt
;
1220 fInfo
->length
= sizeof(int);
1223 sprintf(fInfo
->fldName
, "MIN(%s)", value
->fldName
);
1226 sprintf(fInfo
->fldName
, "MAX(%s)", value
->fldName
);
1229 sprintf(fInfo
->fldName
, "SUM(%s)", value
->fldName
);
1232 sprintf(fInfo
->fldName
, "AVG(%s)", value
->fldName
);
1233 fInfo
->type
= typeDouble
;
1234 fInfo
->length
= sizeof(double);
1237 strcpy(fInfo
->fldName
, value
->fldName
);
1242 int SelStatement::getFldPos(char *name
)
1244 return table
->getFldPos(name
);
1247 bool SelStatement::isInProjectionList(char *name
, AggType aType
)
1249 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1250 FieldName
*fldName
= NULL
;
1251 while (iter
.hasElement()) {
1252 fldName
= (FieldName
*) iter
.nextElement();
1253 if ((strcmp(fldName
->fldName
, name
)==0) && fldName
->aType
== aType
) {