Fix for Bug # 2483638
[csql.git] / src / sql / UpdStatement.cxx
blobe36b28c4d0b7e8d60bd1e05bff19683bb0bf8bf6
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 "Statement.h"
17 #include <Info.h>
19 UpdStatement::UpdStatement()
21 parsedData = NULL;
22 dbMgr = NULL;
23 table = NULL;
24 params = NULL;
25 paramValues = NULL;
26 totalParams = 0;
27 totalAssignParams =0;
30 UpdStatement::~UpdStatement() {
31 if (totalParams) {
32 //TODO::below free cause memory corruption.
33 free(params);
34 params = NULL;
35 free(paramValues);
36 paramValues = NULL;
38 if (table) {
39 table->setCondition(NULL);
40 if (dbMgr) dbMgr->closeTable(table);
43 void* UpdStatement::getParamValuePtr( int pos )
45 ConditionValue *cValue;
46 UpdateFieldValue *uValue;
47 if (pos <= totalAssignParams) {
48 uValue = (UpdateFieldValue*) params[pos-1];
49 return( (void*) uValue->value );
50 } else {
51 cValue = (ConditionValue*) params[pos-1];
52 return( (void*) cValue->value );
56 DbRetVal UpdStatement::getParamFldInfo(int paramPos, FieldInfo *&info)
58 if (paramPos <=0 || paramPos > totalParams) return ErrBadArg;
59 if (NULL == params[paramPos-1])
61 printError(ErrSysFatal, "param not set. Should never happen");
62 return ErrSysFatal;
65 ConditionValue *cValue;
66 UpdateFieldValue *uValue;
67 if (paramPos <= totalAssignParams) {
68 uValue = (UpdateFieldValue*) params[paramPos-1];
69 table->getFieldNameAlone(uValue->fldName,info->fldName);
70 info->type = uValue->type;
71 info->length = uValue->length;
72 info->isNull = uValue->isNullable;
73 } else {
74 cValue = (ConditionValue*) params[paramPos-1];
75 table->getFieldNameAlone(cValue->fName,info->fldName);
76 info->type = cValue->type;
77 info->length = cValue->length;
78 info->isNull = cValue->isNullable;
80 return OK;
83 DbRetVal UpdStatement::execute(int &rowsAffected)
85 DbRetVal rv = OK;
86 //copy param values to binded buffer
87 ConditionValue *cValue;
88 UpdateFieldValue *uValue;
90 for (int i = 0; i < totalParams; i ++)
92 if (i < totalAssignParams) {
93 uValue = (UpdateFieldValue*) params[i];
94 if (paramValues[i] == NULL)
96 continue;
97 //printError(ErrBadCall, "param values not set");
98 //return ErrBadCall;
100 AllDataType::copyVal(uValue->value, paramValues[i], uValue->type, uValue->length);
101 } else {
102 cValue = (ConditionValue*) params[i];
103 if (paramValues[i] == NULL)
105 continue;
106 //printError(ErrBadCall, "param values not set");
107 //return ErrBadCall;
109 AllDataType::copyVal(cValue->value, paramValues[i], cValue->type, cValue->length);
112 rv = table->execute();
113 if (rv != OK) return rv;
114 rowsAffected = 0;
115 void *tuple;
116 ListIterator iter = parsedData->getUpdateFieldValueList().getIterator();
117 while(true)
119 tuple = (char*)table->fetchNoBind(rv);
120 if (rv != OK) break;
121 if (tuple == NULL) {break;}
122 iter.reset();
123 while (iter.hasElement())
125 uValue = (UpdateFieldValue*) iter.nextElement();
126 if(uValue->expre!=NULL)
128 uValue->expre->setTuple(tuple);
129 uValue->expre->setTable(table);
130 AllDataType::copyVal(uValue->value,(uValue->expre)->evaluate(uValue->type),uValue->type, uValue->length);
131 uValue->expre->memFree();
134 rv = table->updateTuple();
135 if (rv != OK) break;
136 rowsAffected++;
138 table->close();
139 return rv;
143 DbRetVal UpdStatement::setParam(int paramNo, void *value)
145 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
146 if (NULL == value) return ErrBadArg;
147 paramValues[paramNo -1] = (char*) value;
148 return OK;
151 DbRetVal UpdStatement::setShortParam(int paramNo, short value)
153 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
154 if (NULL == params[paramNo-1])
156 printError(ErrSysFatal, "param not set. Should never happen");
157 return ErrSysFatal;
160 ConditionValue *cValue;
161 UpdateFieldValue *uValue;
162 if (paramNo <= totalAssignParams) {
163 uValue = (UpdateFieldValue*) params[paramNo-1];
164 *(short*)uValue->value = value;
165 } else {
166 cValue = (ConditionValue*) params[paramNo-1];
167 *(short*)cValue->value = value;
169 return OK;
173 DbRetVal UpdStatement::setIntParam(int paramNo, int value)
175 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
176 if (NULL == params[paramNo-1])
178 printError(ErrSysFatal, "param not set. Should never happen");
179 return ErrSysFatal;
181 ConditionValue *cValue;
182 UpdateFieldValue *uValue;
183 if (paramNo <= totalAssignParams) {
184 uValue = (UpdateFieldValue*) params[paramNo-1];
185 *(int*)uValue->value = value;
186 } else {
187 cValue = (ConditionValue*) params[paramNo-1];
188 *(int*)cValue->value = value;
190 return OK;
193 DbRetVal UpdStatement::setLongParam(int paramNo, long value)
195 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
196 if (NULL == params[paramNo-1])
198 printError(ErrSysFatal, "param not set. Should never happen");
199 return ErrSysFatal;
202 ConditionValue *cValue;
203 UpdateFieldValue *uValue;
204 if (paramNo <= totalAssignParams) {
205 uValue = (UpdateFieldValue*) params[paramNo-1];
206 *(long*)uValue->value = value;
207 } else {
208 cValue = (ConditionValue*) params[paramNo-1];
209 *(long*)cValue->value = value;
211 return OK;
214 DbRetVal UpdStatement::setLongLongParam(int paramNo, long long value)
216 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
217 if (NULL == params[paramNo-1])
219 printError(ErrSysFatal, "param not set. Should never happen");
220 return ErrSysFatal;
223 ConditionValue *cValue;
224 UpdateFieldValue *uValue;
225 if (paramNo <= totalAssignParams) {
226 uValue = (UpdateFieldValue*) params[paramNo-1];
227 *(long long*)uValue->value = value;
228 } else {
229 cValue = (ConditionValue*) params[paramNo-1];
230 *(long long*)cValue->value = value;
232 return OK;
235 DbRetVal UpdStatement::setByteIntParam(int paramNo, ByteInt value)
237 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
238 if (NULL == params[paramNo-1])
240 printError(ErrSysFatal, "param not set. Should never happen");
241 return ErrSysFatal;
244 ConditionValue *cValue;
245 UpdateFieldValue *uValue;
246 if (paramNo <= totalAssignParams) {
247 uValue = (UpdateFieldValue*) params[paramNo-1];
248 *(ByteInt*)uValue->value = value;
249 } else {
250 cValue = (ConditionValue*) params[paramNo-1];
251 *(ByteInt*)cValue->value = value;
253 return OK;
256 DbRetVal UpdStatement::setFloatParam(int paramNo, float value)
258 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
259 if (NULL == params[paramNo-1])
261 printError(ErrSysFatal, "param not set. Should never happen");
262 return ErrSysFatal;
265 ConditionValue *cValue;
266 UpdateFieldValue *uValue;
267 if (paramNo <= totalAssignParams) {
268 uValue = (UpdateFieldValue*) params[paramNo-1];
269 *(float*)uValue->value = value;
270 } else {
271 cValue = (ConditionValue*) params[paramNo-1];
272 *(float*)cValue->value = value;
274 return OK;
278 DbRetVal UpdStatement::setDoubleParam(int paramNo, double value)
280 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
281 if (NULL == params[paramNo-1])
283 printError(ErrSysFatal, "param not set. Should never happen");
284 return ErrSysFatal;
287 ConditionValue *cValue;
288 UpdateFieldValue *uValue;
289 if (paramNo <= totalAssignParams) {
290 uValue = (UpdateFieldValue*) params[paramNo-1];
291 *(double*)uValue->value = value;
292 } else {
293 cValue = (ConditionValue*) params[paramNo-1];
294 *(double*)cValue->value = value;
296 return OK;
299 DbRetVal UpdStatement::setStringParam(int paramNo, char *value)
301 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
302 if (NULL == params[paramNo-1])
304 printError(ErrSysFatal, "param not set. Should never happen");
305 return ErrSysFatal;
308 ConditionValue *cValue;
309 UpdateFieldValue *uValue;
310 if (paramNo <= totalAssignParams) {
311 uValue = (UpdateFieldValue*) params[paramNo-1];
312 strcpy((char*)uValue->value, value);
313 } else {
314 cValue = (ConditionValue*) params[paramNo-1];
315 strcpy((char*)cValue->value, value);
317 return OK;
321 DbRetVal UpdStatement::setDateParam(int paramNo, Date value)
323 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
324 if (NULL == params[paramNo-1])
326 printError(ErrSysFatal, "param not set. Should never happen");
327 return ErrSysFatal;
330 ConditionValue *cValue;
331 UpdateFieldValue *uValue;
332 if (paramNo <= totalAssignParams) {
333 uValue = (UpdateFieldValue*) params[paramNo-1];
334 *(Date*)uValue->value = value;
335 } else {
336 cValue = (ConditionValue*) params[paramNo-1];
337 *(Date*)cValue->value = value;
339 return OK;
342 DbRetVal UpdStatement::setTimeParam(int paramNo, Time value)
344 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
345 if (NULL == params[paramNo-1])
347 printError(ErrSysFatal, "param not set. Should never happen");
348 return ErrSysFatal;
351 ConditionValue *cValue;
352 UpdateFieldValue *uValue;
353 if (paramNo <= totalAssignParams) {
354 uValue = (UpdateFieldValue*) params[paramNo-1];
355 *(Time*)uValue->value = value;
356 } else {
357 cValue = (ConditionValue*) params[paramNo-1];
358 *(Time*)cValue->value = value;
360 return OK;
364 DbRetVal UpdStatement::setTimeStampParam(int paramNo, TimeStamp value)
366 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
367 if (NULL == params[paramNo-1])
369 printError(ErrSysFatal, "param not set. Should never happen");
370 return ErrSysFatal;
373 ConditionValue *cValue;
374 UpdateFieldValue *uValue;
375 if (paramNo <= totalAssignParams) {
376 uValue = (UpdateFieldValue*) params[paramNo-1];
377 *(TimeStamp*)uValue->value = value;
378 } else {
379 cValue = (ConditionValue*) params[paramNo-1];
380 *(TimeStamp*)cValue->value = value;
382 return OK;
385 DbRetVal UpdStatement::setBinaryParam(int paramNo, void *value)
387 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
388 if (NULL == params[paramNo-1])
390 printError(ErrSysFatal, "param not set. Should never happen");
391 return ErrSysFatal;
394 ConditionValue *cValue;
395 UpdateFieldValue *uValue;
396 if (paramNo <= totalAssignParams) {
397 uValue = (UpdateFieldValue*) params[paramNo-1];
398 memcpy(uValue->value, value, 2 * uValue->length);
399 } else {
400 cValue = (ConditionValue*) params[paramNo-1];
401 AllDataType::convertToBinary(cValue->value,value,typeString,cValue->length);
403 return OK;
406 DbRetVal UpdStatement::resolve()
408 if (dbMgr == NULL) return ErrNoConnection;
409 //check whether the table exists
410 table = dbMgr->openTable(parsedData->getTableName());
411 if (table == NULL)
413 printError(ErrNotExists, "Unable to open the table:Table not exists");
414 return ErrNotExists;
417 table->setCondition(parsedData->getCondition());
419 DbRetVal rv = resolveForAssignment();
420 if (rv != OK)
422 //TODO::free memory allocated for params
423 table->setCondition(NULL);
424 dbMgr->closeTable(table);
425 table = NULL;
427 return rv;
430 DbRetVal UpdStatement::resolveForAssignment()
432 //get the fieldname list and validate field names
433 ListIterator iter = parsedData->getUpdateFieldValueList().getIterator();
435 UpdateFieldValue *value;
436 FieldInfo *fInfo = new FieldInfo();
437 int paramPos =1;
438 DbRetVal rv = OK;
439 while (iter.hasElement())
441 value = (UpdateFieldValue*) iter.nextElement();
442 if (NULL == value)
444 delete fInfo;
445 printError(ErrSysFatal, "Should never happen.");
446 return ErrSysFatal;
448 rv = table->getFieldInfo(value->fldName, fInfo);
449 if (ErrNotFound == rv)
451 delete fInfo;
452 printError(ErrSyntaxError, "Field %s does not exist in table",
453 value->fldName);
454 return ErrSyntaxError;
456 if (fInfo->isUnique) {
457 printError(ErrUnique, "Unique field %s cannot be updated", value->fldName);
458 return ErrUnique;
460 value->type = fInfo->type;
461 value->length = fInfo->length;
462 value->isNullable = fInfo->isNull;
463 // for binary datatype input buffer size should be 2 times the length
464 if (value->type == typeBinary)
465 value->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
466 else value->value = AllDataType::alloc(fInfo->type, fInfo->length);
467 table->bindFld(value->fldName, value->value);
468 if( NULL != value->expre )
470 (value->expre)->convertStrToVal(value->type);
471 continue;
473 if (value->parsedString == NULL)
475 if (fInfo->isNull) { delete fInfo; return ErrNullViolation; }
476 table->markFldNull(value->fldName);
477 continue;
479 if (value->parsedString[0] == '?')
481 value->paramNo = paramPos++;
483 if (!value->paramNo) {
484 // for binary datatype buffer is just strcpy'd. It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI
485 if (value->type == typeBinary)
486 strncpy((char *)value->value, value->parsedString, 2 * fInfo->length);
487 else AllDataType::strToValue(value->value, value->parsedString, fInfo->type, value->length);
490 totalAssignParams = paramPos -1;
493 //get the fieldname list and validate field names
494 ListIterator cIter = parsedData->getConditionValueList().getIterator();
495 ConditionValue *cValue = NULL;
496 while (cIter.hasElement())
498 cValue = (ConditionValue*) cIter.nextElement();
499 if (NULL == cValue)
501 delete fInfo;
502 printError(ErrSysFatal, "Should never happen.");
503 return ErrSysFatal;
505 rv = table->getFieldInfo(cValue->fName, fInfo);
506 if (ErrNotFound == rv)
508 delete fInfo;
509 printError(ErrSyntaxError, "Field %s does not exist in table",
510 cValue->fName);
511 return ErrSyntaxError;
513 cValue->type = fInfo->type;
514 cValue->length = fInfo->length;
515 cValue->isNullable = fInfo->isNull;
516 // for binary datatype input buffer size should be 2 times the length
517 if (cValue->type == typeBinary)
519 if(cValue->parsedString[0] == '?')
520 cValue->value = AllDataType::alloc(fInfo->type, fInfo->length);
521 else
522 cValue->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
524 else cValue->value = AllDataType::alloc(fInfo->type, fInfo->length);
525 if (cValue->parsedString == NULL)
527 delete fInfo;
528 printError(ErrSyntaxError, "Condition value should not be NULL");
529 return ErrSyntaxError;
532 if (cValue->parsedString[0] == '?')
534 if(! cValue->opLike) // checks if 'LIKE' operator is used
535 cValue->paramNo = paramPos++;
537 if (!cValue->paramNo) {
538 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
539 AllDataType::strToValue(cValue->value, cValue->parsedString, fInfo->type, fInfo->length);
543 delete fInfo;
544 totalParams = paramPos -1;
545 if (0 == totalParams) return OK;
546 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
547 paramValues = (char**) malloc( totalParams * sizeof(char*));
549 memset(params, 0, totalParams * sizeof(FieldValue*));
550 memset(paramValues, 0, totalParams * sizeof(char*));
552 iter.reset();
553 while(iter.hasElement())
555 value = (UpdateFieldValue*) iter.nextElement();
556 if (value == NULL)
558 free(params); params = NULL;
559 free(paramValues); paramValues = NULL;
560 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
561 return ErrSysFatal;
563 if (0 == value->paramNo) continue;
564 params[value->paramNo -1 ] = value;
567 cIter.reset();
568 while(cIter.hasElement())
570 cValue = (ConditionValue*) cIter.nextElement();
571 if (cValue == NULL)
573 free(params); params = NULL;
574 free(paramValues); paramValues = NULL;
575 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
576 return ErrSysFatal;
578 if (0 == cValue->paramNo) continue;
579 params[cValue->paramNo -1 ] = cValue;
581 return OK;
583 int UpdStatement::getFldPos(char *name)
585 return table->getFldPos(name);