error in parsing date and time leads to wrong value being inserted into the table
[csql.git] / src / storage / TableImpl.cxx
blobf6e7c8b8ad19afefdb80963e44bf239b5db572d4
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>
26 #include<AggTableImpl.h> //for AggType
28 void Table::getFieldNameAlone(char *fname, char *name) {
29 bool dotFound= false;
30 char *fullname = fname;
31 while(*fullname != '\0')
33 if (*fullname == '.') { dotFound = true; break; }
34 fullname++;
36 if (dotFound) strcpy(name, ++fullname); else strcpy(name, fname);
39 void Table::getTableNameAlone(char *fname, char *name) {
40 strcpy(name, fname);
41 char *start = name;
42 bool dotFound = false;
43 while(*name != '\0')
45 if (*name == '.') { *name='\0'; dotFound = true; break; }
46 name++;
48 if (!dotFound) strcpy(start, "");
49 return;
52 DbRetVal TableImpl::bindFld(const char *name, void *val, bool isNullExpl)
54 if (name[0] == '*' ) return OK;
55 //set it in the field list
56 char fieldName[IDENTIFIER_LENGTH];
57 getFieldNameAlone((char*)name, fieldName);
58 DbRetVal rv = fldList_.updateBindVal(fieldName, val, isNullExpl);
59 if (OK != rv) {
60 printError(ErrNotExists, "Field %s does not exist", fieldName);
61 return rv;
63 return OK;
66 bool TableImpl::isFldNull(const char *name){
67 if (name[0] == '*') return false;
68 if ( strncasecmp(name,"COUNT",5) == 0 || strncasecmp(name,"AVG",3) == 0 ||
69 strncasecmp(name,"MIN",3) == 0 || strncasecmp(name,"MAX",3) == 0 ||
70 strncasecmp(name,"SUM",3) == 0 ) return false;
71 char fieldName[IDENTIFIER_LENGTH];
72 getFieldNameAlone((char*)name, fieldName);
73 int colpos = fldList_.getFieldPosition(fieldName);
74 if (-1 == colpos)
76 printError(ErrNotExists, "Field %s does not exist", name);
77 return false;
80 return isFldNull(colpos);
83 int TableImpl::getFldPos(char *name)
85 return fldList_.getFieldPosition(name);
87 void TableImpl::setAliasName(char *name)
89 strcpy(aliasName, name);
91 bool TableImpl::isFldNull(int colpos)
93 if (!curTuple_) return false;
94 if (colpos <1 || colpos > numFlds_) return false;
95 if (isIntUsedForNULL) {
96 int nullVal = *(int*)((char*)curTuple_ + (length_ - 4));
97 if (BITSET(nullVal, colpos-1)) return true;
99 else {
100 char *nullOffset = (char*)curTuple_ + (length_ - os::align(numFlds_));
101 if (nullOffset[colpos-1]) return true;
103 return false;
105 void TableImpl::resetNullinfo()
107 if (isIntUsedForNULL) {
108 iNullInfo =0;
110 else {
111 int i=0;
112 while(i < numFlds_) { cNullInfo[i++] = 0;}
115 DbRetVal TableImpl::markFldNull(char const* name)
117 DbRetVal rv = OK;
118 int colpos = fldList_.getFieldPosition(name);
119 if (-1 == colpos)
121 printError(ErrNotExists, "Field %s does not exist", name);
122 return ErrNotExists;
124 rv = markFldNull(colpos);
125 return rv;
128 DbRetVal TableImpl::markFldNull(int fldpos)
130 if (fldpos <1 || fldpos > numFlds_) return ErrBadArg;
131 if (isIntUsedForNULL) {
132 if (!BITSET(iNotNullInfo, fldpos-1)) SETBIT(iNullInfo, fldpos-1);
133 else {
134 printError(ErrNullViolation, "NOT NULL constraint violation");
135 return ErrNullViolation;
138 else {
139 if (!cNotNullInfo[fldpos-1]) cNullInfo[fldpos-1] = 1;
140 else {
141 printError(ErrNullViolation, "NOT NULL constraint violation");
142 return ErrNullViolation;
145 return OK;
148 void TableImpl::clearFldNull(const char *name)
150 int colpos = fldList_.getFieldPosition(name);
151 if (-1 == colpos)
153 printError(ErrNotExists, "Field %s does not exist", name);
154 return;
156 clearFldNull(colpos);
159 void TableImpl::clearFldNull(int colpos)
161 if (colpos <1 || colpos > numFlds_) return;
162 if (isIntUsedForNULL) CLEARBIT(iNullInfo, colpos-1);
163 else cNullInfo[colpos-1] = 0;
164 return;
167 bool TableImpl::hasIndex(char* fName)
169 if (NULL == indexPtr_) return false;
170 for (int i =0; i < numIndexes_; i++)
172 HashIndexInfo* info = (HashIndexInfo*) idxInfo[i];
173 FieldIterator iter = info->idxFldList.getIterator();
174 if(iter.hasElement())
176 FieldDef *def = iter.nextElement();
177 if(strcmp(def->fldName_, fName) == 0)
178 if(!iter.hasElement())//neglet if it is composite index
179 return true;
182 return false;
185 IndexType TableImpl::getIndexType(char *fName, int *pos)
187 if (NULL == indexPtr_) return unknownIndex;
188 for (int i =0; i < numIndexes_; i++)
190 HashIndexInfo* info = (HashIndexInfo*) idxInfo[i];
191 FieldIterator iter = info->idxFldList.getIterator();
192 if(iter.hasElement())
194 FieldDef *def = iter.nextElement();
195 if(strcmp(def->fldName_, fName) == 0)
196 if(!iter.hasElement()) {//neglet if it is composite index
197 *(int*)pos = i;
198 return info->indType;
202 *(int*)pos = -1;
203 return unknownIndex;
205 void TableImpl::addPredicate(char *fName, ComparisionOp op, void *buf)
207 char fieldName[IDENTIFIER_LENGTH];
208 Table::getFieldNameAlone(fName, fieldName);
209 PredicateImpl *pred = (PredicateImpl*) pred_;
210 PredicateImpl *newPred = new PredicateImpl();
211 newPred->setTerm(fName, op, buf);
212 if (NULL == pred) { pred_ = newPred; predList.append(newPred); return; }
213 if (pred->isSingleTerm())
215 bool res = pred->appendIfSameFld(fName, op, buf);
216 if(res) {
217 delete newPred;
218 return;
221 PredicateImpl *bothPred = new PredicateImpl();
222 bothPred->setTerm(pred, OpAnd, newPred);
223 predList.append(bothPred);
224 pred_ = bothPred;
227 DbRetVal TableImpl::optimize()
229 //table ptr is set in predicate because it needs to access the
230 //type and length to evaluate
231 if( NULL != pred_)
233 PredicateImpl *pred = (PredicateImpl*) pred_;
234 pred->setTable(this);
235 pred->setProjectionList(NULL);
236 pred->setOffsetAndType();
238 DbRetVal rv = createPlan();
239 if (rv != OK) return rv;
240 if (iter) { iter->close(); delete iter; iter = NULL; }
241 if (useIndex_ >= 0)
242 iter = new TupleIterator(pred_, scanType_, idxInfo[useIndex_], chunkPtr_, sysDB_->procSlot,isBetween,isPointLook,shouldNullSearch);
243 else if (scanType_ == fullTableScan)
244 iter = new TupleIterator(pred_, scanType_, NULL, chunkPtr_, sysDB_->procSlot,isBetween,isPointLook,shouldNullSearch);
245 else
247 printError(ErrSysFatal,"Unable to create tuple iterator");
248 //should never happen
249 return ErrSysFatal;
251 iter->setPlan();
252 return OK;
255 DbRetVal TableImpl::execute()
257 if (iter && !iter->isIterClosed())
259 //printError(ErrAlready,"Scan already open:Close and re execute");
260 return ErrAlready;
262 DbRetVal ret = OK;
263 if (!isPlanCreated) ret = optimize();
264 if (OK != ret)
266 printError(ErrSysInternal,"Unable to create the plan");
267 return ErrSysInternal;
269 ret = iter->open();
270 if (OK != ret)
272 printError(ret,"Unable to open the iterator");
273 return ret;
275 return OK;
279 DbRetVal TableImpl::createPlan()
281 if (isPlanCreated) {
282 //will do early return here. plan is generated only when setPredicate is called.
283 if (scanType_ == unknownScan) return ErrSysFatal; //this should never happen
284 else return OK;
286 isBetween=false;
287 isPointLook = false;
288 useIndex_ = -1;
290 FieldIterator fIter = fldList_.getIterator();
291 FieldDef *def = NULL;
292 while ((def = fIter.nextElement())!= NULL) {
293 if (NULL != def->bindVal_) bindList_.append(def);
295 numBindFlds_ = bindList_.size();
296 if (bindListArray_) { ::free(bindListArray_); bindListArray_ = NULL; }
297 bindListArray_ = (void **) malloc(numBindFlds_ * sizeof (void *));
298 void *elem = NULL;
299 int i = 0;
300 ListIterator it = bindList_.getIterator();
301 while ((elem = it.nextElement()) != NULL) bindListArray_[i++] = elem;
302 scanType_ = fullTableScan;
303 isPlanCreated = true;
305 //if there are no predicates then go for full scan
306 //if there are no indexes then go for full scan
307 if (NULL == pred_ || NULL == indexPtr_)
309 return OK;
311 if (NULL != indexPtr_)
313 PredicateImpl *pred = (PredicateImpl*)pred_;
314 //If searching for IS NULL or IS NOT NULL then fullscan
315 if(pred->isIsNullInvolved())
317 scanType_ = fullTableScan;
318 shouldNullSearch=true;
319 return OK;
321 printDebug(DM_Predicate, "predicate does not involve NOT , OR operator");
322 if (!pred->isNotOrInvolved())
324 printDebug(DM_Predicate, "predicate does not involve NOT , OR operator");
325 for (int i =0; i < numIndexes_; i++)
327 bool isAllFldPointLookup = true;
328 HashIndexInfo* info = (HashIndexInfo*) idxInfo[i];
329 FieldIterator iter = info->idxFldList.getIterator();
330 int noOfIfld =0;
331 while(iter.hasElement())
333 noOfIfld++;
334 FieldDef *def = iter.nextElement();
335 if (pred->pointLookupInvolved(def->fldName_))
337 if (!isAllFldPointLookup) break;
338 printDebug(DM_Predicate, "point lookup involved for field %s",def->fldName_);
339 if(hashIndex == info->indType) scanType_ = hashIndexScan;
340 else scanType_ = treeIndexScan;
341 isPointLook = true;
342 useIndex_ = i;
344 else if (pred->isBetweenInvolved(def->fldName_))
346 if (treeIndex == info->indType)
348 scanType_ = treeIndexScan;
349 useIndex_ = i;
350 isBetween=true;
351 break; //no composite index for tree index
352 } else isAllFldPointLookup= false;
354 else if (pred->rangeQueryInvolved(def->fldName_))
356 printDebug(DM_Predicate, "range lookup involved for field %s",def->fldName_);
357 if (treeIndex == info->indType)
359 scanType_ = treeIndexScan;
360 useIndex_ = i;
361 break; //no composite index for tree index
362 } else isAllFldPointLookup=false;
363 }else {
364 useIndex_ = -1;
365 isAllFldPointLookup = false;
366 break;
368 }//while iter.hasElement()
369 if( noOfIfld == 1 && useIndex_ != -1)return OK;
370 if (!isAllFldPointLookup && useIndex_ != -1) return OK;
371 }//for
374 scanType_ = fullTableScan;
375 return OK;
378 void* TableImpl::fetch()
380 fetchNoBind();
381 if (NULL == curTuple_) return curTuple_;
382 copyValuesToBindBuffer(curTuple_);
383 return curTuple_;
385 void* TableImpl::fetch(DbRetVal &rv)
387 fetchNoBind(rv);
388 if (NULL == curTuple_) return curTuple_;
389 copyValuesToBindBuffer(curTuple_);
390 return curTuple_;
393 void* TableImpl::fetchNoBind()
395 if (NULL == iter)
397 printError(ErrNotOpen,"Scan not open or Scan is closed\n");
398 return NULL;
400 void *prevTuple = curTuple_;
401 curTuple_ = iter->next();
402 if (NULL == curTuple_)
404 return NULL;
406 DbRetVal lockRet = OK;
407 if (!loadFlag) {
408 if ((*trans)->isoLevel_ == READ_COMMITTED)
410 //if iso level is read committed, operation duration lock is sufficent
411 //so release it here itself.
412 int tries = Conf::config.getMutexRetries();
413 struct timeval timeout, timeval;
414 timeout.tv_sec = Conf::config.getMutexSecs();
415 timeout.tv_usec = Conf::config.getMutexUSecs();
417 bool status = false;
418 while(true) {
419 lockRet = lMgr_->isExclusiveLocked( curTuple_, trans, status);
420 if (OK != lockRet)
422 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
423 curTuple_ = prevTuple;
424 return NULL;
426 if (!status) break;
427 tries--;
428 if (tries == 0) break;
429 timeval.tv_sec = timeout.tv_sec;
430 timeval.tv_usec = timeout.tv_usec;
431 os::select(0, 0, 0, 0, &timeval);
433 if (tries == 0)
435 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
436 curTuple_ = prevTuple;
437 return NULL;
440 else if ((*trans)->isoLevel_ == READ_REPEATABLE) {
441 if (OK != trySharedLock(curTuple_, trans))
443 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
444 curTuple_ = prevTuple;
445 return NULL;
450 return curTuple_;
452 DbRetVal TableImpl::trySharedLock(void *curTuple, Transaction **trans)
454 DbRetVal lockRet = OK;
455 int tries = Conf::config.getMutexRetries();
456 while((lockRet = lMgr_->getSharedLock(curTuple_, trans)) == ErrLockTimeOut)
458 tries--;
459 if (tries <=0) break;
461 return lockRet;
463 DbRetVal TableImpl::tryExclusiveLock(void *curTuple, Transaction **trans)
465 DbRetVal lockRet = OK;
466 int tries = Conf::config.getMutexRetries();
467 while((lockRet = lMgr_->getExclusiveLock(curTuple_, trans)) == ErrLockTimeOut)
469 tries--;
470 if (tries <=0) break;
472 return lockRet;
475 void* TableImpl::fetchNoBind(DbRetVal &rv)
477 rv = OK;
478 if (NULL == iter)
480 printError(ErrNotOpen,"Scan not open or Scan is closed\n");
481 rv = ErrNotOpen;
482 return NULL;
484 void *prevTuple = curTuple_;
485 curTuple_ = iter->next();
486 if (NULL == curTuple_)
488 return NULL;
490 DbRetVal lockRet = OK;
491 if (!loadFlag) {
492 if ((*trans)->isoLevel_ == READ_REPEATABLE) {
493 lockRet = lMgr_->getSharedLock(curTuple_, trans);
494 if (OK != lockRet)
496 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
497 rv = ErrLockTimeOut;
498 curTuple_ = prevTuple;
499 return NULL;
503 else if ((*trans)->isoLevel_ == READ_COMMITTED)
505 //if iso level is read committed, operation duration lock is sufficent
506 //so release it here itself.
507 int tries = Conf::config.getMutexRetries();
508 //struct timeval timeout;
509 //timeout.tv_sec = Conf::config.getMutexSecs();
510 //timeout.tv_usec = Conf::config.getMutexUSecs();
512 bool status = false;
513 while(true) {
514 lockRet = lMgr_->isExclusiveLocked( curTuple_, trans, status);
515 if (OK != lockRet)
517 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
518 curTuple_ = prevTuple;
519 rv = ErrLockTimeOut;
520 return NULL;
522 if (!status) break;
523 tries--;
524 if (tries == 0) break;
525 //os::select(0, 0, 0, 0, &timeout);
527 if (tries == 0)
529 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
530 curTuple_ = prevTuple;
531 rv = ErrLockTimeOut;
532 return NULL;
536 return curTuple_;
538 DbRetVal TableImpl::fetchAgg(const char * fldName, AggType aType, void *buf, bool &noRec)
540 FieldInfo *info = new FieldInfo();
541 DbRetVal rv = getFieldInfo(fldName, info);
542 if (OK != rv) return rv;
543 bool res= false;
544 if (AGG_MIN == aType || AGG_MAX == aType) {
545 int pos =0;
546 IndexType iType = getIndexType((char*)fldName, &pos);
547 if(treeIndex == iType && pos >=0) {
548 if (AGG_MIN == aType) {
549 HashIndexInfo* hInfo = (HashIndexInfo*) idxInfo[pos];
550 CINDEX *iptr = (CINDEX*) hInfo->indexPtr;
551 TreeNode *fstNode=(TreeNode *)iptr->hashNodeChunk_;
552 TreeIter *iter=NULL;
553 if(fstNode!=NULL){
554 TreeNode *start = (TreeNode *)*((char**)((char*)fstNode + sizeof(TreeNode)));
555 iter = new TreeIter(start,(TreeNode*)iptr->hashNodeChunk_,sysDB_->procSlot);
556 }else{
557 iter = new TreeIter(NULL,(TreeNode*)iptr->hashNodeChunk_,sysDB_->procSlot);
559 char *tuple = (char*) iter->getFirstElement();
560 if (tuple != NULL) {
561 AllDataType::copyVal(buf,(void*)(tuple+info->offset),
562 info->type, info->length);
563 delete iter;
564 return OK;
566 delete iter; iter = NULL;
568 else if (AGG_MAX == aType) {
569 HashIndexInfo* hInfo = (HashIndexInfo*) idxInfo[pos];
570 CINDEX *iptr = (CINDEX*) hInfo->indexPtr;
571 TreeNode *fstNode=(TreeNode *)iptr->hashNodeChunk_;
572 TreeIter *iter=NULL;
573 if(fstNode!=NULL){
574 TreeNode *start = (TreeNode *)*((char**)((char*)fstNode + sizeof(TreeNode)));
575 iter = new TreeIter(start,(TreeNode*)iptr->hashNodeChunk_,sysDB_->procSlot);
576 }else{
577 iter = new TreeIter(NULL,(TreeNode*)iptr->hashNodeChunk_,sysDB_->procSlot);
579 char *tuple = (char*) iter->getLastElement();
580 if (tuple != NULL) {
581 AllDataType::copyVal(buf,(void*)(tuple+info->offset),
582 info->type, info->length);
583 delete iter; iter = NULL;
584 return OK;
586 delete iter; iter=NULL;
589 }else if (AGG_COUNT == aType) {
590 (*(int*)buf) = 0;
594 DataType type = info->type;
595 int length = info->length;
596 int offset = info->offset;
597 int colPos = fldList_.getFieldPosition(fldName);
598 bool isNullable= true;
599 if (info->isNull || info->isPrimary || info->isDefault || info->isAutoIncrement) {
600 isNullable = false;
602 int nullOffset = length_-4;
603 if (aType == AGG_COUNT) {
604 length = sizeof(int);
605 type = typeInt;
607 if (NULL == pred_ && typeInt == type && aType != AGG_AVG)
608 { //perf opt
609 ChunkIterator cIter = ((Chunk*)chunkPtr_)->getIterator();
610 char *tuple =(char*)cIter.nextElement();
611 if (NULL == tuple) {
612 *(int *) buf = 0;
613 noRec = true;
614 return OK;
616 int count =1;
617 if (isNullable) {
618 if (isIntUsedForNULL) {
619 if (BITSET(*(int*)(tuple+nullOffset), colPos-1)) count =0;
621 else {
622 curTuple_= tuple;
623 if(isFldNull(colPos)) count =0;
626 if (aType != AGG_COUNT)
627 AllDataType::copyVal(buf, (void*) (tuple+offset), type, length);
628 void *prev=NULL;
629 prev = curTuple_;
630 cIter.pageSize = PAGE_SIZE;
631 while(1)
633 tuple = (char*)cIter.nextElementInt();
634 if (NULL == tuple) break;
635 if (isNullable) {
636 if (isIntUsedForNULL) {
637 if (BITSET(*(int*)(tuple+nullOffset), colPos-1)) continue;
639 else {
640 curTuple_= tuple;
641 if(isFldNull(colPos)) continue;
644 if (aType == AGG_MIN)
646 if (*(int*)buf >= *((int*)(tuple+offset)))
647 *(int*)buf = *((int*)(tuple+offset));
649 else if (aType == AGG_MAX)
651 if (*(int*)buf <= *((int*)(tuple+offset)))
652 *(int*)buf = *((int*)(tuple+offset));
654 else if (aType == AGG_SUM)
656 *(int*)buf += *((int*)(tuple+offset));
658 else if (aType == AGG_AVG)
660 *(int*)buf = *(int*)buf + *((int*)(tuple+offset));
661 count++;
663 else if (aType == AGG_COUNT)
665 count++;
668 curTuple_= prev;
669 if( AGG_AVG == aType) AllDataType::divVal(buf, &count, type);
670 else if (AGG_COUNT == aType) (*(int*)buf) = count;
671 delete info;
672 return OK;
675 char *tuple = (char*) fetchNoBind(rv);
676 if ( NULL == tuple) { noRec = true; return OK; }
677 int count =1;
679 while(isFldNull(colPos)) {
680 tuple= (char*) fetchNoBind(rv);
681 if (aType == AGG_COUNT) count++;
682 if (tuple) break;
684 if ( NULL == tuple) { noRec = true; return OK; }
686 if (aType == AGG_AVG) {
687 AllDataType::convertToDouble(buf, (void*) (tuple+offset), type);
688 } else if (aType != AGG_COUNT) {
689 AllDataType::copyVal(buf, (void*) (tuple+offset), type, length);
691 while(1) {
692 tuple = (char*) fetchNoBind(rv);
693 if (NULL == tuple) break;
694 if (isNullable) {
695 if (isIntUsedForNULL) {
696 if (BITSET(*(int*)(tuple+nullOffset), colPos-1)) continue;
698 else {
699 curTuple_= tuple;
700 if(isFldNull(colPos)) continue;
703 switch(aType) {
704 case AGG_MIN:
706 res = AllDataType::compareVal(buf, (void*) (tuple+offset),
707 OpGreaterThanEquals,
708 type, length);
709 if (res) AllDataType::copyVal(buf, (void*) (tuple+offset),
710 type, length);
711 break;
713 case AGG_MAX:
715 res = AllDataType::compareVal(buf, (void*) (tuple+offset),
716 OpLessThanEquals,
717 type, length);
718 if (res) AllDataType::copyVal(buf, (void*) (tuple+offset),
719 type, length);
720 break;
722 case AGG_SUM:
724 AllDataType::addVal(buf, (void*) (tuple+offset),
725 type);
726 break;
728 case AGG_AVG:
730 double tmpBuf=0.0;
731 AllDataType::convertToDouble(&tmpBuf, (void*) (tuple+offset), type);
732 AllDataType::addVal(buf, &tmpBuf, typeDouble);
733 count++;
734 break;
736 case AGG_COUNT:
738 count++;
739 break;
743 switch(aType) {
744 case AGG_AVG:
746 AllDataType::divVal((double *)buf, count, type);
747 break;
749 case AGG_COUNT:
751 (*(int*)buf) = count;
752 break;
755 delete info;
756 return OK;
758 DbRetVal TableImpl::getCheckpointMutex()
760 int tries=0;
761 DbRetVal rv = OK;
762 int totalTries = Conf::config.getMutexRetries();
763 struct timeval timeout, timeval;
764 timeout.tv_sec = Conf::config.getMutexSecs();
765 timeout.tv_usec = Conf::config.getMutexUSecs();
767 while (tries < totalTries)
769 rv = sysDB_->getSCheckpointMutex();
770 if (OK == rv) break;
771 timeval.tv_sec = timeout.tv_sec;
772 timeval.tv_usec = timeout.tv_usec;
773 os::select(0,0,0,0,&timeval);
774 tries++;
776 if (tries == totalTries) {
777 printError(ErrLockTimeOut, "Checkpoint server is running. Retry after sometime.");
778 return ErrLockTimeOut;
780 return OK;
782 DbRetVal TableImpl::insertTuple()
784 DbRetVal ret = getCheckpointMutex();
785 if (ret !=OK) return ret;
786 void *tptr = NULL;
787 int tries=0;
788 int totalTries = Conf::config.getMutexRetries();
789 while (tries < totalTries)
791 ret = OK;
792 tptr = ((Chunk*)chunkPtr_)->allocate(db_, &ret);
793 if (tptr !=NULL) break;
794 if (ret != ErrLockTimeOut)
796 sysDB_->releaseCheckpointMutex();
797 printError(ret, "Unable to allocate record from chunk");
798 return ret;
800 tries++;
802 if (NULL == tptr)
804 sysDB_->releaseCheckpointMutex();
805 printError(ret, "Unable to allocate record from chunk after %d retries", tries);
806 return ret;
808 curTuple_ = tptr;
809 if(isFkTbl){
810 TableImpl *fkTbl =NULL;
811 ListIterator tblIter = tblList.getIterator();
812 tblIter.reset();
813 while (tblIter.hasElement()){
814 fkTbl = (TableImpl *) tblIter.nextElement();
815 bool pkRec = isPkTableHasRecord(fkTbl->getName(),fkTbl,true);
816 if(!pkRec){
817 printError(ErrForeignKeyInsert, "Unable to insert into foreign Key table.Check PK table");
818 ((Chunk*)chunkPtr_)->free(db_, tptr);
819 sysDB_->releaseCheckpointMutex();
820 return ErrForeignKeyInsert;
823 tblIter.reset();
825 if (!loadFlag) {
826 //ret = lMgr_->getExclusiveLock(tptr, trans);
827 if (OK != tryExclusiveLock(tptr, trans))
829 ((Chunk*)chunkPtr_)->free(db_, tptr);
830 printError(ret, "Could not get lock for the insert tuple %x", tptr);
831 sysDB_->releaseCheckpointMutex();
832 return ErrLockTimeOut;
836 ret = copyValuesFromBindBuffer(tptr);
837 if (ret != OK)
839 printError(ret, "Unable to copy values from bind buffer");
840 if (!loadFlag) {
841 (*trans)->removeFromHasList(db_, tptr);
842 lMgr_->releaseLock(tptr);
845 FieldIterator fIter = fldList_.getIterator();
846 char *colPtr = (char*) curTuple_;
847 while (fIter.hasElement()) {
848 FieldDef *def = fIter.nextElement();
849 colPtr = (char *) curTuple_ + def->offset_;
850 if (def->type_ == typeVarchar) {
851 char *ptr = (char *) *(long *) colPtr;
852 if (ptr != 0L) ((Chunk *) vcChunkPtr_)->free(db_, ptr);
855 ((Chunk*)chunkPtr_)->free(db_, tptr);
856 sysDB_->releaseCheckpointMutex();
857 return ret;
859 int addSize = 0;
860 if (numFlds_ < 31)
862 addSize = 4;
863 *(int*)((char*)(tptr) + (length_-addSize)) = iNullInfo;
865 else
867 addSize = os::align(numFlds_);
868 os::memcpy(((char*)(tptr) + (length_-addSize)), cNullInfo, addSize);
871 //int tupleSize = length_ + addSize;
872 if (NULL != indexPtr_)
874 int i;
875 //it has index
876 for (i = 0; i < numIndexes_ ; i++)
878 ret = insertIndexNode(*trans, indexPtr_[i], idxInfo[i], tptr);
879 if (ret != OK) { printError(ret, "Error in inserting to index %x", tptr); break;}
881 if ( ret != OK)
883 for (int j = 0; j < i ; j++) {
884 printError(ErrWarning, "Undo:Deleting index node");
885 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
887 if (!loadFlag) {
888 (*trans)->removeFromHasList(db_, tptr);
889 lMgr_->releaseLock(tptr);
892 FieldIterator fIter = fldList_.getIterator();
893 char *colPtr = (char*) curTuple_;
894 while (fIter.hasElement()) {
895 FieldDef *def = fIter.nextElement();
896 colPtr = (char *) curTuple_ + def->offset_;
897 if (def->type_ == typeVarchar) {
898 char *ptr = (char *) *(long *) colPtr;
899 if (ptr != 0L) ((Chunk *) vcChunkPtr_)->free(db_, ptr);
902 ((Chunk*)chunkPtr_)->free(db_, tptr);
903 sysDB_->releaseCheckpointMutex();
904 return ret;
907 if (!loadFlag) {
908 //TODO: number of varchar fields to be stored as a member in TableImpl
909 int nVarchars = 0;
910 FieldIterator fIter = fldList_.getIterator();
911 while (fIter.hasElement()) {
912 FieldDef *def = fIter.nextElement();
913 if (def->type_ == typeVarchar) nVarchars++;
916 // the undo log for insert should contain
917 // tuple ptr + metadata Ptr + no of varchars + ptrs to varchars for insert opearation
918 int size = (3 + nVarchars) * sizeof(void *) + sizeof(int);
919 void *data = malloc(size);
920 char *ptr = (char *)data;
921 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
922 void *metaData = db_->getMetaDataPtr();
923 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
924 *(int *) ptr = nVarchars; ptr += sizeof(int);
925 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
926 fIter = fldList_.getIterator();
927 char *colPtr = (char*) curTuple_;
928 while (fIter.hasElement()) {
929 FieldDef *def = fIter.nextElement();
930 colPtr = (char *) curTuple_ + def->offset_;
931 if (def->type_ == typeVarchar) {
932 *(long *) ptr = (long)colPtr;
933 ptr += sizeof(void *);
936 ret = (*trans)->appendUndoLog(sysDB_, InsertOperation, data, size);
937 ::free(data);
939 if (ret != OK) {
940 printError(ret, "Unable to create undo log for %x %d", tptr, *(int*)tptr);
941 for (int j = 0; j < numIndexes_ ; j++) {
942 printError(ErrWarning, "Deleting index node");
943 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
945 if (!loadFlag) {
946 (*trans)->removeFromHasList(db_, tptr);
947 lMgr_->releaseLock(tptr);
949 ((Chunk*)chunkPtr_)->free(db_, tptr);
951 sysDB_->releaseCheckpointMutex();
952 return ret;
955 DbRetVal TableImpl::deleteTuple()
957 if (NULL == curTuple_)
959 printError(ErrNotOpen, "Scan not open: No Current tuple");
960 return ErrNotOpen;
962 DbRetVal ret = getCheckpointMutex();
963 if (ret != OK) return ret;
964 if(isPkTbl){
965 TableImpl *fkTbl =NULL;
966 ListIterator tblIter = tblFkList.getIterator();
967 tblIter.reset();
968 while (tblIter.hasElement()){
969 fkTbl = (TableImpl *) tblIter.nextElement();
970 bool pkRec = isFkTableHasRecord(fkTbl->getName(),fkTbl);
971 if(pkRec){
972 printError(ErrForeignKeyDelete, "A Relation Exists. Delete from child table first");
973 sysDB_->releaseCheckpointMutex();
974 return ErrForeignKeyDelete;
977 tblIter.reset();
979 if (!loadFlag) {
980 //ret = lMgr_->getExclusiveLock(curTuple_, trans);
981 if (OK != tryExclusiveLock(curTuple_, trans))
983 printError(ret, "Could not get lock for the delete tuple %x",
984 curTuple_);
985 sysDB_->releaseCheckpointMutex();
986 return ErrLockTimeOut;
990 if (NULL != indexPtr_)
992 int i;
993 //it has index
994 for (i = 0; i < numIndexes_ ; i++)
996 ret = deleteIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
997 if (ret != OK) break;
999 if (i != numIndexes_ )
1001 printError(ErrWarning, "Inserting back index node");
1002 for (int j = 0; j < i ; j++)
1003 insertIndexNode(*trans, indexPtr_[j], idxInfo[j], curTuple_);
1004 if (!loadFlag) {
1005 lMgr_->releaseLock(curTuple_);
1006 (*trans)->removeFromHasList(db_, curTuple_);
1008 printError(ret, "Unable to insert index node for tuple %x", curTuple_);
1009 sysDB_->releaseCheckpointMutex();
1010 return ret;
1013 if (!loadFlag) {
1014 // the undo log for delete should contain
1015 // tupleptr + metadataPtr + nVarchars + varchar chunk ptr +
1016 // ptrs to varchars + size and value pairs for varchars
1018 //TODO: number of varchar fields to be stored as a member in TableImpl
1019 void *tptr = curTuple_;
1020 char *colPtr = (char *)curTuple_;
1021 int nVarchars = 0;
1022 int vcLenValPairSize = 0;
1023 FieldIterator fIter = fldList_.getIterator();
1024 while (fIter.hasElement()) {
1025 FieldDef *def = fIter.nextElement();
1026 colPtr = (char *) curTuple_ + def->offset_;
1027 if (def->type_ == typeVarchar) {
1028 nVarchars++;
1029 if (* (long *) colPtr == 0L)
1030 vcLenValPairSize = vcLenValPairSize + sizeof(int);
1031 else vcLenValPairSize = vcLenValPairSize + sizeof(int) +
1032 + os::align(strlen((char *) *(long *)colPtr) + 1);
1035 int size = (3 + nVarchars) * sizeof(void *) + sizeof(int)
1036 + vcLenValPairSize;
1037 void *data = malloc(size);
1038 char *ptr = (char *)data;
1039 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
1040 void *metaData = db_->getMetaDataPtr();
1041 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
1042 *(int *) ptr = nVarchars; ptr += sizeof(int);
1043 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
1044 fIter = fldList_.getIterator();
1045 colPtr = (char*) curTuple_;
1046 char *valLenPairPtr = ptr + nVarchars * sizeof(void *);
1047 while (fIter.hasElement()) {
1048 FieldDef *def = fIter.nextElement();
1049 colPtr = (char *) curTuple_ + def->offset_;
1050 int vcStrLen = 0;
1051 if (def->type_ == typeVarchar) {
1052 *(long *) ptr = (long )colPtr; ptr += sizeof(void *);
1053 if (*(long *) colPtr == 0L) {
1054 *(int *) valLenPairPtr = vcStrLen = 0;
1055 valLenPairPtr += sizeof(int);
1056 } else {
1057 *(int *) valLenPairPtr = vcStrLen =
1058 os::align(strlen((char *)*(long *)colPtr) + 1);
1059 valLenPairPtr += sizeof(int);
1060 strcpy(valLenPairPtr, (char *)*(long *)colPtr);
1061 valLenPairPtr += vcStrLen;
1065 ret = (*trans)->appendUndoLog(sysDB_, DeleteOperation, data, size);
1066 ::free(data);
1068 if (ret != OK) {
1069 printError(ret, "Unable to create undo log for %x ", curTuple_);
1070 for (int j = 0; j < numIndexes_ ; j++) {
1071 printError(ErrWarning, "Inserting back index node");
1072 insertIndexNode(*trans, indexPtr_[j], idxInfo[j], curTuple_);
1074 if (!loadFlag) {
1075 (*trans)->removeFromHasList(db_, curTuple_);
1076 lMgr_->releaseLock(curTuple_);
1080 FieldIterator fIter = fldList_.getIterator();
1081 char *colPtr = (char*) curTuple_;
1082 while (fIter.hasElement()) {
1083 FieldDef *def = fIter.nextElement();
1084 colPtr = (char *) curTuple_ + def->offset_;
1085 if (def->type_ == typeVarchar) {
1086 if (*(long *) colPtr != 0L) {
1087 char *ptr = (char *) *(long *) colPtr;
1088 ((Chunk *) vcChunkPtr_)->free(db_, ptr);
1092 ((Chunk*)chunkPtr_)->free(db_, curTuple_);
1093 iter->prev();
1094 sysDB_->releaseCheckpointMutex();
1095 return ret;
1098 int TableImpl::deleteWhere()
1100 DbRetVal ret = getCheckpointMutex();
1101 if (ret !=OK) return ret;
1103 int tuplesDeleted = 0;
1104 DbRetVal rv = OK;
1105 rv = execute();
1106 if (rv !=OK) {
1107 sysDB_->releaseCheckpointMutex();
1108 return (int) rv;
1110 while(true){
1111 fetchNoBind( rv);
1112 if (rv != OK) { tuplesDeleted = (int)rv; break; }
1113 if (NULL == curTuple_) break;
1114 rv = deleteTuple();
1115 if (rv != OK) {
1116 printError(rv, "Error: Could only delete %d tuples", tuplesDeleted);
1117 closeScan();
1118 sysDB_->releaseCheckpointMutex();
1119 return (int) rv;
1121 tuplesDeleted++;
1123 closeScan();
1124 sysDB_->releaseCheckpointMutex();
1125 return tuplesDeleted;
1128 int TableImpl::truncate()
1130 //take exclusive lock on the table
1131 //get the chunk ptr of the table
1132 //traverse the tablechunks and free all the pages except the first one
1133 //get the chunk ptr of all its indexes
1134 //traverse the indexchunks and free all the pages except the first one
1135 //release table lock
1137 //TEMPORARY FIX
1138 DbRetVal rv = OK;
1139 Predicate* tmpPred = pred_;
1140 pred_ = NULL;
1141 isPlanCreated = false;
1142 int tuplesDeleted = deleteWhere();
1143 isPlanCreated = false;
1144 pred_ = tmpPred;
1145 return tuplesDeleted;
1148 DbRetVal TableImpl::updateTuple()
1150 if (NULL == curTuple_)
1152 printError(ErrNotOpen, "Scan not open: No Current tuple");
1153 return ErrNotOpen;
1155 DbRetVal ret = getCheckpointMutex();
1156 if (ret !=OK) return ret;
1157 if(isFkTbl){
1158 TableImpl *fkTbl =NULL;
1159 ListIterator tblIter = tblList.getIterator();
1160 tblIter.reset();
1161 while (tblIter.hasElement()){
1162 fkTbl = (TableImpl *) tblIter.nextElement();
1163 bool pkRec = isPkTableHasRecord(fkTbl->getName(),fkTbl,false);
1164 if(!pkRec){
1165 printError(ErrForeignKeyInsert, "Unable to insert into foreign Key table.Check PK table");
1166 sysDB_->releaseCheckpointMutex();
1167 return ErrForeignKeyInsert;
1170 tblIter.reset();
1173 if (!loadFlag) {
1174 //ret = lMgr_->getExclusiveLock(curTuple_, trans);
1175 if (OK != tryExclusiveLock(curTuple_, trans))
1177 printError(ret, "Could not get lock for the update tuple %x", curTuple_);
1178 sysDB_->releaseCheckpointMutex();
1179 return ErrLockTimeOut;
1182 if (NULL != indexPtr_)
1184 //it has index
1185 //TODO::If it fails while updating index node, we have to undo all the updates
1186 //on other indexes on the table.Currently it will leave the database in an
1187 //inconsistent state.
1188 for (int i = 0; i < numIndexes_ ; i++)
1190 ret = updateIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
1191 if (ret != OK)
1193 if (!loadFlag) {
1194 lMgr_->releaseLock(curTuple_);
1195 (*trans)->removeFromHasList(db_, curTuple_);
1197 printError(ret, "Unable to update index node for tuple %x", curTuple_);
1198 sysDB_->releaseCheckpointMutex();
1199 return ret;
1204 if (!loadFlag) {
1205 // the undo log for update should contain
1206 // tupleptr + tuple length + actual tuple + metadataPtr +
1207 // nVarchars + varchar chunk ptr + ptrs to varchars +
1208 // size and value pairs for varchars
1210 //TODO: number of varchar fields to be stored as a member in TableImpl
1211 void *tptr = curTuple_;
1212 char *colPtr = (char *)curTuple_;
1213 int nVarchars = 0;
1214 int vcLenValPairSize = 0;
1215 FieldIterator fIter = fldList_.getIterator();
1216 while (fIter.hasElement()) {
1217 FieldDef *def = fIter.nextElement();
1218 colPtr = (char *) curTuple_ + def->offset_;
1219 if (def->type_ == typeVarchar) {
1220 nVarchars++;
1221 if (* (long *) colPtr == 0L)
1222 vcLenValPairSize = vcLenValPairSize + sizeof(int);
1223 else vcLenValPairSize = vcLenValPairSize + sizeof(int) +
1224 + os::align(strlen((char *) *(long *)colPtr) + 1);
1227 int size = (3 + nVarchars) * sizeof(void *) + 2 * sizeof(int) +
1228 vcLenValPairSize + length_;
1229 void *data = malloc(size);
1230 char *ptr = (char *) data;
1231 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
1232 *(int *) ptr = length_; ptr += sizeof(int);
1233 os::memcpy(ptr, tptr, length_); ptr += length_;
1234 void *metaData = db_->getMetaDataPtr();
1235 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
1236 *(int *) ptr = nVarchars; ptr += sizeof(int);
1237 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
1238 fIter = fldList_.getIterator();
1239 colPtr = (char*) curTuple_;
1240 char *valLenPairPtr = ptr + nVarchars * sizeof(void *);
1241 while (fIter.hasElement()) {
1242 FieldDef *def = fIter.nextElement();
1243 colPtr = (char *) curTuple_ + def->offset_;
1244 int vcStrLen = 0;
1245 if (def->type_ == typeVarchar) {
1246 *(long *) ptr = (long)colPtr; ptr += sizeof(void *);
1247 if (*(long *) colPtr == 0L) {
1248 *(int *) valLenPairPtr = vcStrLen = 0;
1249 valLenPairPtr += sizeof(int);
1250 } else {
1251 *(int *) valLenPairPtr = vcStrLen =
1252 os::align(strlen((char *)*(long *)colPtr) + 1);
1253 valLenPairPtr += sizeof(int);
1254 strcpy(valLenPairPtr, (char *)*(long *)colPtr);
1255 valLenPairPtr += vcStrLen;
1259 ret = (*trans)->appendUndoLog(sysDB_, UpdateOperation, data, size);
1260 ::free(data);
1262 if (ret != OK) {
1263 if (!loadFlag) {
1264 lMgr_->releaseLock(curTuple_);
1265 (*trans)->removeFromHasList(db_, curTuple_);
1267 sysDB_->releaseCheckpointMutex();
1268 return ret;
1271 int addSize = 0;
1272 int iNullVal=iNullInfo;
1273 char *cNullVal = NULL;
1274 if (numFlds_ > 32) {
1275 addSize = os::align(numFlds_);
1276 cNullVal = (char *) malloc(addSize);
1277 os::memcpy(cNullVal, cNullInfo, addSize);
1279 bool nullCharSet = false;
1280 if (numFlds_ <= 32){
1281 addSize=4;
1282 if (!iNullVal)
1283 iNullInfo = *(int*)((char*)(curTuple_) + (length_- addSize));
1284 else
1285 *(int*)((char*)(curTuple_) + (length_-addSize)) |= iNullInfo;
1286 } else {
1287 int i=0;
1288 while(i < numFlds_) {
1289 if(cNullInfo[i++]) { nullCharSet = true; break; }
1291 char *null=(char*)(curTuple_) + (length_-addSize);
1292 if (!nullCharSet) {
1293 i=0;
1294 while(i < numFlds_) {
1295 if(null[i]) cNullInfo[i] = null[i];
1296 i++;
1298 } else {
1299 i = 0;
1300 while(i < numFlds_) {
1301 if(cNullInfo[i]) { null[i] |= cNullInfo[i]; }
1302 i++;
1306 DbRetVal rv = copyValuesFromBindBuffer(curTuple_, false);
1307 if (rv != OK && !loadFlag) {
1308 lMgr_->releaseLock(curTuple_);
1309 (*trans)->removeFromHasList(db_, curTuple_);
1310 sysDB_->releaseCheckpointMutex();
1311 return rv;
1313 if (numFlds_ <= 32) {
1314 if (!iNullVal) {
1315 *(int*)((char*)(curTuple_) + (length_-addSize)) = iNullInfo;
1316 iNullInfo=0;
1317 } else iNullInfo=iNullVal;
1318 } else {
1319 int i = 0;
1320 char *null=(char*)(curTuple_) + (length_-addSize);
1321 if (!nullCharSet) {
1322 os::memcpy(null, cNullInfo, addSize);
1323 while (i < numFlds_) cNullInfo[i++] = 0;
1324 } else os::memcpy(cNullInfo, cNullVal, addSize);
1325 free(cNullVal); cNullVal = NULL;
1327 sysDB_->releaseCheckpointMutex();
1328 return OK;
1331 void TableImpl::printInfo()
1333 printf(" <TableName> %s </TableName>\n", tblName_);
1334 printf(" <TupleCount> %d </TupleCount>\n", numTuples());
1335 printf(" <PagesUsed> %d </PagesUsed>\n", pagesUsed());
1336 printf(" <SpaceUsed> %d </SpaceUsed>\n", spaceUsed());
1337 printf(" <Indexes> %d <Indexes>\n", numIndexes_);
1338 printf(" <TupleLength> %d </TupleLength>\n", length_);
1339 printf(" <Fields> %d </Fields>\n", numFlds_);
1340 printf(" <Indexes>\n");
1341 for (int i =0; i<numIndexes_; i++)
1342 printf("<IndexName> %s </IndexName>\n", CatalogTableINDEX::getName(indexPtr_[i]));
1343 printf(" </Indexes>\n");
1346 long long TableImpl::getLastInsertedVal(DbRetVal &rv)
1348 rv=OK;
1349 return *(long long*)ptrToAuto;
1351 DbRetVal TableImpl::copyValuesFromBindBuffer(void *tuplePtr, bool isInsert)
1353 //Iterate through the bind list and copy the value here
1354 FieldIterator fIter = fldList_.getIterator();
1355 char *colPtr = (char*) tuplePtr;
1356 int fldpos=1;
1357 while (fIter.hasElement())
1359 FieldDef *def = fIter.nextElement();
1360 if(def->isAutoIncrement_ && isInsert)
1362 if (OK != takeTableMutex())
1364 printError(ErrLockTimeOut,
1365 " Unable to take table mutex for increment key");
1366 return ErrLockTimeOut;
1368 AllDataType::copyVal(&tempAutoVal,ptrToAuto, def->type_, def->length_);
1369 if(def->bindVal_==NULL)
1371 AllDataType::increment(colPtr, &tempAutoVal , def->type_);
1372 AllDataType::copyVal(ptrToAuto,colPtr, def->type_,
1373 def->length_);
1374 colPtr = colPtr + def->length_;
1375 fldpos++;
1376 }else {
1377 if(AllDataType::compareVal(def->bindVal_, &tempAutoVal, OpGreaterThan,
1378 def->type_)) {
1379 AllDataType::copyVal(ptrToAuto,def->bindVal_, def->type_,
1380 def->length_);
1383 releaseTableMutex();
1384 continue;
1387 if (def->isNull_ && !def->isDefault_ && NULL == def->bindVal_ &&
1388 isInsert)
1390 printError(ErrNullViolation,
1391 "NOT NULL constraint violation for field %s", def->fldName_);
1392 return ErrNullViolation;
1394 if (def->isDefault_ && NULL == def->bindVal_ && isInsert)
1396 if (! def->isNullExplicit_) {
1397 if (def->type_ == typeVarchar) {
1398 DbRetVal rv = OK;
1399 void *ptr =
1400 ((Chunk *) vcChunkPtr_)->allocate(db_, def->length_, &rv);
1401 *(long *)colPtr = (long)ptr;
1402 AllDataType::convert(typeString, def->defaultValueBuf_,
1403 def->type_, ptr, def->length_);
1404 } else {
1405 void *dest = AllDataType::alloc(def->type_, def->length_);
1406 AllDataType::convert(typeString, def->defaultValueBuf_,
1407 def->type_, dest, def->length_);
1408 AllDataType::copyVal(colPtr, dest, def->type_,
1409 def->length_);
1410 free (dest);
1412 } else {
1413 setNullBit(fldpos);
1414 *(long *) colPtr = 0L;
1416 if (def->type_ != typeVarchar) colPtr = colPtr + def->length_;
1417 else colPtr = colPtr + sizeof(void *);
1418 fldpos++;
1419 continue;
1421 switch(def->type_)
1423 case typeString:
1424 if (NULL != def->bindVal_)
1426 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1427 // strncpy((char*)colPtr, (char*)def->bindVal_, def->length_);
1428 // *(((char*)colPtr) + (def->length_-1)) = '\0';
1429 strcpy((char*)colPtr, (char*)def->bindVal_);
1431 else if (!def->isNull_ && isInsert) setNullBit(fldpos);
1432 colPtr = colPtr + def->length_;
1433 break;
1434 case typeBinary:
1435 if (NULL != def->bindVal_ )
1437 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1438 DbRetVal rv = AllDataType::strToValue(colPtr,
1439 (char *) def->bindVal_, def->type_, def->length_);
1440 if (rv != OK) return ErrBadArg;
1441 } else if (!def->isNull_ && isInsert && !def->bindVal_) {
1442 setNullBit(fldpos);
1444 colPtr = colPtr + def->length_;
1445 break;
1446 case typeVarchar:
1447 if (NULL != def->bindVal_) {
1448 if (!isInsert && isFldNull(fldpos)) {clearNullBit(fldpos);}
1449 DbRetVal rv = OK;
1450 if (!isInsert) {
1451 if (*(long *) colPtr != 0L)
1452 ((Chunk *) vcChunkPtr_)->free(db_,
1453 (void *)*(long *)colPtr);
1454 *(long *) colPtr = 0L;
1456 if (strcmp((char *)def->bindVal_,"") != 0) {
1457 void *ptr =
1458 ((Chunk *) vcChunkPtr_)->allocate(db_,
1459 def->length_, &rv);
1460 if (rv != OK) return ErrBadArg;
1461 *(long *)colPtr = (long)ptr;
1462 strcpy((char *)ptr, (char *)def->bindVal_);
1463 } else { setNullBit(fldpos); }
1464 } else if (!def->isNull_ && isInsert) setNullBit(fldpos);
1465 colPtr = colPtr + sizeof(void *);
1466 break;
1467 default:
1468 if (NULL != def->bindVal_) {
1469 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1470 AllDataType::copyVal(colPtr, def->bindVal_, def->type_);
1471 } else { if (!def->isNull_ && isInsert) setNullBit(fldpos); }
1472 colPtr = colPtr + def->length_;
1473 break;
1475 fldpos++;
1477 return OK;
1480 void TableImpl::clearNullBit(int fldpos)
1482 if (fldpos <1 || fldpos > numFlds_) return;
1483 if (isIntUsedForNULL) CLEARBIT(iNullInfo, fldpos-1);
1484 else cNullInfo[fldpos-1] = 0;
1487 void TableImpl::setNullBit(int fldpos)
1489 if (fldpos <1 || fldpos > numFlds_) return;
1490 if (isIntUsedForNULL) SETBIT(iNullInfo, fldpos-1);
1491 else cNullInfo[fldpos-1] = 1;
1494 DbRetVal TableImpl::copyValuesToBindBuffer(void *tuplePtr)
1496 //Iterate through the bind list and copy the value here
1497 char *colPtr = (char*) tuplePtr;
1498 FieldDef *def = NULL;
1499 for (int i = 0; i < numBindFlds_; i++) {
1500 def = (FieldDef *) bindListArray_[i];
1501 colPtr = (char *) tuplePtr + def->offset_;
1502 if (def->type_ != typeVarchar)
1503 AllDataType::copyVal(def->bindVal_, colPtr, def->type_,
1504 def->length_);
1505 else {
1506 char *ptr = (char *) *(long *) colPtr;
1507 if (ptr != NULL) strcpy((char *)def->bindVal_, ptr);
1510 return OK;
1513 //-1 index not supported
1514 DbRetVal TableImpl::insertIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1516 CINDEX *iptr = (CINDEX*)indexPtr;
1517 DbRetVal ret = OK;
1518 printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
1519 Index* idx = Index::getIndex(iptr->indexType_);
1520 ret = idx->insert(this, tr, indexPtr, info, tuple,loadFlag);
1521 return ret;
1524 DbRetVal TableImpl::deleteIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1526 CINDEX *iptr = (CINDEX*)indexPtr;
1527 DbRetVal ret = OK;
1528 Index* idx = Index::getIndex(iptr->indexType_);
1529 ret = idx->remove(this, tr, indexPtr, info, tuple, loadFlag);
1530 return ret;
1532 void TableImpl::printSQLIndexString(FILE *fp, int fd)
1534 if (fp == NULL) fp = stdout;
1535 CatalogTableINDEXFIELD cIndexField(sysDB_);
1536 char fName[IDENTIFIER_LENGTH];
1537 char idxName[IDENTIFIER_LENGTH];
1538 char *fldName = fName;
1539 DataType type;
1540 for (int i = 0; i < numIndexes_ ; i++)
1542 CINDEX *iptr = (CINDEX*) indexPtr_[i];
1543 sprintf(idxName,"%s_idx_Auto_increment",getName());
1544 if(strcmp(iptr->indName_,idxName)==0){ continue; }
1545 if (Conf::config.useDurability()) {
1546 struct Object obj;
1547 strcpy(obj.name, iptr->indName_);
1548 if (iptr->indexType_ == hashIndex) {
1549 obj.type = hIdx;
1550 obj.bucketChunk = ((Chunk *)iptr->chunkPtr_)->getFirstPage();
1551 obj.firstPage = ((Chunk *)iptr->hashNodeChunk_)->getFirstPage();
1552 obj.curPage = ((Chunk *)iptr->hashNodeChunk_)->getCurrentPage();
1553 } else if (iptr->indexType_ == treeIndex) {
1554 obj.type = tIdx;
1555 obj.firstPage = ((Chunk *)iptr->chunkPtr_)->getFirstPage();
1556 obj.curPage = ((Chunk *)iptr->chunkPtr_)->getCurrentPage();
1557 long nodes = ((Chunk *)iptr->chunkPtr_)->getTotalDataNodes();
1558 if(nodes) {
1559 ChunkIterator cIter = ((Chunk *)iptr->chunkPtr_)->getIterator();
1560 obj.bucketChunk = cIter.nextElement();
1561 } else obj.bucketChunk = NULL;
1563 void *buf = &obj;
1564 write(fd, buf, sizeof(obj));
1566 fprintf(fp, "CREATE INDEX %s on %s ( ", iptr->indName_, getName());
1567 FieldList fldList;
1568 cIndexField.getFieldInfo(iptr, fldList);
1569 FieldIterator fIter = fldList.getIterator();
1570 bool firstFld = true;
1571 while(fIter.hasElement())
1573 FieldDef *def = fIter.nextElement();
1574 if (firstFld) { fprintf(fp, " %s ", def->fldName_); firstFld = false; }
1575 else fprintf(fp, " ,%s ", def->fldName_);
1577 fldList.removeAll();
1578 fprintf(fp, " ) ");
1579 if (iptr->indexType_ == hashIndex) fprintf(fp, " HASH ");
1580 else fprintf(fp, " TREE ");
1581 if (((HashIndexInfo*) idxInfo[i])->isUnique) fprintf(fp, " UNIQUE");
1582 if(((HashIndexInfo*) idxInfo[i])->noOfBuckets != 1009 ) fprintf(fp, " SIZE %d ",((HashIndexInfo*) idxInfo[i])->noOfBuckets );
1583 fprintf(fp, ";\n");
1588 DbRetVal TableImpl::updateIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1590 CINDEX *iptr = (CINDEX*)indexPtr;
1591 DbRetVal ret = OK;
1592 Index* idx = Index::getIndex(iptr->indexType_);
1593 //TODO::currently it updates irrespective of whether the key changed or not
1594 //because of this commenting the whole index update code. relook at it and uncomment
1596 ret = idx->update(this, tr, indexPtr, info, tuple, loadFlag);
1598 return ret;
1602 void TableImpl::setTableInfo(char *name, int tblid, size_t length,
1603 int numFld, int numIdx, void *chunk, void *vcchunk)
1605 strcpy(tblName_, name);
1606 tblID_ = tblid;
1607 length_ = length;
1608 numFlds_ = numFld;
1609 numIndexes_ = numIdx;
1610 chunkPtr_ = chunk;
1611 vcChunkPtr_ = vcchunk;
1614 long TableImpl::spaceUsed()
1616 Chunk *chk = (Chunk*)chunkPtr_;
1617 long totSize = chk->getTotalDataNodes() * chk->getSize();
1618 totSize = totSize + (chk->totalPages() * sizeof (PageInfo));
1619 return totSize;
1622 int TableImpl::pagesUsed()
1624 Chunk *chk = (Chunk*)chunkPtr_;
1625 return chk->totalPages();
1628 long TableImpl::numTuples()
1630 return ((Chunk*)chunkPtr_)->getTotalDataNodes();
1633 List TableImpl::getFieldNameList()
1635 List fldNameList;
1636 FieldIterator fIter = fldList_.getIterator();
1637 char fieldName[IDENTIFIER_LENGTH];
1638 while (fIter.hasElement())
1640 FieldDef *def = fIter.nextElement();
1641 Identifier *elem = new Identifier();
1642 Table::getFieldNameAlone(def->fldName_, fieldName);
1643 sprintf(elem->name, "%s.%s", getName(), fieldName);
1644 fldNameList.append(elem);
1646 return fldNameList;
1648 DbRetVal TableImpl::close()
1650 if (iter) { iter->close(); delete iter; iter = NULL; }
1651 TableImpl *fkTbl =NULL;
1652 ListIterator tblIter = tblList.getIterator();
1653 tblIter.reset();
1654 while (tblIter.hasElement()){
1655 fkTbl = (TableImpl *) tblIter.nextElement();
1656 fkTbl->close();
1658 tblList.reset();
1659 tblIter = tblFkList.getIterator();
1660 tblIter.reset();
1661 while (tblIter.hasElement()){
1662 fkTbl = (TableImpl *) tblIter.nextElement();
1663 fkTbl->close();
1665 tblFkList.reset();
1666 printDebug(DM_Database,"Closing table handle: %x", this);
1667 //table->unlock();
1668 //delete pred_;
1669 ListIterator pIter = predList.getIterator();
1670 while (pIter.hasElement())
1672 PredicateImpl *pImpl = (PredicateImpl*) pIter.nextElement();
1673 delete pImpl;
1675 predList.reset();
1676 delete this;
1677 logFinest(Conf::logger, "Closing Table");
1678 return OK;
1681 DbRetVal TableImpl::closeScan()
1683 //do not throw scan not open error
1684 //this function will be called by table handle
1685 if (iter) {
1686 iter->close();
1688 return OK;
1690 DbRetVal TableImpl::takeTableMutex()
1692 struct timeval timeout, timeval;
1693 timeout.tv_sec = Conf::config.getMutexSecs();
1694 timeout.tv_usec = Conf::config.getMutexUSecs();
1695 int tries=0;
1696 int totalTries = Conf::config.getMutexRetries() *2;
1697 int ret =0;
1698 while (tries < totalTries)
1700 ret = sysDB_->getAllocDatabaseMutex();
1701 if (ret == 0) break;
1702 timeval.tv_sec = timeout.tv_sec;
1703 timeval.tv_usec = timeout.tv_usec;
1704 os::select(0, 0, 0, 0, &timeval);
1705 tries++;
1707 if (tries >= totalTries) return ErrLockTimeOut;
1708 return OK;
1710 DbRetVal TableImpl::releaseTableMutex()
1712 sysDB_->releaseAllocDatabaseMutex();
1713 return OK;
1716 DbRetVal TableImpl::lock(bool shared)
1719 DbRetVal ret = OK;
1721 if (shared)
1722 ret = lMgr_->getSharedLock(chunkPtr_, NULL);
1723 else
1724 ret = lMgr_->getExclusiveLock(chunkPtr_, NULL);
1725 if (OK != ret)
1727 printError(ret, "Could not exclusive lock on the table %x", chunkPtr_);
1728 }else {
1729 //do not append for S to X upgrade
1730 if (!ProcessManager::hasLockList.exists(chunkPtr_))
1731 ProcessManager::hasLockList.append(chunkPtr_);
1734 return ret;
1736 DbRetVal TableImpl::unlock()
1739 if (!ProcessManager::hasLockList.exists(chunkPtr_)) return OK;
1740 DbRetVal ret = lMgr_->releaseLock(chunkPtr_);
1741 if (OK != ret)
1743 printError(ret, "Could not release exclusive lock on the table %x", chunkPtr_);
1744 }else
1746 ProcessManager::hasLockList.remove(chunkPtr_);
1749 return OK;
1752 TableImpl::~TableImpl()
1754 if (NULL != iter ) { delete iter; iter = NULL; }
1755 if (NULL != indexPtr_) { delete[] indexPtr_; indexPtr_ = NULL; }
1756 if (NULL != idxInfo)
1758 for (int i = 0; i < numIndexes_; i++) delete idxInfo[i];
1759 delete[] idxInfo;
1760 idxInfo = NULL;
1762 if (numFlds_ > 32 && cNullInfo != NULL) {
1763 free(cNullInfo); cNullInfo = NULL;
1765 if (bindList_.size()) bindList_.reset();
1766 if (bindListArray_) { free (bindListArray_); bindListArray_ = NULL; }
1767 fldList_.removeAll();
1771 void *TableImpl::getBindFldAddr(const char *name)
1773 return fldList_.getBindField(name);
1775 bool TableImpl::isTableInvolved(char *tblName)
1777 //printf("Table isTableInvolved called for %s with %s\n", tblName, getName());
1778 if (0 == strcmp(getName(), tblName)) return true; else return false;
1780 bool TableImpl::pushPredicate(Predicate *pred)
1782 bool ret = false;
1783 PredicateImpl *pImpl = (PredicateImpl*) pred;
1784 char tableName[IDENTIFIER_LENGTH];
1785 Table::getTableNameAlone(pImpl->getFldName1(), tableName);
1786 //printf("predicate tbl name %s\n", tableName);
1788 //if predicate is of form t1.f1=t2.f1 then do not push here
1789 bool isAliasSet = (0 !=strcmp(getAliasName(),"")) ;
1790 if (0 != strcmp(pImpl->getFldName2(),"")) return ret;
1792 if (0 == strcmp(getName(), tableName) ||(isAliasSet && 0 == strcmp(getAliasName(), tableName)))
1794 setPredicate(pred);
1795 //printf("PRABA::pushed predicate in tablehdl %s\n", getName());
1796 ret = true;
1798 return ret;
1801 void TableImpl::setCondition(Condition *p)
1803 isPlanCreated = false;
1804 ListIterator pIter = predList.getIterator();
1805 while (pIter.hasElement())
1807 PredicateImpl *pImpl = (PredicateImpl*) pIter.nextElement();
1808 delete pImpl;
1810 predList.reset();
1812 if (p) pred_ = p->getPredicate(); else pred_ = NULL;
1815 void TableImpl::setPredicate(Predicate *pred)
1817 if (NULL == pred_) { pred_ = pred; return; }
1819 Predicate *curPred = pred_;
1820 PredicateImpl *newPred = new PredicateImpl();
1821 newPred->setTerm(curPred, OpAnd, pred);
1822 newPred->setTable(this);
1823 pred_ = newPred;
1824 return;
1826 void TableImpl::printPlan(int space)
1828 char spaceBuf[IDENTIFIER_LENGTH];
1829 memset(spaceBuf, 32, IDENTIFIER_LENGTH);
1830 spaceBuf[space] = '\0';
1831 printf("%s <TABLE-NODE>\n", spaceBuf);
1832 printf("%s <NAME> %s </NAME>\n", spaceBuf, getName());
1833 printf("%s <ScanType> %s </ScanType>\n", spaceBuf, ScanTypeNames[scanType_]);
1834 PredicateImpl *pred = (PredicateImpl*)pred_;
1835 if (pred) pred->print(space+2);
1836 printf("%s </TABLE-NODE>\n", spaceBuf);
1838 void TableImpl::printSQLForeignString()
1840 DbRetVal rv=OK;
1841 FieldNameList pkFieldList,fkFieldList;
1842 void *tPkptr =NULL;
1843 void *tFkptr = NULL;
1844 void *chunkPk = NULL;
1845 void *vcchunkPk = NULL;
1846 CatalogTableTABLE cTable(sysDB_);
1847 TableImpl *fkTbl =NULL;
1848 ListIterator tblIter = tblList.getIterator();
1849 tblIter.reset();
1850 int firstFK=true;
1851 while (tblIter.hasElement()){
1852 fkTbl = (TableImpl *) tblIter.nextElement();
1853 rv = cTable.getChunkAndTblPtr(fkTbl->getName(), chunkPk, tPkptr,vcchunkPk);
1854 if ( OK != rv){return ;}
1855 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tFkptr, vcchunkPk);
1856 if ( OK != rv){return ;}
1857 CatalogTableFK cFk(sysDB_);
1858 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
1859 if ( OK != rv){return;}
1860 pkFieldList.resetIter();
1861 fkFieldList.resetIter();
1862 char *fldName = NULL;
1863 bool firstField=true;
1864 if(!firstFK) printf(", ");
1865 printf(", FOREIGN KEY ( ");
1866 while((fldName = fkFieldList.nextFieldName())!= NULL)
1868 if (firstField) {
1869 printf("%s",fldName);
1870 firstField=false;
1872 else
1873 printf(",%s",fldName);
1875 printf(" ) REFERENCES %s ( ",fkTbl->getName());
1876 firstField=true;
1877 while((fldName = pkFieldList.nextFieldName())!= NULL)
1879 if (firstField) {
1880 printf("%s",fldName);
1881 firstField=false;
1883 else
1884 printf(",%s",fldName);
1886 printf(" )");
1887 firstFK=true;
1888 pkFieldList.removeAll();
1889 fkFieldList.removeAll();
1891 return;
1893 bool TableImpl::isPkTableHasRecord(char *pkTableName, TableImpl *fkTbl,bool isInsert)
1895 DbRetVal rv=OK;
1896 bool isRecExist=false;
1897 FieldNameList pkFieldList,fkFieldList;
1898 void *tPkptr =NULL;
1899 void *tFkptr = NULL;
1900 void *chunkPk = NULL;
1901 void *vcchunkPk = NULL;
1902 CatalogTableTABLE cTable(sysDB_);
1903 rv = cTable.getChunkAndTblPtr(pkTableName, chunkPk, tPkptr, vcchunkPk);
1904 if ( OK != rv){return false;}
1905 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tFkptr, vcchunkPk);
1906 if ( OK != rv){return false;}
1907 CatalogTableFK cFk(sysDB_);
1908 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
1909 if ( OK != rv){return false;}
1910 int totFld = pkFieldList.size();
1911 Condition *condition = new Condition[totFld];
1912 char *pkFldName = NULL;
1913 char *fkFldName = NULL;
1914 FieldDef *def=NULL;
1915 int i=0;
1916 pkFieldList.resetIter();
1917 fkFieldList.resetIter();
1918 void *val=NULL;
1919 while((pkFldName = pkFieldList.nextFieldName())!= NULL)
1921 fkFldName = fkFieldList.nextFieldName();
1922 FieldIterator fIter = fldList_.getIterator();
1923 while (fIter.hasElement())
1925 def = fIter.nextElement();
1926 if (strcmp(def->fldName_, fkFldName) == 0)
1928 if(NULL == def->bindVal_ && isInsert) { return true; }
1929 if(NULL == def->bindVal_) {
1930 if (def->type_ != typeVarchar)
1931 val = (char*)curTuple_+ def->offset_;
1932 else val = (void *) *(long *) ((char*)curTuple_+
1933 def->offset_);
1934 } else {
1935 val = def->bindVal_;
1937 if(def->type_==typeString)
1938 condition[i].setTerm(pkFldName,OpEquals,&val);
1939 else
1940 condition[i].setTerm(pkFldName,OpEquals,val);
1941 i++;
1942 break;
1946 pkFieldList.removeAll();
1947 fkFieldList.removeAll();
1948 Condition *cond = NULL;
1949 if(i == 0 && !isInsert)return true;
1950 if( i > 1){
1951 cond = new Condition[i-1];
1952 int totcon = i;
1953 i=0;
1954 int j=0;
1955 for(j=0;j<totcon-1;j++)
1957 if(j==0)
1958 cond[j].setTerm(condition[i++].getPredicate(),OpAnd,condition[i++].getPredicate());
1959 else
1960 cond[j].setTerm(cond[j-1].getPredicate(), OpAnd, condition[i++].getPredicate());
1962 fkTbl->setCondition(&cond[j-1]);
1964 else{
1965 fkTbl->setCondition(&condition[i-1]);
1967 fkTbl->execute();
1968 if(fkTbl->fetch()){
1969 fkTbl->closeScan();
1970 delete[] cond;
1971 delete[] condition;
1972 return true;
1974 delete[] cond;
1975 delete[] condition;
1976 return false;
1979 bool TableImpl::isFkTableHasRecord(char *pkTableName, TableImpl *fkTbl)
1981 DbRetVal rv=OK;
1982 FieldNameList pkFieldList,fkFieldList;
1983 void *tPkptr =NULL;
1984 void *tFkptr = NULL;
1985 void *chunkPk = NULL;
1986 void *vcchunkPk = NULL;
1987 CatalogTableTABLE cTable(sysDB_);
1988 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tPkptr, vcchunkPk);
1989 if ( OK != rv){return false;}
1990 rv = cTable.getChunkAndTblPtr(pkTableName, chunkPk, tFkptr, vcchunkPk);
1991 if ( OK != rv){return false;}
1992 CatalogTableFK cFk(sysDB_);
1993 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
1994 if ( OK != rv){return false;}
1995 int totFld = pkFieldList.size();
1996 Condition *condition = new Condition[totFld];
1997 char *pkFldName = NULL;
1998 char *fkFldName = NULL;
1999 FieldDef *def=NULL;
2000 int i=0;
2001 pkFieldList.resetIter();
2002 fkFieldList.resetIter();
2003 while((pkFldName = pkFieldList.nextFieldName())!= NULL)
2005 fkFldName = fkFieldList.nextFieldName();
2006 FieldIterator fIter = fldList_.getIterator();
2007 while (fIter.hasElement())
2009 def = fIter.nextElement();
2010 void *val = NULL;
2011 if (def->type_ != typeVarchar)
2012 val = (char*)curTuple_+ def->offset_;
2013 else val = (void *) *(long *) ((char*)curTuple_+ def->offset_);
2014 if (strcmp(def->fldName_, pkFldName) == 0)
2016 if(def->type_==typeString)
2017 condition[i].setTerm(fkFldName,OpEquals,&val);//((char*)curTuple_+def->offset_));
2018 else
2019 condition[i].setTerm(fkFldName,OpEquals,val);//((char*)curTuple_+def->offset_));
2020 i++;
2021 break;
2025 pkFieldList.removeAll();
2026 fkFieldList.removeAll();
2027 if(i == 0 )return true;
2028 Condition *cond = new Condition[i-1];
2029 i=0;
2030 int j=0;
2031 for(j=0;j<totFld-1;j++)
2033 if(j==0)
2034 cond[j].setTerm(condition[i++].getPredicate(),OpAnd,condition[i++].getPredicate());
2035 else
2036 cond[j].setTerm(cond[j-1].getPredicate(), OpAnd, condition[i++].getPredicate());
2038 if(totFld==1)
2039 fkTbl->setCondition(&condition[totFld-1]);
2040 else
2041 fkTbl->setCondition(&cond[j-1]);
2042 fkTbl->execute();
2043 if(fkTbl->fetch()){
2044 fkTbl->closeScan();
2045 delete[] cond;
2046 delete[] condition;
2047 return true;
2049 delete[] cond;
2050 delete[] condition;
2051 return false;
2053 DbRetVal TableImpl::compact()
2055 DbRetVal rv=OK;
2056 int ret =((Chunk*)chunkPtr_)->compact(db_->procSlot);
2057 if(ret!=0) return ErrLockTimeOut;
2059 if (NULL != vcChunkPtr_) {
2060 ret = ((Chunk*)vcChunkPtr_)->compact(db_->procSlot);
2061 if(ret!=0) return ErrLockTimeOut;
2064 if (NULL != indexPtr_)
2066 int i;
2067 //it has index
2068 for (i = 0; i < numIndexes_ ; i++)
2070 rv = compactIndexNode(indexPtr_[i]);
2071 if (rv != OK) {
2072 printError(rv, "Error in compacting index Node");
2073 break;
2077 return rv;
2080 DbRetVal TableImpl::compactIndexNode( void *indexPtr)
2082 CINDEX *iptr = (CINDEX*)indexPtr;
2083 int ret1=0;
2084 printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
2085 if( hashIndex == (iptr->indexType_) )
2087 ret1 =((Chunk*)iptr->hashNodeChunk_)->compact(db_->procSlot);
2088 if(ret1!=0){
2089 return ErrLockTimeOut;
2091 }else
2093 ret1 =((Chunk*)iptr->chunkPtr_)->compact(db_->procSlot);
2094 if(ret1!=0){
2095 return ErrLockTimeOut;
2098 return OK;