64 bit build fix
[csql.git] / src / sql / UpdStatement.cxx
blob181928939d1b27484255b82922e74305f2048bd4
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 <Info.h>
20 UpdStatement::UpdStatement()
22 parsedData = NULL;
23 dbMgr = NULL;
24 table = NULL;
25 params = NULL;
26 paramValues = NULL;
27 totalParams = 0;
28 totalAssignParams =0;
31 UpdStatement::~UpdStatement() {
32 if (table) { table->close(); table = NULL; }
33 if (totalParams) {
34 //TODO::below free cause memory corruption.
35 free(params);
36 params = NULL;
37 free(paramValues);
38 paramValues = NULL;
41 void* UpdStatement::getParamValuePtr( int pos )
43 ConditionValue *cValue;
44 UpdateFieldValue *uValue;
45 if (pos <= totalAssignParams) {
46 uValue = (UpdateFieldValue*) params[pos-1];
47 return( (void*) uValue->value );
48 } else {
49 cValue = (ConditionValue*) params[pos-1];
50 return( (void*) cValue->value );
54 DbRetVal UpdStatement::getParamFldInfo(int paramPos, FieldInfo *&info)
56 if (paramPos <=0 || paramPos > totalParams) return ErrBadArg;
57 if (NULL == params[paramPos-1])
59 printError(ErrSysFatal, "param not set. Should never happen");
60 return ErrSysFatal;
63 ConditionValue *cValue;
64 UpdateFieldValue *uValue;
65 if (paramPos <= totalAssignParams) {
66 uValue = (UpdateFieldValue*) params[paramPos-1];
67 table->getFieldNameAlone(uValue->fldName,info->fldName);
68 info->type = uValue->type;
69 info->length = uValue->length;
70 info->isNull = uValue->isNullable;
71 } else {
72 cValue = (ConditionValue*) params[paramPos-1];
73 table->getFieldNameAlone(cValue->fName,info->fldName);
74 info->type = cValue->type;
75 info->length = cValue->length;
76 info->isNull = cValue->isNullable;
78 return OK;
81 DbRetVal UpdStatement::execute(int &rowsAffected)
83 DbRetVal rv = OK;
84 //copy param values to binded buffer
85 ConditionValue *cValue;
86 UpdateFieldValue *uValue;
88 for (int i = 0; i < totalParams; i ++)
90 if (i < totalAssignParams) {
91 uValue = (UpdateFieldValue*) params[i];
92 if (paramValues[i] == NULL)
94 continue;
95 //printError(ErrBadCall, "param values not set");
96 //return ErrBadCall;
98 AllDataType::copyVal(uValue->value, paramValues[i], uValue->type, uValue->length);
99 } else {
100 cValue = (ConditionValue*) params[i];
101 if (paramValues[i] == NULL)
103 continue;
104 //printError(ErrBadCall, "param values not set");
105 //return ErrBadCall;
107 AllDataType::copyVal(cValue->value, paramValues[i], cValue->type, cValue->length);
110 rv = table->execute();
111 if (rv != OK) return rv;
112 rowsAffected = 0;
113 void *tuple;
114 ListIterator iter = parsedData->getUpdateFieldValueList().getIterator();
115 bool nullFlag;
116 while(true)
118 tuple = (char*)table->fetchNoBind(rv);
119 if (rv != OK) break;
120 if (tuple == NULL) {break;}
121 iter.reset();
122 while (iter.hasElement())
124 uValue = (UpdateFieldValue*) iter.nextElement();
125 if(uValue->expre!=NULL)
127 nullFlag=false;
128 uValue->expre->setTuple(tuple);
129 uValue->expre->setTable(table);
130 AllDataType::copyVal(uValue->value,(uValue->expre)->evaluate(uValue->type,nullFlag),uValue->type, uValue->length);
131 uValue->expre->memFree();
132 if(nullFlag)
134 rv=table->markFldNull(uValue->fldName);
135 if(rv==ErrNullViolation){return ErrNullViolation;}
139 rv = table->updateTuple();
140 if (rv != OK) break;
141 rowsAffected++;
143 table->closeScan();
144 return rv;
148 DbRetVal UpdStatement::setParam(int paramNo, void *value)
150 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
151 if (NULL == value) return ErrBadArg;
152 paramValues[paramNo -1] = (char*) value;
153 return OK;
156 DbRetVal UpdStatement::setShortParam(int paramNo, short value)
158 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
159 if (NULL == params[paramNo-1])
161 printError(ErrSysFatal, "param not set. Should never happen");
162 return ErrSysFatal;
165 ConditionValue *cValue;
166 UpdateFieldValue *uValue;
167 if (paramNo <= totalAssignParams) {
168 uValue = (UpdateFieldValue*) params[paramNo-1];
169 *(short*)uValue->value = value;
170 } else {
171 cValue = (ConditionValue*) params[paramNo-1];
172 *(short*)cValue->value = value;
174 return OK;
178 DbRetVal UpdStatement::setIntParam(int paramNo, int value)
180 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
181 if (NULL == params[paramNo-1])
183 printError(ErrSysFatal, "param not set. Should never happen");
184 return ErrSysFatal;
186 ConditionValue *cValue;
187 UpdateFieldValue *uValue;
188 if (paramNo <= totalAssignParams) {
189 uValue = (UpdateFieldValue*) params[paramNo-1];
190 *(int*)uValue->value = value;
191 } else {
192 cValue = (ConditionValue*) params[paramNo-1];
193 *(int*)cValue->value = value;
195 return OK;
197 DbRetVal UpdStatement::setNull(int paramNo)
199 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
200 if (NULL == params[paramNo-1])
202 printError(ErrSysFatal, "param not set. Should never happen");
203 return ErrSysFatal;
205 ConditionValue *cValue;
206 UpdateFieldValue *uValue;
207 if (paramNo <= totalAssignParams) {
208 uValue = (UpdateFieldValue*) params[paramNo-1];
209 table->markFldNull(uValue->fldName);
210 } else {
211 printf("paramerise for predicate nullset not supported\n");
214 DbRetVal UpdStatement::setLongParam(int paramNo, 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*)uValue->value = value;
228 } else {
229 cValue = (ConditionValue*) params[paramNo-1];
230 *(long*)cValue->value = value;
232 return OK;
235 DbRetVal UpdStatement::setLongLongParam(int paramNo, long long 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 *(long long*)uValue->value = value;
249 } else {
250 cValue = (ConditionValue*) params[paramNo-1];
251 *(long long*)cValue->value = value;
253 return OK;
256 DbRetVal UpdStatement::setByteIntParam(int paramNo, ByteInt 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 *(ByteInt*)uValue->value = value;
270 } else {
271 cValue = (ConditionValue*) params[paramNo-1];
272 *(ByteInt*)cValue->value = value;
274 return OK;
277 DbRetVal UpdStatement::setFloatParam(int paramNo, float value)
279 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
280 if (NULL == params[paramNo-1])
282 printError(ErrSysFatal, "param not set. Should never happen");
283 return ErrSysFatal;
286 ConditionValue *cValue;
287 UpdateFieldValue *uValue;
288 if (paramNo <= totalAssignParams) {
289 uValue = (UpdateFieldValue*) params[paramNo-1];
290 *(float*)uValue->value = value;
291 } else {
292 cValue = (ConditionValue*) params[paramNo-1];
293 *(float*)cValue->value = value;
295 return OK;
299 DbRetVal UpdStatement::setDoubleParam(int paramNo, double 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 *(double*)uValue->value = value;
313 } else {
314 cValue = (ConditionValue*) params[paramNo-1];
315 *(double*)cValue->value = value;
317 return OK;
320 DbRetVal UpdStatement::setStringParam(int paramNo, char *value)
322 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
323 if (NULL == params[paramNo-1])
325 printError(ErrSysFatal, "param not set. Should never happen");
326 return ErrSysFatal;
329 ConditionValue *cValue;
330 UpdateFieldValue *uValue;
331 if (paramNo <= totalAssignParams) {
332 uValue = (UpdateFieldValue*) params[paramNo-1];
333 strcpy((char*)uValue->value, value);
334 } else {
335 cValue = (ConditionValue*) params[paramNo-1];
336 strcpy((char*)cValue->value, value);
338 return OK;
342 DbRetVal UpdStatement::setDateParam(int paramNo, Date 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 *(Date*)uValue->value = value;
356 } else {
357 cValue = (ConditionValue*) params[paramNo-1];
358 *(Date*)cValue->value = value;
360 return OK;
363 DbRetVal UpdStatement::setTimeParam(int paramNo, Time value)
365 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
366 if (NULL == params[paramNo-1])
368 printError(ErrSysFatal, "param not set. Should never happen");
369 return ErrSysFatal;
372 ConditionValue *cValue;
373 UpdateFieldValue *uValue;
374 if (paramNo <= totalAssignParams) {
375 uValue = (UpdateFieldValue*) params[paramNo-1];
376 *(Time*)uValue->value = value;
377 } else {
378 cValue = (ConditionValue*) params[paramNo-1];
379 *(Time*)cValue->value = value;
381 return OK;
385 DbRetVal UpdStatement::setTimeStampParam(int paramNo, TimeStamp 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 *(TimeStamp*)uValue->value = value;
399 } else {
400 cValue = (ConditionValue*) params[paramNo-1];
401 *(TimeStamp*)cValue->value = value;
403 return OK;
406 DbRetVal UpdStatement::setBinaryParam(int paramNo, void *value, int length)
408 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
409 if (NULL == params[paramNo-1])
411 printError(ErrSysFatal, "param not set. Should never happen");
412 return ErrSysFatal;
415 ConditionValue *cValue;
416 UpdateFieldValue *uValue;
417 if (paramNo <= totalAssignParams) {
418 uValue = (UpdateFieldValue*) params[paramNo-1];
419 memcpy(uValue->value, value, 2 * uValue->length);
420 } else {
421 cValue = (ConditionValue*) params[paramNo-1];
422 AllDataType::convertToBinary(cValue->value,value,typeString,cValue->length);
424 return OK;
427 DbRetVal UpdStatement::resolve()
429 if (dbMgr == NULL) return ErrNoConnection;
430 //check whether the table exists
431 table = dbMgr->openTable(parsedData->getTableName());
432 if (table == NULL)
434 printError(ErrNotExists, "Unable to open the table:Table not exists");
435 return ErrNotExists;
438 table->setCondition(parsedData->getCondition());
440 DbRetVal rv = resolveForAssignment();
441 if (rv != OK)
443 //TODO::free memory allocated for params
444 table->setCondition(NULL);
445 dbMgr->closeTable(table);
446 table = NULL;
448 return rv;
451 DbRetVal UpdStatement::resolveForAssignment()
453 //get the fieldname list and validate field names
454 ListIterator iter = parsedData->getUpdateFieldValueList().getIterator();
456 UpdateFieldValue *value;
457 FieldInfo *fInfo = new FieldInfo();
458 int paramPos =1;
459 DbRetVal rv = OK;
460 while (iter.hasElement())
462 value = (UpdateFieldValue*) iter.nextElement();
463 if (NULL == value)
465 delete fInfo;
466 printError(ErrSysFatal, "Should never happen.");
467 return ErrSysFatal;
469 rv = table->getFieldInfo(value->fldName, fInfo);
470 if (ErrNotFound == rv)
472 delete fInfo;
473 printError(ErrSyntaxError, "Field %s does not exist in table",
474 value->fldName);
475 return ErrSyntaxError;
477 if (fInfo->isUnique) {
478 delete fInfo;
479 printError(ErrUnique, "Unique field %s cannot be updated", value->fldName);
480 return ErrUnique;
482 if (fInfo->isAutoIncrement){
483 delete fInfo;
484 printError(ErrAutoIncUpdate, "Auto_increment key field '%s' cannot be updated \n", value->fldName);
485 return ErrAutoIncUpdate;
488 value->type = fInfo->type;
489 value->length = fInfo->length;
490 value->isNullable = fInfo->isNull;
491 // for binary datatype input buffer size should be 2 times the length
492 if (value->type == typeBinary)
493 value->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
494 else value->value = AllDataType::alloc(fInfo->type, fInfo->length);
495 table->bindFld(value->fldName, value->value);
496 if( NULL != value->expre )
498 (value->expre)->convertStrToVal(value->type);
499 continue;
501 if (value->parsedString == NULL)
503 if (fInfo->isNull) {
504 delete fInfo;
505 printError(ErrNullViolation, "Null Violation Error.");
506 return ErrNullViolation;
508 table->markFldNull(value->fldName);
509 memset(value->value, 0, value->length);
510 continue;
512 if (value->parsedString[0] == '?')
514 value->paramNo = paramPos++;
516 if (!value->paramNo) {
517 // checking for Integer value
518 if((value->type == typeInt) || (value->type==typeShort) || (value->type==typeByteInt) || (value->type==typeLongLong) || (value->type==typeLong)){
519 int len=strlen(value->parsedString);
520 for(int n=0;n<len;n++){
521 int p=value->parsedString[n];
522 if(!(p>=48 && p<=57 || p==45)) {
523 delete fInfo;
524 return ErrBadArg;
528 // for binary datatype buffer is just strcpy'd. It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI
529 if (value->type == typeBinary)
530 strncpy((char *)value->value, value->parsedString, 2 * fInfo->length);
531 else {
532 rv = AllDataType::strToValue(value->value, value->parsedString, fInfo->type, value->length);
533 if (OK != rv)
535 delete fInfo;
536 return ErrBadArg;
539 /* Check for char data type 8kb(8000) */
540 if(value->type==typeString){
541 int len=strlen(value->parsedString);
542 if(len > 8000){
543 printError(ErrBadRange, "Char DataType length should be less than 8kb(8000).");
544 delete fInfo;
545 return ErrBadRange;
551 totalAssignParams = paramPos -1;
552 //get the fieldname list and validate field names
553 ListIterator cIter = parsedData->getConditionValueList().getIterator();
554 ConditionValue *cValue = NULL;
555 while (cIter.hasElement())
557 cValue = (ConditionValue*) cIter.nextElement();
558 if (NULL == cValue)
560 delete fInfo;
561 printError(ErrSysFatal, "Should never happen.");
562 return ErrSysFatal;
564 char tName[IDENTIFIER_LENGTH];
565 Table::getTableNameAlone(cValue->fName,tName);
566 if( strcmp(tName,"")!=0 && strcmp(parsedData->getTableName(),tName)!=0 )
568 delete fInfo;
569 printError(ErrSyntaxError, "Field %s does not exist in table %s", cValue->fName,parsedData->getTableName());
570 return ErrSyntaxError;
573 rv = table->getFieldInfo(cValue->fName, fInfo);
574 if (ErrNotFound == rv)
576 delete fInfo;
577 printError(ErrSyntaxError, "Field %s does not exist in table",
578 cValue->fName);
579 return ErrSyntaxError;
581 cValue->type = fInfo->type;
582 cValue->length = fInfo->length;
583 cValue->isNullable = fInfo->isNull;
584 // for binary datatype input buffer size should be 2 times the length
585 if (cValue->type == typeBinary)
587 if(cValue->parsedString[0] == '?')
588 cValue->value = AllDataType::alloc(fInfo->type, fInfo->length);
589 else
590 cValue->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
592 else cValue->value = AllDataType::alloc(fInfo->type, fInfo->length);
593 if(cValue->paramNo == 1){continue;}
594 if (cValue->parsedString == NULL)
596 delete fInfo;
597 printError(ErrSyntaxError, "Condition value should not be NULL");
598 return ErrSyntaxError;
601 if (cValue->parsedString[0] == '?')
603 //if(! cValue->opLike) // checks if 'LIKE' operator is used
604 cValue->paramNo = paramPos++;
606 if (!cValue->paramNo) {
607 //Checking for integer value
608 if((cValue->type == typeInt) || (cValue->type==typeShort) || (cValue->type==typeByteInt) || (cValue->type==typeLongLong) || (cValue->type==typeLong)){
609 int len = strlen(cValue->parsedString);
610 for(int n=0;n<len;n++){
611 int p=cValue->parsedString[n];
612 if(!(p>=48 && p<=57 || p==45)) {
613 delete fInfo;
614 return ErrBadArg;
618 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
619 rv = AllDataType::strToValue(cValue->value, cValue->parsedString, fInfo->type, fInfo->length);
620 if (OK != rv) {
621 delete fInfo;
622 return ErrBadArg;
626 delete fInfo;
627 totalParams = paramPos -1;
628 if (0 == totalParams) return OK;
629 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
630 paramValues = (char**) malloc( totalParams * sizeof(char*));
632 memset(params, 0, totalParams * sizeof(FieldValue*));
633 memset(paramValues, 0, totalParams * sizeof(char*));
635 iter.reset();
636 while(iter.hasElement())
638 value = (UpdateFieldValue*) iter.nextElement();
639 if (value == NULL)
641 free(params); params = NULL;
642 free(paramValues); paramValues = NULL;
643 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
644 return ErrSysFatal;
646 if (0 == value->paramNo) continue;
647 params[value->paramNo -1 ] = value;
650 cIter.reset();
651 while(cIter.hasElement())
653 cValue = (ConditionValue*) cIter.nextElement();
654 if (cValue == NULL)
656 free(params); params = NULL;
657 free(paramValues); paramValues = NULL;
658 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
659 return ErrSysFatal;
661 if (0 == cValue->paramNo) continue;
662 params[cValue->paramNo -1 ] = cValue;
664 return OK;
666 int UpdStatement::getFldPos(char *name)
668 return table->getFldPos(name);