src/server/TableImpl.cxx

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by www.databasecache.com                           *
00003  *   Contact: praba_tuty@databasecache.com                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015   ***************************************************************************/
00016 #include<Index.h>
00017 #include<CatalogTables.h>
00018 #include<Lock.h>
00019 #include<Debug.h>
00020 #include<Table.h>
00021 #include<TableImpl.h>
00022 #include<Predicate.h>
00023 #include<PredicateImpl.h>
00024 #include<Index.h>
00025 #include<Config.h>
00026 
00027 DbRetVal TableImpl::bindFld(const char *name, void *val)
00028 {
00029     //set it in the field list
00030     DbRetVal rv = fldList_.updateBindVal(name, val);
00031     if (OK != rv) {
00032         printError(ErrNotExists, "Field %s does not exist", name);
00033         return  rv;
00034     }
00035     return OK;
00036 }
00037 
00038 bool TableImpl::isFldNull(const char *name){
00039     int colpos = fldList_.getFieldPosition(name);
00040     if (-1 == colpos)
00041     {
00042         printError(ErrNotExists, "Field %s does not exist", name);
00043         return false;
00044     }
00045 
00046     return isFldNull(colpos);
00047 }
00048 
00049 bool TableImpl::isFldNull(int colpos)
00050 {
00051     if (!curTuple_) return false;
00052     if (colpos <1 || colpos > numFlds_) return false;
00053     char *nullOffset = (char*)curTuple_ - 4;
00054     if (isIntUsedForNULL) {
00055         int nullVal = *(int*)((char*)curTuple_ + (length_ - 4));
00056         if (BITSET(nullVal, colpos)) return true;
00057     }
00058     else {
00059         char *nullOffset = (char*)curTuple_ - os::align(numFlds_);
00060         if (nullOffset[colpos-1]) return true;
00061     }
00062     return false;
00063 }
00064 void TableImpl::markFldNull(char const* name)
00065 {
00066     int colpos = fldList_.getFieldPosition(name);
00067     if (-1 == colpos)
00068     {
00069         printError(ErrNotExists, "Field %s does not exist", name);
00070         return;
00071     }
00072     markFldNull(colpos);
00073 }
00074 
00075 void TableImpl::markFldNull(int fldpos)
00076 {
00077     if (fldpos <1 || fldpos > numFlds_) return;
00078     if (isIntUsedForNULL) {
00079         if (!BITSET(iNotNullInfo, fldpos)) SETBIT(iNullInfo, fldpos);
00080     }
00081     else
00082         if (!BITSET(iNotNullInfo, fldpos)) cNullInfo[fldpos-1] = 1;
00083     return;
00084 }
00085 
00086 void TableImpl::clearFldNull(const char *name)
00087 {
00088     int colpos = fldList_.getFieldPosition(name);
00089     if (-1 == colpos)
00090     {
00091         printError(ErrNotExists, "Field %s does not exist", name);
00092         return;
00093     }
00094 
00095     clearFldNull(colpos);
00096 }
00097 
00098 void TableImpl::clearFldNull(int colpos)
00099 {
00100     if (colpos <1 || colpos > numFlds_) return;
00101     if (isIntUsedForNULL) { 
00102         CLEARBIT(iNullInfo, colpos);
00103     }
00104     else
00105         cNullInfo[colpos-1] = 0;
00106     return;
00107 }
00108 
00109 
00110 DbRetVal TableImpl::execute()
00111 {
00112     if (NULL != iter)
00113     {
00114          printError(ErrAlready,"Scan already open:Close and re execute");
00115          return ErrAlready;
00116     }
00117     //table ptr is set in predicate because it needs to access the
00118     //type and length to evaluate
00119     if( NULL != pred_)
00120     {
00121         PredicateImpl *pred = (PredicateImpl*) pred_;
00122         pred->setTable(this);
00123     }
00124     DbRetVal ret = OK;
00125 
00126     ret = createPlan();
00127     if (OK != ret)
00128     {
00129         printError(ErrSysInternal,"Unable to create the plan");
00130         return ErrSysInternal;
00131     }
00132     if (useIndex_ >= 0) 
00133         iter = new TupleIterator(pred_, scanType_, idxInfo[useIndex_], chunkPtr_, sysDB_->procSlot);
00134     else if (scanType_ == fullTableScan)
00135         iter = new TupleIterator(pred_, scanType_, NULL, chunkPtr_, sysDB_->procSlot);
00136     else
00137     {
00138         printError(ErrSysFatal,"Unable to create tuple iterator");//should never happen
00139         return ErrSysFatal;
00140     }
00141     ret = iter->open();
00142     if (OK != ret)
00143     {
00144         printError(ret,"Unable to open the iterator");
00145         return ret;
00146     }
00147     return OK;
00148 }
00149 
00150 
00151 DbRetVal TableImpl::createPlan()
00152 {
00153     if (isPlanCreated) {
00154         //will do early return here. plan is generated only when setPredicate is called.
00155         if (scanType_ == unknownScan) return ErrSysFatal; //this should never happen
00156         else return OK;
00157     }
00158     useIndex_ = -1;
00159     //if there are no predicates then go for full scan
00160     //if there are no indexes then go for full scan
00161     if (NULL == pred_ || NULL == indexPtr_)
00162     {
00163         scanType_ = fullTableScan;
00164         isPlanCreated = true;
00165         return OK;
00166     }
00167     if (NULL != indexPtr_)
00168     {
00169        PredicateImpl *pred = (PredicateImpl*)pred_;
00170        printDebug(DM_Predicate, "predicate does not involve NOT , OR operator");
00171        if (!pred->isNotOrInvolved())
00172        {
00173            printDebug(DM_Predicate, "predicate does not involve NOT , OR operator");
00174           for (int i =0; i < numIndexes_; i++)
00175           {
00176               char *fName = ((SingleFieldHashIndexInfo*)idxInfo[i])->fldName;
00177               if (pred->pointLookupInvolved(fName))
00178               {
00179                  printDebug(DM_Predicate, "point lookup involved for field %s",fName);
00180                  scanType_ = hashIndexScan;
00181                  useIndex_ = i;
00182                  isPlanCreated = true;
00183                  return OK;
00184               }
00185            }
00186         }
00187     }
00188     scanType_ = fullTableScan;
00189     isPlanCreated = true;
00190     return OK;
00191 }
00192 
00193 void* TableImpl::fetch()
00194 {
00195     fetchNoBind();
00196     if (NULL == curTuple_) return curTuple_;
00197     copyValuesToBindBuffer(curTuple_);
00198     return curTuple_;
00199 }
00200 void* TableImpl::fetch(DbRetVal &rv)
00201 {
00202     fetchNoBind(rv);
00203     if (NULL == curTuple_) return curTuple_;
00204     copyValuesToBindBuffer(curTuple_);
00205     return curTuple_;
00206 }
00207 
00208 void* TableImpl::fetchNoBind()
00209 {
00210     if (NULL == iter)
00211     {
00212         printError(ErrNotOpen,"Scan not open or Scan is closed\n");
00213         return NULL;
00214     }
00215     void *prevTuple = curTuple_;
00216     curTuple_ = iter->next();
00217     if (NULL == curTuple_)
00218     {
00219         return NULL;
00220     }
00221     DbRetVal lockRet = OK;
00222     if ((*trans)->isoLevel_ == READ_REPEATABLE) {
00223         lockRet = lMgr_->getSharedLock(curTuple_, trans);
00224         if (OK != lockRet)
00225         { 
00226             printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
00227             curTuple_ = prevTuple;
00228             return NULL;
00229         }
00230 
00231     }
00232     else if ((*trans)->isoLevel_ == READ_COMMITTED)
00233     {
00234         //if iso level is read committed, operation duration lock is sufficent 
00235         //so release it here itself.
00236         int tries = 5;
00237         struct timeval timeout;
00238         timeout.tv_sec = Conf::config.getMutexSecs();
00239         timeout.tv_usec = Conf::config.getMutexUSecs();
00240 
00241         bool status = false;
00242         while(true) { 
00243             lockRet = lMgr_->isExclusiveLocked( curTuple_, trans, status);
00244             if (OK != lockRet)
00245             { 
00246                 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
00247                 curTuple_ = prevTuple;
00248                 return NULL;
00249             }
00250             if (!status) break; 
00251             tries--;
00252             if (tries == 0) break;
00253             os::select(0, 0, 0, 0, &timeout);
00254 
00255         }
00256         if (tries == 0) 
00257         { 
00258             printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
00259             curTuple_ = prevTuple;
00260             return NULL;
00261         }
00262     }
00263     return curTuple_;
00264 }
00265 
00266 void* TableImpl::fetchNoBind(DbRetVal &rv)
00267 {
00268     rv = OK;
00269     if (NULL == iter)
00270     {
00271         printError(ErrNotOpen,"Scan not open or Scan is closed\n");
00272         rv = ErrNotOpen;
00273         return NULL;
00274     }
00275     void *prevTuple = curTuple_;
00276     curTuple_ = iter->next();
00277     if (NULL == curTuple_)
00278     {
00279         return NULL;
00280     }
00281     DbRetVal lockRet = OK;
00282     if ((*trans)->isoLevel_ == READ_REPEATABLE) {
00283         lockRet = lMgr_->getSharedLock(curTuple_, trans);
00284         if (OK != lockRet)
00285         {
00286             printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
00287             rv = ErrLockTimeOut;
00288             curTuple_ = prevTuple;
00289             return NULL;
00290         }
00291 
00292     }
00293     else if ((*trans)->isoLevel_ == READ_COMMITTED)
00294     {
00295         //if iso level is read committed, operation duration lock is sufficent
00296         //so release it here itself.
00297         int tries = 5;
00298         struct timeval timeout;
00299         timeout.tv_sec = Conf::config.getMutexSecs();
00300         timeout.tv_usec = Conf::config.getMutexUSecs();
00301 
00302         bool status = false;
00303         while(true) {
00304             lockRet = lMgr_->isExclusiveLocked( curTuple_, trans, status);
00305             if (OK != lockRet)
00306             {
00307                 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
00308                 curTuple_ = prevTuple;
00309                 rv = ErrLockTimeOut;
00310                 return NULL;
00311             }
00312             if (!status) break;
00313             tries--;
00314             if (tries == 0) break;
00315             os::select(0, 0, 0, 0, &timeout);
00316 
00317         }
00318         if (tries == 0)
00319         {
00320             printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
00321             curTuple_ = prevTuple;
00322             rv = ErrLockTimeOut;
00323             return NULL;
00324         }
00325     }
00326     return curTuple_;
00327 }
00328 
00329 DbRetVal TableImpl::insertTuple()
00330 {
00331     DbRetVal ret =OK;
00332     void *tptr = ((Chunk*)chunkPtr_)->allocate(db_, &ret);
00333     if (NULL == tptr)
00334     {
00335         printError(ret, "Unable to allocate record from chunk");
00336         return ret;
00337     }
00338     ret = lMgr_->getExclusiveLock(tptr, trans);
00339     if (OK != ret)
00340     {
00341         ((Chunk*)chunkPtr_)->free(db_, tptr);
00342         printError(ret, "Could not get lock for the insert tuple %x", tptr);
00343         return ErrLockTimeOut;
00344     }
00345 
00346 
00347     ret = copyValuesFromBindBuffer(tptr);
00348     if (ret != OK)
00349     {
00350         printError(ret, "Unable to copy values from bind buffer");
00351         (*trans)->removeFromHasList(db_, tptr);
00352         lMgr_->releaseLock(tptr);
00353         ((Chunk*)chunkPtr_)->free(db_, tptr);
00354         return ret;
00355     }
00356 
00357     int addSize = 0;
00358     if (numFlds_ < 31) 
00359     {
00360         addSize = 4; 
00361         *(int*)((char*)(tptr) + (length_-addSize)) = iNullInfo;
00362     }
00363     else 
00364     {
00365         addSize = os::align(numFlds_);
00366         os::memcpy(((char*)(tptr) + (length_-addSize)), cNullInfo, addSize);
00367 
00368     }
00369     //int tupleSize = length_ + addSize;
00370     if (NULL != indexPtr_)
00371     {
00372         int i;
00373         //it has index
00374         for (i = 0; i < numIndexes_ ; i++)
00375         {
00376             ret = insertIndexNode(*trans, indexPtr_[i], idxInfo[i], tptr);
00377             if (ret != OK) { printError(ret, "Error in inserting to index"); break;}
00378         }
00379         if (i != numIndexes_ )
00380         {
00381             for (int j = 0; j < i ; j++) {
00382                 printError(ErrWarning, "Deleting index node");
00383                 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
00384             }
00385             lMgr_->releaseLock(tptr);
00386             (*trans)->removeFromHasList(db_, tptr);
00387             ((Chunk*)chunkPtr_)->free(db_, tptr);
00388             //TMP::remove int derefernce
00389             printError(ret, "PRABA:::Unable to insert index node for tuple %x %d", tptr, *(int*)tptr);
00390             return ret;
00391         }
00392     }
00393     if (undoFlag)
00394         ret = (*trans)->appendUndoLog(sysDB_, InsertOperation, tptr, length_);
00395     return ret;
00396 }
00397 
00398 DbRetVal TableImpl::deleteTuple()
00399 {
00400     if (NULL == curTuple_)
00401     {
00402         printError(ErrNotOpen, "Scan not open: No Current tuple");
00403         return ErrNotOpen;
00404     }
00405     DbRetVal ret = lMgr_->getExclusiveLock(curTuple_, trans);
00406     if (OK != ret)
00407     {
00408         printError(ret, "Could not get lock for the delete tuple %x", curTuple_);
00409         return ErrLockTimeOut;
00410     }
00411 
00412     if (NULL != indexPtr_)
00413     {
00414         int i;
00415         //it has index
00416         for (i = 0; i < numIndexes_ ; i++)
00417         {
00418             ret = deleteIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
00419             if (ret != OK) break;
00420         }
00421         if (i != numIndexes_ )
00422         {
00423             for (int j = 0; j < i ; j++)
00424                 insertIndexNode(*trans, indexPtr_[j], idxInfo[j], curTuple_);
00425             lMgr_->releaseLock(curTuple_);
00426             (*trans)->removeFromHasList(db_, curTuple_);
00427             printError(ret, "Unable to insert index node for tuple %x", curTuple_);
00428             return ret;
00429         }
00430     }
00431     ((Chunk*)chunkPtr_)->free(db_, curTuple_);
00432     if (undoFlag)
00433         ret = (*trans)->appendUndoLog(sysDB_, DeleteOperation, curTuple_, length_);
00434     return ret;
00435 }
00436 
00437 int TableImpl::deleteWhere()
00438 {
00439     int tuplesDeleted = 0;
00440     DbRetVal rv  = OK;
00441     rv =  execute();
00442     if (rv !=OK) return (int) rv;
00443     while(true){
00444         fetchNoBind( rv);
00445         if (rv != OK) { tuplesDeleted = (int)rv; break; }
00446         if (NULL == curTuple_) break;
00447         rv = deleteTuple();
00448         if (rv != OK) {
00449             printError(rv, "Error: Could only delete %d tuples", tuplesDeleted);
00450             close();
00451             return (int) rv;
00452         }
00453         tuplesDeleted++;
00454     }
00455     close();
00456     return tuplesDeleted;
00457 }
00458 
00459 int TableImpl::truncate()
00460 {
00461     //take exclusive lock on the table
00462     //get the chunk ptr of the table
00463     //traverse the tablechunks and free all the pages except the first one
00464     //get the chunk ptr of all its indexes
00465     //traverse the indexchunks and free all the pages except the first one
00466     //release table lock
00467 
00468     //TEMPORARY FIX
00469     DbRetVal rv = OK;
00470     Predicate* tmpPred = pred_;
00471     pred_ = NULL;
00472     isPlanCreated = false;
00473     int tuplesDeleted = deleteWhere();
00474     isPlanCreated = false;
00475     pred_ = tmpPred;
00476     return tuplesDeleted;
00477 }
00478 
00479 DbRetVal TableImpl::updateTuple()
00480 {
00481     if (NULL == curTuple_)
00482     {
00483         printError(ErrNotOpen, "Scan not open: No Current tuple");
00484         return ErrNotOpen;
00485     }
00486     DbRetVal ret = lMgr_->getExclusiveLock(curTuple_, trans);
00487     if (OK != ret)
00488     {
00489         printError(ret, "Could not get lock for the update tuple %x", curTuple_);
00490         return ErrLockTimeOut;
00491     }
00492     if (NULL != indexPtr_)
00493     {
00494         //it has index
00495         //TODO::If it fails while updating index node, we have to undo all the updates 
00496         //on other indexes on the table.Currently it will leave the database in an 
00497         //inconsistent state.
00498         for (int i = 0; i < numIndexes_ ; i++)
00499         {
00500             ret = updateIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
00501             if (ret != OK)
00502             {
00503                 lMgr_->releaseLock(curTuple_);
00504                 (*trans)->removeFromHasList(db_, curTuple_);
00505                 printError(ret, "Unable to update index node for tuple %x", curTuple_);
00506                 return ret;
00507             }
00508         }
00509     }
00510     if (undoFlag)
00511         ret = (*trans)->appendUndoLog(sysDB_, UpdateOperation, curTuple_, length_);
00512     if (ret != OK) return ret;
00513     int addSize = 0;
00514     if (numFlds_ < 31) 
00515     {
00516         addSize = 4; 
00517         *(int*)((char*)(curTuple_) + (length_-addSize)) |= iNullInfo;
00518     }
00519     else 
00520     {
00521         addSize = os::align(numFlds_);
00522         //TODO::Do not do blind memcpy. It should OR each and every char
00523         //os::memcpy(((char*)(curTuple_) + (length_-addSize)), cNullInfo, addSize);
00524 
00525     }
00526 
00527     DbRetVal rv = copyValuesFromBindBuffer(curTuple_, false);
00528     if (rv != OK) { 
00529         lMgr_->releaseLock(curTuple_); 
00530         (*trans)->removeFromHasList(db_, curTuple_); 
00531         return rv; 
00532     }
00533     return OK;
00534 }
00535 
00536 void TableImpl::printInfo()
00537 {
00538     printf("  <TableName> %s </TableName>\n", tblName_);
00539     printf("  <TupleCount> %d </TupleCount>\n", numTuples());
00540     printf("  <PagesUsed> %d </PagesUsed>\n", pagesUsed());
00541     printf("  <SpaceUsed> %d </SpaceUsed>\n", spaceUsed());
00542     printf("  <Indexes> %d <Indexes>\n", numIndexes_);
00543     printf("  <TupleLength> %d </TupleLength>\n", length_);
00544     printf("  <Fields> %d </Fields>\n", numFlds_);
00545     printf("  <Indexes>\n");
00546     for (int i =0; i<numIndexes_; i++)
00547         printf("<IndexName> %s </IndexName>\n", CatalogTableINDEX::getName(indexPtr_[i]));
00548     printf("  </Indexes>\n");
00549 
00550 }
00551 
00552 DbRetVal TableImpl::copyValuesFromBindBuffer(void *tuplePtr, bool isInsert)
00553 {
00554     //Iterate through the bind list and copy the value here
00555     FieldIterator fIter = fldList_.getIterator();
00556     char *colPtr = (char*) tuplePtr;
00557     int fldpos=1;
00558     while (fIter.hasElement())
00559     {
00560         FieldDef def = fIter.nextElement();
00561         if (def.isNull_ && !def.isDefault_ && NULL == def.bindVal_ && isInsert) 
00562         {
00563             printError(ErrNullViolation, "NOT NULL constraint violation for field %s\n", def.fldName_);
00564             return ErrNullViolation;
00565         }
00566         if (def.isDefault_ && NULL == def.bindVal_ && isInsert)
00567         {
00568             void *dest = AllDataType::alloc(def.type_, def.length_);
00569             AllDataType::convert(typeString, def.defaultValueBuf_, def.type_, dest);
00570             AllDataType::copyVal(colPtr, dest, def.type_, def.length_);
00571             colPtr = colPtr + os::align(AllDataType::size(def.type_, def.length_));
00572             fldpos++;
00573             free (dest); 
00574             continue;
00575         }
00576         switch(def.type_)
00577         {
00578             case typeString:
00579                 if (NULL != def.bindVal_)
00580                 {
00581                     strcpy((char*)colPtr, (char*)def.bindVal_);
00582                     *(((char*)colPtr) + (def.length_-1)) = '\0';
00583                 }
00584                 else if (!def.isNull_ && isInsert)  setNullBit(fldpos);
00585                 colPtr = colPtr + os::align(def.length_);
00586                 break;
00587             case typeBinary:
00588                 if (NULL != def.bindVal_ )
00589                     os::memcpy((char*)colPtr, (char*)def.bindVal_, def.length_);
00590                 else if (!def.isNull_ && isInsert)  setNullBit(fldpos);
00591                 colPtr = colPtr + os::align(def.length_);
00592                 break;
00593             default:
00594                 if (NULL != def.bindVal_)
00595                     AllDataType::copyVal(colPtr, def.bindVal_, def.type_);
00596                 else { if (!def.isNull_ && isInsert)  setNullBit(fldpos); }
00597                 colPtr = colPtr + os::align(AllDataType::size(def.type_));
00598                 break;
00599         }
00600         fldpos++;
00601     }
00602     return OK;
00603 }
00604 void TableImpl::setNullBit(int fldpos)
00605 {
00606     if (isIntUsedForNULL) 
00607         SETBIT(iNullInfo, fldpos);
00608     else
00609         cNullInfo[fldpos-1] = 1;
00610 }
00611 DbRetVal TableImpl::copyValuesToBindBuffer(void *tuplePtr)
00612 {
00613     //Iterate through the bind list and copy the value here
00614     FieldIterator fIter = fldList_.getIterator();
00615     char *colPtr = (char*) tuplePtr;
00616     while (fIter.hasElement())
00617     {
00618         FieldDef def = fIter.nextElement();
00619         switch(def.type_)
00620         {
00621             case typeString:
00622                 if (NULL != def.bindVal_)
00623                     strcpy((char*)def.bindVal_, (char*)colPtr);
00624                 colPtr = colPtr + os::align(def.length_);
00625                 break;
00626             case typeBinary:
00627                 if (NULL != def.bindVal_)
00628                     os::memcpy((char*)def.bindVal_, (char*)colPtr, def.length_);
00629                 colPtr = colPtr + os::align(def.length_);
00630                 break;
00631             default:
00632                 if (NULL != def.bindVal_)
00633                     AllDataType::copyVal(def.bindVal_, colPtr, def.type_);
00634                 colPtr = colPtr + os::align(AllDataType::size(def.type_));
00635                 break;
00636         }
00637     }
00638     return OK;
00639 }
00640 
00641 //-1 index not supported
00642 DbRetVal TableImpl::insertIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
00643 {
00644     INDEX *iptr = (INDEX*)indexPtr;
00645     DbRetVal ret = OK;
00646     printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
00647     Index* idx = Index::getIndex(iptr->indexType_);
00648     ret = idx->insert(this, tr, indexPtr, info, tuple,undoFlag);
00649     return ret;
00650 }
00651 
00652 DbRetVal TableImpl::deleteIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
00653 {
00654     INDEX *iptr = (INDEX*)indexPtr;
00655     DbRetVal ret = OK;
00656     Index* idx = Index::getIndex(iptr->indexType_);
00657     ret = idx->remove(this, tr, indexPtr, info, tuple, undoFlag);
00658     return ret;
00659 }
00660 void TableImpl::printSQLIndexString()
00661 {
00662     CatalogTableINDEXFIELD cIndexField(sysDB_);
00663     char fName[IDENTIFIER_LENGTH];
00664     char *fldName = fName; 
00665     DataType type;
00666     for (int i = 0; i < numIndexes_ ; i++)
00667     {
00668         INDEX *iptr = (INDEX*) indexPtr_[i];
00669         cIndexField.getFieldNameAndType((void*)iptr, fldName, type);
00670         printf("CREATE INDEX %s on %s ( %s ) ", iptr->indName_, getName(), fldName);
00671         if (((SingleFieldHashIndexInfo*) idxInfo[i])->isUnique) printf(" UNIQUE;\n"); else printf(";\n");
00672     }
00673 }
00674 
00675 
00676 DbRetVal TableImpl::updateIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
00677 {
00678     INDEX *iptr = (INDEX*)indexPtr;
00679     DbRetVal ret = OK;
00680     Index* idx = Index::getIndex(iptr->indexType_);
00681     //TODO::currently it updates irrespective of whether the key changed or not 
00682     //because of this commenting the whole index update code. relook at it and uncomment
00683 
00684     //ret = idx->update(this, tr, indexPtr, info, tuple, undoFlag);
00685 
00686     return ret;
00687 }
00688 
00689 
00690 void TableImpl::setTableInfo(char *name, int tblid, size_t  length,
00691                        int numFld, int numIdx, void *chunk)
00692 {
00693     strcpy(tblName_, name);
00694     tblID_ = tblid;
00695     length_ = length;
00696     numFlds_ = numFld;
00697     numIndexes_ = numIdx;
00698     chunkPtr_ = chunk;
00699 }
00700 
00701 long TableImpl::spaceUsed()
00702 {
00703     Chunk *chk = (Chunk*)chunkPtr_;
00704     long totSize = chk->getTotalDataNodes() * chk->getSize();
00705     totSize = totSize + (chk->totalPages() * sizeof (PageInfo));
00706     return totSize;
00707 }
00708 
00709 int TableImpl::pagesUsed()
00710 {
00711     Chunk *chk = (Chunk*)chunkPtr_;
00712     return chk->totalPages();
00713 }
00714 
00715 long TableImpl::numTuples()
00716 {
00717     return ((Chunk*)chunkPtr_)->getTotalDataNodes();
00718 }
00719 
00720 List TableImpl::getFieldNameList()
00721 {
00722     List fldNameList;
00723     FieldIterator fIter = fldList_.getIterator();
00724     while (fIter.hasElement())
00725     {
00726         FieldDef def = fIter.nextElement();
00727         Identifier *elem = new Identifier();
00728         strcpy(elem->name, def.fldName_);
00729         fldNameList.append(elem);
00730     } 
00731     return fldNameList;
00732 }
00733 DbRetVal TableImpl::close()
00734 {
00735     if (NULL == iter)
00736     {
00737          printError(ErrNotOpen,"Scan not open");
00738          return ErrNotOpen;
00739     }
00740     iter->close();
00741     delete iter;
00742     iter = NULL;
00743     return OK;
00744 }
00745 DbRetVal TableImpl::lock(bool shared)
00746 {
00747 
00748     DbRetVal ret = OK;
00749 /*
00750     if (shared) 
00751         ret = lMgr_->getSharedLock(chunkPtr_, NULL);
00752     else 
00753         ret = lMgr_->getExclusiveLock(chunkPtr_, NULL);
00754     if (OK != ret)
00755     {
00756         printError(ret, "Could not exclusive lock on the table %x", chunkPtr_);
00757     }else {
00758         //do not append for S to X upgrade
00759         if (!ProcessManager::hasLockList.exists(chunkPtr_)) 
00760             ProcessManager::hasLockList.append(chunkPtr_);
00761     }
00762 */
00763     return ret;
00764 }
00765 DbRetVal TableImpl::unlock()
00766 {
00767 /*
00768     if (!ProcessManager::hasLockList.exists(chunkPtr_)) return OK;
00769     DbRetVal ret = lMgr_->releaseLock(chunkPtr_);
00770     if (OK != ret)
00771     {
00772         printError(ret, "Could not release exclusive lock on the table %x", chunkPtr_);
00773     }else
00774     {
00775         ProcessManager::hasLockList.remove(chunkPtr_);
00776     }
00777 */
00778     return OK;
00779 }
00780 
00781 TableImpl::~TableImpl()
00782 {
00783     if (NULL != iter ) { delete iter; iter = NULL; }
00784     if (NULL != indexPtr_) { delete[] indexPtr_; indexPtr_ = NULL;  }
00785     if (NULL != idxInfo) 
00786     {
00787         for (int i = 0; i < numIndexes_; i++) delete idxInfo[i];
00788         delete[] idxInfo; 
00789         idxInfo = NULL; 
00790     }
00791     if (numFlds_ > 31 && cNullInfo != NULL) { free(cNullInfo); cNullInfo = NULL; }
00792 
00793     fldList_.removeAll();
00794 
00795 }

Generated on Mon Jun 9 22:37:15 2008 for csql by  doxygen 1.4.7