Tree index creation fails if hash index exists on same field
[csql.git] / src / storage / CatalogTables.cxx
blob12e497b03e5328e41c0130cfd642b4bc7f0a8111
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.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<CatalogTables.h>
17 #include<Database.h>
18 #include<Allocator.h>
19 #include<Field.h>
20 #include<Debug.h>
21 char ChunkName[MAX_CHUNKS][CHUNK_NAME_LEN]={"UserChunkTableId","LockTableHashBucketId","LockTableMutexId","LockTableId","TransHasTableId","UndoLogTableId","","","","","DatabaseTableId","UserTableId","TableTableId","FieldTableId","AccessTableId","IndexTableId","IndexFieldTableId",""};
24 DbRetVal CatalogTableTABLE::insert(const char *name, int id, size_t size,
25 int numFlds, void* chunk, void *&tptr)
27 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(TableTableId);
28 DbRetVal rv = OK;
29 tptr = tChunk->allocate(systemDatabase_, &rv);
30 if (NULL == tptr)
32 printError(rv,
33 "Could not allocate memory for for TABLE catalog table");
34 return rv;
36 CTABLE *tableInfo = (CTABLE*)tptr;
37 strcpy(tableInfo->tblName_, name);
38 tableInfo->tblID_ = id;
39 tableInfo->length_ = size;
40 tableInfo->numFlds_ = numFlds;
41 tableInfo->numIndexes_ = 0;
42 tableInfo->chunkPtr_ = chunk;
43 printDebug(DM_SystemDatabase,"One Row inserted into TABLE %x %s",tptr, name);
44 return OK;
47 DbRetVal CatalogTableTABLE::remove(const char *name, void *&chunk, void *&tptr)
49 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(TableTableId);
50 ChunkIterator iter = tChunk->getIterator();
52 void *data = NULL;
53 while ((data = iter.nextElement())!= NULL)
55 if (0 == strcmp(((CTABLE*)data)->tblName_, name))
57 //remove this element and store the tblPtr
58 //there will be only one row for this table(Primary key)
59 tptr = (void*) data;
60 chunk = (Chunk*) ((CTABLE*)data)->chunkPtr_;
61 break;
64 if (NULL != tptr)
66 tChunk->free(systemDatabase_, tptr);
67 printDebug(DM_SystemDatabase,"One Row deleted from TABLE %x %s",tptr, name);
69 else
71 printError(ErrNotExists,"Table %s not exists in TABLE catalog table", name);
72 return ErrNotExists;
74 return OK;
77 DbRetVal CatalogTableTABLE::getChunkAndTblPtr(const char *name,
78 void *&chunk, void *&tptr)
80 Chunk *chk = systemDatabase_->getSystemDatabaseChunk(TableTableId);
81 ChunkIterator iter = chk->getIterator();;
82 while (NULL != (tptr = iter.nextElement()))
84 if (strcmp(((CTABLE*)tptr)->tblName_, name) == 0)
86 //there will be only one row for this table(Primary key)
87 chunk = (Chunk*) ((CTABLE*)tptr)->chunkPtr_;
88 return OK;
91 //table not found in TABLE
92 return ErrNotFound;
95 List CatalogTableTABLE::getTableList()
97 List tableList;
98 Chunk *chk = systemDatabase_->getSystemDatabaseChunk(TableTableId);
99 ChunkIterator iter = chk->getIterator();
100 void *tptr;
101 while (NULL != (tptr = iter.nextElement()))
103 Identifier *elem = new Identifier();
104 strcpy(elem->name, ((CTABLE*)tptr)->tblName_);
105 tableList.append(elem);
107 return tableList;
110 DbRetVal CatalogTableFIELD::insert(FieldIterator &iter, int tblID, void *tptr)
112 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(FieldTableId);
113 DbRetVal rv = OK;
114 while (iter.hasElement())
116 void *fptr = fChunk->allocate(systemDatabase_, &rv);
117 if (NULL == fptr)
119 printError(rv,
120 "Could not allocate for FIELD catalog table");
121 return rv;
123 CFIELD *fldInfo = (CFIELD*)fptr;
124 FieldDef fDef = iter.nextElement();
125 strcpy(fldInfo->fldName_, fDef.fldName_);
126 fldInfo->tblID_ = tblID;
127 fldInfo->tblPtr_ = tptr;
128 fldInfo->type_ = fDef.type_;
129 fldInfo->length_ = fDef.length_;
130 fldInfo->offset_ = 0; //TODO
131 os::memcpy(fldInfo->defaultValueBuf_, fDef.defaultValueBuf_,
132 DEFAULT_VALUE_BUF_LENGTH);
133 fldInfo->isNull_ = fDef.isNull_;
134 fldInfo->isPrimary_ = fDef.isPrimary_;
135 fldInfo->isUnique_ = fDef.isUnique_;
136 fldInfo->isDefault_ = fDef.isDefault_;
137 fldInfo->width_ = 0; //TODO
138 fldInfo->scale_ = 0; //TODO
139 printDebug(DM_SystemDatabase,"One Row inserted into FIELD %x %s",fldInfo, fDef.fldName_);
142 return OK;
145 DbRetVal CatalogTableFIELD::remove(void *tptr)
147 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(FieldTableId);
148 ChunkIterator fIter = fChunk->getIterator();
149 void *data = NULL;
150 while ((data = fIter.nextElement())!= NULL)
152 if (((CFIELD*)data)->tblPtr_ == tptr)
154 //remove this element
155 fChunk->free(systemDatabase_, data);
156 printDebug(DM_SystemDatabase,"One Row deleted from FIELD %x",data);
159 return OK;
162 void CatalogTableFIELD::getFieldInfo(void* tptr, FieldList &list)
164 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(FieldTableId);
165 ChunkIterator fIter = fChunk->getIterator();;
166 void *data = NULL;
167 while (NULL != (data = fIter.nextElement()))
169 if (((CFIELD*)data)->tblPtr_ == tptr)
171 //add the information to the field list
172 CFIELD *fTuple = (CFIELD*)data;
173 FieldDef fldDef;
174 strcpy(fldDef.fldName_, fTuple->fldName_);
175 fldDef.fldName_[IDENTIFIER_LENGTH] = '\0';
176 fldDef.type_ = fTuple->type_;
177 fldDef.length_ = fTuple->length_;
178 fldDef.isDefault_ = fTuple->isDefault_;
179 os::memcpy(fldDef.defaultValueBuf_, fTuple->defaultValueBuf_,
180 DEFAULT_VALUE_BUF_LENGTH);
181 fldDef.isNull_ = fTuple->isNull_;
182 fldDef.isUnique_ = fTuple->isUnique_;
183 fldDef.isPrimary_ = fTuple->isPrimary_;
184 list.append(fldDef);
187 return;
190 DbRetVal CatalogTableFIELD::getFieldPtrs(FieldNameList &fldList,void *tptr, char **&fptr)
192 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(FieldTableId);
193 int i=0;
194 char *fName = NULL;
195 bool found = false;
196 fldList.resetIter();
197 void *data = NULL;
198 DbRetVal rv =OK;
199 while (NULL != (fName = fldList.nextFieldName()))
201 ChunkIterator fIter = fChunk->getIterator();
202 found = false;
203 while (NULL != (data = fIter.nextElement()))
205 if (((CFIELD*)data)->tblPtr_ == tptr)
207 if(0 == strcmp((char*)((CFIELD*)data)->fldName_, fName))
209 found = true;
210 //if (! ((FIELD*)data)->isNull_) rv = ErrBadCall;
211 fptr[i++] = (char*) data;
212 break;
216 if (!found)
218 printError(ErrNotFound,
219 "No entries found in FIELD catalog table for the table specified");
220 return ErrNotFound;
223 return rv;
226 DbRetVal CatalogTableINDEX::insert(const char *name, void *tptr, int numFlds, bool isUnique,
227 void* chunk, int bucketSize, void *hChunk, void *&tupleptr)
229 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
230 ChunkIterator iter = tChunk->getIterator();
232 //Checking for index having same name, proceed further only
233 //if no such indexes are
234 void *data = NULL;
235 while ((data = iter.nextElement())!= NULL)
237 if (0 == strcmp(((CINDEX*)data)->indName_, name))
239 printError(ErrAlready, "Index with name \'%s\' already exists "
240 "on the table \'%s\'.", name, ((CTABLE *)tptr)->tblName_);
241 return ErrAlready;
246 DbRetVal rv =OK;
247 tupleptr = tChunk->allocate(systemDatabase_, &rv);
248 if (NULL == tupleptr)
250 printError(rv,
251 "Could not allocate for INDEX catalog table");
252 return rv;
254 CINDEX *indexInfo = (CINDEX*)tupleptr;
255 strcpy(indexInfo->indName_, name);
256 indexInfo->tblID_ = -1; //Not used currently
257 indexInfo->tblPtr_ = tptr;
258 indexInfo->numFlds_ = numFlds;
259 if (NULL == hChunk)
260 indexInfo->indexType_ = treeIndex;
261 else
262 indexInfo->indexType_ = hashIndex;
263 indexInfo->chunkPtr_ = chunk;
264 indexInfo->hashNodeChunk_ = hChunk;
265 indexInfo->noOfBuckets_ = bucketSize;
266 indexInfo->isUnique_ = isUnique;
267 indexInfo->fstIndFld_=NULL;
268 printDebug(DM_SystemDatabase,"One Row inserted into INDEX %x %s",tupleptr, name);
269 return OK;
272 DbRetVal CatalogTableINDEX::remove(const char *name, void *&chunk, void *&hchunk, void *&iptr)
274 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
275 ChunkIterator iter = fChunk->getIterator();
277 void *data = NULL;
278 while ((data = iter.nextElement())!= NULL)
280 if (0 == strcmp(((CINDEX*)data)->indName_, name))
282 //remove this element and store the tuple ptr
283 //there will be only one row for this table(Primary key)
284 chunk = (Chunk*) ((CINDEX*)data)->chunkPtr_;
285 hchunk = (Chunk*) ((CINDEX*)data)->hashNodeChunk_;
286 iptr = (void*) data;
287 break;
290 if (NULL != iptr)
292 fChunk->free(systemDatabase_, iptr);
293 printDebug(DM_SystemDatabase,"One Row deleted from INDEX %x %s",iptr, name);
295 else
297 printError(ErrNotExists,"Index %s not exists in INDEX catalog table", name);
298 return ErrNotExists;
300 return OK;
302 DbRetVal CatalogTableINDEX::get(const char *name, void *&chunk, void *&hchunk, void *&iptr)
304 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
305 ChunkIterator iter = fChunk->getIterator();
307 void *data = NULL;
308 while ((data = iter.nextElement())!= NULL)
310 if (0 == strcmp(((CINDEX*)data)->indName_, name))
312 //remove this element and store the tuple ptr
313 //there will be only one row for this table(Primary key)
314 chunk = (Chunk*) ((CINDEX*)data)->chunkPtr_;
315 hchunk = (Chunk*) ((CINDEX*)data)->hashNodeChunk_;
316 iptr = (void*) data;
317 break;
320 if (NULL == iptr)
322 printError(ErrNotExists,"Index %s not exists in INDEX catalog table", name);
323 return ErrNotExists;
325 return OK;
328 int CatalogTableINDEX::getNumIndexes(void *tptr)
330 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
331 ChunkIterator iter = fChunk->getIterator();
332 void *iptr = NULL;
333 int numIndex =0;
334 while (NULL != (iptr = iter.nextElement()))
336 if (((CINDEX*)iptr)->tblPtr_ == tptr) numIndex++;
338 return numIndex;
341 char* CatalogTableINDEX::getIndexName(void *tptr, int position)
343 if (position == 0) return NULL;
344 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
345 ChunkIterator iter = fChunk->getIterator();
346 void *iptr = NULL;
347 int numIndex =0;
348 int curPos =0;
349 while (NULL != (iptr = iter.nextElement()))
351 if (((CINDEX*)iptr)->tblPtr_ == tptr) curPos++;
352 if ( curPos == position ) return ((CINDEX*)iptr)->indName_;
354 return NULL;
358 void CatalogTableINDEX::getIndexPtrs(void *tptr, char **&array)
360 void *iptr = NULL;
361 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
362 ChunkIterator iter = fChunk->getIterator();
363 int i=0;
364 while (NULL != (iptr = iter.nextElement()))
366 if (((CINDEX*)iptr)->tblPtr_ == tptr)
368 array[i++] = (char*) iptr;
371 return;
374 ChunkIterator CatalogTableINDEX::getIterator(void *iptr)
376 CINDEX *index = (CINDEX*)iptr;
377 return ((Chunk*)index->chunkPtr_)->getIterator();
381 int CatalogTableINDEX::getNoOfBuckets(void *iptr)
383 CINDEX *index = (CINDEX*)iptr;
384 return index->noOfBuckets_;
387 int CatalogTableINDEX::getUnique(void *iptr)
389 CINDEX *index = (CINDEX*)iptr;
390 return index->isUnique_;
392 char* CatalogTableINDEX::getName(void *iptr)
394 CINDEX *index = (CINDEX*)iptr;
395 return index->indName_;
398 DbRetVal CatalogTableINDEXFIELD::insert(FieldNameList &fldList, void *indexPtr,
399 void *tblPtr, char **&fptr)
402 Chunk *tChunk;
403 tChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
404 ChunkIterator iter = tChunk->getIterator();
405 CINDEXFIELD *fInd=NULL;
406 char *fName =NULL;
407 void *data = NULL;
408 bool isFldInd=false;
409 while ((data = iter.nextElement())!= NULL)
411 if ((((CINDEX*)data)->tblPtr_==tblPtr)
412 && (((CINDEX*)indexPtr)->numFlds_ == ((CINDEX*)data)->numFlds_)
413 && (((CINDEX*)indexPtr)->indexType_==((CINDEX*)data)->indexType_)
414 && (data != indexPtr) )
416 fldList.resetIter();
417 while (NULL != (fName = fldList.nextFieldName()))
419 isFldInd=false;
420 fInd=(CINDEXFIELD*)((CINDEX*)data)->fstIndFld_ ;
421 while (fInd)
423 if (0 == strcmp(((CFIELD *) fInd->fieldPtr)->fldName_, fName))
425 isFldInd=true;
426 break;
428 fInd=fInd->next;
430 if(!isFldInd) break;
432 if(isFldInd)
434 printError(ErrAlready, "Index on this field already exists on table \'%s\' by name \'%s\'", ((CTABLE *)tblPtr)->tblName_, ((CINDEX *)data)->indName_);
435 return ErrAlready;
441 tChunk = systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
442 fldList.resetIter();
443 int i =0;
444 while (NULL != (fName = fldList.nextFieldName()))
446 DbRetVal rv = OK;
447 fInd=(CINDEXFIELD*)((CINDEX*)indexPtr)->fstIndFld_;
448 while(fInd)
450 if (0 == strcmp(((CFIELD *) fInd->fieldPtr)->fldName_, fName))
452 printError(ErrAlready,"Composite Index Can't be created with same Name");
453 fInd=(CINDEXFIELD*)((CINDEX*)indexPtr)->fstIndFld_;
454 CINDEXFIELD *fldI;
455 while(fInd)
457 fldI=fInd;
458 fInd=fInd->next;
459 tChunk->free(systemDatabase_,fldI);
461 return ErrAlready;
463 fInd=fInd->next;
465 void *fieldptr = tChunk->allocate(systemDatabase_, &rv);
466 if (NULL == fieldptr)
468 printError(rv, "Could not allocate for USER catalog table");
469 return rv;
471 CINDEXFIELD *fldInfo = (CINDEXFIELD*)fieldptr;
472 fldInfo->tablePtr = tblPtr;
473 fldInfo->fieldPtr = (CFIELD*)fptr[i++];
474 fldInfo->indexPtr = indexPtr;
475 fldInfo->next=(CINDEXFIELD*)((CINDEX*)indexPtr)->fstIndFld_;
476 ((CINDEX *)indexPtr)->fstIndFld_=fldInfo;
477 printDebug(DM_SystemDatabase,"One Row inserted into INDEXFIELD %x", fldInfo);
479 return OK;
482 DbRetVal CatalogTableINDEXFIELD::remove(void *iptr)
484 Chunk *fChunk;
485 fChunk = systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
486 ChunkIterator fIter = fChunk->getIterator();
487 void *data = NULL;
488 while ((data = fIter.nextElement())!= NULL)
490 if (((CINDEXFIELD*)data)->indexPtr == iptr)
492 //remove this element
493 fChunk->free(systemDatabase_, data);
494 printDebug(DM_SystemDatabase,"One Row deleted from INDEXFIELD %x", data);
497 return OK;
500 DbRetVal CatalogTableINDEXFIELD::getFieldNameAndType(void *index,
501 char *&name, DataType &type)
503 Chunk *ifChunk;
504 ifChunk = systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
505 ChunkIterator ifIter = ifChunk->getIterator();
506 void *data = NULL;
507 while ((data = ifIter.nextElement())!= NULL)
509 if (((CINDEXFIELD*)data)->indexPtr == index)
511 //store the field name
512 name = ((CFIELD*)(((CINDEXFIELD*)data)->fieldPtr))->fldName_;
513 type = ((CFIELD*)(((CINDEXFIELD*)data)->fieldPtr))->type_;
514 return OK;
517 printError(ErrNotExists,"Index %x not exists in catalog table", index);
518 return ErrNotExists;
521 DbRetVal CatalogTableINDEXFIELD::getFieldInfo(void *index, FieldList &list)
523 Chunk *ifChunk;
524 ifChunk = systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
525 ChunkIterator ifIter = ifChunk->getIterator();
526 void *data = NULL;
527 int rowCount =0;
528 while ((data = ifIter.nextElement())!= NULL)
530 if (((CINDEXFIELD*)data)->indexPtr == index)
532 //add the information to the field list
533 CFIELD *fTuple = (CFIELD*)(((CINDEXFIELD*)data)->fieldPtr);
534 FieldDef fldDef;
535 strcpy(fldDef.fldName_, fTuple->fldName_);
536 fldDef.fldName_[IDENTIFIER_LENGTH] = '\0';
537 fldDef.type_ = fTuple->type_;
538 fldDef.length_ = fTuple->length_;
539 fldDef.isDefault_ = fTuple->isDefault_;
540 os::memcpy(fldDef.defaultValueBuf_, fTuple->defaultValueBuf_,
541 DEFAULT_VALUE_BUF_LENGTH);
542 fldDef.isNull_ = fTuple->isNull_;
543 fldDef.isUnique_ = fTuple->isUnique_;
544 fldDef.isPrimary_ = fTuple->isPrimary_;
545 list.append(fldDef);
547 rowCount++;
549 if (!rowCount) {
550 printError(ErrNotExists,"Index %x not exists in catalog table", index);
551 return ErrNotExists;
553 return OK;
556 void CatalogTableINDEXFIELD::printAllIndex()
558 Chunk *chunk=systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
559 ChunkIterator ifIter = chunk->getIterator();
560 void *data = NULL;
561 char indexName[IDENTIFIER_LENGTH] = {'\0'};
562 while ((data = ifIter.nextElement())!= NULL)
564 if(strcmp(indexName,((CINDEX*)(((CINDEXFIELD*)data)->indexPtr))->indName_)!=0)
566 printf(" <Index Name> %s </Index Name> \n",((CINDEX*)(((CINDEXFIELD*)data)->indexPtr))->indName_);
567 if(0==((CINDEX*)(((CINDEXFIELD*)data)->indexPtr))->indexType_)
568 printf(" <Index Type> Hash Index </Index Type> \n");
569 else
570 printf(" <Index Type> Tree Index </Index Type> \n");
571 printf(" <Table Name> %s </Table Name> \n",((CTABLE*)(((CINDEXFIELD*)data)->tablePtr))->tblName_);
572 printf(" <Field Name> %s </Field Name> \n",((CFIELD*)(((CINDEXFIELD*)data)->fieldPtr))->fldName_);
574 else
576 printf(" <Field Name> %s </Field Name> \n",((CFIELD*)(((CINDEXFIELD*)data)->fieldPtr))->fldName_);
578 strcpy(indexName,((CINDEX*)(((CINDEXFIELD*)data)->indexPtr))->indName_);
582 DbRetVal CatalogTableUSER::insert(const char *name, const char *pass)
584 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(UserTableId);
585 DbRetVal rv = OK;
586 CUSER *usrInfo = (CUSER*)tChunk->allocate(systemDatabase_, &rv);
587 if (NULL == usrInfo)
589 printError(rv,
590 "Could not allocate for USER catalog table");
591 return rv;
593 strcpy(usrInfo->userName_, name);
594 strcpy(usrInfo->password_, os::encrypt(pass, "A0"));
595 return OK;
599 DbRetVal CatalogTableUSER::authenticate(const char *name, const char *pass,
600 bool &isAuthenticated, bool &isDba)
602 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(UserTableId);
603 ChunkIterator iter = tChunk->getIterator();
604 void *data = NULL;
605 while (NULL != (data = iter.nextElement()))
607 if (strcmp(((CUSER*)data)->userName_, name) == 0)
609 //verify the password
610 char * enpass = os::encrypt(pass,"A0");
611 if (0 == strcmp(enpass, ((CUSER*)data)->password_))
613 isAuthenticated = true;
614 if (0 == strcmp(((CUSER*)data)->userName_, DBAUSER))
615 isDba = true; else isDba = false;
616 return OK;
620 isAuthenticated = false;
621 return OK;
624 DbRetVal CatalogTableUSER::remove(const char *name)
626 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(UserTableId);
627 ChunkIterator iter = tChunk->getIterator();
628 void *data = NULL;
629 while ((data = iter.nextElement())!= NULL)
631 if (strcmp(((CUSER*)data)->userName_, name) == 0)
633 //remove this element
634 tChunk->free(systemDatabase_, data);
635 return OK;
638 printError(ErrNotExists,"User %s not exists in catalog table", name);
639 return ErrNotExists;
642 DbRetVal CatalogTableUSER::changePass(const char *name, const char *pass)
644 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(UserTableId);
645 ChunkIterator iter = tChunk->getIterator();
646 void *data = NULL;
647 while (NULL != (data = iter.nextElement()))
649 if (strcmp(((CUSER*)data)->userName_, name) == 0)
651 //change the password
652 strcpy(((CUSER*)data)->password_, os::encrypt(pass, "A0"));
653 return OK;
656 printError(ErrNotExists,"User %s not exists in catalog table", name);
657 return ErrNotExists;