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 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
807 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
810 printError(ErrSyntaxError
, "Field %s does not exist in table",
812 return ErrSyntaxError
;
814 if (value
->aType
== AGG_AVG
) {
815 value
->type
= typeDouble
;
816 value
->length
= sizeof(double);
817 } else if (value
->aType
== AGG_COUNT
) {
818 value
->type
= typeInt
;
819 value
->length
= sizeof(int);
821 value
->type
= fInfo
->type
;
822 value
->length
= fInfo
->length
;
824 value
->isNullable
= fInfo
->isNull
;
825 value
->value
= AllDataType::alloc(value
->type
, value
->length
);
826 //table->bindFld(name->fldName, value->value);
827 if(value
->paramNo
==1) continue;//For Predecate t1.f1=t2.f1
828 if (value
->parsedString
== NULL
)
831 printError(ErrSyntaxError
, "Condition value should not be NULL");
832 return ErrSyntaxError
;
834 if (value
->parsedString
[0] == '?')
836 //if(!value->opLike) // checks if 'LIKE' operator is used
837 value
->paramNo
= paramPos
++;
839 if (!value
->paramNo
) {
841 if (value
->type
== typeDate
|| value
->type
== typeTime
||
842 value
->type
== typeTimeStamp
)
843 parsedData
->setCacheWorthy(false);
845 if((value
->type
== typeInt
) || (value
->type
==typeShort
) || (value
->type
==typeByteInt
) || (value
->type
==typeLongLong
) || (value
->type
==typeLong
)){
846 int len
=strlen(value
->parsedString
);
847 for(int n
=0;n
<len
;n
++){
848 int p
=value
->parsedString
[n
];
849 if(!(p
>=48 && p
<=57 || p
==45))
854 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
855 AllDataType::strToValue(value
->value
, value
->parsedString
, value
->type
, value
->length
);
859 totalParams
= paramPos
-1;
860 if (0 == totalParams
) return OK
;
861 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
862 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
863 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
864 memset(paramValues
, 0, totalParams
* sizeof(char*));
866 while(iter
.hasElement())
868 value
= (ConditionValue
*) iter
.nextElement();
871 free(params
); params
= NULL
;
872 free(paramValues
); paramValues
= NULL
;
873 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
876 params
[value
->paramNo
-1 ] = value
;
880 bool SelStatement::isGroupFld(char *fieldName
)
882 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
883 FieldName
*name
= NULL
;
884 while (giter
.hasElement())
886 name
= (FieldName
*) giter
.nextElement();
887 if (0 == strcmp(name
->fldName
, fieldName
)) return true;
892 void* SelStatement::handleSingleTableAggWithoutGroup()
894 if (isPointReturned
) return NULL
;
895 TableImpl
*tblImpl
= (TableImpl
*)table
;
896 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
900 FieldValue
*fVal
= NULL
;
902 while (iter
.hasElement())
904 name
= (FieldName
*) iter
.nextElement();
905 fVal
= bindFields
[i
];
907 rv
= tblImpl
->fetchAgg(name
->fldName
, name
->aType
, fVal
->value
, noRec
);
908 if (OK
!= rv
) return NULL
;
910 tblImpl
->closeScan();
913 isPointReturned
= true;
914 if(noRec
&& name
->aType
!= AGG_COUNT
) return NULL
;
917 void* SelStatement::fetch()
922 tuple
= handleSingleTableAggWithoutGroup();
923 if (NULL
== tuple
) return NULL
;
925 if (isOffsetReached
) {
926 if (!isRecLimitReached
) {
927 tuple
= table
->fetch();
928 if (NULL
!= tuple
) numRecords
++;
929 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
934 while(recordOffset
<= parsedData
->getOffset()) {
935 tuple
= table
->fetch();
936 if (NULL
== tuple
) break;
939 isOffsetReached
= true;
940 if (NULL
!= tuple
) numRecords
++;
941 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
944 if (NULL
== tuple
) return NULL
;
946 //copy values to binded buffer
948 for (int i
= 0; i
< totalFields
; i
++)
950 value
= bindFields
[i
];
951 if (bindFieldValues
[i
] == NULL
)
953 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
956 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
961 void* SelStatement::fetch(DbRetVal
&rv
)
966 tuple
= handleSingleTableAggWithoutGroup();
967 if (NULL
== tuple
) return NULL
;
969 if (isOffsetReached
) {
970 if (!isRecLimitReached
) {
971 tuple
= table
->fetch(rv
);
972 if (NULL
!= tuple
) numRecords
++;
973 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
977 while(recordOffset
<= parsedData
->getOffset()) {
978 tuple
= table
->fetch(rv
);
979 if (NULL
== tuple
) break;
982 isOffsetReached
= true;
983 if (NULL
!= tuple
) numRecords
++;
984 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
987 if (NULL
== tuple
) return NULL
;
988 //copy values to binded buffer
990 for (int i
= 0; i
< totalFields
; i
++)
992 value
= bindFields
[i
];
993 if (bindFieldValues
[i
] == NULL
)
995 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
998 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
1003 DbRetVal
SelStatement::close()
1005 isPointReturned
= false;
1006 if (table
) return table
->closeScan();
1010 void* SelStatement::getParamValuePtr( int pos
)
1012 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
1013 return ( (void*) p
->value
);
1016 char* SelStatement::getFieldName ( int pos
)
1018 //TODO::if not yet prepared return error
1019 //TODO::check the upper limit for projpos
1020 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1022 while (iter
.hasElement())
1024 FieldName
*name
= (FieldName
*) iter
.nextElement();
1025 if (position
== pos
) {
1028 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
1031 return name
->fldName
;
1038 DataType
SelStatement::getFieldType( int pos
)
1040 FieldValue
*v
= bindFields
[pos
];
1041 return ( (DataType
) v
->type
);
1044 int SelStatement::getFieldLength( int pos
)
1046 FieldValue
*v
= bindFields
[pos
];
1047 return ( (int) v
->type
);
1050 void* SelStatement::fetchAndPrint(bool SQL
)
1053 if(handleAggWithTbl
)
1055 tuple
= handleSingleTableAggWithoutGroup();
1057 if (isOffsetReached
) {
1058 if (!isRecLimitReached
) {
1059 tuple
= table
->fetch();
1060 if (NULL
!= tuple
) numRecords
++;
1061 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1065 int recordOffset
=0;
1066 while(recordOffset
<= parsedData
->getOffset()) {
1067 tuple
= table
->fetch();
1068 if (NULL
== tuple
) break;
1071 isOffsetReached
= true;
1072 if (NULL
!= tuple
) numRecords
++;
1073 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1076 if (NULL
== tuple
) return NULL
;
1081 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
1084 for (int i
= 0; i
< totalFields
; i
++)
1086 value
= bindFields
[i
];
1087 if (!value
->isInResSet
) continue;
1088 nullValueSet
= table
->isFldNull(value
->fldName
);
1096 else if (value
->aType
!= AGG_COUNT
) printf("NULL\t");
1122 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
1133 } else printf("\t");
1136 if (SQL
) printf(");\n");
1140 void* SelStatement::next()
1142 if(handleAggWithTbl
)
1144 return handleSingleTableAggWithoutGroup();
1146 return( table
->fetch() );
1150 void* SelStatement::getFieldValuePtr( int pos
)
1152 FieldValue
*v
= bindFields
[pos
];
1153 return ( (void*) v
->value
);
1156 void* SelStatement::getFieldValuePtr( char *name
)
1159 char fName
[IDENTIFIER_LENGTH
];
1160 for (int i
= 0; i
< totalFields
; i
++)
1162 value
= bindFields
[i
];
1163 table
->getFieldNameAlone(value
->fldName
,fName
);
1164 if (strcmp(fName
,name
)==0)
1166 return ( (void*) value
->value
);
1172 void SelStatement::getProjFieldType(int *data
)
1175 for (int i
= 0; i
< totalFields
; i
++)
1177 value
= bindFields
[i
];
1178 data
[i
+1] = value
->type
;
1182 int SelStatement::noOfProjFields()
1187 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
1191 //TODO::if not yet prepared return error
1192 //TODO::check the upper limit for projpos
1193 if (projpos
< 0 || projpos
>totalFields
) return ErrBadArg
;
1194 FieldValue
*value
= bindFields
[projpos
-1];
1195 fInfo
->type
= value
->type
;
1196 fInfo
->length
= value
->length
;
1197 fInfo
->isNull
= value
->isNullable
;
1198 fInfo
->aType
= value
->aType
;
1199 fInfo
->offset
= value
->offset
;
1200 fInfo
->isPrimary
= value
->isPrimary
;
1201 fInfo
->isUnique
= value
->isUnique
;
1202 fInfo
->isAutoIncrement
= value
->isAutoIncrement
;
1203 fInfo
->isDefault
= value
->isDefault
;
1204 if (fInfo
->aType
== AGG_UNKNOWN
) {
1205 strcpy(fInfo
->fldName
, value
->fldName
);
1206 if (fInfo
->isDefault
) strcpy(fInfo
->defaultValueBuf
, value
->defValBuf
);
1209 switch(fInfo
->aType
)
1212 sprintf(fInfo
->fldName
, "COUNT(%s)", value
->fldName
);
1213 fInfo
->type
= typeInt
;
1214 fInfo
->length
= sizeof(int);
1217 sprintf(fInfo
->fldName
, "MIN(%s)", value
->fldName
);
1220 sprintf(fInfo
->fldName
, "MAX(%s)", value
->fldName
);
1223 sprintf(fInfo
->fldName
, "SUM(%s)", value
->fldName
);
1226 sprintf(fInfo
->fldName
, "AVG(%s)", value
->fldName
);
1227 fInfo
->type
= typeDouble
;
1228 fInfo
->length
= sizeof(double);
1231 strcpy(fInfo
->fldName
, value
->fldName
);
1236 int SelStatement::getFldPos(char *name
)
1238 return table
->getFldPos(name
);
1241 bool SelStatement::isInProjectionList(char *name
, AggType aType
)
1243 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1244 FieldName
*fldName
= NULL
;
1245 while (iter
.hasElement()) {
1246 fldName
= (FieldName
*) iter
.nextElement();
1247 if ((strcmp(fldName
->fldName
, name
)==0) && fldName
->aType
== aType
) {