windows changes
[csql.git] / src / storage / TableImpl.cxx
blob360f15bd535ef75744c1230c9c3d41cb0a94fe0b
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, OpGreaterThan,
1382 def->type_)) {
1383 AllDataType::copyVal(ptrToAuto,def->bindVal_, def->type_,
1384 def->length_);
1387 releaseTableMutex();
1388 continue;
1391 if (def->isNull_ && !def->isDefault_ && NULL == def->bindVal_ &&
1392 isInsert)
1394 printError(ErrNullViolation,
1395 "NOT NULL constraint violation for field %s", def->fldName_);
1396 return ErrNullViolation;
1398 if (def->isDefault_ && NULL == def->bindVal_ && isInsert)
1400 if (! def->isNullExplicit_) {
1401 if (def->type_ == typeVarchar) {
1402 DbRetVal rv = OK;
1403 void *ptr =
1404 ((Chunk *) vcChunkPtr_)->allocate(db_, def->length_, &rv);
1405 *(long *)colPtr = (long)ptr;
1406 AllDataType::convert(typeString, def->defaultValueBuf_,
1407 def->type_, ptr, def->length_);
1408 } else {
1409 void *dest = AllDataType::alloc(def->type_, def->length_);
1410 AllDataType::convert(typeString, def->defaultValueBuf_,
1411 def->type_, dest, def->length_);
1412 AllDataType::copyVal(colPtr, dest, def->type_,
1413 def->length_);
1414 free (dest);
1416 } else {
1417 setNullBit(fldpos);
1418 *(long *) colPtr = 0L;
1420 if (def->type_ != typeVarchar) colPtr = colPtr + def->length_;
1421 else colPtr = colPtr + sizeof(void *);
1422 fldpos++;
1423 continue;
1425 switch(def->type_)
1427 case typeString:
1428 if (NULL != def->bindVal_)
1430 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1431 // strncpy((char*)colPtr, (char*)def->bindVal_, def->length_);
1432 // *(((char*)colPtr) + (def->length_-1)) = '\0';
1433 strcpy((char*)colPtr, (char*)def->bindVal_);
1435 else if (!def->isNull_ && isInsert) setNullBit(fldpos);
1436 colPtr = colPtr + def->length_;
1437 break;
1438 case typeBinary:
1439 if (NULL != def->bindVal_ )
1441 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1442 DbRetVal rv = AllDataType::strToValue(colPtr,
1443 (char *) def->bindVal_, def->type_, def->length_);
1444 if (rv != OK) return ErrBadArg;
1445 } else if (!def->isNull_ && isInsert && !def->bindVal_) {
1446 setNullBit(fldpos);
1448 colPtr = colPtr + def->length_;
1449 break;
1450 case typeVarchar:
1451 if (NULL != def->bindVal_) {
1452 if (!isInsert && isFldNull(fldpos)) {clearNullBit(fldpos);}
1453 DbRetVal rv = OK;
1454 if (!isInsert) {
1455 if (*(long *) colPtr != 0L)
1456 ((Chunk *) vcChunkPtr_)->free(db_,
1457 (void *)*(long *)colPtr);
1458 *(long *) colPtr = 0L;
1460 if (strcmp((char *)def->bindVal_,"") != 0) {
1461 void *ptr =
1462 ((Chunk *) vcChunkPtr_)->allocate(db_,
1463 def->length_, &rv);
1464 if (rv != OK) return ErrBadArg;
1465 *(long *)colPtr = (long)ptr;
1466 strcpy((char *)ptr, (char *)def->bindVal_);
1467 } else { setNullBit(fldpos); }
1468 } else if (!def->isNull_ && isInsert) setNullBit(fldpos);
1469 colPtr = colPtr + sizeof(void *);
1470 break;
1471 default:
1472 if (NULL != def->bindVal_) {
1473 if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);}
1474 AllDataType::copyVal(colPtr, def->bindVal_, def->type_);
1475 } else { if (!def->isNull_ && isInsert) setNullBit(fldpos); }
1476 colPtr = colPtr + def->length_;
1477 break;
1479 fldpos++;
1481 return OK;
1484 void TableImpl::clearNullBit(int fldpos)
1486 if (fldpos <1 || fldpos > numFlds_) return;
1487 if (isIntUsedForNULL) CLEARBIT(iNullInfo, fldpos-1);
1488 else cNullInfo[fldpos-1] = 0;
1491 void TableImpl::setNullBit(int fldpos)
1493 if (fldpos <1 || fldpos > numFlds_) return;
1494 if (isIntUsedForNULL) SETBIT(iNullInfo, fldpos-1);
1495 else cNullInfo[fldpos-1] = 1;
1498 DbRetVal TableImpl::copyValuesToBindBuffer(void *tuplePtr)
1500 //Iterate through the bind list and copy the value here
1501 char *colPtr = (char*) tuplePtr;
1502 FieldDef *def = NULL;
1503 for (int i = 0; i < numBindFlds_; i++) {
1504 def = (FieldDef *) bindListArray_[i];
1505 colPtr = (char *) tuplePtr + def->offset_;
1506 if (def->type_ != typeVarchar)
1507 AllDataType::copyVal(def->bindVal_, colPtr, def->type_,
1508 def->length_);
1509 else {
1510 char *ptr = (char *) *(long *) colPtr;
1511 if (ptr != NULL) strcpy((char *)def->bindVal_, ptr);
1514 return OK;
1517 //-1 index not supported
1518 DbRetVal TableImpl::insertIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1520 CINDEX *iptr = (CINDEX*)indexPtr;
1521 DbRetVal ret = OK;
1522 printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
1523 Index* idx = Index::getIndex(iptr->indexType_);
1524 ret = idx->insert(this, tr, indexPtr, info, tuple,loadFlag);
1525 return ret;
1528 DbRetVal TableImpl::deleteIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1530 CINDEX *iptr = (CINDEX*)indexPtr;
1531 DbRetVal ret = OK;
1532 Index* idx = Index::getIndex(iptr->indexType_);
1533 ret = idx->remove(this, tr, indexPtr, info, tuple, loadFlag);
1534 return ret;
1536 void TableImpl::printSQLIndexString(FILE *fp, int fd)
1538 if (fp == NULL) fp = stdout;
1539 CatalogTableINDEXFIELD cIndexField(sysDB_);
1540 char fName[IDENTIFIER_LENGTH];
1541 char idxName[IDENTIFIER_LENGTH];
1542 char *fldName = fName;
1543 DataType type;
1544 for (int i = 0; i < numIndexes_ ; i++)
1546 CINDEX *iptr = (CINDEX*) indexPtr_[i];
1547 sprintf(idxName,"%s_idx_Auto_increment",getName());
1548 if(strcmp(iptr->indName_,idxName)==0){ continue; }
1549 if (Conf::config.useDurability()) {
1550 struct Object obj;
1551 strcpy(obj.name, iptr->indName_);
1552 if (iptr->indexType_ == hashIndex) {
1553 obj.type = hIdx;
1554 obj.bucketChunk = ((Chunk *)iptr->chunkPtr_)->getFirstPage();
1555 obj.firstPage = ((Chunk *)iptr->hashNodeChunk_)->getFirstPage();
1556 obj.curPage = ((Chunk *)iptr->hashNodeChunk_)->getCurrentPage();
1557 } else if (iptr->indexType_ == treeIndex) {
1558 obj.type = tIdx;
1559 obj.firstPage = ((Chunk *)iptr->chunkPtr_)->getFirstPage();
1560 obj.curPage = ((Chunk *)iptr->chunkPtr_)->getCurrentPage();
1561 long nodes = ((Chunk *)iptr->chunkPtr_)->getTotalDataNodes();
1562 if(nodes) {
1563 ChunkIterator cIter = ((Chunk *)iptr->chunkPtr_)->getIterator();
1564 obj.bucketChunk = cIter.nextElement();
1565 } else obj.bucketChunk = NULL;
1567 //TODO::Trie
1568 void *buf = &obj;
1569 write(fd, buf, sizeof(obj));
1571 fprintf(fp, "CREATE INDEX %s on %s ( ", iptr->indName_, getName());
1572 FieldList fldList;
1573 cIndexField.getFieldInfo(iptr, fldList);
1574 FieldIterator fIter = fldList.getIterator();
1575 bool firstFld = true;
1576 while(fIter.hasElement())
1578 FieldDef *def = fIter.nextElement();
1579 if (firstFld) { fprintf(fp, " %s ", def->fldName_); firstFld = false; }
1580 else fprintf(fp, " ,%s ", def->fldName_);
1582 fldList.removeAll();
1583 fprintf(fp, " ) ");
1585 if (iptr->indexType_ == hashIndex) fprintf(fp, " HASH ");
1586 else if (iptr->indexType_ == treeIndex) fprintf(fp, " TREE ");
1587 else fprintf(fp, " TRIE ");
1589 HashIndexInfo* hInfo = (HashIndexInfo*)idxInfo[i];
1590 if (hInfo->isUnique) fprintf(fp, " UNIQUE");
1591 if(hInfo->noOfBuckets != 1009 &&
1592 hInfo->noOfBuckets !=0) fprintf(fp, " SIZE %d ",((HashIndexInfo*) idxInfo[i])->noOfBuckets );
1593 fprintf(fp, ";\n");
1598 DbRetVal TableImpl::updateIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
1600 CINDEX *iptr = (CINDEX*)indexPtr;
1601 DbRetVal ret = OK;
1602 Index* idx = Index::getIndex(iptr->indexType_);
1603 //TODO::currently it updates irrespective of whether the key changed or not
1604 //because of this commenting the whole index update code. relook at it and uncomment
1606 ret = idx->update(this, tr, indexPtr, info, tuple, loadFlag);
1608 return ret;
1612 void TableImpl::setTableInfo(char *name, int tblid, size_t length,
1613 int numFld, int numIdx, void *chunk, void *vcchunk)
1615 strcpy(tblName_, name);
1616 tblID_ = tblid;
1617 length_ = length;
1618 numFlds_ = numFld;
1619 numIndexes_ = numIdx;
1620 chunkPtr_ = chunk;
1621 vcChunkPtr_ = vcchunk;
1624 long TableImpl::spaceUsed()
1626 Chunk *chk = (Chunk*)chunkPtr_;
1627 long totSize = chk->getTotalDataNodes() * chk->getSize();
1628 totSize = totSize + (chk->totalPages() * sizeof (PageInfo));
1629 return totSize;
1632 int TableImpl::pagesUsed()
1634 Chunk *chk = (Chunk*)chunkPtr_;
1635 return chk->totalPages();
1638 long TableImpl::numTuples()
1640 return ((Chunk*)chunkPtr_)->getTotalDataNodes();
1643 List TableImpl::getFieldNameList()
1645 List fldNameList;
1646 FieldIterator fIter = fldList_.getIterator();
1647 char fieldName[IDENTIFIER_LENGTH];
1648 while (fIter.hasElement())
1650 FieldDef *def = fIter.nextElement();
1651 Identifier *elem = new Identifier();
1652 Table::getFieldNameAlone(def->fldName_, fieldName);
1653 sprintf(elem->name, "%s.%s", getName(), fieldName);
1654 fldNameList.append(elem);
1656 return fldNameList;
1658 DbRetVal TableImpl::close()
1660 if (iter) { iter->close(); delete iter; iter = NULL; }
1661 TableImpl *fkTbl =NULL;
1662 ListIterator tblIter = tblList.getIterator();
1663 tblIter.reset();
1664 while (tblIter.hasElement()){
1665 fkTbl = (TableImpl *) tblIter.nextElement();
1666 fkTbl->close();
1668 tblList.reset();
1669 tblIter = tblFkList.getIterator();
1670 tblIter.reset();
1671 while (tblIter.hasElement()){
1672 fkTbl = (TableImpl *) tblIter.nextElement();
1673 fkTbl->close();
1675 tblFkList.reset();
1676 printDebug(DM_Database,"Closing table handle: %x", this);
1677 //table->unlock();
1678 //delete pred_;
1679 ListIterator pIter = predList.getIterator();
1680 while (pIter.hasElement())
1682 PredicateImpl *pImpl = (PredicateImpl*) pIter.nextElement();
1683 delete pImpl;
1685 predList.reset();
1686 delete this;
1687 logFinest(Conf::logger, "Closing Table");
1688 return OK;
1691 DbRetVal TableImpl::closeScan()
1693 //do not throw scan not open error
1694 //this function will be called by table handle
1695 if (iter) {
1696 iter->close();
1698 return OK;
1700 DbRetVal TableImpl::takeTableMutex()
1702 struct timeval timeout, timeval;
1703 timeout.tv_sec = Conf::config.getMutexSecs();
1704 timeout.tv_usec = Conf::config.getMutexUSecs();
1705 int tries=0;
1706 int totalTries = Conf::config.getMutexRetries() *2;
1707 int ret =0;
1708 while (tries < totalTries)
1710 ret = sysDB_->getAllocDatabaseMutex();
1711 if (ret == 0) break;
1712 timeval.tv_sec = timeout.tv_sec;
1713 timeval.tv_usec = timeout.tv_usec;
1714 os::select(0, 0, 0, 0, &timeval);
1715 tries++;
1717 if (tries >= totalTries) return ErrLockTimeOut;
1718 return OK;
1720 DbRetVal TableImpl::releaseTableMutex()
1722 sysDB_->releaseAllocDatabaseMutex();
1723 return OK;
1726 DbRetVal TableImpl::lock(bool shared)
1729 DbRetVal ret = OK;
1731 if (shared)
1732 ret = lMgr_->getSharedLock(chunkPtr_, NULL);
1733 else
1734 ret = lMgr_->getExclusiveLock(chunkPtr_, NULL);
1735 if (OK != ret)
1737 printError(ret, "Could not exclusive lock on the table %x", chunkPtr_);
1738 }else {
1739 //do not append for S to X upgrade
1740 if (!ProcessManager::hasLockList.exists(chunkPtr_))
1741 ProcessManager::hasLockList.append(chunkPtr_);
1744 return ret;
1746 DbRetVal TableImpl::unlock()
1749 if (!ProcessManager::hasLockList.exists(chunkPtr_)) return OK;
1750 DbRetVal ret = lMgr_->releaseLock(chunkPtr_);
1751 if (OK != ret)
1753 printError(ret, "Could not release exclusive lock on the table %x", chunkPtr_);
1754 }else
1756 ProcessManager::hasLockList.remove(chunkPtr_);
1759 return OK;
1762 TableImpl::~TableImpl()
1764 if (NULL != iter ) { delete iter; iter = NULL; }
1765 if (NULL != indexPtr_) { delete[] indexPtr_; indexPtr_ = NULL; }
1766 if (NULL != idxInfo)
1768 for (int i = 0; i < numIndexes_; i++) delete idxInfo[i];
1769 delete[] idxInfo;
1770 idxInfo = NULL;
1772 if (numFlds_ > 32 && cNullInfo != NULL) {
1773 free(cNullInfo); cNullInfo = NULL;
1775 if (bindList_.size()) bindList_.reset();
1776 if (bindListArray_) { free (bindListArray_); bindListArray_ = NULL; }
1777 fldList_.removeAll();
1781 void *TableImpl::getBindFldAddr(const char *name)
1783 return fldList_.getBindField(name);
1785 bool TableImpl::isTableInvolved(char *tblName)
1787 //printf("Table isTableInvolved called for %s with %s\n", tblName, getName());
1788 if (0 == strcmp(getName(), tblName)) return true; else return false;
1790 bool TableImpl::pushPredicate(Predicate *pred)
1792 bool ret = false;
1793 PredicateImpl *pImpl = (PredicateImpl*) pred;
1794 char tableName[IDENTIFIER_LENGTH];
1795 Table::getTableNameAlone(pImpl->getFldName1(), tableName);
1796 //printf("predicate tbl name %s\n", tableName);
1798 //if predicate is of form t1.f1=t2.f1 then do not push here
1799 bool isAliasSet = (0 !=strcmp(getAliasName(),"")) ;
1800 if (0 != strcmp(pImpl->getFldName2(),"")) return ret;
1802 if (0 == strcmp(getName(), tableName) ||(isAliasSet && 0 == strcmp(getAliasName(), tableName)))
1804 setPredicate(pred);
1805 //printf("PRABA::pushed predicate in tablehdl %s\n", getName());
1806 ret = true;
1808 return ret;
1811 void TableImpl::setCondition(Condition *p)
1813 isPlanCreated = false;
1814 ListIterator pIter = predList.getIterator();
1815 while (pIter.hasElement())
1817 PredicateImpl *pImpl = (PredicateImpl*) pIter.nextElement();
1818 delete pImpl;
1820 predList.reset();
1822 if (p) pred_ = p->getPredicate(); else pred_ = NULL;
1825 void TableImpl::setPredicate(Predicate *pred)
1827 if (NULL == pred_) { pred_ = pred; return; }
1829 Predicate *curPred = pred_;
1830 PredicateImpl *newPred = new PredicateImpl();
1831 newPred->setTerm(curPred, OpAnd, pred);
1832 newPred->setTable(this);
1833 pred_ = newPred;
1834 return;
1836 void TableImpl::printPlan(int space)
1838 char spaceBuf[IDENTIFIER_LENGTH];
1839 memset(spaceBuf, 32, IDENTIFIER_LENGTH);
1840 spaceBuf[space] = '\0';
1841 printf("%s <TABLE-NODE>\n", spaceBuf);
1842 printf("%s <NAME> %s </NAME>\n", spaceBuf, getName());
1843 printf("%s <ScanType> %s </ScanType>\n", spaceBuf, ScanTypeNames[scanType_]);
1844 PredicateImpl *pred = (PredicateImpl*)pred_;
1845 if (pred) pred->print(space+2);
1846 printf("%s </TABLE-NODE>\n", spaceBuf);
1848 void TableImpl::printSQLForeignString()
1850 DbRetVal rv=OK;
1851 FieldNameList pkFieldList,fkFieldList;
1852 void *tPkptr =NULL;
1853 void *tFkptr = NULL;
1854 void *chunkPk = NULL;
1855 void *vcchunkPk = NULL;
1856 CatalogTableTABLE cTable(sysDB_);
1857 TableImpl *fkTbl =NULL;
1858 ListIterator tblIter = tblList.getIterator();
1859 tblIter.reset();
1860 int firstFK=true;
1861 while (tblIter.hasElement()){
1862 fkTbl = (TableImpl *) tblIter.nextElement();
1863 rv = cTable.getChunkAndTblPtr(fkTbl->getName(), chunkPk, tPkptr,vcchunkPk);
1864 if ( OK != rv){return ;}
1865 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tFkptr, vcchunkPk);
1866 if ( OK != rv){return ;}
1867 CatalogTableFK cFk(sysDB_);
1868 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
1869 if ( OK != rv){return;}
1870 pkFieldList.resetIter();
1871 fkFieldList.resetIter();
1872 char *fldName = NULL;
1873 bool firstField=true;
1874 if(!firstFK) printf(", ");
1875 printf(", FOREIGN KEY ( ");
1876 while((fldName = fkFieldList.nextFieldName())!= NULL)
1878 if (firstField) {
1879 printf("%s",fldName);
1880 firstField=false;
1882 else
1883 printf(",%s",fldName);
1885 printf(" ) REFERENCES %s ( ",fkTbl->getName());
1886 firstField=true;
1887 while((fldName = pkFieldList.nextFieldName())!= NULL)
1889 if (firstField) {
1890 printf("%s",fldName);
1891 firstField=false;
1893 else
1894 printf(",%s",fldName);
1896 printf(" )");
1897 firstFK=true;
1898 pkFieldList.removeAll();
1899 fkFieldList.removeAll();
1901 return;
1903 bool TableImpl::isPkTableHasRecord(char *pkTableName, TableImpl *fkTbl,bool isInsert)
1905 DbRetVal rv=OK;
1906 bool isRecExist=false;
1907 FieldNameList pkFieldList,fkFieldList;
1908 void *tPkptr =NULL;
1909 void *tFkptr = NULL;
1910 void *chunkPk = NULL;
1911 void *vcchunkPk = NULL;
1912 CatalogTableTABLE cTable(sysDB_);
1913 rv = cTable.getChunkAndTblPtr(pkTableName, chunkPk, tPkptr, vcchunkPk);
1914 if ( OK != rv){return false;}
1915 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tFkptr, vcchunkPk);
1916 if ( OK != rv){return false;}
1917 CatalogTableFK cFk(sysDB_);
1918 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
1919 if ( OK != rv){return false;}
1920 int totFld = pkFieldList.size();
1921 Condition *condition = new Condition[totFld];
1922 char *pkFldName = NULL;
1923 char *fkFldName = NULL;
1924 FieldDef *def=NULL;
1925 int i=0;
1926 pkFieldList.resetIter();
1927 fkFieldList.resetIter();
1928 void *val=NULL;
1929 while((pkFldName = pkFieldList.nextFieldName())!= NULL)
1931 fkFldName = fkFieldList.nextFieldName();
1932 FieldIterator fIter = fldList_.getIterator();
1933 while (fIter.hasElement())
1935 def = fIter.nextElement();
1936 if (strcmp(def->fldName_, fkFldName) == 0)
1938 if(NULL == def->bindVal_ && isInsert) { return true; }
1939 if(NULL == def->bindVal_) {
1940 if (def->type_ != typeVarchar)
1941 val = (char*)curTuple_+ def->offset_;
1942 else val = (void *) *(long *) ((char*)curTuple_+
1943 def->offset_);
1944 } else {
1945 val = def->bindVal_;
1947 if(def->type_==typeString)
1948 condition[i].setTerm(pkFldName,OpEquals,&val);
1949 else
1950 condition[i].setTerm(pkFldName,OpEquals,val);
1951 i++;
1952 break;
1956 pkFieldList.removeAll();
1957 fkFieldList.removeAll();
1958 Condition *cond = NULL;
1959 if(i == 0 && !isInsert)return true;
1960 if( i > 1){
1961 cond = new Condition[i-1];
1962 int totcon = i;
1963 i=0;
1964 int j=0;
1965 for(j=0;j<totcon-1;j++)
1967 if(j==0)
1968 cond[j].setTerm(condition[i++].getPredicate(),OpAnd,condition[i++].getPredicate());
1969 else
1970 cond[j].setTerm(cond[j-1].getPredicate(), OpAnd, condition[i++].getPredicate());
1972 fkTbl->setCondition(&cond[j-1]);
1974 else{
1975 fkTbl->setCondition(&condition[i-1]);
1977 fkTbl->execute();
1978 if(fkTbl->fetch()){
1979 fkTbl->closeScan();
1980 delete[] cond;
1981 delete[] condition;
1982 return true;
1984 delete[] cond;
1985 delete[] condition;
1986 return false;
1989 bool TableImpl::isFkTableHasRecord(char *pkTableName, TableImpl *fkTbl)
1991 DbRetVal rv=OK;
1992 FieldNameList pkFieldList,fkFieldList;
1993 void *tPkptr =NULL;
1994 void *tFkptr = NULL;
1995 void *chunkPk = NULL;
1996 void *vcchunkPk = NULL;
1997 CatalogTableTABLE cTable(sysDB_);
1998 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tPkptr, vcchunkPk);
1999 if ( OK != rv){return false;}
2000 rv = cTable.getChunkAndTblPtr(pkTableName, chunkPk, tFkptr, vcchunkPk);
2001 if ( OK != rv){return false;}
2002 CatalogTableFK cFk(sysDB_);
2003 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
2004 if ( OK != rv){return false;}
2005 int totFld = pkFieldList.size();
2006 Condition *condition = new Condition[totFld];
2007 char *pkFldName = NULL;
2008 char *fkFldName = NULL;
2009 FieldDef *def=NULL;
2010 int i=0;
2011 pkFieldList.resetIter();
2012 fkFieldList.resetIter();
2013 while((pkFldName = pkFieldList.nextFieldName())!= NULL)
2015 fkFldName = fkFieldList.nextFieldName();
2016 FieldIterator fIter = fldList_.getIterator();
2017 while (fIter.hasElement())
2019 def = fIter.nextElement();
2020 void *val = NULL;
2021 if (def->type_ != typeVarchar)
2022 val = (char*)curTuple_+ def->offset_;
2023 else val = (void *) *(long *) ((char*)curTuple_+ def->offset_);
2024 if (strcmp(def->fldName_, pkFldName) == 0)
2026 if(def->type_==typeString)
2027 condition[i].setTerm(fkFldName,OpEquals,&val);//((char*)curTuple_+def->offset_));
2028 else
2029 condition[i].setTerm(fkFldName,OpEquals,val);//((char*)curTuple_+def->offset_));
2030 i++;
2031 break;
2035 pkFieldList.removeAll();
2036 fkFieldList.removeAll();
2037 if(i == 0 )return true;
2038 Condition *cond = new Condition[i-1];
2039 i=0;
2040 int j=0;
2041 for(j=0;j<totFld-1;j++)
2043 if(j==0)
2044 cond[j].setTerm(condition[i++].getPredicate(),OpAnd,condition[i++].getPredicate());
2045 else
2046 cond[j].setTerm(cond[j-1].getPredicate(), OpAnd, condition[i++].getPredicate());
2048 if(totFld==1)
2049 fkTbl->setCondition(&condition[totFld-1]);
2050 else
2051 fkTbl->setCondition(&cond[j-1]);
2052 fkTbl->execute();
2053 if(fkTbl->fetch()){
2054 fkTbl->closeScan();
2055 delete[] cond;
2056 delete[] condition;
2057 return true;
2059 delete[] cond;
2060 delete[] condition;
2061 return false;
2063 DbRetVal TableImpl::compact()
2065 DbRetVal rv=OK;
2066 int ret =((Chunk*)chunkPtr_)->compact(db_->procSlot);
2067 if(ret!=0) return ErrLockTimeOut;
2069 if (NULL != vcChunkPtr_) {
2070 ret = ((Chunk*)vcChunkPtr_)->compact(db_->procSlot);
2071 if(ret!=0) return ErrLockTimeOut;
2074 if (NULL != indexPtr_)
2076 int i;
2077 //it has index
2078 for (i = 0; i < numIndexes_ ; i++)
2080 rv = compactIndexNode(indexPtr_[i]);
2081 if (rv != OK) {
2082 printError(rv, "Error in compacting index Node");
2083 break;
2087 return rv;
2090 DbRetVal TableImpl::compactIndexNode( void *indexPtr)
2092 CINDEX *iptr = (CINDEX*)indexPtr;
2093 int ret1=0;
2094 printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
2095 if( hashIndex == (iptr->indexType_) )
2097 ret1 =((Chunk*)iptr->hashNodeChunk_)->compact(db_->procSlot);
2098 if(ret1!=0){
2099 return ErrLockTimeOut;
2101 }else if (treeIndex == (iptr->indexType_))
2103 ret1 =((Chunk*)iptr->chunkPtr_)->compact(db_->procSlot);
2104 if(ret1!=0){
2105 return ErrLockTimeOut;
2107 } else if ( trieIndex == (iptr->indexType_))
2109 ret1 =((Chunk*)iptr->chunkPtr_)->compact(db_->procSlot);
2110 if(ret1!=0){
2111 return ErrLockTimeOut;
2113 ret1 =((Chunk*)iptr->hashNodeChunk_)->compact(db_->procSlot);
2114 if(ret1!=0){
2115 return ErrLockTimeOut;
2118 return OK;