statement caching modifications and cache stmt display
[csql.git] / src / sql / AlterTblStatement.cxx
blobce6ad2f996465c69bb9e8d37a8d7adbf4387a430
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 table = dbMgr->openTable(parsedData->getTableName());
43 if (table == NULL)
45 printError(ErrNotExists, "Unable to open the table:Table not exists");
46 return ErrNotExists;
48 altType = parsedData->getAlterType();
49 if(altType == ALTERMODIFY)
51 printError(ErrUnknown, " NOT Done \n");
52 return ErrUnknown;
54 rv = resolveForAddDropColumn();
55 return rv;
58 DbRetVal AlterTblStatement::execute(int &rowsAffected)
60 DbRetVal rv = OK;
61 if( altType == ALTERTABLERENAME)
63 rv = dbMgr->renameTable(parsedData->getTableName(), parsedData->getIndexName());
64 return rv;
65 }else if( altType == ALTERFIELDRENAME)
67 rv = dbMgr->renameField(parsedData->getTableName(), parsedData->getIndexName(),parsedData->getPKTableName());
68 return rv;
70 rv = executeForAddDropColumn(rowsAffected);
71 return rv;
74 DbRetVal AlterTblStatement::resolveForAddDropColumn()
76 DbRetVal rv = OK;
77 if( altType == ALTERTABLERENAME || altType == ALTERFIELDRENAME) return OK;
78 List fNameList = table->getFieldNameList();
79 FieldList extraFldList = parsedData->getCreFldList() ;
80 ListIterator fNameIter = fNameList.getIterator();
81 FieldInfo *info = new FieldInfo();
82 int fcount = 1; void *valBuf; int ret=0;
83 Identifier *elem = NULL;
84 noOfOldTabFld = fNameList.size();
85 totalFields = noOfOldTabFld + extraFldList.size();
86 bindFieldValues = (void**) malloc( totalFields * sizeof(char*));
87 memset(bindFieldValues, 0, totalFields * sizeof(char*));
88 char fldName[IDENTIFIER_LENGTH];
89 int i = 1;
90 while (fNameIter.hasElement())
92 elem = (Identifier*) fNameIter.nextElement();
93 table->getFieldInfo((const char*)elem->name, info);
94 Table::getFieldNameAlone(elem->name,fldName);
95 //TODO :: Should free
96 valBuf = AllDataType::alloc(info->type, info->length);
97 table->bindFld(elem->name, valBuf);
98 if(altType == ALTERDROP && 0 == strcmp(parsedData->getIndexName(),fldName)){
99 bindFieldValues[totalFields-i] = valBuf; //Store Last
100 i--;
102 else {
103 bindFieldValues[fcount-1] = valBuf;
104 ret = tblDef.addField(fldName,info->type, info->length, info->defaultValueBuf, info->isNull, info->isAutoIncrement);
105 if( 0 != ret )
107 printError(ErrUnknown, "Error while adding field");
108 rv = ErrUnknown;
109 break;
111 fcount++;
114 fNameIter.reset();
115 while (fNameIter.hasElement())
117 delete (Identifier*) fNameIter.nextElement();
119 fNameList.reset();
120 if(altType == ALTERDROP)
122 delete info;
123 return rv;
125 FieldIterator iter = extraFldList.getIterator();
126 FieldName *name = NULL;
127 ListIterator nIter = parsedData->getFieldNameList().getIterator();
128 while (iter.hasElement())
130 FieldDef *fDef = iter.nextElement();
131 nIter.reset();
132 while (nIter.hasElement())
134 name = (FieldName*)nIter.nextElement();
135 if (strcmp(name->fldName, fDef->fldName_) == 0) fDef->isNull_ = true;
137 if (!fDef->isDefault_ || fDef->isDefault_ && fDef->defaultValueBuf_[0] == '\0') {
138 ret = tblDef.addField(fDef->fldName_, fDef->type_, fDef->length_,
139 NULL,fDef->isNull_,fDef->isAutoIncrement_);
140 } else {
141 ret = tblDef.addField(fDef->fldName_, fDef->type_, fDef->length_,
142 fDef->defaultValueBuf_,fDef->isNull_,fDef->isAutoIncrement_);
144 if( 0 != ret )
146 printError(ErrUnknown, "Error while adding field");
147 rv = ErrUnknown;
148 break;
150 valBuf = AllDataType::alloc(fDef->type_, fDef->length_);
151 bindFieldValues[fcount-1] = valBuf;
153 delete info;
154 return rv;
157 DbRetVal AlterTblStatement::executeForAddDropColumn(int &rowsAffected)
159 DbRetVal rv = OK;
160 char tblName[IDENTIFIER_LENGTH];
161 sprintf(tblName,"%s_temp",parsedData->getTableName());
162 rv = dbMgr->createTable(tblName, tblDef);
163 if (rv != OK) return rv;
164 rv = createIndex(parsedData->getTableName(),tblName);
165 if (rv != OK){
166 dbMgr->dropTable(tblName);
167 return rv;
169 //TODO:Create Foreign Key Info
170 Table *tempTable = dbMgr->openTable(tblName);
171 List fNameList = tempTable->getFieldNameList();
172 ListIterator fNameIter = fNameList.getIterator();
173 FieldInfo *info = new FieldInfo();
174 int fcount = 1; void *valBuf;
175 Identifier *elem = NULL;
176 while (fNameIter.hasElement())
178 elem = (Identifier*) fNameIter.nextElement();
179 tempTable->getFieldInfo((const char*)elem->name, info);
180 valBuf = bindFieldValues[fcount-1];
181 tempTable->bindFld(elem->name, valBuf);
182 fcount++;
184 table->setCondition(NULL);
185 rv = table->execute();
186 if (rv != OK)
188 dbMgr->closeTable(tempTable);
189 dbMgr->dropTable(tblName);
190 return rv;
192 void *tuple = NULL;
193 while(true)
195 int extraField = totalFields - noOfOldTabFld;
196 tuple = (char*)table->fetch();
197 if (tuple == NULL) {break;}
198 int i=1;
199 while(extraField--)
201 tempTable->markFldNull(noOfOldTabFld+i);
202 i++;
204 rv = tempTable->insertTuple();
205 if (rv != OK) break;
207 if (rv != OK){
208 dbMgr->closeTable(tempTable);
209 dbMgr->dropTable(tblName);
210 return rv;
212 char tblName1[IDENTIFIER_LENGTH];
213 sprintf(tblName1,"%s_temp2",parsedData->getTableName());
214 rv = dbMgr->renameTable(parsedData->getTableName(),tblName1);
215 if (rv != OK){
216 dbMgr->closeTable(tempTable);
217 dbMgr->dropTable(tblName);
218 return rv;
220 rv = dbMgr->renameTable(tblName,parsedData->getTableName());
221 if (rv != OK){
222 dbMgr->renameTable(tblName1,parsedData->getTableName());
223 dbMgr->closeTable(tempTable);
224 dbMgr->dropTable(tblName);
225 return rv;
227 rv = dbMgr->dropTable(tblName1);
228 if (rv != OK){
229 dbMgr->renameTable(tblName1,parsedData->getTableName());
230 dbMgr->closeTable(tempTable);
231 dbMgr->dropTable(tblName);
232 return rv;
234 return rv;
236 DbRetVal AlterTblStatement::createIndex(const char *oldName,const char *newName)
238 DbRetVal rv=OK;
239 CatalogTableINDEXFIELD cIndexField(((DatabaseManagerImpl *)dbMgr)->sysDb());
240 ListIterator iter = cIndexField.getIndexListIterater((char*)oldName);
241 IndexInfoForDriver *info=NULL;
242 char name[IDENTIFIER_LENGTH]="";
243 char indName[IDENTIFIER_LENGTH]="";
244 char tempIndexName[IDENTIFIER_LENGTH] ="";
245 sprintf(tempIndexName, "%s_idx1_Primary", oldName);
246 bool shouldCreateIndex = false;
247 bool isFirstEntry=true;
248 HashIndexInitInfo *idxInfo = NULL, *indexInfo2 = NULL;
249 while(iter.hasElement())
251 if(shouldCreateIndex)
253 if(idxInfo->isPrimary && 0 == strcmp(info->indexName,tempIndexName))
254 sprintf(indName, "%s_idx1_Primary", newName);
255 rv = dbMgr->createIndex(indName, idxInfo);
256 if (rv != OK)
258 delete idxInfo;
259 return rv;
261 delete idxInfo;
262 shouldCreateIndex = false;
263 idxInfo = NULL;
265 info = (IndexInfoForDriver *) iter.nextElement();
266 if((0 == strcmp(info->indexName,indName)))
268 if(idxInfo) idxInfo->list.append(info->fieldName);
269 else printf("should not happen\n");
270 }else{
271 idxInfo = new HashIndexInitInfo();
272 strcpy(idxInfo->tableName, newName);
273 strcpy(indName,info->indexName);
274 if(!isFirstEntry)shouldCreateIndex =true;
275 isFirstEntry = false;
276 idxInfo->indType =(IndexType) info->type;
277 idxInfo->isPrimary = info->isPrimary ;
278 idxInfo->isUnique = info->isUnique;
279 idxInfo->list.append(info->fieldName);
282 if(idxInfo->isPrimary && 0 == strcmp(info->indexName,tempIndexName))
283 sprintf(indName, "%s_idx1_Primary", newName);
284 rv = dbMgr->createIndex(indName, idxInfo);
285 if (rv != OK)
287 delete idxInfo;
288 return rv;
290 delete idxInfo;
291 return OK;
295 DbRetVal AlterTblStatement::resolveForModifyColumn()
297 DbRetVal rv = OK;
298 return rv;