fix for trie index
[csql.git] / src / sql / AlterTblStatement.cxx
blob18b3f0416ab75e838f933f789a84acd830a9a8f1
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 ret = tblDef.addField(fldName,info->type, info->length, info->defaultValueBuf, info->isNull, info->isAutoIncrement);
115 if( 0 != ret )
117 printError(ErrUnknown, "Error while adding field");
118 rv = ErrUnknown;
119 break;
121 fcount++;
124 fNameIter.reset();
125 while (fNameIter.hasElement())
127 delete (Identifier*) fNameIter.nextElement();
129 fNameList.reset();
130 if(altType == ALTERDROP)
132 delete info;
133 return rv;
135 FieldIterator iter = extraFldList.getIterator();
136 FieldName *name = NULL;
137 ListIterator nIter = parsedData->getFieldNameList().getIterator();
138 while (iter.hasElement())
140 FieldDef *fDef = iter.nextElement();
141 nIter.reset();
142 while (nIter.hasElement())
144 name = (FieldName*)nIter.nextElement();
145 if (strcmp(name->fldName, fDef->fldName_) == 0) fDef->isNull_ = true;
147 if (!fDef->isDefault_ || fDef->isDefault_ && fDef->defaultValueBuf_[0] == '\0') {
148 ret = tblDef.addField(fDef->fldName_, fDef->type_, fDef->length_,
149 NULL,fDef->isNull_,fDef->isAutoIncrement_);
150 } else {
151 ret = tblDef.addField(fDef->fldName_, fDef->type_, fDef->length_,
152 fDef->defaultValueBuf_,fDef->isNull_,fDef->isAutoIncrement_);
154 if( 0 != ret )
156 printError(ErrUnknown, "Error while adding field");
157 rv = ErrUnknown;
158 break;
160 valBuf = AllDataType::alloc(fDef->type_, fDef->length_);
161 bindFieldValues[fcount-1] = valBuf;
163 delete info;
164 return rv;
167 DbRetVal AlterTblStatement::executeForAddDropColumn(int &rowsAffected)
169 DbRetVal rv = OK;
170 char tblName[IDENTIFIER_LENGTH];
171 sprintf(tblName,"%s_temp",parsedData->getTableName());
172 rv = dbMgr->createTable(tblName, tblDef);
173 if (rv != OK) return rv;
174 rv = createIndex(parsedData->getTableName(),tblName);
175 if (rv != OK){
176 dbMgr->dropTable(tblName);
177 return rv;
179 //TODO:Create Foreign Key Info
180 Table *tempTable = dbMgr->openTable(tblName);
181 List fNameList = tempTable->getFieldNameList();
182 ListIterator fNameIter = fNameList.getIterator();
183 FieldInfo *info = new FieldInfo();
184 int fcount = 1; void *valBuf;
185 Identifier *elem = NULL;
186 while (fNameIter.hasElement())
188 elem = (Identifier*) fNameIter.nextElement();
189 tempTable->getFieldInfo((const char*)elem->name, info);
190 valBuf = bindFieldValues[fcount-1];
191 tempTable->bindFld(elem->name, valBuf);
192 fcount++;
194 table->setCondition(NULL);
195 rv = table->execute();
196 if (rv != OK)
198 dbMgr->closeTable(tempTable);
199 dbMgr->dropTable(tblName);
200 return rv;
202 void *tuple = NULL;
203 while(true)
205 int extraField = totalFields - noOfOldTabFld;
206 tuple = (char*)table->fetch();
207 if (tuple == NULL) {break;}
208 int i=1;
209 while(extraField--)
211 tempTable->markFldNull(noOfOldTabFld+i);
212 i++;
214 rv = tempTable->insertTuple();
215 if (rv != OK) break;
217 if (rv != OK){
218 dbMgr->closeTable(tempTable);
219 dbMgr->dropTable(tblName);
220 return rv;
222 char tblName1[IDENTIFIER_LENGTH];
223 sprintf(tblName1,"%s_temp2",parsedData->getTableName());
224 rv = dbMgr->renameTable(parsedData->getTableName(),tblName1);
225 if (rv != OK){
226 dbMgr->closeTable(tempTable);
227 dbMgr->dropTable(tblName);
228 return rv;
230 rv = dbMgr->renameTable(tblName,parsedData->getTableName());
231 if (rv != OK){
232 dbMgr->renameTable(tblName1,parsedData->getTableName());
233 dbMgr->closeTable(tempTable);
234 dbMgr->dropTable(tblName);
235 return rv;
237 rv = dbMgr->dropTable(tblName1);
238 if (rv != OK){
239 dbMgr->renameTable(tblName1,parsedData->getTableName());
240 dbMgr->closeTable(tempTable);
241 dbMgr->dropTable(tblName);
242 return rv;
244 return rv;
246 DbRetVal AlterTblStatement::createIndex(const char *oldName,const char *newName)
248 DbRetVal rv=OK;
249 CatalogTableINDEXFIELD cIndexField(((DatabaseManagerImpl *)dbMgr)->sysDb());
250 ListIterator iter = cIndexField.getIndexListIterater((char*)oldName);
251 IndexInfoForDriver *info=NULL;
252 char name[IDENTIFIER_LENGTH]="";
253 char indName[IDENTIFIER_LENGTH]="";
254 char tempIndexName[IDENTIFIER_LENGTH] ="";
255 sprintf(tempIndexName, "%s_idx1_Primary", oldName);
256 bool shouldCreateIndex = false;
257 bool isFirstEntry=true;
258 HashIndexInitInfo *idxInfo = NULL, *indexInfo2 = NULL;
259 while(iter.hasElement())
261 if(shouldCreateIndex)
263 if(idxInfo->isPrimary && 0 == strcmp(info->indexName,tempIndexName))
264 sprintf(indName, "%s_idx1_Primary", newName);
265 rv = dbMgr->createIndex(indName, idxInfo);
266 if (rv != OK)
268 delete idxInfo;
269 return rv;
271 delete idxInfo;
272 shouldCreateIndex = false;
273 idxInfo = NULL;
275 info = (IndexInfoForDriver *) iter.nextElement();
276 if((0 == strcmp(info->indexName,indName)))
278 if(idxInfo) idxInfo->list.append(info->fieldName);
279 else printf("should not happen\n");
280 }else{
281 idxInfo = new HashIndexInitInfo();
282 strcpy(idxInfo->tableName, newName);
283 strcpy(indName,info->indexName);
284 if(!isFirstEntry)shouldCreateIndex =true;
285 isFirstEntry = false;
286 idxInfo->indType =(IndexType) info->type;
287 idxInfo->isPrimary = info->isPrimary ;
288 idxInfo->isUnique = info->isUnique;
289 idxInfo->list.append(info->fieldName);
292 if (idxInfo == NULL) return OK;
293 if(idxInfo->isPrimary && 0 == strcmp(info->indexName,tempIndexName))
294 sprintf(indName, "%s_idx1_Primary", newName);
295 rv = dbMgr->createIndex(indName, idxInfo);
296 if (rv != OK)
298 delete idxInfo;
299 return rv;
301 delete idxInfo;
302 return OK;
306 DbRetVal AlterTblStatement::resolveForModifyColumn()
308 DbRetVal rv = OK;
309 return rv;