varchar size not proper and join table with qualifed and unqualifed field names in...
[csql.git] / src / sql / AlterTblStatement.cxx
blob063ebf758300f05412d1151d1d3e4dbfcb5c338e
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>
20 AlterTblStatement::AlterTblStatement()
22 bindFieldValues = NULL;
23 table = NULL;
24 totalFields = 0 ;
27 AlterTblStatement::~AlterTblStatement()
29 if (table) { table->close(); table = NULL; }
30 if(totalFields){
31 for(int i=0;i<totalFields;i++)
33 free(bindFieldValues[i]);
35 free(bindFieldValues); bindFieldValues = NULL;
39 DbRetVal AlterTblStatement::resolve()
41 DbRetVal rv = OK;
42 altType = parsedData->getAlterType();
43 if(altType == ALTERMODIFY)
45 printError(ErrUnknown, " NOT Done \n");
46 return ErrUnknown;
48 rv = resolveForAddDropColumn();
49 return rv;
52 DbRetVal AlterTblStatement::execute(int &rowsAffected)
54 DbRetVal rv = OK;
55 DatabaseManagerImpl *dmgr = (DatabaseManagerImpl *)dbMgr;
56 IsolationLevel iso = dmgr->txnMgr()->getIsoLevel();
57 rv = dmgr->txnMgr()->rollback(dmgr->lockMgr());
58 rv = dmgr->txnMgr()->startTransaction(dmgr->lockMgr(),iso);
60 if( altType == ALTERTABLERENAME)
62 rv = dbMgr->renameTable(parsedData->getTableName(), parsedData->getIndexName());
63 return rv;
64 }else if( altType == ALTERFIELDRENAME)
66 if (strcmp(parsedData->getIndexName(),parsedData->getPKTableName())==0)
67 return OK;
68 rv = dbMgr->renameField(parsedData->getTableName(), parsedData->getIndexName(),parsedData->getPKTableName());
69 return rv;
70 }else if(ALTERINDEXRENAME == altType){
71 rv = dbMgr->renameIndex(parsedData->getTableName(), parsedData->getIndexName());
72 return rv;
74 rv = executeForAddDropColumn(rowsAffected);
75 return rv;
78 DbRetVal AlterTblStatement::resolveForAddDropColumn()
80 DbRetVal rv = OK;
81 if( altType == ALTERTABLERENAME || altType == ALTERFIELDRENAME || altType == ALTERINDEXRENAME) return OK;
82 table = dbMgr->openTable(parsedData->getTableName());
83 if (table == NULL)
85 printError(ErrNotExists, "Unable to open the table:Table not exists");
86 return ErrNotExists;
88 List fNameList = table->getFieldNameList();
89 FieldList extraFldList = parsedData->getCreFldList() ;
90 ListIterator fNameIter = fNameList.getIterator();
91 FieldInfo *info = new FieldInfo();
92 int fcount = 1; void *valBuf; int ret=0;
93 Identifier *elem = NULL;
94 noOfOldTabFld = fNameList.size();
95 totalFields = noOfOldTabFld + extraFldList.size();
96 bindFieldValues = (void**) malloc( totalFields * sizeof(char*));
97 memset(bindFieldValues, 0, totalFields * sizeof(char*));
98 char fldName[IDENTIFIER_LENGTH];
99 int i = 1;
100 while (fNameIter.hasElement())
102 elem = (Identifier*) fNameIter.nextElement();
103 table->getFieldInfo((const char*)elem->name, info);
104 Table::getFieldNameAlone(elem->name,fldName);
105 //TODO :: Should free
106 valBuf = AllDataType::alloc(info->type, info->length);
107 table->bindFld(elem->name, valBuf);
108 if(altType == ALTERDROP && 0 == strcmp(parsedData->getIndexName(),fldName)){
109 bindFieldValues[totalFields-i] = valBuf; //Store Last
110 i--;
112 else {
113 bindFieldValues[fcount-1] = valBuf;
114 if (info->type == typeVarchar || info->type == typeString)
115 info->length++;
117 ret = tblDef.addField(fldName,info->type, info->length, info->defaultValueBuf, info->isNull, info->isAutoIncrement);
118 if( 0 != ret )
120 printError(ErrUnknown, "Error while adding field");
121 rv = ErrUnknown;
122 break;
124 fcount++;
127 fNameIter.reset();
128 while (fNameIter.hasElement())
130 delete (Identifier*) fNameIter.nextElement();
132 fNameList.reset();
133 if(altType == ALTERDROP)
135 delete info;
136 return rv;
138 FieldIterator iter = extraFldList.getIterator();
139 FieldName *name = NULL;
140 ListIterator nIter = parsedData->getFieldNameList().getIterator();
141 while (iter.hasElement())
143 FieldDef *fDef = iter.nextElement();
144 nIter.reset();
145 while (nIter.hasElement())
147 name = (FieldName*)nIter.nextElement();
148 if (strcmp(name->fldName, fDef->fldName_) == 0) fDef->isNull_ = true;
150 if (fDef->type_ == typeVarchar || fDef->type_ == typeString) {
151 fDef->length_++;
152 //varchar and char require \0 to be stored at the end
154 if (!fDef->isDefault_ || fDef->isDefault_ && fDef->defaultValueBuf_[0] == '\0') {
155 ret = tblDef.addField(fDef->fldName_, fDef->type_, fDef->length_,
156 NULL,fDef->isNull_,fDef->isAutoIncrement_);
157 } else {
158 ret = tblDef.addField(fDef->fldName_, fDef->type_, fDef->length_,
159 fDef->defaultValueBuf_,fDef->isNull_,fDef->isAutoIncrement_);
161 if( 0 != ret )
163 printError(ErrUnknown, "Error while adding field");
164 rv = ErrUnknown;
165 break;
167 valBuf = AllDataType::alloc(fDef->type_, fDef->length_);
168 bindFieldValues[fcount-1] = valBuf;
170 delete info;
171 return rv;
174 DbRetVal AlterTblStatement::executeForAddDropColumn(int &rowsAffected)
176 DbRetVal rv = OK;
177 char tblName[IDENTIFIER_LENGTH];
178 sprintf(tblName,"%s_temp",parsedData->getTableName());
179 rv = dbMgr->createTable(tblName, tblDef);
180 if (rv != OK) return rv;
181 rv = createIndex(parsedData->getTableName(),tblName);
182 if (rv != OK){
183 dbMgr->dropTable(tblName);
184 return rv;
186 //TODO:Create Foreign Key Info
187 Table *tempTable = dbMgr->openTable(tblName);
188 List fNameList = tempTable->getFieldNameList();
189 ListIterator fNameIter = fNameList.getIterator();
190 FieldInfo *info = new FieldInfo();
191 int fcount = 1; void *valBuf;
192 Identifier *elem = NULL;
193 while (fNameIter.hasElement())
195 elem = (Identifier*) fNameIter.nextElement();
196 tempTable->getFieldInfo((const char*)elem->name, info);
197 valBuf = bindFieldValues[fcount-1];
198 tempTable->bindFld(elem->name, valBuf);
199 fcount++;
201 table->setCondition(NULL);
202 rv = table->execute();
203 if (rv != OK)
205 dbMgr->closeTable(tempTable);
206 dbMgr->dropTable(tblName);
207 return rv;
209 void *tuple = NULL;
210 while(true)
212 int extraField = totalFields - noOfOldTabFld;
213 tuple = (char*)table->fetch();
214 if (tuple == NULL) {break;}
215 int i=1;
216 while(extraField--)
218 tempTable->markFldNull(noOfOldTabFld+i);
219 i++;
221 rv = tempTable->insertTuple();
222 if (rv != OK) break;
224 if (rv != OK){
225 dbMgr->closeTable(tempTable);
226 dbMgr->dropTable(tblName);
227 return rv;
229 char tblName1[IDENTIFIER_LENGTH];
230 sprintf(tblName1,"%s_temp2",parsedData->getTableName());
231 rv = dbMgr->renameTable(parsedData->getTableName(),tblName1);
232 if (rv != OK){
233 dbMgr->closeTable(tempTable);
234 dbMgr->dropTable(tblName);
235 return rv;
237 rv = dbMgr->renameTable(tblName,parsedData->getTableName());
238 if (rv != OK){
239 dbMgr->renameTable(tblName1,parsedData->getTableName());
240 dbMgr->closeTable(tempTable);
241 dbMgr->dropTable(tblName);
242 return rv;
244 rv = dbMgr->dropTable(tblName1);
245 if (rv != OK){
246 dbMgr->renameTable(tblName1,parsedData->getTableName());
247 dbMgr->closeTable(tempTable);
248 dbMgr->dropTable(tblName);
249 return rv;
251 return rv;
253 DbRetVal AlterTblStatement::createIndex(const char *oldName,const char *newName)
255 DbRetVal rv=OK;
256 CatalogTableINDEXFIELD cIndexField(((DatabaseManagerImpl *)dbMgr)->sysDb());
257 ListIterator iter = cIndexField.getIndexListIterater((char*)oldName);
258 IndexInfoForDriver *info=NULL;
259 char name[IDENTIFIER_LENGTH]="";
260 char indName[IDENTIFIER_LENGTH]="";
261 char tempIndexName[IDENTIFIER_LENGTH] ="";
262 sprintf(tempIndexName, "%s_idx1_Primary", oldName);
263 bool shouldCreateIndex = false;
264 bool isFirstEntry=true;
265 HashIndexInitInfo *idxInfo = NULL, *indexInfo2 = NULL;
266 while(iter.hasElement())
268 if(shouldCreateIndex)
270 if(idxInfo->isPrimary && 0 == strcmp(info->indexName,tempIndexName))
271 sprintf(indName, "%s_idx1_Primary", newName);
272 rv = dbMgr->createIndex(indName, idxInfo);
273 if (rv != OK)
275 delete idxInfo;
276 return rv;
278 delete idxInfo;
279 shouldCreateIndex = false;
280 idxInfo = NULL;
282 info = (IndexInfoForDriver *) iter.nextElement();
283 if((0 == strcmp(info->indexName,indName)))
285 if(idxInfo) idxInfo->list.append(info->fieldName);
286 else printf("should not happen\n");
287 }else{
288 idxInfo = new HashIndexInitInfo();
289 strcpy(idxInfo->tableName, newName);
290 strcpy(indName,info->indexName);
291 if(!isFirstEntry)shouldCreateIndex =true;
292 isFirstEntry = false;
293 idxInfo->indType =(IndexType) info->type;
294 idxInfo->isPrimary = info->isPrimary ;
295 idxInfo->isUnique = info->isUnique;
296 idxInfo->list.append(info->fieldName);
299 if (idxInfo == NULL) return OK;
300 if(idxInfo->isPrimary && 0 == strcmp(info->indexName,tempIndexName))
301 sprintf(indName, "%s_idx1_Primary", newName);
302 rv = dbMgr->createIndex(indName, idxInfo);
303 if (rv != OK)
305 delete idxInfo;
306 return rv;
308 delete idxInfo;
309 return OK;
313 DbRetVal AlterTblStatement::resolveForModifyColumn()
315 DbRetVal rv = OK;
316 return rv;