error in parsing date and time leads to wrong value being inserted into the table
[csql.git] / src / server / TableImpl.cxx
blob710e10f05a51b74337169ddeae422a8eaa2a5cb0
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<Index.h>
17 #include<CatalogTables.h>
18 #include<Lock.h>
19 #include<Debug.h>
20 #include<Table.h>
21 #include<TableImpl.h>
22 #include<Predicate.h>
23 #include<PredicateImpl.h>
24 #include<Index.h>
25 #include<Config.h>
27 DbRetVal TableImpl::bindFld(const char *name, void *val)
29 //set it in the field list
30 DbRetVal rv = fldList_.updateBindVal(name, val);
31 if (OK != rv) {
32 printError(ErrNotExists, "Field %s does not exist", name);
33 return rv;
35 return OK;
38 bool TableImpl::isFldNull(const char *name){
39 int colpos = fldList_.getFieldPosition(name);
40 if (-1 == colpos)
42 printError(ErrNotExists, "Field %s does not exist", name);
43 return false;
46 return isFldNull(colpos);
49 bool TableImpl::isFldNull(int colpos)
51 if (!curTuple_) return false;
52 if (colpos <1 || colpos > numFlds_) return false;
53 char *nullOffset = (char*)curTuple_ - 4;
54 if (isIntUsedForNULL) {
55 int nullVal = *(int*)((char*)curTuple_ + (length_ - 4));
56 if (BITSET(nullVal, colpos)) return true;
58 else {
59 char *nullOffset = (char*)curTuple_ - os::align(numFlds_);
60 if (nullOffset[colpos-1]) return true;
62 return false;
64 void TableImpl::markFldNull(char const* name)
66 int colpos = fldList_.getFieldPosition(name);
67 if (-1 == colpos)
69 printError(ErrNotExists, "Field %s does not exist", name);
70 return;
72 markFldNull(colpos);
75 void TableImpl::markFldNull(int fldpos)
77 if (fldpos <1 || fldpos > numFlds_) return;
78 if (isIntUsedForNULL) {
79 if (!BITSET(iNotNullInfo, fldpos)) SETBIT(iNullInfo, fldpos);
81 else
82 if (!BITSET(iNotNullInfo, fldpos)) cNullInfo[fldpos-1] = 1;
83 return;
86 void TableImpl::clearFldNull(const char *name)
88 int colpos = fldList_.getFieldPosition(name);
89 if (-1 == colpos)
91 printError(ErrNotExists, "Field %s does not exist", name);
92 return;
95 clearFldNull(colpos);
98 void TableImpl::clearFldNull(int colpos)
100 if (colpos <1 || colpos > numFlds_) return;
101 if (isIntUsedForNULL) {
102 CLEARBIT(iNullInfo, colpos);
104 else
105 cNullInfo[colpos-1] = 0;
106 return;
110 DbRetVal TableImpl::execute()
112 if (NULL != iter)
114 printError(ErrAlready,"Scan already open:Close and re execute");
115 return ErrAlready;
117 //table ptr is set in predicate because it needs to access the
118 //type and length to evaluate
119 if( NULL != pred_)
121 PredicateImpl *pred = (PredicateImpl*) pred_;
122 pred->setTable(this);
124 DbRetVal ret = OK;
126 ret = createPlan();
127 if (OK != ret)
129 printError(ErrSysInternal,"Unable to create the plan");
130 return ErrSysInternal;
132 if (useIndex_ >= 0)
133 iter = new TupleIterator(pred_, scanType_, idxInfo[useIndex_], chunkPtr_, sysDB_->procSlot);
134 else if (scanType_ == fullTableScan)
135 iter = new TupleIterator(pred_, scanType_, NULL, chunkPtr_, sysDB_->procSlot);
136 else
138 printError(ErrSysFatal,"Unable to create tuple iterator");//should never happen
139 return ErrSysFatal;
141 ret = iter->open();
142 if (OK != ret)
144 printError(ret,"Unable to open the iterator");
145 return ret;
147 return OK;
151 DbRetVal TableImpl::createPlan()
153 if (isPlanCreated) {
154 //will do early return here. plan is generated only when setPredicate is called.
155 if (scanType_ == unknownScan) return ErrSysFatal; //this should never happen
156 else return OK;
158 useIndex_ = -1;
159 //if there are no predicates then go for full scan
160 //if there are no indexes then go for full scan
161 if (NULL == pred_ || NULL == indexPtr_)
163 scanType_ = fullTableScan;
164 isPlanCreated = true;
165 return OK;
167 if (NULL != indexPtr_)
169 PredicateImpl *pred = (PredicateImpl*)pred_;
170 printDebug(DM_Predicate, "predicate does not involve NOT , OR operator");
171 if (!pred->isNotOrInvolved())
173 printDebug(DM_Predicate, "predicate does not involve NOT , OR operator");
174 for (int i =0; i < numIndexes_; i++)
176 HashIndexInfo* info = (HashIndexInfo*) idxInfo[i];
177 FieldIterator iter = info->idxFldList.getIterator();
178 while(iter.hasElement())
180 FieldDef def = iter.nextElement();
181 if (pred->pointLookupInvolved(def.fldName_))
183 printDebug(DM_Predicate, "point lookup involved for field %s",def.fldName_);
184 scanType_ = hashIndexScan;
185 isPlanCreated = true;
186 useIndex_ = i;
188 else
190 useIndex_ = -1;
191 break;
193 }//while iter.hasElement()
194 if (useIndex_ != -1) return OK;
195 }//for
198 scanType_ = fullTableScan;
199 isPlanCreated = true;
200 return OK;
203 void* TableImpl::fetch()
205 fetchNoBind();
206 if (NULL == curTuple_) return curTuple_;
207 copyValuesToBindBuffer(curTuple_);
208 return curTuple_;
210 void* TableImpl::fetch(DbRetVal &rv)
212 fetchNoBind(rv);
213 if (NULL == curTuple_) return curTuple_;
214 copyValuesToBindBuffer(curTuple_);
215 return curTuple_;
218 void* TableImpl::fetchNoBind()
220 if (NULL == iter)
222 printError(ErrNotOpen,"Scan not open or Scan is closed\n");
223 return NULL;
225 void *prevTuple = curTuple_;
226 curTuple_ = iter->next();
227 if (NULL == curTuple_)
229 return NULL;
231 DbRetVal lockRet = OK;
232 if ((*trans)->isoLevel_ == READ_REPEATABLE) {
233 lockRet = lMgr_->getSharedLock(curTuple_, trans);
234 if (OK != lockRet)
236 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
237 curTuple_ = prevTuple;
238 return NULL;
242 else if ((*trans)->isoLevel_ == READ_COMMITTED)
244 //if iso level is read committed, operation duration lock is sufficent
245 //so release it here itself.
246 int tries = 5;
247 struct timeval timeout;
248 timeout.tv_sec = Conf::config.getMutexSecs();
249 timeout.tv_usec = Conf::config.getMutexUSecs();
251 bool status = false;
252 while(true) {
253 lockRet = lMgr_->isExclusiveLocked( curTuple_, trans, status);
254 if (OK != lockRet)
256 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
257 curTuple_ = prevTuple;
258 return NULL;
260 if (!status) break;
261 tries--;
262 if (tries == 0) break;
263 os::select(0, 0, 0, 0, &timeout);
266 if (tries == 0)
268 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
269 curTuple_ = prevTuple;
270 return NULL;
273 return curTuple_;
276 void* TableImpl::fetchNoBind(DbRetVal &rv)
278 rv = OK;
279 if (NULL == iter)
281 printError(ErrNotOpen,"Scan not open or Scan is closed\n");
282 rv = ErrNotOpen;
283 return NULL;
285 void *prevTuple = curTuple_;
286 curTuple_ = iter->next();
287 if (NULL == curTuple_)
289 return NULL;
291 DbRetVal lockRet = OK;
292 if ((*trans)->isoLevel_ == READ_REPEATABLE) {
293 lockRet = lMgr_->getSharedLock(curTuple_, trans);
294 if (OK != lockRet)
296 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
297 rv = ErrLockTimeOut;
298 curTuple_ = prevTuple;
299 return NULL;
303 else if ((*trans)->isoLevel_ == READ_COMMITTED)
305 //if iso level is read committed, operation duration lock is sufficent
306 //so release it here itself.
307 int tries = 5;
308 struct timeval timeout;
309 timeout.tv_sec = Conf::config.getMutexSecs();
310 timeout.tv_usec = Conf::config.getMutexUSecs();
312 bool status = false;
313 while(true) {
314 lockRet = lMgr_->isExclusiveLocked( curTuple_, trans, status);
315 if (OK != lockRet)
317 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
318 curTuple_ = prevTuple;
319 rv = ErrLockTimeOut;
320 return NULL;
322 if (!status) break;
323 tries--;
324 if (tries == 0) break;
325 os::select(0, 0, 0, 0, &timeout);
328 if (tries == 0)
330 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
331 curTuple_ = prevTuple;
332 rv = ErrLockTimeOut;
333 return NULL;
336 return curTuple_;
339 DbRetVal TableImpl::insertTuple()
341 DbRetVal ret =OK;
342 void *tptr = ((Chunk*)chunkPtr_)->allocate(db_, &ret);
343 if (NULL == tptr)
345 printError(ret, "Unable to allocate record from chunk");
346 return ret;
348 ret = lMgr_->getExclusiveLock(tptr, trans);
349 if (OK != ret)
351 ((Chunk*)chunkPtr_)->free(db_, tptr);
352 printError(ret, "Could not get lock for the insert tuple %x", tptr);
353 return ErrLockTimeOut;
357 ret = copyValuesFromBindBuffer(tptr);
358 if (ret != OK)
360 printError(ret, "Unable to copy values from bind buffer");
361 (*trans)->removeFromHasList(db_, tptr);
362 lMgr_->releaseLock(tptr);
363 ((Chunk*)chunkPtr_)->free(db_, tptr);
364 return ret;
367 int addSize = 0;
368 if (numFlds_ < 31)
370 addSize = 4;
371 *(int*)((char*)(tptr) + (length_-addSize)) = iNullInfo;
373 else
375 addSize = os::align(numFlds_);
376 os::memcpy(((char*)(tptr) + (length_-addSize)), cNullInfo, addSize);
379 //int tupleSize = length_ + addSize;
380 if (NULL != indexPtr_)
382 int i;
383 //it has index
384 for (i = 0; i < numIndexes_ ; i++)
386 ret = insertIndexNode(*trans, indexPtr_[i], idxInfo[i], tptr);
387 if (ret != OK) { printError(ret, "Error in inserting to index"); break;}
389 if (i != numIndexes_ )
391 for (int j = 0; j < i ; j++) {
392 printError(ErrWarning, "Deleting index node");
393 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
395 lMgr_->releaseLock(tptr);
396 (*trans)->removeFromHasList(db_, tptr);
397 ((Chunk*)chunkPtr_)->free(db_, tptr);
398 //PRABA::TEMP
399 //printError(ret, "Unable to insert index node for tuple %x ", tptr);
400 printError(ret, "Unable to insert index node for tuple %x %d", tptr, *(int*)tptr);
401 return ret;
404 if (undoFlag)
405 ret = (*trans)->appendUndoLog(sysDB_, InsertOperation, tptr, length_);
406 if (ret != OK) {
407 printError(ret, "Unable to create undo log for %x %d", tptr, *(int*)tptr);
408 for (int j = 0; j < numIndexes_ ; j++) {
409 printError(ErrWarning, "Deleting index node");
410 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
412 lMgr_->releaseLock(tptr);
413 (*trans)->removeFromHasList(db_, tptr);
414 ((Chunk*)chunkPtr_)->free(db_, tptr);
416 return ret;
419 DbRetVal TableImpl::deleteTuple()
421 if (NULL == curTuple_)
423 printError(ErrNotOpen, "Scan not open: No Current tuple");
424 return ErrNotOpen;
426 DbRetVal ret = lMgr_->getExclusiveLock(curTuple_, trans);
427 if (OK != ret)
429 printError(ret, "Could not get lock for the delete tuple %x", curTuple_);
430 return ErrLockTimeOut;
433 if (NULL != indexPtr_)
435 int i;
436 //it has index
437 for (i = 0; i < numIndexes_ ; i++)
439 ret = deleteIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
440 if (ret != OK) break;
442 if (i != numIndexes_ )
444 for (int j = 0; j < i ; j++)
445 insertIndexNode(*trans, indexPtr_[j], idxInfo[j], curTuple_);
446 lMgr_->releaseLock(curTuple_);
447 (*trans)->removeFromHasList(db_, curTuple_);
448 printError(ret, "Unable to insert index node for tuple %x", curTuple_);
449 return ret;
452 ((Chunk*)chunkPtr_)->free(db_, curTuple_);
453 if (undoFlag)
454 ret = (*trans)->appendUndoLog(sysDB_, DeleteOperation, curTuple_, length_);
455 return ret;
458 int TableImpl::deleteWhere()
460 int tuplesDeleted = 0;
461 DbRetVal rv = OK;
462 rv = execute();
463 if (rv !=OK) return (int) rv;
464 while(true){
465 fetchNoBind( rv);
466 if (rv != OK) { tuplesDeleted = (int)rv; break; }
467 if (NULL == curTuple_) break;
468 rv = deleteTuple();
469 if (rv != OK) {
470 printError(rv, "Error: Could only delete %d tuples", tuplesDeleted);
471 close();
472 return (int) rv;
474 tuplesDeleted++;
476 close();
477 return tuplesDeleted;
480 int TableImpl::truncate()
482 //take exclusive lock on the table
483 //get the chunk ptr of the table
484 //traverse the tablechunks and free all the pages except the first one
485 //get the chunk ptr of all its indexes
486 //traverse the indexchunks and free all the pages except the first one
487 //release table lock
489 //TEMPORARY FIX
490 DbRetVal rv = OK;
491 Predicate* tmpPred = pred_;
492 pred_ = NULL;
493 isPlanCreated = false;
494 int tuplesDeleted = deleteWhere();
495 isPlanCreated = false;
496 pred_ = tmpPred;
497 return tuplesDeleted;
500 DbRetVal TableImpl::updateTuple()
502 if (NULL == curTuple_)
504 printError(ErrNotOpen, "Scan not open: No Current tuple");
505 return ErrNotOpen;
507 DbRetVal ret = lMgr_->getExclusiveLock(curTuple_, trans);
508 if (OK != ret)
510 printError(ret, "Could not get lock for the update tuple %x", curTuple_);
511 return ErrLockTimeOut;
513 if (NULL != indexPtr_)
515 //it has index
516 //TODO::If it fails while updating index node, we have to undo all the updates
517 //on other indexes on the table.Currently it will leave the database in an
518 //inconsistent state.
519 for (int i = 0; i < numIndexes_ ; i++)
521 ret = updateIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
522 if (ret != OK)
524 lMgr_->releaseLock(curTuple_);
525 (*trans)->removeFromHasList(db_, curTuple_);
526 printError(ret, "Unable to update index node for tuple %x", curTuple_);
527 return ret;
531 if (undoFlag)
532 ret = (*trans)->appendUndoLog(sysDB_, UpdateOperation, curTuple_, length_);
533 if (ret != OK) return ret;
534 int addSize = 0;
535 if (numFlds_ < 31)
537 addSize = 4;
538 *(int*)((char*)(curTuple_) + (length_-addSize)) |= iNullInfo;
540 else
542 addSize = os::align(numFlds_);
543 //TODO::Do not do blind memcpy. It should OR each and every char
544 //os::memcpy(((char*)(curTuple_) + (length_-addSize)), cNullInfo, addSize);
548 DbRetVal rv = copyValuesFromBindBuffer(curTuple_, false);
549 if (rv != OK) {
550 lMgr_->releaseLock(curTuple_);
551 (*trans)->removeFromHasList(db_, curTuple_);
552 return rv;
554 return OK;
557 void TableImpl::printInfo()
559 printf(" <TableName> %s </TableName>\n", tblName_);
560 printf(" <TupleCount> %d </TupleCount>\n", numTuples());
561 printf(" <PagesUsed> %d </PagesUsed>\n", pagesUsed());
562 printf(" <SpaceUsed> %d </SpaceUsed>\n", spaceUsed());
563 printf(" <Indexes> %d <Indexes>\n", numIndexes_);
564 printf(" <TupleLength> %d </TupleLength>\n", length_);
565 printf(" <Fields> %d </Fields>\n", numFlds_);
566 printf(" <Indexes>\n");
567 for (int i =0; i<numIndexes_; i++)
568 printf("<IndexName> %s </IndexName>\n", CatalogTableINDEX::getName(indexPtr_[i]));
569 printf(" </Indexes>\n");
573 DbRetVal TableImpl::copyValuesFromBindBuffer(void *tuplePtr, bool isInsert)
575 //Iterate through the bind list and copy the value here
576 FieldIterator fIter = fldList_.getIterator();
577 char *colPtr = (char*) tuplePtr;
578 int fldpos=1;
579 while (fIter.hasElement())
581 FieldDef def = fIter.nextElement();
582 if (def.isNull_ && !def.isDefault_ && NULL == def.bindVal_ && isInsert)
584 printError(ErrNullViolation, "NOT NULL constraint violation for field %s\n", def.fldName_);
585 return ErrNullViolation;
587 if (def.isDefault_ && NULL == def.bindVal_ && isInsert)
589 void *dest = AllDataType::alloc(def.type_, def.length_);
590 AllDataType::convert(typeString, def.defaultValueBuf_, def.type_, dest, def.length_);
591 AllDataType::copyVal(colPtr, dest, def.type_, def.length_);
592 colPtr = colPtr + os::align(AllDataType::size(def.type_, def.length_));
593 fldpos++;
594 free (dest);
595 continue;
597 switch(def.type_)
599 case typeString:
600 if (NULL != def.bindVal_)
602 strcpy((char*)colPtr, (char*)def.bindVal_);
603 *(((char*)colPtr) + (def.length_-1)) = '\0';
605 else if (!def.isNull_ && isInsert) setNullBit(fldpos);
606 colPtr = colPtr + os::align(def.length_);
607 break;
608 case typeBinary:
609 if (NULL != def.bindVal_ ) {
610 DbRetVal rv = AllDataType::strToValue(colPtr, (char *) def.bindVal_, def.type_, def.length_);
611 if (rv != OK) return ErrBadArg;
613 else if (!def.isNull_ && isInsert) setNullBit(fldpos);
614 colPtr = colPtr + os::align(def.length_);
615 break;
616 default:
617 if (NULL != def.bindVal_)
618 AllDataType::copyVal(colPtr, def.bindVal_, def.type_);
619 else { if (!def.isNull_ && isInsert) setNullBit(fldpos); }
620 colPtr = colPtr + os::align(AllDataType::size(def.type_));
621 break;
623 fldpos++;
625 return OK;
627 void TableImpl::setNullBit(int fldpos)
629 if (isIntUsedForNULL)
630 SETBIT(iNullInfo, fldpos);
631 else
632 cNullInfo[fldpos-1] = 1;
634 DbRetVal TableImpl::copyValuesToBindBuffer(void *tuplePtr)
636 //Iterate through the bind list and copy the value here
637 FieldIterator fIter = fldList_.getIterator();
638 char *colPtr = (char*) tuplePtr;
639 while (fIter.hasElement())
641 FieldDef def = fIter.nextElement();
642 if (NULL != def.bindVal_)
643 AllDataType::copyVal(def.bindVal_, colPtr, def.type_, def.length_);
644 colPtr = colPtr + os::align(AllDataType::size(def.type_, def.length_));
646 return OK;
649 //-1 index not supported
650 DbRetVal TableImpl::insertIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
652 INDEX *iptr = (INDEX*)indexPtr;
653 DbRetVal ret = OK;
654 printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
655 Index* idx = Index::getIndex(iptr->indexType_);
656 ret = idx->insert(this, tr, indexPtr, info, tuple,undoFlag);
657 return ret;
660 DbRetVal TableImpl::deleteIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
662 INDEX *iptr = (INDEX*)indexPtr;
663 DbRetVal ret = OK;
664 Index* idx = Index::getIndex(iptr->indexType_);
665 ret = idx->remove(this, tr, indexPtr, info, tuple, undoFlag);
666 return ret;
668 void TableImpl::printSQLIndexString()
670 CatalogTableINDEXFIELD cIndexField(sysDB_);
671 char fName[IDENTIFIER_LENGTH];
672 char *fldName = fName;
673 DataType type;
674 for (int i = 0; i < numIndexes_ ; i++)
676 INDEX *iptr = (INDEX*) indexPtr_[i];
677 //cIndexField.getFieldNameAndType((void*)iptr, fldName, type);
678 //printf("CREATE INDEX %s on %s ( %s ) ", iptr->indName_, getName(), fldName);
679 printf("CREATE INDEX %s on %s ( ", iptr->indName_, getName());
680 FieldList fldList;
681 cIndexField.getFieldInfo(iptr, fldList);
682 FieldIterator fIter = fldList.getIterator();
683 bool firstFld = true;
684 while(fIter.hasElement())
686 FieldDef def = fIter.nextElement();
687 if (firstFld) { printf(" %s ", def.fldName_); firstFld = false; }
688 else printf(" ,%s ", def.fldName_);
690 printf(" ) ");
691 if (((HashIndexInfo*) idxInfo[i])->isUnique) printf(" UNIQUE;\n"); else printf(";\n");
696 DbRetVal TableImpl::updateIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
698 INDEX *iptr = (INDEX*)indexPtr;
699 DbRetVal ret = OK;
700 Index* idx = Index::getIndex(iptr->indexType_);
701 //TODO::currently it updates irrespective of whether the key changed or not
702 //because of this commenting the whole index update code. relook at it and uncomment
704 ret = idx->update(this, tr, indexPtr, info, tuple, undoFlag);
706 return ret;
710 void TableImpl::setTableInfo(char *name, int tblid, size_t length,
711 int numFld, int numIdx, void *chunk)
713 strcpy(tblName_, name);
714 tblID_ = tblid;
715 length_ = length;
716 numFlds_ = numFld;
717 numIndexes_ = numIdx;
718 chunkPtr_ = chunk;
721 long TableImpl::spaceUsed()
723 Chunk *chk = (Chunk*)chunkPtr_;
724 long totSize = chk->getTotalDataNodes() * chk->getSize();
725 totSize = totSize + (chk->totalPages() * sizeof (PageInfo));
726 return totSize;
729 int TableImpl::pagesUsed()
731 Chunk *chk = (Chunk*)chunkPtr_;
732 return chk->totalPages();
735 long TableImpl::numTuples()
737 return ((Chunk*)chunkPtr_)->getTotalDataNodes();
740 List TableImpl::getFieldNameList()
742 List fldNameList;
743 FieldIterator fIter = fldList_.getIterator();
744 while (fIter.hasElement())
746 FieldDef def = fIter.nextElement();
747 Identifier *elem = new Identifier();
748 strcpy(elem->name, def.fldName_);
749 fldNameList.append(elem);
751 return fldNameList;
753 DbRetVal TableImpl::close()
755 if (NULL == iter)
757 printError(ErrNotOpen,"Scan not open");
758 return ErrNotOpen;
760 iter->close();
761 delete iter;
762 iter = NULL;
763 return OK;
765 DbRetVal TableImpl::lock(bool shared)
768 DbRetVal ret = OK;
770 if (shared)
771 ret = lMgr_->getSharedLock(chunkPtr_, NULL);
772 else
773 ret = lMgr_->getExclusiveLock(chunkPtr_, NULL);
774 if (OK != ret)
776 printError(ret, "Could not exclusive lock on the table %x", chunkPtr_);
777 }else {
778 //do not append for S to X upgrade
779 if (!ProcessManager::hasLockList.exists(chunkPtr_))
780 ProcessManager::hasLockList.append(chunkPtr_);
783 return ret;
785 DbRetVal TableImpl::unlock()
788 if (!ProcessManager::hasLockList.exists(chunkPtr_)) return OK;
789 DbRetVal ret = lMgr_->releaseLock(chunkPtr_);
790 if (OK != ret)
792 printError(ret, "Could not release exclusive lock on the table %x", chunkPtr_);
793 }else
795 ProcessManager::hasLockList.remove(chunkPtr_);
798 return OK;
801 TableImpl::~TableImpl()
803 if (NULL != iter ) { delete iter; iter = NULL; }
804 if (NULL != indexPtr_) { delete[] indexPtr_; indexPtr_ = NULL; }
805 if (NULL != idxInfo)
807 for (int i = 0; i < numIndexes_; i++) delete idxInfo[i];
808 delete[] idxInfo;
809 idxInfo = NULL;
811 if (numFlds_ > 31 && cNullInfo != NULL) { free(cNullInfo); cNullInfo = NULL; }
813 fldList_.removeAll();