autoinc and tree index predicate fix
[csql.git] / src / storage / TableImpl.cxx
blobcee2f5e3055d0e2dc9130763e77cf52940398760
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)
340 scanType_ = hashIndexScan;
341 else if (trieIndex == info->indType)
342 scanType_ = trieIndexScan;
343 else
344 scanType_ = treeIndexScan;
345 isPointLook = true;
346 useIndex_ = i;
348 else if (pred->isBetweenInvolved(def->fldName_))
350 if (treeIndex == info->indType)
352 scanType_ = treeIndexScan;
353 useIndex_ = i;
354 isBetween=true;
355 break; //no composite index for tree index
356 } else isAllFldPointLookup= false;
358 else if (pred->rangeQueryInvolved(def->fldName_))
360 printDebug(DM_Predicate, "range lookup involved for field %s",def->fldName_);
361 if (treeIndex == info->indType)
363 scanType_ = treeIndexScan;
364 useIndex_ = i;
365 break; //no composite index for tree index
366 } else isAllFldPointLookup=false;
367 }else {
368 useIndex_ = -1;
369 isAllFldPointLookup = false;
370 break;
372 }//while iter.hasElement()
373 if( noOfIfld == 1 && useIndex_ != -1)return OK;
374 if (!isAllFldPointLookup && useIndex_ != -1) return OK;
375 }//for
378 scanType_ = fullTableScan;
379 return OK;
382 void* TableImpl::fetch()
384 fetchNoBind();
385 if (NULL == curTuple_) return curTuple_;
386 copyValuesToBindBuffer(curTuple_);
387 return curTuple_;
389 void* TableImpl::fetch(DbRetVal &rv)
391 fetchNoBind(rv);
392 if (NULL == curTuple_) return curTuple_;
393 copyValuesToBindBuffer(curTuple_);
394 return curTuple_;
397 void* TableImpl::fetchNoBind()
399 if (NULL == iter)
401 printError(ErrNotOpen,"Scan not open or Scan is closed\n");
402 return NULL;
404 void *prevTuple = curTuple_;
405 curTuple_ = iter->next();
406 if (NULL == curTuple_)
408 return NULL;
410 DbRetVal lockRet = OK;
411 if (!loadFlag) {
412 if ((*trans)->isoLevel_ == READ_COMMITTED)
414 //if iso level is read committed, operation duration lock is sufficent
415 //so release it here itself.
416 int tries = Conf::config.getMutexRetries();
417 struct timeval timeout, timeval;
418 timeout.tv_sec = Conf::config.getMutexSecs();
419 timeout.tv_usec = Conf::config.getMutexUSecs();
421 bool status = false;
422 while(true) {
423 lockRet = lMgr_->isExclusiveLocked( curTuple_, trans, status);
424 if (OK != lockRet)
426 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
427 curTuple_ = prevTuple;
428 return NULL;
430 if (!status) break;
431 tries--;
432 if (tries == 0) break;
433 timeval.tv_sec = timeout.tv_sec;
434 timeval.tv_usec = timeout.tv_usec;
435 os::select(0, 0, 0, 0, &timeval);
437 if (tries == 0)
439 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
440 curTuple_ = prevTuple;
441 return NULL;
444 else if ((*trans)->isoLevel_ == READ_REPEATABLE) {
445 if (OK != trySharedLock(curTuple_, trans))
447 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
448 curTuple_ = prevTuple;
449 return NULL;
454 return curTuple_;
456 DbRetVal TableImpl::trySharedLock(void *curTuple, Transaction **trans)
458 DbRetVal lockRet = OK;
459 int tries = Conf::config.getMutexRetries();
460 while((lockRet = lMgr_->getSharedLock(curTuple_, trans)) == ErrLockTimeOut)
462 tries--;
463 if (tries <=0) break;
465 return lockRet;
467 DbRetVal TableImpl::tryExclusiveLock(void *curTuple, Transaction **trans)
469 DbRetVal lockRet = OK;
470 int tries = Conf::config.getMutexRetries();
471 while((lockRet = lMgr_->getExclusiveLock(curTuple_, trans)) == ErrLockTimeOut)
473 tries--;
474 if (tries <=0) break;
476 return lockRet;
479 void* TableImpl::fetchNoBind(DbRetVal &rv)
481 rv = OK;
482 if (NULL == iter)
484 printError(ErrNotOpen,"Scan not open or Scan is closed\n");
485 rv = ErrNotOpen;
486 return NULL;
488 void *prevTuple = curTuple_;
489 curTuple_ = iter->next();
490 if (NULL == curTuple_)
492 return NULL;
494 DbRetVal lockRet = OK;
495 if (!loadFlag) {
496 if ((*trans)->isoLevel_ == READ_REPEATABLE) {
497 lockRet = lMgr_->getSharedLock(curTuple_, trans);
498 if (OK != lockRet)
500 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
501 rv = ErrLockTimeOut;
502 curTuple_ = prevTuple;
503 return NULL;
507 else if ((*trans)->isoLevel_ == READ_COMMITTED)
509 //if iso level is read committed, operation duration lock is sufficent
510 //so release it here itself.
511 int tries = Conf::config.getMutexRetries();
512 //struct timeval timeout;
513 //timeout.tv_sec = Conf::config.getMutexSecs();
514 //timeout.tv_usec = Conf::config.getMutexUSecs();
516 bool status = false;
517 while(true) {
518 lockRet = lMgr_->isExclusiveLocked( curTuple_, trans, status);
519 if (OK != lockRet)
521 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
522 curTuple_ = prevTuple;
523 rv = ErrLockTimeOut;
524 return NULL;
526 if (!status) break;
527 tries--;
528 if (tries == 0) break;
529 //os::select(0, 0, 0, 0, &timeout);
531 if (tries == 0)
533 printError(lockRet, "Unable to get the lock for the tuple %x", curTuple_);
534 curTuple_ = prevTuple;
535 rv = ErrLockTimeOut;
536 return NULL;
540 return curTuple_;
542 DbRetVal TableImpl::fetchAgg(const char * fldName, AggType aType, void *buf, bool &noRec)
544 FieldInfo *info = new FieldInfo();
545 DbRetVal rv = getFieldInfo(fldName, info);
546 if (OK != rv) return rv;
547 bool res= false;
548 if (AGG_MIN == aType || AGG_MAX == aType) {
549 int pos =0;
550 IndexType iType = getIndexType((char*)fldName, &pos);
551 if(treeIndex == iType && pos >=0) {
552 if (AGG_MIN == aType) {
553 HashIndexInfo* hInfo = (HashIndexInfo*) idxInfo[pos];
554 CINDEX *iptr = (CINDEX*) hInfo->indexPtr;
555 TreeNode *fstNode=(TreeNode *)iptr->hashNodeChunk_;
556 TreeIter *iter=NULL;
557 if(fstNode!=NULL){
558 TreeNode *start = (TreeNode *)*((char**)((char*)fstNode + sizeof(TreeNode)));
559 iter = new TreeIter(start,(TreeNode*)iptr->hashNodeChunk_,sysDB_->procSlot);
560 }else{
561 iter = new TreeIter(NULL,(TreeNode*)iptr->hashNodeChunk_,sysDB_->procSlot);
563 char *tuple = (char*) iter->getFirstElement();
564 if (tuple != NULL) {
565 AllDataType::copyVal(buf,(void*)(tuple+info->offset),
566 info->type, info->length);
567 delete iter;
568 return OK;
570 delete iter; iter = NULL;
572 else if (AGG_MAX == aType) {
573 HashIndexInfo* hInfo = (HashIndexInfo*) idxInfo[pos];
574 CINDEX *iptr = (CINDEX*) hInfo->indexPtr;
575 TreeNode *fstNode=(TreeNode *)iptr->hashNodeChunk_;
576 TreeIter *iter=NULL;
577 if(fstNode!=NULL){
578 TreeNode *start = (TreeNode *)*((char**)((char*)fstNode + sizeof(TreeNode)));
579 iter = new TreeIter(start,(TreeNode*)iptr->hashNodeChunk_,sysDB_->procSlot);
580 }else{
581 iter = new TreeIter(NULL,(TreeNode*)iptr->hashNodeChunk_,sysDB_->procSlot);
583 char *tuple = (char*) iter->getLastElement();
584 if (tuple != NULL) {
585 AllDataType::copyVal(buf,(void*)(tuple+info->offset),
586 info->type, info->length);
587 delete iter; iter = NULL;
588 return OK;
590 delete iter; iter=NULL;
593 }else if (AGG_COUNT == aType) {
594 (*(int*)buf) = 0;
598 DataType type = info->type;
599 int length = info->length;
600 int offset = info->offset;
601 int colPos = fldList_.getFieldPosition(fldName);
602 bool isNullable= true;
603 if (info->isNull || info->isPrimary || info->isDefault || info->isAutoIncrement) {
604 isNullable = false;
606 int nullOffset = length_-4;
607 if (aType == AGG_COUNT) {
608 length = sizeof(int);
609 type = typeInt;
611 if (NULL == pred_ && typeInt == type && aType != AGG_AVG)
612 { //perf opt
613 ChunkIterator cIter = ((Chunk*)chunkPtr_)->getIterator();
614 char *tuple =(char*)cIter.nextElement();
615 if (NULL == tuple) {
616 *(int *) buf = 0;
617 noRec = true;
618 return OK;
620 int count =1;
621 if (isNullable) {
622 if (isIntUsedForNULL) {
623 if (BITSET(*(int*)(tuple+nullOffset), colPos-1)) count =0;
625 else {
626 curTuple_= tuple;
627 if(isFldNull(colPos)) count =0;
630 if (aType != AGG_COUNT)
631 AllDataType::copyVal(buf, (void*) (tuple+offset), type, length);
632 void *prev=NULL;
633 prev = curTuple_;
634 cIter.pageSize = PAGE_SIZE;
635 while(1)
637 tuple = (char*)cIter.nextElementInt();
638 if (NULL == tuple) break;
639 if (isNullable) {
640 if (isIntUsedForNULL) {
641 if (BITSET(*(int*)(tuple+nullOffset), colPos-1)) continue;
643 else {
644 curTuple_= tuple;
645 if(isFldNull(colPos)) continue;
648 if (aType == AGG_MIN)
650 if (*(int*)buf >= *((int*)(tuple+offset)))
651 *(int*)buf = *((int*)(tuple+offset));
653 else if (aType == AGG_MAX)
655 if (*(int*)buf <= *((int*)(tuple+offset)))
656 *(int*)buf = *((int*)(tuple+offset));
658 else if (aType == AGG_SUM)
660 *(int*)buf += *((int*)(tuple+offset));
662 else if (aType == AGG_AVG)
664 *(int*)buf = *(int*)buf + *((int*)(tuple+offset));
665 count++;
667 else if (aType == AGG_COUNT)
669 count++;
672 curTuple_= prev;
673 if( AGG_AVG == aType) AllDataType::divVal(buf, &count, type);
674 else if (AGG_COUNT == aType) (*(int*)buf) = count;
675 delete info;
676 return OK;
679 char *tuple = (char*) fetchNoBind(rv);
680 if ( NULL == tuple) { noRec = true; return OK; }
681 int count =1;
683 while(isFldNull(colPos)) {
684 tuple= (char*) fetchNoBind(rv);
685 if (aType == AGG_COUNT) count++;
686 if (tuple) break;
688 if ( NULL == tuple) { noRec = true; return OK; }
690 if (aType == AGG_AVG) {
691 AllDataType::convertToDouble(buf, (void*) (tuple+offset), type);
692 } else if (aType != AGG_COUNT) {
693 AllDataType::copyVal(buf, (void*) (tuple+offset), type, length);
695 while(1) {
696 tuple = (char*) fetchNoBind(rv);
697 if (NULL == tuple) break;
698 if (isNullable) {
699 if (isIntUsedForNULL) {
700 if (BITSET(*(int*)(tuple+nullOffset), colPos-1)) continue;
702 else {
703 curTuple_= tuple;
704 if(isFldNull(colPos)) continue;
707 switch(aType) {
708 case AGG_MIN:
710 res = AllDataType::compareVal(buf, (void*) (tuple+offset),
711 OpGreaterThanEquals,
712 type, length);
713 if (res) AllDataType::copyVal(buf, (void*) (tuple+offset),
714 type, length);
715 break;
717 case AGG_MAX:
719 res = AllDataType::compareVal(buf, (void*) (tuple+offset),
720 OpLessThanEquals,
721 type, length);
722 if (res) AllDataType::copyVal(buf, (void*) (tuple+offset),
723 type, length);
724 break;
726 case AGG_SUM:
728 AllDataType::addVal(buf, (void*) (tuple+offset),
729 type);
730 break;
732 case AGG_AVG:
734 double tmpBuf=0.0;
735 AllDataType::convertToDouble(&tmpBuf, (void*) (tuple+offset), type);
736 AllDataType::addVal(buf, &tmpBuf, typeDouble);
737 count++;
738 break;
740 case AGG_COUNT:
742 count++;
743 break;
747 switch(aType) {
748 case AGG_AVG:
750 AllDataType::divVal((double *)buf, count, type);
751 break;
753 case AGG_COUNT:
755 (*(int*)buf) = count;
756 break;
759 delete info;
760 return OK;
762 DbRetVal TableImpl::getCheckpointMutex()
764 int tries=0;
765 DbRetVal rv = OK;
766 int totalTries = Conf::config.getMutexRetries();
767 struct timeval timeout, timeval;
768 timeout.tv_sec = Conf::config.getMutexSecs();
769 timeout.tv_usec = Conf::config.getMutexUSecs();
771 while (tries < totalTries)
773 rv = sysDB_->getSCheckpointMutex();
774 if (OK == rv) break;
775 timeval.tv_sec = timeout.tv_sec;
776 timeval.tv_usec = timeout.tv_usec;
777 os::select(0,0,0,0,&timeval);
778 tries++;
780 if (tries == totalTries) {
781 printError(ErrLockTimeOut, "Checkpoint server is running. Retry after sometime.");
782 return ErrLockTimeOut;
784 return OK;
786 DbRetVal TableImpl::insertTuple()
788 DbRetVal ret = getCheckpointMutex();
789 if (ret !=OK) return ret;
790 void *tptr = NULL;
791 int tries=0;
792 int totalTries = Conf::config.getMutexRetries();
793 while (tries < totalTries)
795 ret = OK;
796 tptr = ((Chunk*)chunkPtr_)->allocate(db_, &ret);
797 if (tptr !=NULL) break;
798 if (ret != ErrLockTimeOut)
800 sysDB_->releaseCheckpointMutex();
801 printError(ret, "Unable to allocate record from chunk");
802 return ret;
804 tries++;
806 if (NULL == tptr)
808 sysDB_->releaseCheckpointMutex();
809 printError(ret, "Unable to allocate record from chunk after %d retries", tries);
810 return ret;
812 curTuple_ = tptr;
813 if(isFkTbl){
814 TableImpl *fkTbl =NULL;
815 ListIterator tblIter = tblList.getIterator();
816 tblIter.reset();
817 while (tblIter.hasElement()){
818 fkTbl = (TableImpl *) tblIter.nextElement();
819 bool pkRec = isPkTableHasRecord(fkTbl->getName(),fkTbl,true);
820 if(!pkRec){
821 printError(ErrForeignKeyInsert, "Unable to insert into foreign Key table.Check PK table");
822 ((Chunk*)chunkPtr_)->free(db_, tptr);
823 sysDB_->releaseCheckpointMutex();
824 return ErrForeignKeyInsert;
827 tblIter.reset();
829 if (!loadFlag) {
830 //ret = lMgr_->getExclusiveLock(tptr, trans);
831 if (OK != tryExclusiveLock(tptr, trans))
833 ((Chunk*)chunkPtr_)->free(db_, tptr);
834 printError(ret, "Could not get lock for the insert tuple %x", tptr);
835 sysDB_->releaseCheckpointMutex();
836 return ErrLockTimeOut;
840 ret = copyValuesFromBindBuffer(tptr);
841 if (ret != OK)
843 printError(ret, "Unable to copy values from bind buffer");
844 if (!loadFlag) {
845 (*trans)->removeFromHasList(db_, tptr);
846 lMgr_->releaseLock(tptr);
849 FieldIterator fIter = fldList_.getIterator();
850 char *colPtr = (char*) curTuple_;
851 while (fIter.hasElement()) {
852 FieldDef *def = fIter.nextElement();
853 colPtr = (char *) curTuple_ + def->offset_;
854 if (def->type_ == typeVarchar) {
855 char *ptr = (char *) *(long *) colPtr;
856 if (ptr != 0L) ((Chunk *) vcChunkPtr_)->free(db_, ptr);
859 ((Chunk*)chunkPtr_)->free(db_, tptr);
860 sysDB_->releaseCheckpointMutex();
861 return ret;
863 int addSize = 0;
864 if (numFlds_ < 31)
866 addSize = 4;
867 *(int*)((char*)(tptr) + (length_-addSize)) = iNullInfo;
869 else
871 addSize = os::align(numFlds_);
872 os::memcpy(((char*)(tptr) + (length_-addSize)), cNullInfo, addSize);
875 //int tupleSize = length_ + addSize;
876 if (NULL != indexPtr_)
878 int i;
879 //it has index
880 for (i = 0; i < numIndexes_ ; i++)
882 ret = insertIndexNode(*trans, indexPtr_[i], idxInfo[i], tptr);
883 if (ret != OK) { printError(ret, "Error in inserting to index %x", tptr); break;}
885 if ( ret != OK)
887 for (int j = 0; j < i ; j++) {
888 printError(ErrWarning, "Undo:Deleting index node");
889 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
891 if (!loadFlag) {
892 (*trans)->removeFromHasList(db_, tptr);
893 lMgr_->releaseLock(tptr);
896 FieldIterator fIter = fldList_.getIterator();
897 char *colPtr = (char*) curTuple_;
898 while (fIter.hasElement()) {
899 FieldDef *def = fIter.nextElement();
900 colPtr = (char *) curTuple_ + def->offset_;
901 if (def->type_ == typeVarchar) {
902 char *ptr = (char *) *(long *) colPtr;
903 if (ptr != 0L) ((Chunk *) vcChunkPtr_)->free(db_, ptr);
906 ((Chunk*)chunkPtr_)->free(db_, tptr);
907 sysDB_->releaseCheckpointMutex();
908 return ret;
911 if (!loadFlag) {
912 //TODO: number of varchar fields to be stored as a member in TableImpl
913 int nVarchars = 0;
914 FieldIterator fIter = fldList_.getIterator();
915 while (fIter.hasElement()) {
916 FieldDef *def = fIter.nextElement();
917 if (def->type_ == typeVarchar) nVarchars++;
920 // the undo log for insert should contain
921 // tuple ptr + metadata Ptr + no of varchars + ptrs to varchars for insert opearation
922 int size = (3 + nVarchars) * sizeof(void *) + sizeof(int);
923 void *data = malloc(size);
924 char *ptr = (char *)data;
925 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
926 void *metaData = db_->getMetaDataPtr();
927 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
928 *(int *) ptr = nVarchars; ptr += sizeof(int);
929 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
930 fIter = fldList_.getIterator();
931 char *colPtr = (char*) curTuple_;
932 while (fIter.hasElement()) {
933 FieldDef *def = fIter.nextElement();
934 colPtr = (char *) curTuple_ + def->offset_;
935 if (def->type_ == typeVarchar) {
936 *(long *) ptr = (long)colPtr;
937 ptr += sizeof(void *);
940 ret = (*trans)->appendUndoLog(sysDB_, InsertOperation, data, size);
941 ::free(data);
943 if (ret != OK) {
944 printError(ret, "Unable to create undo log for %x %d", tptr, *(int*)tptr);
945 for (int j = 0; j < numIndexes_ ; j++) {
946 printError(ErrWarning, "Deleting index node");
947 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
949 if (!loadFlag) {
950 (*trans)->removeFromHasList(db_, tptr);
951 lMgr_->releaseLock(tptr);
953 ((Chunk*)chunkPtr_)->free(db_, tptr);
955 sysDB_->releaseCheckpointMutex();
956 return ret;
959 DbRetVal TableImpl::deleteTuple()
961 if (NULL == curTuple_)
963 printError(ErrNotOpen, "Scan not open: No Current tuple");
964 return ErrNotOpen;
966 DbRetVal ret = getCheckpointMutex();
967 if (ret != OK) return ret;
968 if(isPkTbl){
969 TableImpl *fkTbl =NULL;
970 ListIterator tblIter = tblFkList.getIterator();
971 tblIter.reset();
972 while (tblIter.hasElement()){
973 fkTbl = (TableImpl *) tblIter.nextElement();
974 bool pkRec = isFkTableHasRecord(fkTbl->getName(),fkTbl);
975 if(pkRec){
976 printError(ErrForeignKeyDelete, "A Relation Exists. Delete from child table first");
977 sysDB_->releaseCheckpointMutex();
978 return ErrForeignKeyDelete;
981 tblIter.reset();
983 if (!loadFlag) {
984 //ret = lMgr_->getExclusiveLock(curTuple_, trans);
985 if (OK != tryExclusiveLock(curTuple_, trans))
987 printError(ret, "Could not get lock for the delete tuple %x",
988 curTuple_);
989 sysDB_->releaseCheckpointMutex();
990 return ErrLockTimeOut;
994 if (NULL != indexPtr_)
996 int i;
997 //it has index
998 for (i = 0; i < numIndexes_ ; i++)
1000 ret = deleteIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
1001 if (ret != OK) break;
1003 if (i != numIndexes_ )
1005 printError(ErrWarning, "Inserting back index node");
1006 for (int j = 0; j < i ; j++)
1007 insertIndexNode(*trans, indexPtr_[j], idxInfo[j], curTuple_);
1008 if (!loadFlag) {
1009 lMgr_->releaseLock(curTuple_);
1010 (*trans)->removeFromHasList(db_, curTuple_);
1012 printError(ret, "Unable to insert index node for tuple %x", curTuple_);
1013 sysDB_->releaseCheckpointMutex();
1014 return ret;
1017 if (!loadFlag) {
1018 // the undo log for delete should contain
1019 // tupleptr + metadataPtr + nVarchars + varchar chunk ptr +
1020 // ptrs to varchars + size and value pairs for varchars
1022 //TODO: number of varchar fields to be stored as a member in TableImpl
1023 void *tptr = curTuple_;
1024 char *colPtr = (char *)curTuple_;
1025 int nVarchars = 0;
1026 int vcLenValPairSize = 0;
1027 FieldIterator fIter = fldList_.getIterator();
1028 while (fIter.hasElement()) {
1029 FieldDef *def = fIter.nextElement();
1030 colPtr = (char *) curTuple_ + def->offset_;
1031 if (def->type_ == typeVarchar) {
1032 nVarchars++;
1033 if (* (long *) colPtr == 0L)
1034 vcLenValPairSize = vcLenValPairSize + sizeof(int);
1035 else vcLenValPairSize = vcLenValPairSize + sizeof(int) +
1036 + os::align(strlen((char *) *(long *)colPtr) + 1);
1039 int size = (3 + nVarchars) * sizeof(void *) + sizeof(int)
1040 + vcLenValPairSize;
1041 void *data = malloc(size);
1042 char *ptr = (char *)data;
1043 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
1044 void *metaData = db_->getMetaDataPtr();
1045 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
1046 *(int *) ptr = nVarchars; ptr += sizeof(int);
1047 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
1048 fIter = fldList_.getIterator();
1049 colPtr = (char*) curTuple_;
1050 char *valLenPairPtr = ptr + nVarchars * sizeof(void *);
1051 while (fIter.hasElement()) {
1052 FieldDef *def = fIter.nextElement();
1053 colPtr = (char *) curTuple_ + def->offset_;
1054 int vcStrLen = 0;
1055 if (def->type_ == typeVarchar) {
1056 *(long *) ptr = (long )colPtr; ptr += sizeof(void *);
1057 if (*(long *) colPtr == 0L) {
1058 *(int *) valLenPairPtr = vcStrLen = 0;
1059 valLenPairPtr += sizeof(int);
1060 } else {
1061 *(int *) valLenPairPtr = vcStrLen =
1062 os::align(strlen((char *)*(long *)colPtr) + 1);
1063 valLenPairPtr += sizeof(int);
1064 strcpy(valLenPairPtr, (char *)*(long *)colPtr);
1065 valLenPairPtr += vcStrLen;
1069 ret = (*trans)->appendUndoLog(sysDB_, DeleteOperation, data, size);
1070 ::free(data);
1072 if (ret != OK) {
1073 printError(ret, "Unable to create undo log for %x ", curTuple_);
1074 for (int j = 0; j < numIndexes_ ; j++) {
1075 printError(ErrWarning, "Inserting back index node");
1076 insertIndexNode(*trans, indexPtr_[j], idxInfo[j], curTuple_);
1078 if (!loadFlag) {
1079 (*trans)->removeFromHasList(db_, curTuple_);
1080 lMgr_->releaseLock(curTuple_);
1084 FieldIterator fIter = fldList_.getIterator();
1085 char *colPtr = (char*) curTuple_;
1086 while (fIter.hasElement()) {
1087 FieldDef *def = fIter.nextElement();
1088 colPtr = (char *) curTuple_ + def->offset_;
1089 if (def->type_ == typeVarchar) {
1090 if (*(long *) colPtr != 0L) {
1091 char *ptr = (char *) *(long *) colPtr;
1092 ((Chunk *) vcChunkPtr_)->free(db_, ptr);
1096 ((Chunk*)chunkPtr_)->free(db_, curTuple_);
1097 iter->prev();
1098 sysDB_->releaseCheckpointMutex();
1099 return ret;
1102 int TableImpl::deleteWhere()
1104 DbRetVal ret = getCheckpointMutex();
1105 if (ret !=OK) return ret;
1107 int tuplesDeleted = 0;
1108 DbRetVal rv = OK;
1109 rv = execute();
1110 if (rv !=OK) {
1111 sysDB_->releaseCheckpointMutex();
1112 return (int) rv;
1114 while(true){
1115 fetchNoBind( rv);
1116 if (rv != OK) { tuplesDeleted = (int)rv; break; }
1117 if (NULL == curTuple_) break;
1118 rv = deleteTuple();
1119 if (rv != OK) {
1120 printError(rv, "Error: Could only delete %d tuples", tuplesDeleted);
1121 closeScan();
1122 sysDB_->releaseCheckpointMutex();
1123 return (int) rv;
1125 tuplesDeleted++;
1127 closeScan();
1128 sysDB_->releaseCheckpointMutex();
1129 return tuplesDeleted;
1132 int TableImpl::truncate()
1134 //take exclusive lock on the table
1135 //get the chunk ptr of the table
1136 //traverse the tablechunks and free all the pages except the first one
1137 //get the chunk ptr of all its indexes
1138 //traverse the indexchunks and free all the pages except the first one
1139 //release table lock
1141 //TEMPORARY FIX
1142 DbRetVal rv = OK;
1143 Predicate* tmpPred = pred_;
1144 pred_ = NULL;
1145 isPlanCreated = false;
1146 int tuplesDeleted = deleteWhere();
1147 isPlanCreated = false;
1148 pred_ = tmpPred;
1149 return tuplesDeleted;
1152 DbRetVal TableImpl::updateTuple()
1154 if (NULL == curTuple_)
1156 printError(ErrNotOpen, "Scan not open: No Current tuple");
1157 return ErrNotOpen;
1159 DbRetVal ret = getCheckpointMutex();
1160 if (ret !=OK) return ret;
1161 if(isFkTbl){
1162 TableImpl *fkTbl =NULL;
1163 ListIterator tblIter = tblList.getIterator();
1164 tblIter.reset();
1165 while (tblIter.hasElement()){
1166 fkTbl = (TableImpl *) tblIter.nextElement();
1167 bool pkRec = isPkTableHasRecord(fkTbl->getName(),fkTbl,false);
1168 if(!pkRec){
1169 printError(ErrForeignKeyInsert, "Unable to insert into foreign Key table.Check PK table");
1170 sysDB_->releaseCheckpointMutex();
1171 return ErrForeignKeyInsert;
1174 tblIter.reset();
1177 if (!loadFlag) {
1178 //ret = lMgr_->getExclusiveLock(curTuple_, trans);
1179 if (OK != tryExclusiveLock(curTuple_, trans))
1181 printError(ret, "Could not get lock for the update tuple %x", curTuple_);
1182 sysDB_->releaseCheckpointMutex();
1183 return ErrLockTimeOut;
1186 if (NULL != indexPtr_)
1188 //it has index
1189 //TODO::If it fails while updating index node, we have to undo all the updates
1190 //on other indexes on the table.Currently it will leave the database in an
1191 //inconsistent state.
1192 for (int i = 0; i < numIndexes_ ; i++)
1194 ret = updateIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
1195 if (ret != OK)
1197 if (!loadFlag) {
1198 lMgr_->releaseLock(curTuple_);
1199 (*trans)->removeFromHasList(db_, curTuple_);
1201 printError(ret, "Unable to update index node for tuple %x", curTuple_);
1202 sysDB_->releaseCheckpointMutex();
1203 return ret;
1208 if (!loadFlag) {
1209 // the undo log for update should contain
1210 // tupleptr + tuple length + actual tuple + metadataPtr +
1211 // nVarchars + varchar chunk ptr + ptrs to varchars +
1212 // size and value pairs for varchars
1214 //TODO: number of varchar fields to be stored as a member in TableImpl
1215 void *tptr = curTuple_;
1216 char *colPtr = (char *)curTuple_;
1217 int nVarchars = 0;
1218 int vcLenValPairSize = 0;
1219 FieldIterator fIter = fldList_.getIterator();
1220 while (fIter.hasElement()) {
1221 FieldDef *def = fIter.nextElement();
1222 colPtr = (char *) curTuple_ + def->offset_;
1223 if (def->type_ == typeVarchar) {
1224 nVarchars++;
1225 if (* (long *) colPtr == 0L)
1226 vcLenValPairSize = vcLenValPairSize + sizeof(int);
1227 else vcLenValPairSize = vcLenValPairSize + sizeof(int) +
1228 + os::align(strlen((char *) *(long *)colPtr) + 1);
1231 int size = (3 + nVarchars) * sizeof(void *) + 2 * sizeof(int) +
1232 vcLenValPairSize + length_;
1233 void *data = malloc(size);
1234 char *ptr = (char *) data;
1235 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
1236 *(int *) ptr = length_; ptr += sizeof(int);
1237 os::memcpy(ptr, tptr, length_); ptr += length_;
1238 void *metaData = db_->getMetaDataPtr();
1239 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
1240 *(int *) ptr = nVarchars; ptr += sizeof(int);
1241 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
1242 fIter = fldList_.getIterator();
1243 colPtr = (char*) curTuple_;
1244 char *valLenPairPtr = ptr + nVarchars * sizeof(void *);
1245 while (fIter.hasElement()) {
1246 FieldDef *def = fIter.nextElement();
1247 colPtr = (char *) curTuple_ + def->offset_;
1248 int vcStrLen = 0;
1249 if (def->type_ == typeVarchar) {
1250 *(long *) ptr = (long)colPtr; ptr += sizeof(void *);
1251 if (*(long *) colPtr == 0L) {
1252 *(int *) valLenPairPtr = vcStrLen = 0;
1253 valLenPairPtr += sizeof(int);
1254 } else {
1255 *(int *) valLenPairPtr = vcStrLen =
1256 os::align(strlen((char *)*(long *)colPtr) + 1);
1257 valLenPairPtr += sizeof(int);
1258 strcpy(valLenPairPtr, (char *)*(long *)colPtr);
1259 valLenPairPtr += vcStrLen;
1263 ret = (*trans)->appendUndoLog(sysDB_, UpdateOperation, data, size);
1264 ::free(data);
1266 if (ret != OK) {
1267 if (!loadFlag) {
1268 lMgr_->releaseLock(curTuple_);
1269 (*trans)->removeFromHasList(db_, curTuple_);
1271 sysDB_->releaseCheckpointMutex();
1272 return ret;
1275 int addSize = 0;
1276 int iNullVal=iNullInfo;
1277 char *cNullVal = NULL;
1278 if (numFlds_ > 32) {
1279 addSize = os::align(numFlds_);
1280 cNullVal = (char *) malloc(addSize);
1281 os::memcpy(cNullVal, cNullInfo, addSize);
1283 bool nullCharSet = false;
1284 if (numFlds_ <= 32){
1285 addSize=4;
1286 if (!iNullVal)
1287 iNullInfo = *(int*)((char*)(curTuple_) + (length_- addSize));
1288 else
1289 *(int*)((char*)(curTuple_) + (length_-addSize)) |= iNullInfo;
1290 } else {
1291 int i=0;
1292 while(i < numFlds_) {
1293 if(cNullInfo[i++]) { nullCharSet = true; break; }
1295 char *null=(char*)(curTuple_) + (length_-addSize);
1296 if (!nullCharSet) {
1297 i=0;
1298 while(i < numFlds_) {
1299 if(null[i]) cNullInfo[i] = null[i];
1300 i++;
1302 } else {
1303 i = 0;
1304 while(i < numFlds_) {
1305 if(cNullInfo[i]) { null[i] |= cNullInfo[i]; }
1306 i++;
1310 DbRetVal rv = copyValuesFromBindBuffer(curTuple_, false);
1311 if (rv != OK && !loadFlag) {
1312 lMgr_->releaseLock(curTuple_);
1313 (*trans)->removeFromHasList(db_, curTuple_);
1314 sysDB_->releaseCheckpointMutex();
1315 return rv;
1317 if (numFlds_ <= 32) {
1318 if (!iNullVal) {
1319 *(int*)((char*)(curTuple_) + (length_-addSize)) = iNullInfo;
1320 iNullInfo=0;
1321 } else iNullInfo=iNullVal;
1322 } else {
1323 int i = 0;
1324 char *null=(char*)(curTuple_) + (length_-addSize);
1325 if (!nullCharSet) {
1326 os::memcpy(null, cNullInfo, addSize);
1327 while (i < numFlds_) cNullInfo[i++] = 0;
1328 } else os::memcpy(cNullInfo, cNullVal, addSize);
1329 free(cNullVal); cNullVal = NULL;
1331 sysDB_->releaseCheckpointMutex();
1332 return OK;
1335 void TableImpl::printInfo()
1337 printf(" <TableName> %s </TableName>\n", tblName_);
1338 printf(" <TupleCount> %d </TupleCount>\n", numTuples());
1339 printf(" <PagesUsed> %d </PagesUsed>\n", pagesUsed());
1340 printf(" <SpaceUsed> %d </SpaceUsed>\n", spaceUsed());
1341 printf(" <Indexes> %d <Indexes>\n", numIndexes_);
1342 printf(" <TupleLength> %d </TupleLength>\n", length_);
1343 printf(" <Fields> %d </Fields>\n", numFlds_);
1344 printf(" <Indexes>\n");
1345 for (int i =0; i<numIndexes_; i++)
1346 printf("<IndexName> %s </IndexName>\n", CatalogTableINDEX::getName(indexPtr_[i]));
1347 printf(" </Indexes>\n");
1350 long long TableImpl::getLastInsertedVal(DbRetVal &rv)
1352 rv=OK;
1353 return *(long long*)ptrToAuto;
1355 DbRetVal TableImpl::copyValuesFromBindBuffer(void *tuplePtr, bool isInsert)
1357 //Iterate through the bind list and copy the value here
1358 FieldIterator fIter = fldList_.getIterator();
1359 char *colPtr = (char*) tuplePtr;
1360 int fldpos=1;
1361 while (fIter.hasElement())
1363 FieldDef *def = fIter.nextElement();
1364 if(def->isAutoIncrement_ && isInsert)
1366 if (OK != takeTableMutex())
1368 printError(ErrLockTimeOut,
1369 " Unable to take table mutex for increment key");
1370 return ErrLockTimeOut;
1372 AllDataType::copyVal(&tempAutoVal,ptrToAuto, def->type_, def->length_);
1373 if(def->bindVal_==NULL)
1375 AllDataType::increment(colPtr, &tempAutoVal , def->type_);
1376 AllDataType::copyVal(ptrToAuto,colPtr, def->type_,
1377 def->length_);
1378 colPtr = colPtr + def->length_;
1379 fldpos++;
1380 }else {
1381 if(AllDataType::compareVal(def->bindVal_, &tempAutoVal,
1382 OpGreaterThan, def->type_))
1384 AllDataType::copyVal(ptrToAuto,def->bindVal_, def->type_,
1385 def->length_);
1387 AllDataType::copyVal(colPtr, def->bindVal_, def->type_,
1388 def->length_);
1389 colPtr = colPtr + def->length_;
1390 fldpos++;
1392 releaseTableMutex();
1393 continue;
1396 if (def->isNull_ && !def->isDefault_ && NULL == def->bindVal_ &&
1397 isInsert)
1399 printError(ErrNullViolation,
1400 "NOT NULL constraint violation for field %s", def->fldName_);
1401 return ErrNullViolation;
1403 if (def->isDefault_ && NULL == def->bindVal_ && isInsert)
1405 if (! def->isNullExplicit_) {
1406 if (def->type_ == typeVarchar) {
1407 DbRetVal rv = OK;
1408 void *ptr =
1409 ((Chunk *) vcChunkPtr_)->allocate(db_, def->length_, &rv);
1410 *(long *)colPtr = (long)ptr;
1411 AllDataType::convert(typeString, def->defaultValueBuf_,
1412 def->type_, ptr, def->length_);
1413 } else {
1414 void *dest = AllDataType::alloc(def->type_, def->length_);
1415 AllDataType::convert(typeString, def->defaultValueBuf_,
1416 def->type_, dest, def->length_);
1417 AllDataType::copyVal(colPtr, dest, def->type_,
1418 def->length_);
1419 free (dest);
1421 } else {
1422 setNullBit(fldpos);
1423 *(long *) colPtr = 0L;
1425 if (def->type_ != typeVarchar) colPtr = colPtr + def->length_;
1426 else colPtr = colPtr + sizeof(void *);
1427 fldpos++;
1428 continue;
1430 switch(def->type_)
1432 case typeString:
1433 if (NULL != def->bindVal_)
1435 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1436 // strncpy((char*)colPtr, (char*)def->bindVal_, def->length_);
1437 // *(((char*)colPtr) + (def->length_-1)) = '\0';
1438 strcpy((char*)colPtr, (char*)def->bindVal_);
1440 else if (!def->isNull_ && isInsert) setNullBit(fldpos);
1441 colPtr = colPtr + def->length_;
1442 break;
1443 case typeBinary:
1444 if (NULL != def->bindVal_ )
1446 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1447 DbRetVal rv = AllDataType::strToValue(colPtr,
1448 (char *) def->bindVal_, def->type_, def->length_);
1449 if (rv != OK) return ErrBadArg;
1450 } else if (!def->isNull_ && isInsert && !def->bindVal_) {
1451 setNullBit(fldpos);
1453 colPtr = colPtr + def->length_;
1454 break;
1455 case typeVarchar:
1456 if (NULL != def->bindVal_) {
1457 if (!isInsert && isFldNull(fldpos)) {clearNullBit(fldpos);}
1458 DbRetVal rv = OK;
1459 if (!isInsert) {
1460 if (*(long *) colPtr != 0L)
1461 ((Chunk *) vcChunkPtr_)->free(db_,
1462 (void *)*(long *)colPtr);
1463 *(long *) colPtr = 0L;
1465 if (strcmp((char *)def->bindVal_,"") != 0) {
1466 void *ptr =
1467 ((Chunk *) vcChunkPtr_)->allocate(db_,
1468 def->length_, &rv);
1469 if (rv != OK) return ErrBadArg;
1470 *(long *)colPtr = (long)ptr;
1471 strcpy((char *)ptr, (char *)def->bindVal_);
1472 } else { setNullBit(fldpos); }
1473 } else if (!def->isNull_ && isInsert) setNullBit(fldpos);
1474 colPtr = colPtr + sizeof(void *);
1475 break;
1476 default:
1477 if (NULL != def->bindVal_) {
1478 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1479 AllDataType::copyVal(colPtr, def->bindVal_, def->type_);
1480 } else { if (!def->isNull_ && isInsert) setNullBit(fldpos); }
1481 colPtr = colPtr + def->length_;
1482 break;
1484 fldpos++;
1486 return OK;
1489 void TableImpl::clearNullBit(int fldpos)
1491 if (fldpos <1 || fldpos > numFlds_) return;
1492 if (isIntUsedForNULL) CLEARBIT(iNullInfo, fldpos-1);
1493 else cNullInfo[fldpos-1] = 0;
1496 void TableImpl::setNullBit(int fldpos)
1498 if (fldpos <1 || fldpos > numFlds_) return;
1499 if (isIntUsedForNULL) SETBIT(iNullInfo, fldpos-1);
1500 else cNullInfo[fldpos-1] = 1;
1503 DbRetVal TableImpl::copyValuesToBindBuffer(void *tuplePtr)
1505 //Iterate through the bind list and copy the value here
1506 char *colPtr = (char*) tuplePtr;
1507 FieldDef *def = NULL;
1508 for (int i = 0; i < numBindFlds_; i++) {
1509 def = (FieldDef *) bindListArray_[i];
1510 colPtr = (char *) tuplePtr + def->offset_;
1511 if (def->type_ != typeVarchar)
1512 AllDataType::copyVal(def->bindVal_, colPtr, def->type_,
1513 def->length_);
1514 else {
1515 char *ptr = (char *) *(long *) colPtr;
1516 if (ptr != NULL) strcpy((char *)def->bindVal_, ptr);
1519 return OK;
1522 //-1 index not supported
1523 DbRetVal TableImpl::insertIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1525 CINDEX *iptr = (CINDEX*)indexPtr;
1526 DbRetVal ret = OK;
1527 printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
1528 Index* idx = Index::getIndex(iptr->indexType_);
1529 ret = idx->insert(this, tr, indexPtr, info, tuple,loadFlag);
1530 return ret;
1533 DbRetVal TableImpl::deleteIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1535 CINDEX *iptr = (CINDEX*)indexPtr;
1536 DbRetVal ret = OK;
1537 Index* idx = Index::getIndex(iptr->indexType_);
1538 ret = idx->remove(this, tr, indexPtr, info, tuple, loadFlag);
1539 return ret;
1541 void TableImpl::printSQLIndexString(FILE *fp, int fd)
1543 if (fp == NULL) fp = stdout;
1544 CatalogTableINDEXFIELD cIndexField(sysDB_);
1545 char fName[IDENTIFIER_LENGTH];
1546 char idxName[IDENTIFIER_LENGTH];
1547 char *fldName = fName;
1548 DataType type;
1549 for (int i = 0; i < numIndexes_ ; i++)
1551 CINDEX *iptr = (CINDEX*) indexPtr_[i];
1552 sprintf(idxName,"%s_idx_Auto_increment",getName());
1553 if(strcmp(iptr->indName_,idxName)==0){ continue; }
1554 if (Conf::config.useDurability()) {
1555 struct Object obj;
1556 strcpy(obj.name, iptr->indName_);
1557 if (iptr->indexType_ == hashIndex) {
1558 obj.type = hIdx;
1559 obj.bucketChunk = ((Chunk *)iptr->chunkPtr_)->getFirstPage();
1560 obj.firstPage = ((Chunk *)iptr->hashNodeChunk_)->getFirstPage();
1561 obj.curPage = ((Chunk *)iptr->hashNodeChunk_)->getCurrentPage();
1562 } else if (iptr->indexType_ == treeIndex) {
1563 obj.type = tIdx;
1564 obj.firstPage = ((Chunk *)iptr->chunkPtr_)->getFirstPage();
1565 obj.curPage = ((Chunk *)iptr->chunkPtr_)->getCurrentPage();
1566 long nodes = ((Chunk *)iptr->chunkPtr_)->getTotalDataNodes();
1567 if(nodes) {
1568 ChunkIterator cIter = ((Chunk *)iptr->chunkPtr_)->getIterator();
1569 obj.bucketChunk = cIter.nextElement();
1570 } else obj.bucketChunk = NULL;
1572 //TODO::Trie
1573 void *buf = &obj;
1574 write(fd, buf, sizeof(obj));
1576 fprintf(fp, "CREATE INDEX %s on %s ( ", iptr->indName_, getName());
1577 FieldList fldList;
1578 cIndexField.getFieldInfo(iptr, fldList);
1579 FieldIterator fIter = fldList.getIterator();
1580 bool firstFld = true;
1581 while(fIter.hasElement())
1583 FieldDef *def = fIter.nextElement();
1584 if (firstFld) { fprintf(fp, " %s ", def->fldName_); firstFld = false; }
1585 else fprintf(fp, " ,%s ", def->fldName_);
1587 fldList.removeAll();
1588 fprintf(fp, " ) ");
1590 if (iptr->indexType_ == hashIndex) fprintf(fp, " HASH ");
1591 else if (iptr->indexType_ == treeIndex) fprintf(fp, " TREE ");
1592 else fprintf(fp, " TRIE ");
1594 HashIndexInfo* hInfo = (HashIndexInfo*)idxInfo[i];
1595 if (hInfo->isUnique) fprintf(fp, " UNIQUE");
1596 if(hInfo->noOfBuckets != 1009 &&
1597 hInfo->noOfBuckets !=0) fprintf(fp, " SIZE %d ",((HashIndexInfo*) idxInfo[i])->noOfBuckets );
1598 fprintf(fp, ";\n");
1603 DbRetVal TableImpl::updateIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1605 CINDEX *iptr = (CINDEX*)indexPtr;
1606 DbRetVal ret = OK;
1607 Index* idx = Index::getIndex(iptr->indexType_);
1608 //TODO::currently it updates irrespective of whether the key changed or not
1609 //because of this commenting the whole index update code. relook at it and uncomment
1611 ret = idx->update(this, tr, indexPtr, info, tuple, loadFlag);
1613 return ret;
1617 void TableImpl::setTableInfo(char *name, int tblid, size_t length,
1618 int numFld, int numIdx, void *chunk, void *vcchunk)
1620 strcpy(tblName_, name);
1621 tblID_ = tblid;
1622 length_ = length;
1623 numFlds_ = numFld;
1624 numIndexes_ = numIdx;
1625 chunkPtr_ = chunk;
1626 vcChunkPtr_ = vcchunk;
1629 long TableImpl::spaceUsed()
1631 Chunk *chk = (Chunk*)chunkPtr_;
1632 long totSize = chk->getTotalDataNodes() * chk->getSize();
1633 totSize = totSize + (chk->totalPages() * sizeof (PageInfo));
1634 return totSize;
1637 int TableImpl::pagesUsed()
1639 Chunk *chk = (Chunk*)chunkPtr_;
1640 return chk->totalPages();
1643 long TableImpl::numTuples()
1645 return ((Chunk*)chunkPtr_)->getTotalDataNodes();
1648 List TableImpl::getFieldNameList()
1650 List fldNameList;
1651 FieldIterator fIter = fldList_.getIterator();
1652 char fieldName[IDENTIFIER_LENGTH];
1653 while (fIter.hasElement())
1655 FieldDef *def = fIter.nextElement();
1656 Identifier *elem = new Identifier();
1657 Table::getFieldNameAlone(def->fldName_, fieldName);
1658 sprintf(elem->name, "%s.%s", getName(), fieldName);
1659 fldNameList.append(elem);
1661 return fldNameList;
1663 DbRetVal TableImpl::close()
1665 if (iter) { iter->close(); delete iter; iter = NULL; }
1666 TableImpl *fkTbl =NULL;
1667 ListIterator tblIter = tblList.getIterator();
1668 tblIter.reset();
1669 while (tblIter.hasElement()){
1670 fkTbl = (TableImpl *) tblIter.nextElement();
1671 fkTbl->close();
1673 tblList.reset();
1674 tblIter = tblFkList.getIterator();
1675 tblIter.reset();
1676 while (tblIter.hasElement()){
1677 fkTbl = (TableImpl *) tblIter.nextElement();
1678 fkTbl->close();
1680 tblFkList.reset();
1681 printDebug(DM_Database,"Closing table handle: %x", this);
1682 //table->unlock();
1683 //delete pred_;
1684 ListIterator pIter = predList.getIterator();
1685 while (pIter.hasElement())
1687 PredicateImpl *pImpl = (PredicateImpl*) pIter.nextElement();
1688 delete pImpl;
1690 predList.reset();
1691 delete this;
1692 logFinest(Conf::logger, "Closing Table");
1693 return OK;
1696 DbRetVal TableImpl::closeScan()
1698 //do not throw scan not open error
1699 //this function will be called by table handle
1700 if (iter) {
1701 iter->close();
1703 return OK;
1705 DbRetVal TableImpl::takeTableMutex()
1707 struct timeval timeout, timeval;
1708 timeout.tv_sec = Conf::config.getMutexSecs();
1709 timeout.tv_usec = Conf::config.getMutexUSecs();
1710 int tries=0;
1711 int totalTries = Conf::config.getMutexRetries() *2;
1712 int ret =0;
1713 while (tries < totalTries)
1715 ret = sysDB_->getAllocDatabaseMutex();
1716 if (ret == 0) break;
1717 timeval.tv_sec = timeout.tv_sec;
1718 timeval.tv_usec = timeout.tv_usec;
1719 os::select(0, 0, 0, 0, &timeval);
1720 tries++;
1722 if (tries >= totalTries) return ErrLockTimeOut;
1723 return OK;
1725 DbRetVal TableImpl::releaseTableMutex()
1727 sysDB_->releaseAllocDatabaseMutex();
1728 return OK;
1731 DbRetVal TableImpl::lock(bool shared)
1734 DbRetVal ret = OK;
1736 if (shared)
1737 ret = lMgr_->getSharedLock(chunkPtr_, NULL);
1738 else
1739 ret = lMgr_->getExclusiveLock(chunkPtr_, NULL);
1740 if (OK != ret)
1742 printError(ret, "Could not exclusive lock on the table %x", chunkPtr_);
1743 }else {
1744 //do not append for S to X upgrade
1745 if (!ProcessManager::hasLockList.exists(chunkPtr_))
1746 ProcessManager::hasLockList.append(chunkPtr_);
1749 return ret;
1751 DbRetVal TableImpl::unlock()
1754 if (!ProcessManager::hasLockList.exists(chunkPtr_)) return OK;
1755 DbRetVal ret = lMgr_->releaseLock(chunkPtr_);
1756 if (OK != ret)
1758 printError(ret, "Could not release exclusive lock on the table %x", chunkPtr_);
1759 }else
1761 ProcessManager::hasLockList.remove(chunkPtr_);
1764 return OK;
1767 TableImpl::~TableImpl()
1769 if (NULL != iter ) { delete iter; iter = NULL; }
1770 if (NULL != indexPtr_) { delete[] indexPtr_; indexPtr_ = NULL; }
1771 if (NULL != idxInfo)
1773 for (int i = 0; i < numIndexes_; i++) delete idxInfo[i];
1774 delete[] idxInfo;
1775 idxInfo = NULL;
1777 if (numFlds_ > 32 && cNullInfo != NULL) {
1778 free(cNullInfo); cNullInfo = NULL;
1780 if (bindList_.size()) bindList_.reset();
1781 if (bindListArray_) { free (bindListArray_); bindListArray_ = NULL; }
1782 fldList_.removeAll();
1786 void *TableImpl::getBindFldAddr(const char *name)
1788 return fldList_.getBindField(name);
1790 bool TableImpl::isTableInvolved(char *tblName)
1792 //printf("Table isTableInvolved called for %s with %s\n", tblName, getName());
1793 if (0 == strcmp(getName(), tblName)) return true; else return false;
1795 bool TableImpl::pushPredicate(Predicate *pred)
1797 bool ret = false;
1798 PredicateImpl *pImpl = (PredicateImpl*) pred;
1799 char tableName[IDENTIFIER_LENGTH];
1800 Table::getTableNameAlone(pImpl->getFldName1(), tableName);
1801 //printf("predicate tbl name %s\n", tableName);
1803 //if predicate is of form t1.f1=t2.f1 then do not push here
1804 bool isAliasSet = (0 !=strcmp(getAliasName(),"")) ;
1805 if (0 != strcmp(pImpl->getFldName2(),"")) return ret;
1807 if (0 == strcmp(getName(), tableName) ||(isAliasSet && 0 == strcmp(getAliasName(), tableName)))
1809 setPredicate(pred);
1810 //printf("PRABA::pushed predicate in tablehdl %s\n", getName());
1811 ret = true;
1813 return ret;
1816 void TableImpl::setCondition(Condition *p)
1818 isPlanCreated = false;
1819 ListIterator pIter = predList.getIterator();
1820 while (pIter.hasElement())
1822 PredicateImpl *pImpl = (PredicateImpl*) pIter.nextElement();
1823 delete pImpl;
1825 predList.reset();
1827 if (p) pred_ = p->getPredicate(); else pred_ = NULL;
1830 void TableImpl::setPredicate(Predicate *pred)
1832 if (NULL == pred_) { pred_ = pred; return; }
1834 Predicate *curPred = pred_;
1835 PredicateImpl *newPred = new PredicateImpl();
1836 newPred->setTerm(curPred, OpAnd, pred);
1837 newPred->setTable(this);
1838 pred_ = newPred;
1839 return;
1841 void TableImpl::printPlan(int space)
1843 char spaceBuf[IDENTIFIER_LENGTH];
1844 memset(spaceBuf, 32, IDENTIFIER_LENGTH);
1845 spaceBuf[space] = '\0';
1846 printf("%s <TABLE-NODE>\n", spaceBuf);
1847 printf("%s <NAME> %s </NAME>\n", spaceBuf, getName());
1848 printf("%s <ScanType> %s </ScanType>\n", spaceBuf, ScanTypeNames[scanType_]);
1849 PredicateImpl *pred = (PredicateImpl*)pred_;
1850 if (pred) pred->print(space+2);
1851 printf("%s </TABLE-NODE>\n", spaceBuf);
1853 void TableImpl::printSQLForeignString()
1855 DbRetVal rv=OK;
1856 FieldNameList pkFieldList,fkFieldList;
1857 void *tPkptr =NULL;
1858 void *tFkptr = NULL;
1859 void *chunkPk = NULL;
1860 void *vcchunkPk = NULL;
1861 CatalogTableTABLE cTable(sysDB_);
1862 TableImpl *fkTbl =NULL;
1863 ListIterator tblIter = tblList.getIterator();
1864 tblIter.reset();
1865 int firstFK=true;
1866 while (tblIter.hasElement()){
1867 fkTbl = (TableImpl *) tblIter.nextElement();
1868 rv = cTable.getChunkAndTblPtr(fkTbl->getName(), chunkPk, tPkptr,vcchunkPk);
1869 if ( OK != rv){return ;}
1870 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tFkptr, vcchunkPk);
1871 if ( OK != rv){return ;}
1872 CatalogTableFK cFk(sysDB_);
1873 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
1874 if ( OK != rv){return;}
1875 pkFieldList.resetIter();
1876 fkFieldList.resetIter();
1877 char *fldName = NULL;
1878 bool firstField=true;
1879 if(!firstFK) printf(", ");
1880 printf(", FOREIGN KEY ( ");
1881 while((fldName = fkFieldList.nextFieldName())!= NULL)
1883 if (firstField) {
1884 printf("%s",fldName);
1885 firstField=false;
1887 else
1888 printf(",%s",fldName);
1890 printf(" ) REFERENCES %s ( ",fkTbl->getName());
1891 firstField=true;
1892 while((fldName = pkFieldList.nextFieldName())!= NULL)
1894 if (firstField) {
1895 printf("%s",fldName);
1896 firstField=false;
1898 else
1899 printf(",%s",fldName);
1901 printf(" )");
1902 firstFK=true;
1903 pkFieldList.removeAll();
1904 fkFieldList.removeAll();
1906 return;
1908 bool TableImpl::isPkTableHasRecord(char *pkTableName, TableImpl *fkTbl,bool isInsert)
1910 DbRetVal rv=OK;
1911 bool isRecExist=false;
1912 FieldNameList pkFieldList,fkFieldList;
1913 void *tPkptr =NULL;
1914 void *tFkptr = NULL;
1915 void *chunkPk = NULL;
1916 void *vcchunkPk = NULL;
1917 CatalogTableTABLE cTable(sysDB_);
1918 rv = cTable.getChunkAndTblPtr(pkTableName, chunkPk, tPkptr, vcchunkPk);
1919 if ( OK != rv){return false;}
1920 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tFkptr, vcchunkPk);
1921 if ( OK != rv){return false;}
1922 CatalogTableFK cFk(sysDB_);
1923 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
1924 if ( OK != rv){return false;}
1925 int totFld = pkFieldList.size();
1926 Condition *condition = new Condition[totFld];
1927 char *pkFldName = NULL;
1928 char *fkFldName = NULL;
1929 FieldDef *def=NULL;
1930 int i=0;
1931 pkFieldList.resetIter();
1932 fkFieldList.resetIter();
1933 void *val=NULL;
1934 while((pkFldName = pkFieldList.nextFieldName())!= NULL)
1936 fkFldName = fkFieldList.nextFieldName();
1937 FieldIterator fIter = fldList_.getIterator();
1938 while (fIter.hasElement())
1940 def = fIter.nextElement();
1941 if (strcmp(def->fldName_, fkFldName) == 0)
1943 if(NULL == def->bindVal_ && isInsert) { return true; }
1944 if(NULL == def->bindVal_) {
1945 if (def->type_ != typeVarchar)
1946 val = (char*)curTuple_+ def->offset_;
1947 else val = (void *) *(long *) ((char*)curTuple_+
1948 def->offset_);
1949 } else {
1950 val = def->bindVal_;
1952 if(def->type_==typeString)
1953 condition[i].setTerm(pkFldName,OpEquals,&val);
1954 else
1955 condition[i].setTerm(pkFldName,OpEquals,val);
1956 i++;
1957 break;
1961 pkFieldList.removeAll();
1962 fkFieldList.removeAll();
1963 Condition *cond = NULL;
1964 if(i == 0 && !isInsert)return true;
1965 if( i > 1){
1966 cond = new Condition[i-1];
1967 int totcon = i;
1968 i=0;
1969 int j=0;
1970 for(j=0;j<totcon-1;j++)
1972 if(j==0)
1973 cond[j].setTerm(condition[i++].getPredicate(),OpAnd,condition[i++].getPredicate());
1974 else
1975 cond[j].setTerm(cond[j-1].getPredicate(), OpAnd, condition[i++].getPredicate());
1977 fkTbl->setCondition(&cond[j-1]);
1979 else{
1980 fkTbl->setCondition(&condition[i-1]);
1982 fkTbl->execute();
1983 if(fkTbl->fetch()){
1984 fkTbl->closeScan();
1985 delete[] cond;
1986 delete[] condition;
1987 return true;
1989 delete[] cond;
1990 delete[] condition;
1991 return false;
1994 bool TableImpl::isFkTableHasRecord(char *pkTableName, TableImpl *fkTbl)
1996 DbRetVal rv=OK;
1997 FieldNameList pkFieldList,fkFieldList;
1998 void *tPkptr =NULL;
1999 void *tFkptr = NULL;
2000 void *chunkPk = NULL;
2001 void *vcchunkPk = NULL;
2002 CatalogTableTABLE cTable(sysDB_);
2003 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tPkptr, vcchunkPk);
2004 if ( OK != rv){return false;}
2005 rv = cTable.getChunkAndTblPtr(pkTableName, chunkPk, tFkptr, vcchunkPk);
2006 if ( OK != rv){return false;}
2007 CatalogTableFK cFk(sysDB_);
2008 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
2009 if ( OK != rv){return false;}
2010 int totFld = pkFieldList.size();
2011 Condition *condition = new Condition[totFld];
2012 char *pkFldName = NULL;
2013 char *fkFldName = NULL;
2014 FieldDef *def=NULL;
2015 int i=0;
2016 pkFieldList.resetIter();
2017 fkFieldList.resetIter();
2018 while((pkFldName = pkFieldList.nextFieldName())!= NULL)
2020 fkFldName = fkFieldList.nextFieldName();
2021 FieldIterator fIter = fldList_.getIterator();
2022 while (fIter.hasElement())
2024 def = fIter.nextElement();
2025 void *val = NULL;
2026 if (def->type_ != typeVarchar)
2027 val = (char*)curTuple_+ def->offset_;
2028 else val = (void *) *(long *) ((char*)curTuple_+ def->offset_);
2029 if (strcmp(def->fldName_, pkFldName) == 0)
2031 if(def->type_==typeString)
2032 condition[i].setTerm(fkFldName,OpEquals,&val);//((char*)curTuple_+def->offset_));
2033 else
2034 condition[i].setTerm(fkFldName,OpEquals,val);//((char*)curTuple_+def->offset_));
2035 i++;
2036 break;
2040 pkFieldList.removeAll();
2041 fkFieldList.removeAll();
2042 if(i == 0 )return true;
2043 Condition *cond = new Condition[i-1];
2044 i=0;
2045 int j=0;
2046 for(j=0;j<totFld-1;j++)
2048 if(j==0)
2049 cond[j].setTerm(condition[i++].getPredicate(),OpAnd,condition[i++].getPredicate());
2050 else
2051 cond[j].setTerm(cond[j-1].getPredicate(), OpAnd, condition[i++].getPredicate());
2053 if(totFld==1)
2054 fkTbl->setCondition(&condition[totFld-1]);
2055 else
2056 fkTbl->setCondition(&cond[j-1]);
2057 fkTbl->execute();
2058 if(fkTbl->fetch()){
2059 fkTbl->closeScan();
2060 delete[] cond;
2061 delete[] condition;
2062 return true;
2064 delete[] cond;
2065 delete[] condition;
2066 return false;
2068 DbRetVal TableImpl::compact()
2070 DbRetVal rv=OK;
2071 int ret =((Chunk*)chunkPtr_)->compact(db_->procSlot);
2072 if(ret!=0) return ErrLockTimeOut;
2074 if (NULL != vcChunkPtr_) {
2075 ret = ((Chunk*)vcChunkPtr_)->compact(db_->procSlot);
2076 if(ret!=0) return ErrLockTimeOut;
2079 if (NULL != indexPtr_)
2081 int i;
2082 //it has index
2083 for (i = 0; i < numIndexes_ ; i++)
2085 rv = compactIndexNode(indexPtr_[i]);
2086 if (rv != OK) {
2087 printError(rv, "Error in compacting index Node");
2088 break;
2092 return rv;
2095 DbRetVal TableImpl::compactIndexNode( void *indexPtr)
2097 CINDEX *iptr = (CINDEX*)indexPtr;
2098 int ret1=0;
2099 printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
2100 if( hashIndex == (iptr->indexType_) )
2102 ret1 =((Chunk*)iptr->hashNodeChunk_)->compact(db_->procSlot);
2103 if(ret1!=0){
2104 return ErrLockTimeOut;
2106 }else if (treeIndex == (iptr->indexType_))
2108 ret1 =((Chunk*)iptr->chunkPtr_)->compact(db_->procSlot);
2109 if(ret1!=0){
2110 return ErrLockTimeOut;
2112 } else if ( trieIndex == (iptr->indexType_))
2114 ret1 =((Chunk*)iptr->chunkPtr_)->compact(db_->procSlot);
2115 if(ret1!=0){
2116 return ErrLockTimeOut;
2118 ret1 =((Chunk*)iptr->hashNodeChunk_)->compact(db_->procSlot);
2119 if(ret1!=0){
2120 return ErrLockTimeOut;
2123 return OK;