1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
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. *
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. *
15 ***************************************************************************/
17 #include <Statement.h>
18 #include <TableImpl.h>
20 AlterTblStatement::AlterTblStatement()
22 bindFieldValues
= NULL
;
27 AlterTblStatement::~AlterTblStatement()
29 if (table
) { table
->close(); table
= NULL
; }
31 for(int i
=0;i
<totalFields
;i
++)
33 free(bindFieldValues
[i
]);
35 free(bindFieldValues
); bindFieldValues
= NULL
;
39 DbRetVal
AlterTblStatement::resolve()
42 altType
= parsedData
->getAlterType();
43 if(altType
== ALTERMODIFY
)
45 printError(ErrUnknown
, " NOT Done \n");
48 rv
= resolveForAddDropColumn();
52 DbRetVal
AlterTblStatement::execute(int &rowsAffected
)
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());
64 }else if( altType
== ALTERFIELDRENAME
)
66 if (strcmp(parsedData
->getIndexName(),parsedData
->getPKTableName())==0)
68 rv
= dbMgr
->renameField(parsedData
->getTableName(), parsedData
->getIndexName(),parsedData
->getPKTableName());
70 }else if(ALTERINDEXRENAME
== altType
){
71 rv
= dbMgr
->renameIndex(parsedData
->getTableName(), parsedData
->getIndexName());
74 rv
= executeForAddDropColumn(rowsAffected
);
78 DbRetVal
AlterTblStatement::resolveForAddDropColumn()
81 if( altType
== ALTERTABLERENAME
|| altType
== ALTERFIELDRENAME
|| altType
== ALTERINDEXRENAME
) return OK
;
82 table
= dbMgr
->openTable(parsedData
->getTableName());
85 printError(ErrNotExists
, "Unable to open the table:Table not exists");
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
];
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
113 bindFieldValues
[fcount
-1] = valBuf
;
114 ret
= tblDef
.addField(fldName
,info
->type
, info
->length
, info
->defaultValueBuf
, info
->isNull
, info
->isAutoIncrement
);
117 printError(ErrUnknown
, "Error while adding field");
125 while (fNameIter
.hasElement())
127 delete (Identifier
*) fNameIter
.nextElement();
130 if(altType
== ALTERDROP
)
135 FieldIterator iter
= extraFldList
.getIterator();
136 FieldName
*name
= NULL
;
137 ListIterator nIter
= parsedData
->getFieldNameList().getIterator();
138 while (iter
.hasElement())
140 FieldDef
*fDef
= iter
.nextElement();
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_
);
151 ret
= tblDef
.addField(fDef
->fldName_
, fDef
->type_
, fDef
->length_
,
152 fDef
->defaultValueBuf_
,fDef
->isNull_
,fDef
->isAutoIncrement_
);
156 printError(ErrUnknown
, "Error while adding field");
160 valBuf
= AllDataType::alloc(fDef
->type_
, fDef
->length_
);
161 bindFieldValues
[fcount
-1] = valBuf
;
167 DbRetVal
AlterTblStatement::executeForAddDropColumn(int &rowsAffected
)
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
);
176 dbMgr
->dropTable(tblName
);
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
);
194 table
->setCondition(NULL
);
195 rv
= table
->execute();
198 dbMgr
->closeTable(tempTable
);
199 dbMgr
->dropTable(tblName
);
205 int extraField
= totalFields
- noOfOldTabFld
;
206 tuple
= (char*)table
->fetch();
207 if (tuple
== NULL
) {break;}
211 tempTable
->markFldNull(noOfOldTabFld
+i
);
214 rv
= tempTable
->insertTuple();
218 dbMgr
->closeTable(tempTable
);
219 dbMgr
->dropTable(tblName
);
222 char tblName1
[IDENTIFIER_LENGTH
];
223 sprintf(tblName1
,"%s_temp2",parsedData
->getTableName());
224 rv
= dbMgr
->renameTable(parsedData
->getTableName(),tblName1
);
226 dbMgr
->closeTable(tempTable
);
227 dbMgr
->dropTable(tblName
);
230 rv
= dbMgr
->renameTable(tblName
,parsedData
->getTableName());
232 dbMgr
->renameTable(tblName1
,parsedData
->getTableName());
233 dbMgr
->closeTable(tempTable
);
234 dbMgr
->dropTable(tblName
);
237 rv
= dbMgr
->dropTable(tblName1
);
239 dbMgr
->renameTable(tblName1
,parsedData
->getTableName());
240 dbMgr
->closeTable(tempTable
);
241 dbMgr
->dropTable(tblName
);
246 DbRetVal
AlterTblStatement::createIndex(const char *oldName
,const char *newName
)
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
);
272 shouldCreateIndex
= false;
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");
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
);
306 DbRetVal
AlterTblStatement::resolveForModifyColumn()