Fix for Bug # 2483638
[csql.git] / src / storage / CatalogTables.cxx
blob3a761c3cc791725456a89a7fc1ef86ef353274c0
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_ = fDef.offset_;
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.offset_ = fTuple->offset_;
179 fldDef.isDefault_ = fTuple->isDefault_;
180 os::memcpy(fldDef.defaultValueBuf_, fTuple->defaultValueBuf_,
181 DEFAULT_VALUE_BUF_LENGTH);
182 fldDef.isNull_ = fTuple->isNull_;
183 fldDef.isUnique_ = fTuple->isUnique_;
184 fldDef.isPrimary_ = fTuple->isPrimary_;
185 list.append(fldDef);
188 return;
191 DbRetVal CatalogTableFIELD::getFieldPtrs(FieldNameList &fldList,void *tptr, char **&fptr)
193 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(FieldTableId);
194 int i=0;
195 char *fName = NULL;
196 bool found = false;
197 fldList.resetIter();
198 void *data = NULL;
199 DbRetVal rv =OK;
200 while (NULL != (fName = fldList.nextFieldName()))
202 ChunkIterator fIter = fChunk->getIterator();
203 found = false;
204 while (NULL != (data = fIter.nextElement()))
206 if (((CFIELD*)data)->tblPtr_ == tptr)
208 if(0 == strcmp((char*)((CFIELD*)data)->fldName_, fName))
210 found = true;
211 //if (! ((FIELD*)data)->isNull_) rv = ErrBadCall;
212 fptr[i++] = (char*) data;
213 break;
217 if (!found)
219 printError(ErrNotFound,
220 "No entries found in FIELD catalog table for the table specified");
221 return ErrNotFound;
224 return rv;
227 DbRetVal CatalogTableINDEX::insert(const char *name, void *tptr, int numFlds, bool isUnique,
228 void* chunk, int bucketSize, void *hChunk, void *&tupleptr)
230 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
231 ChunkIterator iter = tChunk->getIterator();
233 //Checking for index having same name, proceed further only
234 //if no such indexes are
235 void *data = NULL;
236 while ((data = iter.nextElement())!= NULL)
238 if (0 == strcmp(((CINDEX*)data)->indName_, name))
240 printError(ErrAlready, "Index with name \'%s\' already exists "
241 "on the table \'%s\'.", name, ((CTABLE *)tptr)->tblName_);
242 return ErrAlready;
247 DbRetVal rv =OK;
248 tupleptr = tChunk->allocate(systemDatabase_, &rv);
249 if (NULL == tupleptr)
251 printError(rv,
252 "Could not allocate for INDEX catalog table");
253 return rv;
255 CINDEX *indexInfo = (CINDEX*)tupleptr;
256 strcpy(indexInfo->indName_, name);
257 indexInfo->tblID_ = -1; //Not used currently
258 indexInfo->tblPtr_ = tptr;
259 indexInfo->numFlds_ = numFlds;
260 if (NULL == hChunk)
261 indexInfo->indexType_ = treeIndex;
262 else
263 indexInfo->indexType_ = hashIndex;
264 indexInfo->chunkPtr_ = chunk;
265 indexInfo->hashNodeChunk_ = hChunk;
266 indexInfo->noOfBuckets_ = bucketSize;
267 indexInfo->isUnique_ = isUnique;
268 indexInfo->fstIndFld_=NULL;
269 printDebug(DM_SystemDatabase,"One Row inserted into INDEX %x %s",tupleptr, name);
270 return OK;
273 DbRetVal CatalogTableINDEX::remove(const char *name, void *&chunk, void *&hchunk, void *&iptr)
275 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
276 ChunkIterator iter = fChunk->getIterator();
278 void *data = NULL;
279 while ((data = iter.nextElement())!= NULL)
281 if (0 == strcmp(((CINDEX*)data)->indName_, name))
283 //remove this element and store the tuple ptr
284 //there will be only one row for this table(Primary key)
285 chunk = (Chunk*) ((CINDEX*)data)->chunkPtr_;
286 hchunk = (Chunk*) ((CINDEX*)data)->hashNodeChunk_;
287 iptr = (void*) data;
288 break;
291 if (NULL != iptr)
293 fChunk->free(systemDatabase_, iptr);
294 printDebug(DM_SystemDatabase,"One Row deleted from INDEX %x %s",iptr, name);
296 else
298 printError(ErrNotExists,"Index %s not exists in INDEX catalog table", name);
299 return ErrNotExists;
301 return OK;
303 DbRetVal CatalogTableINDEX::get(const char *name, void *&chunk, void *&hchunk, void *&iptr)
305 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
306 ChunkIterator iter = fChunk->getIterator();
308 void *data = NULL;
309 while ((data = iter.nextElement())!= NULL)
311 if (0 == strcmp(((CINDEX*)data)->indName_, name))
313 //remove this element and store the tuple ptr
314 //there will be only one row for this table(Primary key)
315 chunk = (Chunk*) ((CINDEX*)data)->chunkPtr_;
316 hchunk = (Chunk*) ((CINDEX*)data)->hashNodeChunk_;
317 iptr = (void*) data;
318 break;
321 if (NULL == iptr)
323 printError(ErrNotExists,"Index %s not exists in INDEX catalog table", name);
324 return ErrNotExists;
326 return OK;
329 int CatalogTableINDEX::getNumIndexes(void *tptr)
331 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
332 ChunkIterator iter = fChunk->getIterator();
333 void *iptr = NULL;
334 int numIndex =0;
335 while (NULL != (iptr = iter.nextElement()))
337 if (((CINDEX*)iptr)->tblPtr_ == tptr) numIndex++;
339 return numIndex;
342 char* CatalogTableINDEX::getIndexName(void *tptr, int position)
344 if (position == 0) return NULL;
345 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
346 ChunkIterator iter = fChunk->getIterator();
347 void *iptr = NULL;
348 int numIndex =0;
349 int curPos =0;
350 while (NULL != (iptr = iter.nextElement()))
352 if (((CINDEX*)iptr)->tblPtr_ == tptr) curPos++;
353 if ( curPos == position ) return ((CINDEX*)iptr)->indName_;
355 return NULL;
359 void CatalogTableINDEX::getIndexPtrs(void *tptr, char **&array)
361 void *iptr = NULL;
362 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
363 ChunkIterator iter = fChunk->getIterator();
364 int i=0;
365 while (NULL != (iptr = iter.nextElement()))
367 if (((CINDEX*)iptr)->tblPtr_ == tptr)
369 array[i++] = (char*) iptr;
372 return;
375 ChunkIterator CatalogTableINDEX::getIterator(void *iptr)
377 CINDEX *index = (CINDEX*)iptr;
378 return ((Chunk*)index->chunkPtr_)->getIterator();
382 int CatalogTableINDEX::getNoOfBuckets(void *iptr)
384 CINDEX *index = (CINDEX*)iptr;
385 return index->noOfBuckets_;
388 int CatalogTableINDEX::getUnique(void *iptr)
390 CINDEX *index = (CINDEX*)iptr;
391 return index->isUnique_;
393 char* CatalogTableINDEX::getName(void *iptr)
395 CINDEX *index = (CINDEX*)iptr;
396 return index->indName_;
399 DbRetVal CatalogTableINDEXFIELD::insert(FieldNameList &fldList, void *indexPtr,
400 void *tblPtr, char **&fptr)
403 Chunk *tChunk;
404 tChunk = systemDatabase_->getSystemDatabaseChunk(IndexTableId);
405 ChunkIterator iter = tChunk->getIterator();
406 CINDEXFIELD *fInd=NULL;
407 char *fName =NULL;
408 void *data = NULL;
409 bool isFldInd=false;
410 while ((data = iter.nextElement())!= NULL)
412 if ((((CINDEX*)data)->tblPtr_==tblPtr)
413 && (((CINDEX*)indexPtr)->numFlds_ == ((CINDEX*)data)->numFlds_)
414 && (((CINDEX*)indexPtr)->indexType_==((CINDEX*)data)->indexType_)
415 && (data != indexPtr) )
417 fldList.resetIter();
418 while (NULL != (fName = fldList.nextFieldName()))
420 isFldInd=false;
421 fInd=(CINDEXFIELD*)((CINDEX*)data)->fstIndFld_ ;
422 while (fInd)
424 if (0 == strcmp(((CFIELD *) fInd->fieldPtr)->fldName_, fName))
426 isFldInd=true;
427 break;
429 fInd=fInd->next;
431 if(!isFldInd) break;
433 if(isFldInd)
435 printError(ErrAlready, "Index on this field already exists on table \'%s\' by name \'%s\'", ((CTABLE *)tblPtr)->tblName_, ((CINDEX *)data)->indName_);
436 return ErrAlready;
442 tChunk = systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
443 fldList.resetIter();
444 int i =0;
445 while (NULL != (fName = fldList.nextFieldName()))
447 DbRetVal rv = OK;
448 fInd=(CINDEXFIELD*)((CINDEX*)indexPtr)->fstIndFld_;
449 while(fInd)
451 if (0 == strcmp(((CFIELD *) fInd->fieldPtr)->fldName_, fName))
453 printError(ErrAlready,"Composite Index Can't be created with same Name");
454 fInd=(CINDEXFIELD*)((CINDEX*)indexPtr)->fstIndFld_;
455 CINDEXFIELD *fldI;
456 while(fInd)
458 fldI=fInd;
459 fInd=fInd->next;
460 tChunk->free(systemDatabase_,fldI);
462 return ErrAlready;
464 fInd=fInd->next;
466 void *fieldptr = tChunk->allocate(systemDatabase_, &rv);
467 if (NULL == fieldptr)
469 printError(rv, "Could not allocate for USER catalog table");
470 return rv;
472 CINDEXFIELD *fldInfo = (CINDEXFIELD*)fieldptr;
473 fldInfo->tablePtr = tblPtr;
474 fldInfo->fieldPtr = (CFIELD*)fptr[i++];
475 fldInfo->indexPtr = indexPtr;
476 fldInfo->next=(CINDEXFIELD*)((CINDEX*)indexPtr)->fstIndFld_;
477 ((CINDEX *)indexPtr)->fstIndFld_=fldInfo;
478 printDebug(DM_SystemDatabase,"One Row inserted into INDEXFIELD %x", fldInfo);
480 return OK;
483 DbRetVal CatalogTableINDEXFIELD::remove(void *iptr)
485 Chunk *fChunk;
486 fChunk = systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
487 ChunkIterator fIter = fChunk->getIterator();
488 void *data = NULL;
489 while ((data = fIter.nextElement())!= NULL)
491 if (((CINDEXFIELD*)data)->indexPtr == iptr)
493 //remove this element
494 fChunk->free(systemDatabase_, data);
495 printDebug(DM_SystemDatabase,"One Row deleted from INDEXFIELD %x", data);
498 return OK;
501 DbRetVal CatalogTableINDEXFIELD::getFieldNameAndType(void *index,
502 char *&name, DataType &type)
504 Chunk *ifChunk;
505 ifChunk = systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
506 ChunkIterator ifIter = ifChunk->getIterator();
507 void *data = NULL;
508 while ((data = ifIter.nextElement())!= NULL)
510 if (((CINDEXFIELD*)data)->indexPtr == index)
512 //store the field name
513 name = ((CFIELD*)(((CINDEXFIELD*)data)->fieldPtr))->fldName_;
514 type = ((CFIELD*)(((CINDEXFIELD*)data)->fieldPtr))->type_;
515 return OK;
518 printError(ErrNotExists,"Index %x not exists in catalog table", index);
519 return ErrNotExists;
522 DbRetVal CatalogTableINDEXFIELD::getFieldInfo(void *index, FieldList &list)
524 Chunk *ifChunk;
525 ifChunk = systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
526 ChunkIterator ifIter = ifChunk->getIterator();
527 void *data = NULL;
528 int rowCount =0;
529 while ((data = ifIter.nextElement())!= NULL)
531 if (((CINDEXFIELD*)data)->indexPtr == index)
533 //add the information to the field list
534 CFIELD *fTuple = (CFIELD*)(((CINDEXFIELD*)data)->fieldPtr);
535 FieldDef fldDef;
536 strcpy(fldDef.fldName_, fTuple->fldName_);
537 fldDef.fldName_[IDENTIFIER_LENGTH] = '\0';
538 fldDef.type_ = fTuple->type_;
539 fldDef.length_ = fTuple->length_;
540 fldDef.offset_ = fTuple->offset_;
541 fldDef.isDefault_ = fTuple->isDefault_;
542 os::memcpy(fldDef.defaultValueBuf_, fTuple->defaultValueBuf_,
543 DEFAULT_VALUE_BUF_LENGTH);
544 fldDef.isNull_ = fTuple->isNull_;
545 fldDef.isUnique_ = fTuple->isUnique_;
546 fldDef.isPrimary_ = fTuple->isPrimary_;
547 list.append(fldDef);
549 rowCount++;
551 if (!rowCount) {
552 printError(ErrNotExists,"Index %x not exists in catalog table", index);
553 return ErrNotExists;
555 return OK;
558 void CatalogTableINDEXFIELD::printAllIndex()
560 Chunk *chunk=systemDatabase_->getSystemDatabaseChunk(IndexFieldTableId);
561 ChunkIterator ifIter = chunk->getIterator();
562 void *data = NULL;
563 char indexName[IDENTIFIER_LENGTH] = {'\0'};
564 while ((data = ifIter.nextElement())!= NULL)
566 if(strcmp(indexName,((CINDEX*)(((CINDEXFIELD*)data)->indexPtr))->indName_)!=0)
568 printf(" <Index Name> %s </Index Name> \n",((CINDEX*)(((CINDEXFIELD*)data)->indexPtr))->indName_);
569 if(0==((CINDEX*)(((CINDEXFIELD*)data)->indexPtr))->indexType_)
570 printf(" <Index Type> Hash Index </Index Type> \n");
571 else
572 printf(" <Index Type> Tree Index </Index Type> \n");
573 printf(" <Table Name> %s </Table Name> \n",((CTABLE*)(((CINDEXFIELD*)data)->tablePtr))->tblName_);
574 printf(" <Field Name> %s </Field Name> \n",((CFIELD*)(((CINDEXFIELD*)data)->fieldPtr))->fldName_);
576 else
578 printf(" <Field Name> %s </Field Name> \n",((CFIELD*)(((CINDEXFIELD*)data)->fieldPtr))->fldName_);
580 strcpy(indexName,((CINDEX*)(((CINDEXFIELD*)data)->indexPtr))->indName_);
584 DbRetVal CatalogTableUSER::insert(const char *name, const char *pass)
586 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(UserTableId);
587 DbRetVal rv = OK;
588 CUSER *usrInfo = (CUSER*)tChunk->allocate(systemDatabase_, &rv);
589 if (NULL == usrInfo)
591 printError(rv,
592 "Could not allocate for USER catalog table");
593 return rv;
595 strcpy(usrInfo->userName_, name);
596 strcpy(usrInfo->password_, os::encrypt(pass, "A0"));
597 return OK;
601 DbRetVal CatalogTableUSER::authenticate(const char *name, const char *pass,
602 bool &isAuthenticated, bool &isDba)
604 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(UserTableId);
605 ChunkIterator iter = tChunk->getIterator();
606 void *data = NULL;
607 while (NULL != (data = iter.nextElement()))
609 if (strcmp(((CUSER*)data)->userName_, name) == 0)
611 //verify the password
612 char * enpass = os::encrypt(pass,"A0");
613 if (0 == strcmp(enpass, ((CUSER*)data)->password_))
615 isAuthenticated = true;
616 if (0 == strcmp(((CUSER*)data)->userName_, DBAUSER))
617 isDba = true; else isDba = false;
618 return OK;
622 isAuthenticated = false;
623 return OK;
626 DbRetVal CatalogTableUSER::remove(const char *name)
628 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(UserTableId);
629 ChunkIterator iter = tChunk->getIterator();
630 void *data = NULL;
631 while ((data = iter.nextElement())!= NULL)
633 if (strcmp(((CUSER*)data)->userName_, name) == 0)
635 //remove this element
636 tChunk->free(systemDatabase_, data);
637 return OK;
640 printError(ErrNotExists,"User %s not exists in catalog table", name);
641 return ErrNotExists;
644 DbRetVal CatalogTableUSER::changePass(const char *name, const char *pass)
646 Chunk *tChunk = systemDatabase_->getSystemDatabaseChunk(UserTableId);
647 ChunkIterator iter = tChunk->getIterator();
648 void *data = NULL;
649 while (NULL != (data = iter.nextElement()))
651 if (strcmp(((CUSER*)data)->userName_, name) == 0)
653 //change the password
654 strcpy(((CUSER*)data)->password_, os::encrypt(pass, "A0"));
655 return OK;
658 printError(ErrNotExists,"User %s not exists in catalog table", name);
659 return ErrNotExists;