Removing dependency for Cache module in MMDB build
[csql.git] / src / sql / SelStatement.cxx
blob6c2ab9d9adc45f992c8ee27bc5951fa7226a7b25
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 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();
350 if (NULL == name)
352 dbMgr->closeTable(table);
353 table = NULL;
354 delete fInfo;
355 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
356 return ErrSysFatal;
358 bool isBindFld=false;
359 if ('*' == name->fldName[0] && name->aType == AGG_UNKNOWN)
361 rv = resolveStar();
362 if (rv != OK)
364 dbMgr->closeTable(table);
365 table = NULL;
366 delete fInfo;
367 return rv;
369 if (parsedData->getGroupFieldNameList().size()!= 0
370 && !isSingleTableNoGrp)
372 if (!aggTable)
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.
378 break;
379 }else {
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);
386 table = NULL;
387 delete fInfo;
388 printError(ErrSyntaxError, "Field %s does not exist in table",
389 name->fldName);
390 return ErrSyntaxError;
392 FieldValue *newVal = new FieldValue();
393 strcpy(newVal->fldName,name->fldName);
394 newVal->parsedString = NULL;
395 newVal->paramNo = 0;
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",
415 fInfo->fldName);
416 dbMgr->closeTable(table);
417 if (aggTable) { delete aggTable; aggTable = NULL; }
418 table = NULL;
419 delete fInfo;
420 return ErrBadArg;
423 else {
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;
438 isBindFld=true;
439 break;
442 if (!isBindFld) {
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,
448 2 * fInfo->length);
449 else newVal->value = AllDataType::alloc(fInfo->type,
450 fInfo->length);
451 } else {
452 if (name->aType == AGG_AVG) {
453 newVal->value = AllDataType::alloc(typeDouble,
454 sizeof(double));
455 memset(newVal->value, 0, sizeof(double));
457 else if (name->aType == AGG_COUNT) {
458 newVal->value = AllDataType::alloc(typeInt,
459 sizeof(int));
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)
473 if (!aggTable) {
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);
486 bindFldList.reset();
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;
498 newVal->paramNo = 0;
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));
512 } else {
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();
523 if (rv != OK)
525 delete fInfo;
526 if (aggTable) { delete aggTable; aggTable = NULL; }
527 else dbMgr->closeTable(table);
528 table = NULL;
529 return rv;
532 table->setCondition(parsedData->getCondition());
534 rv = resolveForCondition();
535 if (rv != OK)
537 delete fInfo;
538 //TODO::free memory allocated for params
539 if (aggTable) { delete aggTable; aggTable = NULL; }
540 else {
541 table->setCondition(NULL);
542 dbMgr->closeTable(table);
544 table = NULL;
545 return rv;
547 rv = resolveGroupFld(aggTable);
548 if (rv != OK)
550 delete fInfo;
551 //TODO::free memory allocated for params
552 if (aggTable) { delete aggTable; aggTable = NULL; }
553 else if (table)
555 table->setCondition(NULL);
556 dbMgr->closeTable(table);
558 table = NULL;
559 return rv;
562 rv = resolveOrderByFld();
563 if (rv != OK)
565 delete fInfo;
566 delete table;
567 table = NULL;
568 return rv;
570 rv = resolveDistinct();
571 delete fInfo;
572 if(parsedData->getExplain()) isExplain = true;
573 return rv;
575 DbRetVal SelStatement::resolveDistinct()
577 if (!parsedData->getDistinct()) {
578 return OK;
580 OrderTableImpl *orderTable = new OrderTableImpl();
581 orderTable->setTable(table);
582 orderTable->setProjList(parsedData->getFieldValueList());
583 orderTable->setOrderByList(parsedData->getFieldValueList());
584 orderTable->setDistinct();
585 table = orderTable;
586 handleAggWithTbl= false;
587 return OK;
591 DbRetVal SelStatement::resolveOrderByFld()
593 if (0 == parsedData->getOrderFieldNameList().size()) {
594 return OK;
596 OrderTableImpl *orderTable = new OrderTableImpl();
597 orderTable->setTable(table);
598 orderTable->setProjList(parsedData->getFieldValueList());
599 ListIterator giter = parsedData->getOrderFieldNameList().getIterator();
600 FieldName *name = NULL;
601 DbRetVal rv = OK;
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)
609 delete fInfo;
610 printError(ErrSyntaxError, "Field %s does not exist in table",
611 name->fldName);
612 return ErrSyntaxError;
614 /*FieldValue *newVal = new FieldValue();
615 strcpy(newVal->fldName,name->fldName);
616 newVal->parsedString = NULL;
617 newVal->paramNo = 0;
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
630 delete fInfo;
631 table = orderTable;
632 handleAggWithTbl= false;
633 return OK;
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;
653 DbRetVal rv = OK;
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)
661 delete fInfo;
662 printError(ErrSyntaxError, "Field %s does not exist in table",
663 name->fldName);
664 return ErrSyntaxError;
666 FieldValue *newVal = new FieldValue();
667 strcpy(newVal->fldName,name->fldName);
668 newVal->parsedString = NULL;
669 newVal->paramNo = 0;
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);
684 delete fInfo;
685 aggTable->setCondition(parsedData->getHavingCondition());
686 /*if (giter.hasElement())
688 printError(ErrSyntaxError, "Only one field allowed in group\n");
689 return ErrSyntaxError;
691 table = aggTable;
692 return OK;
695 DbRetVal SelStatement::resolveStar()
697 DbRetVal rv = OK;
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)
710 delete fInfo;
711 fNameList.reset();
712 printError(ErrSysFatal, "Should never happen.");
713 return ErrSysFatal;
715 newVal = new FieldValue();
716 strcpy(newVal->fldName,fName);
717 newVal->parsedString = NULL;
718 newVal->paramNo = 0;
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);
735 if (rv != OK) {
736 delete fInfo;
737 return rv;
740 fNameIter.reset();
741 while (fNameIter.hasElement())
742 delete (Identifier *) fNameIter.nextElement();
743 fNameList.reset();
744 delete fInfo;
745 return OK;
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();
756 int colNo =0;
757 FieldValue *value = NULL;
758 valIter.reset();
759 while(valIter.hasElement())
761 value = (FieldValue*) valIter.nextElement();
762 if (value == NULL)
764 free(bindFields); bindFields = NULL;
765 free(bindFieldValues); bindFieldValues = NULL;
766 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
767 return ErrSysFatal;
769 bindFields[colNo++ ] = value;
771 return OK;
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();
782 int paramPos =1;
783 DbRetVal rv = OK;
784 while (iter.hasElement())
786 value = (ConditionValue*) iter.nextElement();
787 if (NULL == value)
789 delete fInfo;
790 printError(ErrSysFatal, "Should never happen.");
791 return ErrSysFatal;
793 rv = table->getFieldInfo(value->fName, fInfo);
794 if (ErrNotFound == rv || ErrNotExists == rv)
796 delete fInfo;
797 printError(ErrSyntaxError, "Field %s does not exist in table",
798 value->fName);
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);
807 } else {
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)
817 delete fInfo;
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) {
827 // for valid Integer
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))
833 return ErrBadArg;
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);
841 delete fInfo;
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*));
848 iter.reset();
849 while(iter.hasElement())
851 value = (ConditionValue*) iter.nextElement();
852 if (value == NULL)
854 free(params); params = NULL;
855 free(paramValues); paramValues = NULL;
856 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
857 return ErrSysFatal;
859 params[value->paramNo -1 ] = value;
861 return OK;
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;
872 return false;
875 void* SelStatement::handleSingleTableAggWithoutGroup()
877 if (isPointReturned) return NULL;
878 TableImpl *tblImpl = (TableImpl*)table;
879 ListIterator iter = parsedData->getFieldNameList().getIterator();
880 int i=0;
881 DbRetVal rv = OK;
882 FieldName *name;
883 FieldValue *fVal = NULL;
884 bool noRec = false;
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;
892 i++;
893 tblImpl->closeScan();
894 tblImpl->execute();
896 isPointReturned = true;
897 if(noRec && name->aType != AGG_COUNT) return NULL;
898 return fVal;
900 void* SelStatement::fetch()
902 void *tuple = NULL;
903 if(handleAggWithTbl)
905 tuple = handleSingleTableAggWithoutGroup();
906 if (NULL == tuple) return NULL;
907 }else {
908 if (isOffsetReached) {
909 if (!isRecLimitReached) {
910 tuple = table->fetch();
911 if (NULL != tuple) numRecords++;
912 if (numRecords == parsedData->getLimit()) isRecLimitReached=true;
915 else {
916 int recordOffset =0;
917 while(recordOffset <= parsedData->getOffset()) {
918 tuple = table->fetch();
919 if (NULL == tuple) break;
920 recordOffset++;
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
930 FieldValue *value;
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");
937 return NULL;
939 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
941 return tuple;
944 void* SelStatement::fetch(DbRetVal &rv)
946 void *tuple = NULL;
947 if(handleAggWithTbl)
949 tuple = handleSingleTableAggWithoutGroup();
950 if (NULL == tuple) return NULL;
951 }else {
952 if (isOffsetReached) {
953 if (!isRecLimitReached) {
954 tuple = table->fetch(rv);
955 if (NULL != tuple) numRecords++;
956 if (numRecords == parsedData->getLimit()) isRecLimitReached=true;
958 } else {
959 int recordOffset =0;
960 while(recordOffset <= parsedData->getOffset()) {
961 tuple = table->fetch(rv);
962 if (NULL == tuple) break;
963 recordOffset++;
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
972 FieldValue *value;
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);
979 return NULL;
981 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
983 return tuple;
986 DbRetVal SelStatement::close()
988 isPointReturned = false;
989 if (table) return table->closeScan();
990 else return OK;
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();
1004 int position = 1;
1005 while (iter.hasElement())
1007 FieldName *name = (FieldName*) iter.nextElement();
1008 if (position == pos) {
1009 if (NULL == name)
1011 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
1012 return (char*) 0;
1014 return name->fldName;
1016 position++;
1018 return (char*) 0;
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)
1035 void *tuple = NULL;
1036 if(handleAggWithTbl)
1038 tuple = handleSingleTableAggWithoutGroup();
1039 }else {
1040 if (isOffsetReached) {
1041 if (!isRecLimitReached) {
1042 tuple = table->fetch();
1043 if (NULL != tuple) numRecords++;
1044 if (numRecords == parsedData->getLimit()) isRecLimitReached=true;
1047 else {
1048 int recordOffset =0;
1049 while(recordOffset <= parsedData->getOffset()) {
1050 tuple = table->fetch();
1051 if (NULL == tuple) break;
1052 recordOffset++;
1054 isOffsetReached = true;
1055 if (NULL != tuple) numRecords++;
1056 if (numRecords == parsedData->getLimit()) isRecLimitReached=true;
1059 if (NULL == tuple) return NULL;
1060 FieldValue *value;
1061 bool nullValueSet;
1062 char stmt[128];
1063 if (SQL) {
1064 sprintf(stmt, "INSERT INTO %s VALUES(", table->getName());
1065 printf("%s", stmt);
1067 for (int i = 0; i < totalFields; i++)
1069 value = bindFields[i];
1070 if (!value->isInResSet) continue;
1071 nullValueSet = table->isFldNull(value->fldName);
1072 if (nullValueSet) {
1073 if (SQL) {
1074 if (i==0)
1075 printf("NULL");
1076 else
1077 printf(", NULL");
1079 else if (value->aType != AGG_COUNT) printf("NULL\t");
1080 else printf("0\t");
1082 else {
1083 if (SQL) {
1084 switch(value->type)
1086 case typeString:
1087 case typeBinary:
1088 case typeDate:
1089 case typeTime:
1090 case typeTimeStamp:
1092 if (i==0)
1093 printf(" '");
1094 else
1095 printf(", '");
1096 break;
1098 default:
1100 if (i!=0)
1101 printf(",");
1105 AllDataType::printVal(value->value, value->type, value->length);
1106 if (SQL) {
1107 switch(value->type)
1109 case typeString:
1110 case typeBinary:
1111 case typeDate:
1112 case typeTime:
1113 case typeTimeStamp:
1114 printf("'");
1116 } else printf("\t");
1119 if (SQL) printf(");\n");
1120 return tuple;
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 )
1141 FieldValue *value;
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 );
1153 return NULL;
1155 void SelStatement::getProjFieldType(int *data)
1157 FieldValue *value;
1158 for (int i = 0; i < totalFields; i++)
1160 value = bindFields[i];
1161 data[i+1] = value->type;
1165 int SelStatement::noOfProjFields()
1167 return totalFields;
1170 DbRetVal SelStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
1173 DbRetVal rv = OK;
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);
1190 return OK;
1192 switch(fInfo->aType)
1194 case AGG_COUNT:
1195 sprintf(fInfo->fldName, "COUNT(%s)", value->fldName);
1196 fInfo->type = typeInt;
1197 fInfo->length = sizeof(int);
1198 break;
1199 case AGG_MIN:
1200 sprintf(fInfo->fldName, "MIN(%s)", value->fldName);
1201 break;
1202 case AGG_MAX:
1203 sprintf(fInfo->fldName, "MAX(%s)", value->fldName);
1204 break;
1205 case AGG_SUM:
1206 sprintf(fInfo->fldName, "SUM(%s)", value->fldName);
1207 break;
1208 case AGG_AVG:
1209 sprintf(fInfo->fldName, "AVG(%s)", value->fldName);
1210 fInfo->type = typeDouble;
1211 fInfo->length = sizeof(double);
1212 break;
1213 default:
1214 strcpy(fInfo->fldName, value->fldName);
1215 break;
1217 return rv;
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) {
1231 return true;
1234 return false;