Bug:2572075 SQLFetch dumps core when more fileds are binded than
[csql.git] / src / sql / SelStatement.cxx
blob6864649e3be145f8204a00245d14e2d9ce851754
1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
4 * *
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. *
9 * *
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. *
14 * *
15 ***************************************************************************/
16 #include <os.h>
17 #include <Statement.h>
18 #include <TableImpl.h>
19 #include <OrderTableImpl.h>
21 SelStatement::SelStatement()
23 parsedData = NULL;
24 dbMgr = NULL;
25 table = NULL;
26 params = NULL;
27 paramValues = NULL;
28 totalParams = 0;
29 bindFields = NULL;
30 bindFieldValues = NULL;
31 totalFields = 0;
32 isPointReturned = false;
33 handleAggWithTbl=false;
34 numRecords = 0;
35 isOffsetReached = false;
36 isRecLimitReached = false;
37 isExplain=false;
38 isJoin=false;
41 SelStatement::~SelStatement()
43 close();
44 if (table) { table->close(); table = NULL; }
45 if (totalParams) {
46 free(params);
47 params = NULL;
48 free(paramValues);
49 paramValues = NULL;
51 if (totalFields)
53 free(bindFields);
54 bindFields = 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];
64 if (NULL == cValue)
66 printError(ErrSysFatal, "condition value is null. Should never happen");
67 return ErrSysFatal;
69 table->getFieldNameAlone(cValue->fName,info->fldName);
70 info->type = cValue->type;
71 info->length = cValue->length;
72 info->isNull = cValue->isNullable;
73 return OK;
75 DbRetVal SelStatement::execute(int &rowsAffected)
77 DbRetVal rv = OK;
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)
85 continue;
86 //printError(ErrBadCall, "param values not set");
87 //return ErrBadCall;
89 AllDataType::copyVal(value->value, paramValues[i], value->type, value->length);
91 //table->printPlan(0);
92 //printf("Execute Called\n");
93 rv = table->execute();
94 numRecords = 0;
95 isOffsetReached = false;
96 isRecLimitReached = false;
98 if (isExplain) table->printPlan(0);
99 return rv;
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;
107 return OK;
110 DbRetVal SelStatement::setShortParam(int paramNo, short value)
112 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
113 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
114 if (NULL == cValue)
116 printError(ErrSysFatal, "field value is null. Should never happen");
117 return ErrSysFatal;
119 *(short*)cValue->value = value;
120 return OK;
123 DbRetVal SelStatement::setIntParam(int paramNo, int value)
125 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
126 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
127 if (NULL == cValue)
129 printError(ErrSysFatal, "condition value is null. Should never happen");
130 return ErrSysFatal;
132 *(int*)cValue->value = value;
133 return OK;
135 DbRetVal SelStatement::setLongParam(int paramNo, long value)
137 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
138 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
139 if (NULL == cValue)
141 printError(ErrSysFatal, "condition value is null. Should never happen");
142 return ErrSysFatal;
144 *(long*)cValue->value = value;
145 return OK;
148 DbRetVal SelStatement::setLongLongParam(int paramNo, long long value)
150 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
151 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
152 if (NULL == cValue)
154 printError(ErrSysFatal, "condition value is null. Should never happen");
155 return ErrSysFatal;
157 *(long long*)cValue->value = value;
158 return OK;
160 DbRetVal SelStatement::setByteIntParam(int paramNo, ByteInt value)
162 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
163 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
164 if (NULL == cValue)
166 printError(ErrSysFatal, "condition value is null. Should never happen");
167 return ErrSysFatal;
169 *(ByteInt*)cValue->value = value;
170 return OK;
172 DbRetVal SelStatement::setFloatParam(int paramNo, float value)
174 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
175 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
176 if (NULL == cValue)
178 printError(ErrSysFatal, "condition value is null. Should never happen");
179 return ErrSysFatal;
181 *(float*)cValue->value = value;
182 return OK;
184 DbRetVal SelStatement::setDoubleParam(int paramNo, double value)
186 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
187 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
188 if (NULL == cValue)
190 printError(ErrSysFatal, "condition value is null. Should never happen");
191 return ErrSysFatal;
193 *(double*)cValue->value = value;
194 return OK;
196 DbRetVal SelStatement::setStringParam(int paramNo, char *value)
198 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
199 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
200 if (NULL == cValue)
202 printError(ErrSysFatal, "condition value is null. Should never happen");
203 return ErrSysFatal;
205 strcpy((char*)cValue->value, value);
206 return OK;
208 DbRetVal SelStatement::setDateParam(int paramNo, Date value)
210 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
211 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
212 if (NULL == cValue)
214 printError(ErrSysFatal, "condition value is null. Should never happen");
215 return ErrSysFatal;
217 *(Date*)cValue->value = value;
218 return OK;
220 DbRetVal SelStatement::setTimeParam(int paramNo, Time value)
222 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
223 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
224 if (NULL == cValue)
226 printError(ErrSysFatal, "condition value is null. Should never happen");
227 return ErrSysFatal;
229 *(Time*)cValue->value = value;
230 return OK;
232 DbRetVal SelStatement::setTimeStampParam(int paramNo, TimeStamp value)
234 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
235 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
236 if (NULL == cValue)
238 printError(ErrSysFatal, "condition value is null. Should never happen");
239 return ErrSysFatal;
241 *(TimeStamp*)cValue->value = value;
242 return OK;
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];
249 if (NULL == cValue)
251 printError(ErrSysFatal, "condition value is null. Should never happen");
252 return ErrSysFatal;
254 AllDataType::convertToBinary(cValue->value,value,typeString,cValue->length);
255 return OK;
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;
265 return OK;
267 bool SelStatement::isTableAlreadyPresent(char *tblName, char *aliasName)
269 ListIterator titer = parsedData->getTableNameList().getIterator();
270 int count =0;
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;
278 return true;
280 DbRetVal SelStatement::openTables()
282 if (dbMgr == NULL) return ErrNoConnection;
283 JoinTableImpl *jHdl = NULL;
284 Table *tHdl = NULL, *prevHdl = NULL;
285 isJoin = false;
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);
300 if ( NULL == tHdl )
302 printError(ErrNotExists,
303 "Unable to open the table:Table not exists");
304 if (prevHdl) delete prevHdl;
305 return ErrNotExists;
307 TableImpl *tImpl= (TableImpl*) tHdl;
308 tImpl->setAliasName(t->aliasName);
309 if (NULL != prevHdl)
311 isJoin = true;
312 jHdl = new JoinTableImpl();
313 jHdl->setTable(prevHdl, tHdl);
314 JoinTypeNode *node = (JoinTypeNode*) jiter.nextElement();
315 if (node == NULL) {
316 printError(ErrSyntaxError,
317 "Join Type and number of tables do not match");
318 delete jHdl;
319 return ErrSyntaxError;
321 jHdl->setJoinType(node->jType);
322 prevHdl = jHdl;
323 continue;
325 prevHdl = tHdl;
328 if (isJoin) table = jHdl; else table = tHdl;
329 return OK;
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();
339 List bindFldList;
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();
354 if (NULL == name)
356 dbMgr->closeTable(table);
357 table = NULL;
358 delete fInfo;
359 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
360 return ErrSysFatal;
362 bool isBindFld=false;
363 if ('*' == name->fldName[0] && name->aType == AGG_UNKNOWN)
365 rv = resolveStar();
366 if (rv != OK)
368 dbMgr->closeTable(table);
369 table = NULL;
370 delete fInfo;
371 return rv;
373 if (parsedData->getGroupFieldNameList().size()!= 0
374 && !isSingleTableNoGrp)
376 if (!aggTable)
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.
382 break;
383 } else {
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);
392 table = NULL;
393 delete fInfo;
394 printError(ErrSyntaxError, "Field %s does not exist in table",
395 name->fldName);
396 return ErrSyntaxError;
398 FieldValue *newVal = new FieldValue();
399 strcpy(newVal->fldName,name->fldName);
400 newVal->parsedString = NULL;
401 newVal->paramNo = 0;
402 newVal->aType = name->aType;
403 if (!isMixPrjList) {
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",
427 fInfo->fldName);
428 dbMgr->closeTable(table);
429 if (aggTable) { delete aggTable; aggTable = NULL; }
430 table = NULL;
431 delete fInfo;
432 return ErrBadArg;
435 else {
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;
450 isBindFld=true;
451 break;
454 if (!isBindFld) {
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,
460 2 * fInfo->length);
461 else newVal->value = AllDataType::alloc(fInfo->type,
462 fInfo->length);
463 } else {
464 if (name->aType == AGG_AVG) {
465 newVal->value = AllDataType::alloc(typeDouble,
466 sizeof(double));
467 memset(newVal->value, 0, sizeof(double));
469 else if (name->aType == AGG_COUNT) {
470 newVal->value = AllDataType::alloc(typeInt,
471 sizeof(int));
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);
481 if (OK !=rv) {
482 if (newVal->isAllocVal) free(newVal->value);
483 delete newVal;
484 delete fInfo;
485 return rv;
488 else if (!isSingleTableNoGrp)
490 if (!aggTable) {
491 aggTable = new AggTableImpl();
492 aggTable->setTable(table);
494 rv = aggTable->bindFld(name->fldName, name->aType, newVal->value);
495 if (OK !=rv) {
496 if (newVal->isAllocVal) free(newVal->value);
497 delete newVal; delete fInfo; delete aggTable;
498 aggTable = NULL; table = NULL;
499 return rv;
502 if (name->aType !=AGG_UNKNOWN && isSingleTableNoGrp)
503 handleAggWithTbl= true;
504 parsedData->insertFieldValue(newVal);
506 if (!isBindFld) bindFldList.append(name);
508 bindFldList.reset();
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;
520 newVal->paramNo = 0;
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));
534 } else {
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();
545 if (rv != OK)
547 delete fInfo;
548 if (aggTable) { delete aggTable; aggTable = NULL; }
549 else dbMgr->closeTable(table);
550 table = NULL;
551 return rv;
554 table->setCondition(parsedData->getCondition());
556 rv = resolveForCondition();
557 if (rv != OK)
559 delete fInfo;
560 //TODO::free memory allocated for params
561 if (aggTable) { delete aggTable; aggTable = NULL; }
562 else {
563 table->setCondition(NULL);
564 dbMgr->closeTable(table);
566 table = NULL;
567 return rv;
569 if (NULL == parsedData->getCondition()) parsedData->setCacheWorthy(false);
570 rv = resolveGroupFld(aggTable, isGroupFld);
571 if (rv != OK)
573 delete fInfo;
574 //TODO::free memory allocated for params
575 if (aggTable) { delete aggTable; aggTable = NULL; }
576 else if (table)
578 table->setCondition(NULL);
579 dbMgr->closeTable(table);
581 table = NULL;
582 return rv;
584 if (isMixPrjList && ! isGroupFld) {
585 printError(ErrSyntax, "Group By Field required.");
586 delete fInfo;
587 if (aggTable) { delete aggTable; aggTable = NULL; }
588 else if (table)
590 table->setCondition(NULL);
591 dbMgr->closeTable(table);
593 table = NULL;
594 return ErrSyntax;
597 rv = resolveOrderByFld();
598 if (rv != OK)
600 delete fInfo;
601 delete table;
602 table = NULL;
603 return rv;
605 rv = resolveDistinct();
606 delete fInfo;
607 if(parsedData->getExplain()) isExplain = true;
608 else
609 isExplain= false;
610 return rv;
612 DbRetVal SelStatement::resolveDistinct()
614 if (!parsedData->getDistinct()) {
615 return OK;
617 OrderTableImpl *orderTable = new OrderTableImpl();
618 orderTable->setTable(table);
619 orderTable->setProjList(parsedData->getFieldValueList());
620 orderTable->setOrderByList(parsedData->getFieldValueList());
621 orderTable->setDistinct();
622 table = orderTable;
623 handleAggWithTbl= false;
624 return OK;
628 DbRetVal SelStatement::resolveOrderByFld()
630 if (0 == parsedData->getOrderFieldNameList().size()) {
631 return OK;
633 OrderTableImpl *orderTable = new OrderTableImpl();
634 orderTable->setTable(table);
635 orderTable->setProjList(parsedData->getFieldValueList());
636 ListIterator giter = parsedData->getOrderFieldNameList().getIterator();
637 FieldName *name = NULL;
638 DbRetVal rv = OK;
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)
646 delete fInfo;
647 printError(ErrSyntaxError, "Field %s does not exist in table",
648 name->fldName);
649 return ErrSyntaxError;
651 /*FieldValue *newVal = new FieldValue();
652 strcpy(newVal->fldName,name->fldName);
653 newVal->parsedString = NULL;
654 newVal->paramNo = 0;
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
667 delete fInfo;
668 table = orderTable;
669 handleAggWithTbl= false;
670 return OK;
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",
687 name->fldName);
688 return ErrSyntaxError;
692 DbRetVal rv = OK;
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)
700 delete fInfo;
701 printError(ErrSyntaxError, "Field %s does not exist in table",
702 name->fldName);
703 return ErrSyntaxError;
705 FieldValue *newVal = new FieldValue();
706 strcpy(newVal->fldName,name->fldName);
707 newVal->parsedString = NULL;
708 newVal->paramNo = 0;
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);
723 delete fInfo;
724 aggTable->setCondition(parsedData->getHavingCondition());
725 /*if (giter.hasElement())
727 printError(ErrSyntaxError, "Only one field allowed in group\n");
728 return ErrSyntaxError;
730 table = aggTable;
731 isGrpFld = true;
732 return OK;
735 DbRetVal SelStatement::resolveStar()
737 DbRetVal rv = OK;
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)
750 delete fInfo;
751 fNameList.reset();
752 printError(ErrSysFatal, "Should never happen.");
753 return ErrSysFatal;
755 newVal = new FieldValue();
756 strcpy(newVal->fldName,fName);
757 newVal->parsedString = NULL;
758 newVal->paramNo = 0;
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);
775 if (rv != OK) {
776 delete fInfo;
777 return rv;
780 fNameIter.reset();
781 while (fNameIter.hasElement())
782 delete (Identifier *) fNameIter.nextElement();
783 fNameList.reset();
784 delete fInfo;
785 return OK;
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();
796 int colNo =0;
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();
803 if (value == NULL)
805 free(bindFields); bindFields = NULL;
806 free(bindFieldValues); bindFieldValues = NULL;
807 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
808 return ErrSysFatal;
810 bindFields[colNo++] = value;
812 return OK;
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();
823 int paramPos =1;
824 DbRetVal rv = OK;
825 while (iter.hasElement())
827 value = (ConditionValue*) iter.nextElement();
828 if (NULL == value)
830 delete fInfo;
831 printError(ErrSysFatal, "Should never happen.");
832 return ErrSysFatal;
834 if(!value->isFunctionInvolve){
835 rv = table->getFieldInfo(value->fName, fInfo);
836 if (ErrNotFound == rv || ErrNotExists == rv)
838 delete fInfo;
839 printError(ErrSyntaxError, "Field %s does not exist in table",
840 value->fName);
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);
849 } else {
850 value->type = fInfo->type;
851 value->length = fInfo->length;
853 value->isNullable = fInfo->isNull;
854 }else{
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)
862 delete fInfo;
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) {
871 // for valid Integer
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)) {
882 delete fInfo;
883 return ErrBadArg;
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);
891 if (OK != rv) {
892 delete fInfo;
893 return ErrBadArg;
897 delete fInfo;
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*));
904 iter.reset();
905 while(iter.hasElement())
907 value = (ConditionValue*) iter.nextElement();
908 if (value == NULL)
910 free(params); params = NULL;
911 free(paramValues); paramValues = NULL;
912 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
913 return ErrSysFatal;
915 if (value->paramNo) params[value->paramNo - 1] = value;
917 return OK;
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;
928 return false;
931 void* SelStatement::handleSingleTableAggWithoutGroup()
933 if (isPointReturned) return NULL;
934 TableImpl *tblImpl = (TableImpl*)table;
935 ListIterator iter = parsedData->getFieldNameList().getIterator();
936 int i=0;
937 DbRetVal rv = OK;
938 FieldName *name;
939 FieldValue *fVal = NULL;
940 bool noRec = false;
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;
948 i++;
949 tblImpl->closeScan();
950 tblImpl->execute();
952 isPointReturned = true;
953 if(noRec && name->aType != AGG_COUNT) return NULL;
954 return fVal;
956 void* SelStatement::fetch()
958 void *tuple = NULL;
959 if(handleAggWithTbl)
961 tuple = handleSingleTableAggWithoutGroup();
962 if (NULL == tuple) return NULL;
963 }else {
964 if (isOffsetReached) {
965 if (!isRecLimitReached) {
966 tuple = table->fetch();
967 if (NULL != tuple) numRecords++;
968 if (numRecords == parsedData->getLimit()) isRecLimitReached=true;
971 else {
972 int recordOffset =0;
973 while(recordOffset <= parsedData->getOffset()) {
974 tuple = table->fetch();
975 if (NULL == tuple) break;
976 recordOffset++;
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
986 FieldValue *value;
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");
993 return NULL;
995 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
997 return tuple;
1000 void* SelStatement::fetch(DbRetVal &rv)
1002 void *tuple = NULL;
1003 if(handleAggWithTbl)
1005 tuple = handleSingleTableAggWithoutGroup();
1006 if (NULL == tuple) return NULL;
1007 }else {
1008 if (isOffsetReached) {
1009 if (!isRecLimitReached) {
1010 tuple = table->fetch(rv);
1011 if (NULL != tuple) numRecords++;
1012 if (numRecords == parsedData->getLimit()) isRecLimitReached=true;
1014 } else {
1015 int recordOffset =0;
1016 while(recordOffset <= parsedData->getOffset()) {
1017 tuple = table->fetch(rv);
1018 if (NULL == tuple) break;
1019 recordOffset++;
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
1028 FieldValue *value;
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);
1035 return NULL;
1037 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
1039 return tuple;
1042 DbRetVal SelStatement::close()
1044 isPointReturned = false;
1045 isExplain = false;
1046 if (table) return table->closeScan();
1047 else return OK;
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();
1061 int position = 1;
1062 while (iter.hasElement())
1064 FieldName *name = (FieldName*) iter.nextElement();
1065 if (position == pos) {
1066 if (NULL == name)
1068 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
1069 return (char*) 0;
1071 return name->fldName;
1073 position++;
1075 return (char*) 0;
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)
1092 void *tuple = NULL;
1093 if(handleAggWithTbl)
1095 tuple = handleSingleTableAggWithoutGroup();
1096 }else {
1097 if (isOffsetReached) {
1098 if (!isRecLimitReached) {
1099 tuple = table->fetch();
1100 if (NULL != tuple) numRecords++;
1101 if (numRecords == parsedData->getLimit()) isRecLimitReached=true;
1104 else {
1105 int recordOffset =0;
1106 while(recordOffset <= parsedData->getOffset()) {
1107 tuple = table->fetch();
1108 if (NULL == tuple) break;
1109 recordOffset++;
1111 isOffsetReached = true;
1112 if (NULL != tuple) numRecords++;
1113 if (numRecords == parsedData->getLimit()) isRecLimitReached=true;
1116 if (NULL == tuple) return NULL;
1117 FieldValue *value;
1118 bool nullValueSet;
1119 char stmt[128];
1120 if (SQL) {
1121 sprintf(stmt, "INSERT INTO %s VALUES(", table->getName());
1122 printf("%s", stmt);
1124 for (int i = 0; i < totalFields; i++)
1126 value = bindFields[i];
1127 if (!value->isInResSet) continue;
1128 nullValueSet = table->isFldNull(value->fldName);
1129 if (nullValueSet) {
1130 if (SQL) {
1131 if (i==0)
1132 printf("NULL");
1133 else
1134 printf(", NULL");
1136 else if (value->aType != AGG_COUNT) printf("NULL\t");
1137 else printf("0\t");
1139 else {
1140 if (SQL) {
1141 switch(value->type)
1143 case typeString:
1144 case typeVarchar:
1145 case typeBinary:
1146 case typeDate:
1147 case typeTime:
1148 case typeTimeStamp:
1150 if (i==0)
1151 printf(" '");
1152 else
1153 printf(", '");
1154 break;
1156 default:
1158 if (i!=0)
1159 printf(",");
1163 AllDataType::printVal(value->value, value->type, value->length);
1164 if (SQL) {
1165 switch(value->type)
1167 case typeString:
1168 case typeVarchar:
1169 case typeBinary:
1170 case typeDate:
1171 case typeTime:
1172 case typeTimeStamp:
1173 printf("'");
1175 } else printf("\t");
1178 if (SQL) printf(");\n");
1179 return tuple;
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 )
1201 FieldValue *value;
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 );
1213 return NULL;
1215 void SelStatement::getProjFieldType(int *data)
1217 FieldValue *value;
1218 for (int i = 0; i < totalFields; i++)
1220 value = bindFields[i];
1221 data[i+1] = value->type;
1225 int SelStatement::noOfProjFields()
1227 return totalFields;
1230 DbRetVal SelStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
1233 DbRetVal rv = OK;
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);
1250 return OK;
1252 switch(fInfo->aType)
1254 case AGG_COUNT:
1255 sprintf(fInfo->fldName, "COUNT(%s)", value->fldName);
1256 fInfo->type = typeInt;
1257 fInfo->length = sizeof(int);
1258 break;
1259 case AGG_MIN:
1260 sprintf(fInfo->fldName, "MIN(%s)", value->fldName);
1261 break;
1262 case AGG_MAX:
1263 sprintf(fInfo->fldName, "MAX(%s)", value->fldName);
1264 break;
1265 case AGG_SUM:
1266 sprintf(fInfo->fldName, "SUM(%s)", value->fldName);
1267 break;
1268 case AGG_AVG:
1269 sprintf(fInfo->fldName, "AVG(%s)", value->fldName);
1270 fInfo->type = typeDouble;
1271 fInfo->length = sizeof(double);
1272 break;
1273 default:
1274 strcpy(fInfo->fldName, value->fldName);
1275 break;
1277 return rv;
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) {
1291 return true;
1294 return false;