1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 ***************************************************************************/
17 #include <Statement.h>
18 #include <TableImpl.h>
19 #include <OrderTableImpl.h>
21 SelStatement::SelStatement()
30 bindFieldValues
= NULL
;
32 isPointReturned
= false;
33 handleAggWithTbl
=false;
35 isOffsetReached
= false;
36 isRecLimitReached
= false;
41 SelStatement::~SelStatement()
44 if (table
) { table
->close(); table
= NULL
; }
55 free(bindFieldValues
);
56 bindFieldValues
= NULL
;
60 DbRetVal
SelStatement::getParamFldInfo(int paramNo
, FieldInfo
*&info
)
62 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
63 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
66 printError(ErrSysFatal
, "condition value is null. Should never happen");
69 table
->getFieldNameAlone(cValue
->fName
,info
->fldName
);
70 info
->type
= cValue
->type
;
71 info
->length
= cValue
->length
;
72 info
->isNull
= cValue
->isNullable
;
75 DbRetVal
SelStatement::execute(int &rowsAffected
)
78 //copy param values to binded buffer
79 ConditionValue
*value
;
80 for (int i
= 0; i
< totalParams
; i
++)
82 value
= (ConditionValue
*) params
[i
];
83 if (paramValues
[i
] == NULL
)
86 //printError(ErrBadCall, "param values not set");
89 AllDataType::copyVal(value
->value
, paramValues
[i
], value
->type
, value
->length
);
91 //table->printPlan(0);
92 //printf("Execute Called\n");
93 rv
= table
->execute();
95 isOffsetReached
= false;
96 isRecLimitReached
= false;
98 if (isExplain
) table
->printPlan(0);
102 DbRetVal
SelStatement::setParam(int paramNo
, void *value
)
104 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
105 if (NULL
== value
) return ErrBadArg
;
106 paramValues
[paramNo
-1] = (char*) value
;
110 DbRetVal
SelStatement::setShortParam(int paramNo
, short value
)
112 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
113 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
116 printError(ErrSysFatal
, "field value is null. Should never happen");
119 *(short*)cValue
->value
= value
;
123 DbRetVal
SelStatement::setIntParam(int paramNo
, int value
)
125 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
126 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
129 printError(ErrSysFatal
, "condition value is null. Should never happen");
132 *(int*)cValue
->value
= value
;
135 DbRetVal
SelStatement::setLongParam(int paramNo
, long value
)
137 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
138 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
141 printError(ErrSysFatal
, "condition value is null. Should never happen");
144 *(long*)cValue
->value
= value
;
148 DbRetVal
SelStatement::setLongLongParam(int paramNo
, long long value
)
150 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
151 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
154 printError(ErrSysFatal
, "condition value is null. Should never happen");
157 *(long long*)cValue
->value
= value
;
160 DbRetVal
SelStatement::setByteIntParam(int paramNo
, ByteInt value
)
162 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
163 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
166 printError(ErrSysFatal
, "condition value is null. Should never happen");
169 *(ByteInt
*)cValue
->value
= value
;
172 DbRetVal
SelStatement::setFloatParam(int paramNo
, float value
)
174 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
175 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
178 printError(ErrSysFatal
, "condition value is null. Should never happen");
181 *(float*)cValue
->value
= value
;
184 DbRetVal
SelStatement::setDoubleParam(int paramNo
, double value
)
186 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
187 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
190 printError(ErrSysFatal
, "condition value is null. Should never happen");
193 *(double*)cValue
->value
= value
;
196 DbRetVal
SelStatement::setStringParam(int paramNo
, char *value
)
198 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
199 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
202 printError(ErrSysFatal
, "condition value is null. Should never happen");
205 strcpy((char*)cValue
->value
, value
);
208 DbRetVal
SelStatement::setDateParam(int paramNo
, Date value
)
210 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
211 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
214 printError(ErrSysFatal
, "condition value is null. Should never happen");
217 *(Date
*)cValue
->value
= value
;
220 DbRetVal
SelStatement::setTimeParam(int paramNo
, Time value
)
222 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
223 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
226 printError(ErrSysFatal
, "condition value is null. Should never happen");
229 *(Time
*)cValue
->value
= value
;
232 DbRetVal
SelStatement::setTimeStampParam(int paramNo
, TimeStamp value
)
234 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
235 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
238 printError(ErrSysFatal
, "condition value is null. Should never happen");
241 *(TimeStamp
*)cValue
->value
= value
;
245 DbRetVal
SelStatement::setBinaryParam(int paramNo
, void *value
, int length
)
247 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
248 ConditionValue
*cValue
= (ConditionValue
*) params
[paramNo
-1];
251 printError(ErrSysFatal
, "condition value is null. Should never happen");
254 AllDataType::convertToBinary(cValue
->value
,value
,typeString
,cValue
->length
);
258 DbRetVal
SelStatement::setBindField(int colNo
, void *value
)
260 if (colNo
<=0) return ErrBadArg
;
261 //TODO: check the upper limit
262 //if (colNo > table->getFieldNameList().size()) return ErrBadArg;
263 if (NULL
== value
) return ErrBadArg
;
264 bindFieldValues
[colNo
-1] = (char*) value
;
267 bool SelStatement::isTableAlreadyPresent(char *tblName
, char *aliasName
)
269 ListIterator titer
= parsedData
->getTableNameList().getIterator();
271 while (titer
.hasElement())
273 TableName
*t
= (TableName
*)titer
.nextElement();
274 if (strcmp(t
->tblName
, tblName
) ==0 &&
275 strcmp(t
->aliasName
, aliasName
) ==0) count
++;
277 if (count
== 1) return false;
280 DbRetVal
SelStatement::openTables()
282 if (dbMgr
== NULL
) return ErrNoConnection
;
283 JoinTableImpl
*jHdl
= NULL
;
284 Table
*tHdl
= NULL
, *prevHdl
= NULL
;
286 //check whether all the table exists
287 ListIterator titer
= parsedData
->getTableNameList().getIterator();
288 ListIterator jiter
= parsedData
->getJoinTypeList().getIterator();
289 while (titer
.hasElement())
291 TableName
*t
= (TableName
*)titer
.nextElement();
292 parsedData
->setTableName(t
->tblName
);
293 if (isTableAlreadyPresent(t
->tblName
, t
->aliasName
)) {
294 printError(ErrSyntaxError
,
295 "Referencing same table again %s", t
->tblName
);
296 if (prevHdl
) delete prevHdl
;
297 return ErrSyntaxError
;
299 tHdl
= dbMgr
->openTable(t
->tblName
);
302 printError(ErrNotExists
,
303 "Unable to open the table:Table not exists");
304 if (prevHdl
) delete prevHdl
;
307 TableImpl
*tImpl
= (TableImpl
*) tHdl
;
308 tImpl
->setAliasName(t
->aliasName
);
312 jHdl
= new JoinTableImpl();
313 jHdl
->setTable(prevHdl
, tHdl
);
314 JoinTypeNode
*node
= (JoinTypeNode
*) jiter
.nextElement();
316 printError(ErrSyntaxError
,
317 "Join Type and number of tables do not match");
319 return ErrSyntaxError
;
321 jHdl
->setJoinType(node
->jType
);
328 if (isJoin
) table
= jHdl
; else table
= tHdl
;
331 DbRetVal
SelStatement::resolve()
333 DbRetVal rv
= openTables();
334 if (rv
!= OK
) return rv
;
335 //get the fieldname list and validate field names
336 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
337 FieldName
*name
= NULL
;
338 FieldInfo
*fInfo
= new FieldInfo();
340 bool isSingleTableNoGrp
= false;
341 if(parsedData
->getTableNameList().size() == 1 &&
342 parsedData
->getGroupFieldNameList().size() == 0)
344 isSingleTableNoGrp
= true;
346 AggTableImpl
*aggTable
= NULL
;
347 while (iter
.hasElement())
349 name
= (FieldName
*)iter
.nextElement();
352 dbMgr
->closeTable(table
);
355 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
358 bool isBindFld
=false;
359 if ('*' == name
->fldName
[0] && name
->aType
== AGG_UNKNOWN
)
364 dbMgr
->closeTable(table
);
369 if (parsedData
->getGroupFieldNameList().size()!= 0
370 && !isSingleTableNoGrp
)
373 aggTable
= new AggTableImpl();
374 aggTable
->setTable(table
);
376 //as soon as it encounters *, it breaks the loop negleting other field names
377 //as they all are deleted during resolveStar method.
380 if ('*' == name
->fldName
[0] && name
->aType
!= AGG_COUNT
) {return ErrSyntaxError
;}
381 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
382 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
384 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
385 else dbMgr
->closeTable(table
);
388 printError(ErrSyntaxError
, "Field %s does not exist in table",
390 return ErrSyntaxError
;
392 FieldValue
*newVal
= new FieldValue();
393 strcpy(newVal
->fldName
,name
->fldName
);
394 newVal
->parsedString
= NULL
;
396 newVal
->aType
= name
->aType
;
397 newVal
->isInResSet
= true;
398 newVal
->offset
= fInfo
->offset
;
399 newVal
->isPrimary
= fInfo
->isPrimary
;
400 newVal
->isUnique
= fInfo
->isUnique
;
401 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
402 newVal
->isDefault
= fInfo
->isDefault
;
403 if (newVal
->isDefault
)
404 strcpy(newVal
->defValBuf
, fInfo
->defaultValueBuf
);
405 else newVal
->defValBuf
[0] ='\0';
406 if (name
->aType
== AGG_COUNT
) {
407 newVal
->type
= typeInt
;
408 newVal
->length
= sizeof(int);
410 else if (name
->aType
== AGG_AVG
) {
411 newVal
->type
= typeDouble
;
412 newVal
->length
= sizeof(double);
413 if (!AllDataType::isValidFieldForAvg(fInfo
->type
)) {
414 printError(ErrBadArg
, "Illegal operation for field %s",
416 dbMgr
->closeTable(table
);
417 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
424 newVal
->type
= fInfo
->type
;
425 newVal
->length
= fInfo
->length
;
427 newVal
->isNullable
= fInfo
->isNull
;
428 FieldName
*bFldName
=NULL
;
429 ListIterator it
= bindFldList
.getIterator();
430 while (it
.hasElement())
432 bFldName
= (FieldName
*)it
.nextElement();
433 if(0==strcmp(bFldName
->fldName
,name
->fldName
) &&
434 name
->aType
== AGG_UNKNOWN
)
436 newVal
->value
=table
->getBindFldAddr(name
->fldName
);
437 newVal
->isAllocVal
=false;
443 if ( name
->aType
== AGG_UNKNOWN
||
444 (name
->aType
!= AGG_COUNT
&&
445 name
->aType
!= AGG_AVG
) ) {
446 if(newVal
->type
== typeBinary
)
447 newVal
->value
= AllDataType::alloc(fInfo
->type
,
449 else newVal
->value
= AllDataType::alloc(fInfo
->type
,
452 if (name
->aType
== AGG_AVG
) {
453 newVal
->value
= AllDataType::alloc(typeDouble
,
455 memset(newVal
->value
, 0, sizeof(double));
457 else if (name
->aType
== AGG_COUNT
) {
458 newVal
->value
= AllDataType::alloc(typeInt
,
460 memset(newVal
->value
, 0, sizeof(int));
464 newVal
->isAllocVal
=true;
466 if (name
->aType
==AGG_UNKNOWN
&&
467 parsedData
->getGroupFieldNameList().size()== 0) {
468 rv
= table
->bindFld(name
->fldName
, newVal
->value
);
469 if (OK
!=rv
) return rv
;
471 else if (!isSingleTableNoGrp
)
474 aggTable
= new AggTableImpl();
475 aggTable
->setTable(table
);
477 rv
= aggTable
->bindFld(name
->fldName
, name
->aType
, newVal
->value
);
478 if (OK
!=rv
) return rv
;
480 if (name
->aType
!=AGG_UNKNOWN
&& isSingleTableNoGrp
)
481 handleAggWithTbl
= true;
482 parsedData
->insertFieldValue(newVal
);
484 if (!isBindFld
) bindFldList
.append(name
);
488 //Check if the having list is present in projection list or not.
489 //If not present bind here not to be printed in fetchAndPrint later.
490 ListIterator hiter
= parsedData
->getHavingFieldNameList().getIterator();
491 while (hiter
.hasElement()) {
492 FieldName
*fnm
= (FieldName
*) hiter
.nextElement();
493 rv
= table
->getFieldInfo(fnm
->fldName
, fInfo
);
494 if (!isInProjectionList(fnm
->fldName
, fnm
->aType
)) {
495 FieldValue
*newVal
= new FieldValue();
496 strcpy(newVal
->fldName
,fnm
->fldName
);
497 newVal
->parsedString
= NULL
;
499 newVal
->aType
= fnm
->aType
;
500 newVal
->isInResSet
= false;
501 newVal
->isNullable
= fInfo
->isNull
;
502 newVal
->offset
= fInfo
->offset
;
503 newVal
->isPrimary
= fInfo
->isPrimary
;
504 newVal
->isUnique
= fInfo
->isUnique
;
505 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
506 if (fnm
->aType
== AGG_AVG
) {
507 newVal
->value
= AllDataType::alloc(typeDouble
, sizeof(double));
508 memset(newVal
->value
, 0, sizeof(double));
509 } else if (fnm
->aType
== AGG_COUNT
) {
510 newVal
->value
= AllDataType::alloc(typeInt
, sizeof(int));
511 memset(newVal
->value
, 0, sizeof(int));
513 newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
514 memset(newVal
->value
, 0, fInfo
->length
);
516 newVal
->isAllocVal
= true;
517 parsedData
->insertFieldValue(newVal
);
518 aggTable
->bindFld(fnm
->fldName
, fnm
->aType
, newVal
->value
);
522 rv
= setBindFieldAndValues();
526 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
527 else dbMgr
->closeTable(table
);
532 table
->setCondition(parsedData
->getCondition());
534 rv
= resolveForCondition();
538 //TODO::free memory allocated for params
539 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
541 table
->setCondition(NULL
);
542 dbMgr
->closeTable(table
);
547 rv
= resolveGroupFld(aggTable
);
551 //TODO::free memory allocated for params
552 if (aggTable
) { delete aggTable
; aggTable
= NULL
; }
555 table
->setCondition(NULL
);
556 dbMgr
->closeTable(table
);
562 rv
= resolveOrderByFld();
570 rv
= resolveDistinct();
572 if(parsedData
->getExplain()) isExplain
= true;
575 DbRetVal
SelStatement::resolveDistinct()
577 if (!parsedData
->getDistinct()) {
580 OrderTableImpl
*orderTable
= new OrderTableImpl();
581 orderTable
->setTable(table
);
582 orderTable
->setProjList(parsedData
->getFieldValueList());
583 orderTable
->setOrderByList(parsedData
->getFieldValueList());
584 orderTable
->setDistinct();
586 handleAggWithTbl
= false;
591 DbRetVal
SelStatement::resolveOrderByFld()
593 if (0 == parsedData
->getOrderFieldNameList().size()) {
596 OrderTableImpl
*orderTable
= new OrderTableImpl();
597 orderTable
->setTable(table
);
598 orderTable
->setProjList(parsedData
->getFieldValueList());
599 ListIterator giter
= parsedData
->getOrderFieldNameList().getIterator();
600 FieldName
*name
= NULL
;
602 FieldInfo
*fInfo
= new FieldInfo();
603 while (giter
.hasElement())
605 name
= (FieldName
*)giter
.nextElement();
606 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
607 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
610 printError(ErrSyntaxError
, "Field %s does not exist in table",
612 return ErrSyntaxError
;
614 /*FieldValue *newVal = new FieldValue();
615 strcpy(newVal->fldName,name->fldName);
616 newVal->parsedString = NULL;
618 newVal->type = fInfo->type;
619 newVal->isNullable = fInfo->isNull;
620 newVal->length = fInfo->length;
621 if (newVal->type == typeBinary)
622 newVal->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
623 else newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
624 newVal->isAllocVal=true;
625 parsedData->insertFieldValue(newVal);
627 if (name
->aType
== AGG_UNKNOWN
) orderTable
->setOrderBy(name
->fldName
);
628 else orderTable
->setOrderBy(name
->fldName
, true); //descending
632 handleAggWithTbl
= false;
636 DbRetVal
SelStatement::resolveGroupFld(AggTableImpl
*aggTable
)
638 if (!aggTable
) return OK
;
640 //check whether all non aggregate projections are from group list
641 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
642 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
643 FieldName
*name
= NULL
;
644 while (iter
.hasElement())
646 name
= (FieldName
*) iter
.nextElement();
647 if (name
->aType
== AGG_UNKNOWN
&& !isGroupFld(name
->fldName
) ) {
648 printError(ErrSyntaxError
, "Non aggregate projection contains non group field: %s", name
->fldName
);
649 return ErrSyntaxError
;
654 FieldInfo
*fInfo
= new FieldInfo();
655 while (giter
.hasElement())
657 name
= (FieldName
*)giter
.nextElement();
658 rv
= table
->getFieldInfo(name
->fldName
, fInfo
);
659 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
662 printError(ErrSyntaxError
, "Field %s does not exist in table",
664 return ErrSyntaxError
;
666 FieldValue
*newVal
= new FieldValue();
667 strcpy(newVal
->fldName
,name
->fldName
);
668 newVal
->parsedString
= NULL
;
670 newVal
->type
= fInfo
->type
;
671 newVal
->isNullable
= fInfo
->isNull
;
672 newVal
->length
= fInfo
->length
;
673 newVal
->offset
= fInfo
->offset
;
674 newVal
->isPrimary
= fInfo
->isPrimary
;
675 newVal
->isUnique
= fInfo
->isUnique
;
676 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
677 if (newVal
->type
== typeBinary
)
678 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
679 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
680 newVal
->isAllocVal
=true;
681 parsedData
->insertFieldValue(newVal
);
682 aggTable
->setGroup(name
->fldName
, newVal
->value
);
685 aggTable
->setCondition(parsedData
->getHavingCondition());
686 /*if (giter.hasElement())
688 printError(ErrSyntaxError, "Only one field allowed in group\n");
689 return ErrSyntaxError;
695 DbRetVal
SelStatement::resolveStar()
698 parsedData
->clearFieldNameList();
699 FieldValue
*newVal
= NULL
;
700 List fNameList
= table
->getFieldNameList();
701 ListIterator fNameIter
= fNameList
.getIterator();
702 //fNameList.resetIter(); //do not remove this.
703 FieldInfo
*fInfo
= new FieldInfo();
704 for (int i
= 0; i
< fNameList
.size() ; i
++)
706 char *fName
= ((Identifier
*)(fNameIter
.nextElement()))->name
;
707 rv
= table
->getFieldInfo(fName
, fInfo
);
708 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
712 printError(ErrSysFatal
, "Should never happen.");
715 newVal
= new FieldValue();
716 strcpy(newVal
->fldName
,fName
);
717 newVal
->parsedString
= NULL
;
719 newVal
->type
= fInfo
->type
;
720 newVal
->length
= fInfo
->length
;
721 newVal
->offset
= fInfo
->offset
;
722 newVal
->isPrimary
= fInfo
->isPrimary
;
723 newVal
->isUnique
= fInfo
->isUnique
;
724 newVal
->isAutoIncrement
= fInfo
->isAutoIncrement
;
726 // for binary datatype input buffer size should be 2 times the length
727 if(newVal
->type
== typeBinary
)
728 newVal
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
729 else newVal
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
730 newVal
->isAllocVal
=true;
731 newVal
->isInResSet
= true;
732 parsedData
->insertFieldValue(newVal
);
733 parsedData
->insertField(fName
);
734 rv
= table
->bindFld(fName
, newVal
->value
);
741 while (fNameIter
.hasElement())
742 delete (Identifier
*) fNameIter
.nextElement();
748 DbRetVal
SelStatement::setBindFieldAndValues()
750 totalFields
= parsedData
->getFieldNameList().size();
751 bindFields
= (FieldValue
**) malloc ( totalFields
* sizeof(FieldValue
*));
752 bindFieldValues
= (char**) malloc( totalFields
* sizeof(char*));
753 memset(bindFields
, 0, totalFields
* sizeof(FieldValue
*));
754 memset(bindFieldValues
, 0, totalFields
* sizeof(char*));
755 ListIterator valIter
= parsedData
->getFieldValueList().getIterator();
757 FieldValue
*value
= NULL
;
759 while(valIter
.hasElement())
761 value
= (FieldValue
*) valIter
.nextElement();
764 free(bindFields
); bindFields
= NULL
;
765 free(bindFieldValues
); bindFieldValues
= NULL
;
766 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
769 bindFields
[colNo
++ ] = value
;
775 DbRetVal
SelStatement::resolveForCondition()
777 //get the fieldname list and validate field names
778 ListIterator iter
= parsedData
->getConditionValueList().getIterator();
780 ConditionValue
*value
;
781 FieldInfo
*fInfo
= new FieldInfo();
784 while (iter
.hasElement())
786 value
= (ConditionValue
*) iter
.nextElement();
790 printError(ErrSysFatal
, "Should never happen.");
793 rv
= table
->getFieldInfo(value
->fName
, fInfo
);
794 if (ErrNotFound
== rv
|| ErrNotExists
== rv
)
797 printError(ErrSyntaxError
, "Field %s does not exist in table",
799 return ErrSyntaxError
;
801 if (value
->aType
== AGG_AVG
) {
802 value
->type
= typeDouble
;
803 value
->length
= sizeof(double);
804 } else if (value
->aType
== AGG_COUNT
) {
805 value
->type
= typeInt
;
806 value
->length
= sizeof(int);
808 value
->type
= fInfo
->type
;
809 value
->length
= fInfo
->length
;
811 value
->isNullable
= fInfo
->isNull
;
812 value
->value
= AllDataType::alloc(value
->type
, value
->length
);
813 //table->bindFld(name->fldName, value->value);
814 if(value
->paramNo
==1) continue;//For Predecate t1.f1=t2.f1
815 if (value
->parsedString
== NULL
)
818 printError(ErrSyntaxError
, "Condition value should not be NULL");
819 return ErrSyntaxError
;
821 if (value
->parsedString
[0] == '?')
823 //if(!value->opLike) // checks if 'LIKE' operator is used
824 value
->paramNo
= paramPos
++;
826 if (!value
->paramNo
) {
828 if((value
->type
== typeInt
) || (value
->type
==typeShort
) || (value
->type
==typeByteInt
) || (value
->type
==typeLongLong
) || (value
->type
==typeLong
)){
829 int len
=strlen(value
->parsedString
);
830 for(int n
=0;n
<len
;n
++){
831 int p
=value
->parsedString
[n
];
832 if(!(p
>=48 && p
<=57 || p
==45))
837 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
838 AllDataType::strToValue(value
->value
, value
->parsedString
, value
->type
, value
->length
);
842 totalParams
= paramPos
-1;
843 if (0 == totalParams
) return OK
;
844 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
845 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
846 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
847 memset(paramValues
, 0, totalParams
* sizeof(char*));
849 while(iter
.hasElement())
851 value
= (ConditionValue
*) iter
.nextElement();
854 free(params
); params
= NULL
;
855 free(paramValues
); paramValues
= NULL
;
856 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
859 params
[value
->paramNo
-1 ] = value
;
863 bool SelStatement::isGroupFld(char *fieldName
)
865 ListIterator giter
= parsedData
->getGroupFieldNameList().getIterator();
866 FieldName
*name
= NULL
;
867 while (giter
.hasElement())
869 name
= (FieldName
*) giter
.nextElement();
870 if (0 == strcmp(name
->fldName
, fieldName
)) return true;
875 void* SelStatement::handleSingleTableAggWithoutGroup()
877 if (isPointReturned
) return NULL
;
878 TableImpl
*tblImpl
= (TableImpl
*)table
;
879 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
883 FieldValue
*fVal
= NULL
;
885 while (iter
.hasElement())
887 name
= (FieldName
*) iter
.nextElement();
888 fVal
= bindFields
[i
];
890 rv
= tblImpl
->fetchAgg(name
->fldName
, name
->aType
, fVal
->value
, noRec
);
891 if (OK
!= rv
) return NULL
;
893 tblImpl
->closeScan();
896 isPointReturned
= true;
897 if(noRec
&& name
->aType
!= AGG_COUNT
) return NULL
;
900 void* SelStatement::fetch()
905 tuple
= handleSingleTableAggWithoutGroup();
906 if (NULL
== tuple
) return NULL
;
908 if (isOffsetReached
) {
909 if (!isRecLimitReached
) {
910 tuple
= table
->fetch();
911 if (NULL
!= tuple
) numRecords
++;
912 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
917 while(recordOffset
<= parsedData
->getOffset()) {
918 tuple
= table
->fetch();
919 if (NULL
== tuple
) break;
922 isOffsetReached
= true;
923 if (NULL
!= tuple
) numRecords
++;
924 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
927 if (NULL
== tuple
) return NULL
;
929 //copy values to binded buffer
931 for (int i
= 0; i
< totalFields
; i
++)
933 value
= bindFields
[i
];
934 if (bindFieldValues
[i
] == NULL
)
936 printError(ErrBadCall
, "Fields are not binded properly. Should never happen");
939 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
944 void* SelStatement::fetch(DbRetVal
&rv
)
949 tuple
= handleSingleTableAggWithoutGroup();
950 if (NULL
== tuple
) return NULL
;
952 if (isOffsetReached
) {
953 if (!isRecLimitReached
) {
954 tuple
= table
->fetch(rv
);
955 if (NULL
!= tuple
) numRecords
++;
956 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
960 while(recordOffset
<= parsedData
->getOffset()) {
961 tuple
= table
->fetch(rv
);
962 if (NULL
== tuple
) break;
965 isOffsetReached
= true;
966 if (NULL
!= tuple
) numRecords
++;
967 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
970 if (NULL
== tuple
) return NULL
;
971 //copy values to binded buffer
973 for (int i
= 0; i
< totalFields
; i
++)
975 value
= bindFields
[i
];
976 if (bindFieldValues
[i
] == NULL
)
978 printError(ErrBadCall
, "Fields are not binded properly. Should never happen %d", i
);
981 AllDataType::copyVal(bindFieldValues
[i
], value
->value
, value
->type
, value
->length
);
986 DbRetVal
SelStatement::close()
988 isPointReturned
= false;
989 if (table
) return table
->closeScan();
993 void* SelStatement::getParamValuePtr( int pos
)
995 ConditionValue
*p
= (ConditionValue
*) params
[pos
-1];
996 return ( (void*) p
->value
);
999 char* SelStatement::getFieldName ( int pos
)
1001 //TODO::if not yet prepared return error
1002 //TODO::check the upper limit for projpos
1003 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1005 while (iter
.hasElement())
1007 FieldName
*name
= (FieldName
*) iter
.nextElement();
1008 if (position
== pos
) {
1011 printError(ErrSysFatal
, "Should never happen. Field Name list has NULL");
1014 return name
->fldName
;
1021 DataType
SelStatement::getFieldType( int pos
)
1023 FieldValue
*v
= bindFields
[pos
];
1024 return ( (DataType
) v
->type
);
1027 int SelStatement::getFieldLength( int pos
)
1029 FieldValue
*v
= bindFields
[pos
];
1030 return ( (int) v
->type
);
1033 void* SelStatement::fetchAndPrint(bool SQL
)
1036 if(handleAggWithTbl
)
1038 tuple
= handleSingleTableAggWithoutGroup();
1040 if (isOffsetReached
) {
1041 if (!isRecLimitReached
) {
1042 tuple
= table
->fetch();
1043 if (NULL
!= tuple
) numRecords
++;
1044 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1048 int recordOffset
=0;
1049 while(recordOffset
<= parsedData
->getOffset()) {
1050 tuple
= table
->fetch();
1051 if (NULL
== tuple
) break;
1054 isOffsetReached
= true;
1055 if (NULL
!= tuple
) numRecords
++;
1056 if (numRecords
== parsedData
->getLimit()) isRecLimitReached
=true;
1059 if (NULL
== tuple
) return NULL
;
1064 sprintf(stmt
, "INSERT INTO %s VALUES(", table
->getName());
1067 for (int i
= 0; i
< totalFields
; i
++)
1069 value
= bindFields
[i
];
1070 if (!value
->isInResSet
) continue;
1071 nullValueSet
= table
->isFldNull(value
->fldName
);
1079 else if (value
->aType
!= AGG_COUNT
) printf("NULL\t");
1105 AllDataType::printVal(value
->value
, value
->type
, value
->length
);
1116 } else printf("\t");
1119 if (SQL
) printf(");\n");
1123 void* SelStatement::next()
1125 if(handleAggWithTbl
)
1127 return handleSingleTableAggWithoutGroup();
1129 return( table
->fetch() );
1133 void* SelStatement::getFieldValuePtr( int pos
)
1135 FieldValue
*v
= bindFields
[pos
];
1136 return ( (void*) v
->value
);
1139 void* SelStatement::getFieldValuePtr( char *name
)
1142 char fName
[IDENTIFIER_LENGTH
];
1143 for (int i
= 0; i
< totalFields
; i
++)
1145 value
= bindFields
[i
];
1146 table
->getFieldNameAlone(value
->fldName
,fName
);
1147 if (strcmp(fName
,name
)==0)
1149 return ( (void*) value
->value
);
1155 void SelStatement::getProjFieldType(int *data
)
1158 for (int i
= 0; i
< totalFields
; i
++)
1160 value
= bindFields
[i
];
1161 data
[i
+1] = value
->type
;
1165 int SelStatement::noOfProjFields()
1170 DbRetVal
SelStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
1174 //TODO::if not yet prepared return error
1175 //TODO::check the upper limit for projpos
1176 if (projpos
< 0 || projpos
>totalFields
) return ErrBadArg
;
1177 FieldValue
*value
= bindFields
[projpos
-1];
1178 fInfo
->type
= value
->type
;
1179 fInfo
->length
= value
->length
;
1180 fInfo
->isNull
= value
->isNullable
;
1181 fInfo
->aType
= value
->aType
;
1182 fInfo
->offset
= value
->offset
;
1183 fInfo
->isPrimary
= value
->isPrimary
;
1184 fInfo
->isUnique
= value
->isUnique
;
1185 fInfo
->isAutoIncrement
= value
->isAutoIncrement
;
1186 fInfo
->isDefault
= value
->isDefault
;
1187 if (fInfo
->aType
== AGG_UNKNOWN
) {
1188 strcpy(fInfo
->fldName
, value
->fldName
);
1189 if (fInfo
->isDefault
) strcpy(fInfo
->defaultValueBuf
, value
->defValBuf
);
1192 switch(fInfo
->aType
)
1195 sprintf(fInfo
->fldName
, "COUNT(%s)", value
->fldName
);
1196 fInfo
->type
= typeInt
;
1197 fInfo
->length
= sizeof(int);
1200 sprintf(fInfo
->fldName
, "MIN(%s)", value
->fldName
);
1203 sprintf(fInfo
->fldName
, "MAX(%s)", value
->fldName
);
1206 sprintf(fInfo
->fldName
, "SUM(%s)", value
->fldName
);
1209 sprintf(fInfo
->fldName
, "AVG(%s)", value
->fldName
);
1210 fInfo
->type
= typeDouble
;
1211 fInfo
->length
= sizeof(double);
1214 strcpy(fInfo
->fldName
, value
->fldName
);
1219 int SelStatement::getFldPos(char *name
)
1221 return table
->getFldPos(name
);
1224 bool SelStatement::isInProjectionList(char *name
, AggType aType
)
1226 ListIterator iter
= parsedData
->getFieldNameList().getIterator();
1227 FieldName
*fldName
= NULL
;
1228 while (iter
.hasElement()) {
1229 fldName
= (FieldName
*) iter
.nextElement();
1230 if ((strcmp(fldName
->fldName
, name
)==0) && fldName
->aType
== aType
) {