1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
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. *
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. *
15 ***************************************************************************/
17 #include<CatalogTables.h>
23 #include<PredicateImpl.h>
27 void Table::getFieldNameAlone(char *fname
, char *name
) {
29 char *fullname
= fname
;
30 while(*fullname
!= '\0')
32 if (*fullname
== '.') { dotFound
= true; break; }
35 if (dotFound
) strcpy(name
, ++fullname
); else strcpy(name
, fname
);
38 void Table::getTableNameAlone(char *fname
, char *name
) {
41 bool dotFound
= false;
44 if (*name
== '.') { *name
='\0'; dotFound
= true; break; }
47 if (!dotFound
) strcpy(start
, "");
51 DbRetVal
TableImpl::bindFld(const char *name
, void *val
)
53 if (name
[0] == '*' ) return OK
;
54 //set it in the field list
55 char fieldName
[IDENTIFIER_LENGTH
];
56 getFieldNameAlone((char*)name
, fieldName
);
57 DbRetVal rv
= fldList_
.updateBindVal(fieldName
, val
);
59 printError(ErrNotExists
, "Field %s does not exist", fieldName
);
65 bool TableImpl::isFldNull(const char *name
){
66 char fieldName
[IDENTIFIER_LENGTH
];
67 getFieldNameAlone((char*)name
, fieldName
);
68 int colpos
= fldList_
.getFieldPosition(fieldName
);
71 printError(ErrNotExists
, "Field %s does not exist", name
);
75 return isFldNull(colpos
);
78 int TableImpl::getFldPos(char *name
)
80 return fldList_
.getFieldPosition(name
);
82 bool TableImpl::isFldNull(int colpos
)
84 if (!curTuple_
) return false;
85 if (colpos
<1 || colpos
> numFlds_
) return false;
86 if (isIntUsedForNULL
) {
87 int nullVal
= *(int*)((char*)curTuple_
+ (length_
- 4));
88 if (BITSET(nullVal
, colpos
)) return true;
91 char *nullOffset
= (char*)curTuple_
- os::align(numFlds_
);
92 if (nullOffset
[colpos
-1]) return true;
96 void TableImpl::resetNullinfo()
98 if (isIntUsedForNULL
) {
103 while(i
< numFlds_
) { cNullInfo
[0] = 0;}
106 DbRetVal
TableImpl::markFldNull(char const* name
)
109 int colpos
= fldList_
.getFieldPosition(name
);
112 printError(ErrNotExists
, "Field %s does not exist", name
);
115 rv
= markFldNull(colpos
);
119 DbRetVal
TableImpl::markFldNull(int fldpos
)
121 if (fldpos
<1 || fldpos
> numFlds_
) return ErrBadArg
;
122 bool isBitSet
= false;
123 if (isIntUsedForNULL
) {
124 if (!BITSET(iNotNullInfo
, fldpos
)) {
125 SETBIT(iNullInfo
, fldpos
);
129 printError(ErrNullViolation
, "NOT NULL constraint violation");
130 return ErrNullViolation
;
134 if (!BITSET(iNotNullInfo
, fldpos
)) cNullInfo
[fldpos
-1] = 1;
136 printError(ErrNullViolation
, "NOT NULL constraint violation");
137 return ErrNullViolation
;
143 void TableImpl::clearFldNull(const char *name
)
145 int colpos
= fldList_
.getFieldPosition(name
);
148 printError(ErrNotExists
, "Field %s does not exist", name
);
152 clearFldNull(colpos
);
155 void TableImpl::clearFldNull(int colpos
)
157 if (colpos
<1 || colpos
> numFlds_
) return;
158 if (isIntUsedForNULL
) {
159 CLEARBIT(iNullInfo
, colpos
);
162 cNullInfo
[colpos
-1] = 0;
167 DbRetVal
TableImpl::execute()
171 printError(ErrAlready
,"Scan already open:Close and re execute");
174 //table ptr is set in predicate because it needs to access the
175 //type and length to evaluate
178 PredicateImpl
*pred
= (PredicateImpl
*) pred_
;
179 pred
->setTable(this);
180 pred
->setProjectionList(NULL
);
184 ret
= createPlan(betcheck
);
187 printError(ErrSysInternal
,"Unable to create the plan");
188 return ErrSysInternal
;
191 iter
= new TupleIterator(pred_
, scanType_
, idxInfo
[useIndex_
], chunkPtr_
, sysDB_
->procSlot
,betcheck
);
192 else if (scanType_
== fullTableScan
)
193 iter
= new TupleIterator(pred_
, scanType_
, NULL
, chunkPtr_
, sysDB_
->procSlot
,betcheck
);
196 printError(ErrSysFatal
,"Unable to create tuple iterator");//should never happen
202 printError(ret
,"Unable to open the iterator");
209 DbRetVal
TableImpl::createPlan(bool &bet
)
212 //will do early return here. plan is generated only when setPredicate is called.
213 if (scanType_
== unknownScan
) return ErrSysFatal
; //this should never happen
217 //if there are no predicates then go for full scan
218 //if there are no indexes then go for full scan
219 if (NULL
== pred_
|| NULL
== indexPtr_
)
221 scanType_
= fullTableScan
;
222 isPlanCreated
= true;
225 if (NULL
!= indexPtr_
)
227 PredicateImpl
*pred
= (PredicateImpl
*)pred_
;
228 printDebug(DM_Predicate
, "predicate does not involve NOT , OR operator");
229 if (!pred
->isNotOrInvolved())
231 printDebug(DM_Predicate
, "predicate does not involve NOT , OR operator");
232 for (int i
=0; i
< numIndexes_
; i
++)
234 HashIndexInfo
* info
= (HashIndexInfo
*) idxInfo
[i
];
235 FieldIterator iter
= info
->idxFldList
.getIterator();
236 while(iter
.hasElement())
238 FieldDef def
= iter
.nextElement();
239 if (pred
->pointLookupInvolved(def
.fldName_
))
241 printDebug(DM_Predicate
, "point lookup involved for field %s",def
.fldName_
);
242 if(hashIndex
== info
->indType
) scanType_
= hashIndexScan
;
243 else scanType_
= treeIndexScan
;
244 isPlanCreated
= true;
247 else if (pred
->isBetweenInvolved(def
.fldName_
))
249 if (treeIndex
== info
->indType
)
251 scanType_
= treeIndexScan
;
252 isPlanCreated
= true;
255 break; //no composite index for tree index
258 else if (pred
->rangeQueryInvolved(def
.fldName_
))
260 printDebug(DM_Predicate
, "range lookup involved for field %s",def
.fldName_
);
261 if (treeIndex
== info
->indType
)
263 scanType_
= treeIndexScan
;
264 isPlanCreated
= true;
266 break; //no composite index for tree index
272 }//while iter.hasElement()
273 if (useIndex_
!= -1) return OK
;
277 scanType_
= fullTableScan
;
278 isPlanCreated
= true;
282 void* TableImpl::fetch()
285 if (NULL
== curTuple_
) return curTuple_
;
286 copyValuesToBindBuffer(curTuple_
);
289 void* TableImpl::fetch(DbRetVal
&rv
)
292 if (NULL
== curTuple_
) return curTuple_
;
293 copyValuesToBindBuffer(curTuple_
);
297 void* TableImpl::fetchNoBind()
301 printError(ErrNotOpen
,"Scan not open or Scan is closed\n");
304 void *prevTuple
= curTuple_
;
305 curTuple_
= iter
->next();
306 if (NULL
== curTuple_
)
310 DbRetVal lockRet
= OK
;
311 if ((*trans
)->isoLevel_
== READ_REPEATABLE
) {
312 lockRet
= lMgr_
->getSharedLock(curTuple_
, trans
);
315 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
316 curTuple_
= prevTuple
;
321 else if ((*trans
)->isoLevel_
== READ_COMMITTED
)
323 //if iso level is read committed, operation duration lock is sufficent
324 //so release it here itself.
326 struct timeval timeout
;
327 timeout
.tv_sec
= Conf::config
.getMutexSecs();
328 timeout
.tv_usec
= Conf::config
.getMutexUSecs();
332 lockRet
= lMgr_
->isExclusiveLocked( curTuple_
, trans
, status
);
335 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
336 curTuple_
= prevTuple
;
341 if (tries
== 0) break;
342 os::select(0, 0, 0, 0, &timeout
);
347 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
348 curTuple_
= prevTuple
;
355 void* TableImpl::fetchNoBind(DbRetVal
&rv
)
360 printError(ErrNotOpen
,"Scan not open or Scan is closed\n");
364 void *prevTuple
= curTuple_
;
365 curTuple_
= iter
->next();
366 if (NULL
== curTuple_
)
370 DbRetVal lockRet
= OK
;
371 if ((*trans
)->isoLevel_
== READ_REPEATABLE
) {
372 lockRet
= lMgr_
->getSharedLock(curTuple_
, trans
);
375 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
377 curTuple_
= prevTuple
;
382 else if ((*trans
)->isoLevel_
== READ_COMMITTED
)
384 //if iso level is read committed, operation duration lock is sufficent
385 //so release it here itself.
387 struct timeval timeout
;
388 timeout
.tv_sec
= Conf::config
.getMutexSecs();
389 timeout
.tv_usec
= Conf::config
.getMutexUSecs();
393 lockRet
= lMgr_
->isExclusiveLocked( curTuple_
, trans
, status
);
396 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
397 curTuple_
= prevTuple
;
403 if (tries
== 0) break;
404 os::select(0, 0, 0, 0, &timeout
);
409 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
410 curTuple_
= prevTuple
;
418 DbRetVal
TableImpl::insertTuple()
421 void *tptr
= ((Chunk
*)chunkPtr_
)->allocate(db_
, &ret
);
424 printError(ret
, "Unable to allocate record from chunk");
427 ret
= lMgr_
->getExclusiveLock(tptr
, trans
);
430 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
431 printError(ret
, "Could not get lock for the insert tuple %x", tptr
);
432 return ErrLockTimeOut
;
437 ret
= copyValuesFromBindBuffer(tptr
);
440 printError(ret
, "Unable to copy values from bind buffer");
441 (*trans
)->removeFromHasList(db_
, tptr
);
442 lMgr_
->releaseLock(tptr
);
443 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
450 *(int*)((char*)(tptr
) + (length_
-addSize
)) = iNullInfo
;
454 addSize
= os::align(numFlds_
);
455 os::memcpy(((char*)(tptr
) + (length_
-addSize
)), cNullInfo
, addSize
);
458 //int tupleSize = length_ + addSize;
459 if (NULL
!= indexPtr_
)
463 for (i
= 0; i
< numIndexes_
; i
++)
465 ret
= insertIndexNode(*trans
, indexPtr_
[i
], idxInfo
[i
], tptr
);
466 if (ret
!= OK
) { printError(ret
, "Error in inserting to index"); break;}
468 if (i
!= numIndexes_
)
470 for (int j
= 0; j
< i
; j
++) {
471 printError(ErrWarning
, "Deleting index node");
472 deleteIndexNode(*trans
, indexPtr_
[j
], idxInfo
[j
], tptr
);
474 lMgr_
->releaseLock(tptr
);
475 (*trans
)->removeFromHasList(db_
, tptr
);
476 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
478 //printError(ret, "Unable to insert index node for tuple %x ", tptr);
479 printError(ret
, "Unable to insert index node for tuple %x %d", tptr
, *(int*)tptr
);
484 ret
= (*trans
)->appendUndoLog(sysDB_
, InsertOperation
, tptr
, length_
);
486 printError(ret
, "Unable to create undo log for %x %d", tptr
, *(int*)tptr
);
487 for (int j
= 0; j
< numIndexes_
; j
++) {
488 printError(ErrWarning
, "Deleting index node");
489 deleteIndexNode(*trans
, indexPtr_
[j
], idxInfo
[j
], tptr
);
491 lMgr_
->releaseLock(tptr
);
492 (*trans
)->removeFromHasList(db_
, tptr
);
493 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
498 DbRetVal
TableImpl::deleteTuple()
500 if (NULL
== curTuple_
)
502 printError(ErrNotOpen
, "Scan not open: No Current tuple");
505 DbRetVal ret
= lMgr_
->getExclusiveLock(curTuple_
, trans
);
508 printError(ret
, "Could not get lock for the delete tuple %x", curTuple_
);
509 return ErrLockTimeOut
;
512 if (NULL
!= indexPtr_
)
516 for (i
= 0; i
< numIndexes_
; i
++)
518 ret
= deleteIndexNode(*trans
, indexPtr_
[i
], idxInfo
[i
], curTuple_
);
519 if (ret
!= OK
) break;
521 if (i
!= numIndexes_
)
523 for (int j
= 0; j
< i
; j
++)
524 insertIndexNode(*trans
, indexPtr_
[j
], idxInfo
[j
], curTuple_
);
525 lMgr_
->releaseLock(curTuple_
);
526 (*trans
)->removeFromHasList(db_
, curTuple_
);
527 printError(ret
, "Unable to insert index node for tuple %x", curTuple_
);
531 ((Chunk
*)chunkPtr_
)->free(db_
, curTuple_
);
533 ret
= (*trans
)->appendUndoLog(sysDB_
, DeleteOperation
, curTuple_
, length_
);
538 int TableImpl::deleteWhere()
540 int tuplesDeleted
= 0;
543 if (rv
!=OK
) return (int) rv
;
546 if (rv
!= OK
) { tuplesDeleted
= (int)rv
; break; }
547 if (NULL
== curTuple_
) break;
550 printError(rv
, "Error: Could only delete %d tuples", tuplesDeleted
);
557 return tuplesDeleted
;
560 int TableImpl::truncate()
562 //take exclusive lock on the table
563 //get the chunk ptr of the table
564 //traverse the tablechunks and free all the pages except the first one
565 //get the chunk ptr of all its indexes
566 //traverse the indexchunks and free all the pages except the first one
571 Predicate
* tmpPred
= pred_
;
573 isPlanCreated
= false;
574 int tuplesDeleted
= deleteWhere();
575 isPlanCreated
= false;
577 return tuplesDeleted
;
580 DbRetVal
TableImpl::updateTuple()
582 if (NULL
== curTuple_
)
584 printError(ErrNotOpen
, "Scan not open: No Current tuple");
587 DbRetVal ret
= lMgr_
->getExclusiveLock(curTuple_
, trans
);
590 printError(ret
, "Could not get lock for the update tuple %x", curTuple_
);
591 return ErrLockTimeOut
;
593 if (NULL
!= indexPtr_
)
596 //TODO::If it fails while updating index node, we have to undo all the updates
597 //on other indexes on the table.Currently it will leave the database in an
598 //inconsistent state.
599 for (int i
= 0; i
< numIndexes_
; i
++)
601 ret
= updateIndexNode(*trans
, indexPtr_
[i
], idxInfo
[i
], curTuple_
);
604 lMgr_
->releaseLock(curTuple_
);
605 (*trans
)->removeFromHasList(db_
, curTuple_
);
606 printError(ret
, "Unable to update index node for tuple %x", curTuple_
);
612 ret
= (*trans
)->appendUndoLog(sysDB_
, UpdateOperation
, curTuple_
, length_
);
613 if (ret
!= OK
) return ret
;
615 int iNullVal
=iNullInfo
;
619 iNullInfo
= *(int*)((char*)(curTuple_
) + (length_
- addSize
));
623 *(int*)((char*)(curTuple_
) + (length_
-addSize
)) |= iNullInfo
;
626 DbRetVal rv
= copyValuesFromBindBuffer(curTuple_
, false);
628 lMgr_
->releaseLock(curTuple_
);
629 (*trans
)->removeFromHasList(db_
, curTuple_
);
636 *(int*)((char*)(curTuple_
) + (length_
-addSize
)) = iNullInfo
;
639 else iNullInfo
=iNullVal
;
643 addSize
= os::align(numFlds_
);
644 //TODO::Do not do blind memcpy. It should OR each and every char
645 //os::memcpy(((char*)(curTuple_) + (length_-addSize)), cNullInfo, addSize);
651 void TableImpl::printInfo()
653 printf(" <TableName> %s </TableName>\n", tblName_
);
654 printf(" <TupleCount> %d </TupleCount>\n", numTuples());
655 printf(" <PagesUsed> %d </PagesUsed>\n", pagesUsed());
656 printf(" <SpaceUsed> %d </SpaceUsed>\n", spaceUsed());
657 printf(" <Indexes> %d <Indexes>\n", numIndexes_
);
658 printf(" <TupleLength> %d </TupleLength>\n", length_
);
659 printf(" <Fields> %d </Fields>\n", numFlds_
);
660 printf(" <Indexes>\n");
661 for (int i
=0; i
<numIndexes_
; i
++)
662 printf("<IndexName> %s </IndexName>\n", CatalogTableINDEX::getName(indexPtr_
[i
]));
663 printf(" </Indexes>\n");
667 DbRetVal
TableImpl::copyValuesFromBindBuffer(void *tuplePtr
, bool isInsert
)
669 //Iterate through the bind list and copy the value here
670 FieldIterator fIter
= fldList_
.getIterator();
671 char *colPtr
= (char*) tuplePtr
;
673 while (fIter
.hasElement())
675 FieldDef def
= fIter
.nextElement();
676 if (def
.isNull_
&& !def
.isDefault_
&& NULL
== def
.bindVal_
&& isInsert
)
678 printError(ErrNullViolation
, "NOT NULL constraint violation for field %s\n", def
.fldName_
);
679 return ErrNullViolation
;
681 if (def
.isDefault_
&& NULL
== def
.bindVal_
&& isInsert
)
683 void *dest
= AllDataType::alloc(def
.type_
, def
.length_
);
684 AllDataType::convert(typeString
, def
.defaultValueBuf_
, def
.type_
, dest
, def
.length_
);
685 AllDataType::copyVal(colPtr
, dest
, def
.type_
, def
.length_
);
686 colPtr
= colPtr
+ os::align(AllDataType::size(def
.type_
, def
.length_
));
694 if (NULL
!= def
.bindVal_
)
696 if(!isInsert
&& isFldNull(fldpos
)){clearNullBit(fldpos
);}
697 strcpy((char*)colPtr
, (char*)def
.bindVal_
);
698 *(((char*)colPtr
) + (def
.length_
-1)) = '\0';
700 else if (!def
.isNull_
&& !def
.bindVal_
&& isInsert
) setNullBit(fldpos
);
701 colPtr
= colPtr
+ os::align(def
.length_
);
704 if (NULL
!= def
.bindVal_
) {
705 if(!isInsert
&& isFldNull(fldpos
)){clearNullBit(fldpos
);}
706 DbRetVal rv
= AllDataType::strToValue(colPtr
, (char *) def
.bindVal_
, def
.type_
, def
.length_
);
707 if (rv
!= OK
) return ErrBadArg
;
709 else if (!def
.isNull_
&& isInsert
&& !def
.bindVal_
) setNullBit(fldpos
);
710 colPtr
= colPtr
+ os::align(def
.length_
);
713 if (NULL
!= def
.bindVal_
){
714 if(!isInsert
&& isFldNull(fldpos
)){clearNullBit(fldpos
);}
715 AllDataType::copyVal(colPtr
, def
.bindVal_
, def
.type_
);}
716 else { if (!def
.isNull_
&& isInsert
) setNullBit(fldpos
); }
717 colPtr
= colPtr
+ os::align(AllDataType::size(def
.type_
));
724 void TableImpl::clearNullBit(int fldpos
)
726 if (isIntUsedForNULL
){
727 CLEARBIT(iNullInfo
, fldpos
);}
729 cNullInfo
[fldpos
-1] = 0;
731 void TableImpl::setNullBit(int fldpos
)
733 if (isIntUsedForNULL
)
734 SETBIT(iNullInfo
, fldpos
);
736 cNullInfo
[fldpos
-1] = 1;
738 DbRetVal
TableImpl::copyValuesToBindBuffer(void *tuplePtr
)
740 //Iterate through the bind list and copy the value here
741 FieldIterator fIter
= fldList_
.getIterator();
742 char *colPtr
= (char*) tuplePtr
;
743 while (fIter
.hasElement())
745 FieldDef def
= fIter
.nextElement();
746 if (NULL
!= def
.bindVal_
)
747 AllDataType::copyVal(def
.bindVal_
, colPtr
, def
.type_
, def
.length_
);
748 colPtr
= colPtr
+ os::align(AllDataType::size(def
.type_
, def
.length_
));
753 //-1 index not supported
754 DbRetVal
TableImpl::insertIndexNode(Transaction
*tr
, void *indexPtr
, IndexInfo
*info
, void *tuple
)
756 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
758 printDebug(DM_Table
, "Inside insertIndexNode type %d", iptr
->indexType_
);
759 Index
* idx
= Index::getIndex(iptr
->indexType_
);
760 ret
= idx
->insert(this, tr
, indexPtr
, info
, tuple
,undoFlag
);
764 DbRetVal
TableImpl::deleteIndexNode(Transaction
*tr
, void *indexPtr
, IndexInfo
*info
, void *tuple
)
766 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
768 Index
* idx
= Index::getIndex(iptr
->indexType_
);
769 ret
= idx
->remove(this, tr
, indexPtr
, info
, tuple
, undoFlag
);
772 void TableImpl::printSQLIndexString()
774 CatalogTableINDEXFIELD
cIndexField(sysDB_
);
775 char fName
[IDENTIFIER_LENGTH
];
776 char *fldName
= fName
;
778 for (int i
= 0; i
< numIndexes_
; i
++)
780 CINDEX
*iptr
= (CINDEX
*) indexPtr_
[i
];
781 printf("CREATE INDEX %s on %s ( ", iptr
->indName_
, getName());
783 cIndexField
.getFieldInfo(iptr
, fldList
);
784 FieldIterator fIter
= fldList
.getIterator();
785 bool firstFld
= true;
786 while(fIter
.hasElement())
788 FieldDef def
= fIter
.nextElement();
789 if (firstFld
) { printf(" %s ", def
.fldName_
); firstFld
= false; }
790 else printf(" ,%s ", def
.fldName_
);
793 if (iptr
->indexType_
== hashIndex
) printf(" HASH ");
794 else printf(" TREE ");
795 if (((HashIndexInfo
*) idxInfo
[i
])->isUnique
) printf(" UNIQUE;\n"); else printf(";\n");
800 DbRetVal
TableImpl::updateIndexNode(Transaction
*tr
, void *indexPtr
, IndexInfo
*info
, void *tuple
)
802 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
804 Index
* idx
= Index::getIndex(iptr
->indexType_
);
805 //TODO::currently it updates irrespective of whether the key changed or not
806 //because of this commenting the whole index update code. relook at it and uncomment
808 ret
= idx
->update(this, tr
, indexPtr
, info
, tuple
, undoFlag
);
814 void TableImpl::setTableInfo(char *name
, int tblid
, size_t length
,
815 int numFld
, int numIdx
, void *chunk
)
817 strcpy(tblName_
, name
);
821 numIndexes_
= numIdx
;
825 long TableImpl::spaceUsed()
827 Chunk
*chk
= (Chunk
*)chunkPtr_
;
828 long totSize
= chk
->getTotalDataNodes() * chk
->getSize();
829 totSize
= totSize
+ (chk
->totalPages() * sizeof (PageInfo
));
833 int TableImpl::pagesUsed()
835 Chunk
*chk
= (Chunk
*)chunkPtr_
;
836 return chk
->totalPages();
839 long TableImpl::numTuples()
841 return ((Chunk
*)chunkPtr_
)->getTotalDataNodes();
844 List
TableImpl::getFieldNameList()
847 FieldIterator fIter
= fldList_
.getIterator();
848 char fieldName
[IDENTIFIER_LENGTH
];
849 while (fIter
.hasElement())
851 FieldDef def
= fIter
.nextElement();
852 Identifier
*elem
= new Identifier();
853 Table::getFieldNameAlone(def
.fldName_
, fieldName
);
854 sprintf(elem
->name
, "%s.%s", getName(), fieldName
);
855 fldNameList
.append(elem
);
859 DbRetVal
TableImpl::close()
863 //printError(ErrNotOpen,"Scan not open");
865 //PRABA::when called multiple times it gives error
873 DbRetVal
TableImpl::closeScan()
875 //do not throw scan not open error
876 //this function will be called by table handle
884 DbRetVal
TableImpl::lock(bool shared
)
890 ret = lMgr_->getSharedLock(chunkPtr_, NULL);
892 ret = lMgr_->getExclusiveLock(chunkPtr_, NULL);
895 printError(ret, "Could not exclusive lock on the table %x", chunkPtr_);
897 //do not append for S to X upgrade
898 if (!ProcessManager::hasLockList.exists(chunkPtr_))
899 ProcessManager::hasLockList.append(chunkPtr_);
904 DbRetVal
TableImpl::unlock()
907 if (!ProcessManager::hasLockList.exists(chunkPtr_)) return OK;
908 DbRetVal ret = lMgr_->releaseLock(chunkPtr_);
911 printError(ret, "Could not release exclusive lock on the table %x", chunkPtr_);
914 ProcessManager::hasLockList.remove(chunkPtr_);
920 TableImpl::~TableImpl()
922 if (NULL
!= iter
) { delete iter
; iter
= NULL
; }
923 if (NULL
!= indexPtr_
) { delete[] indexPtr_
; indexPtr_
= NULL
; }
926 for (int i
= 0; i
< numIndexes_
; i
++) delete idxInfo
[i
];
930 if (numFlds_
> 31 && cNullInfo
!= NULL
) { free(cNullInfo
); cNullInfo
= NULL
; }
932 fldList_
.removeAll();
936 void *TableImpl::getBindFldAddr(const char *name
)
938 return fldList_
.getBindField(name
);
940 bool TableImpl::isTableInvolved(char *tblName
)
942 //printf("Table isTableInvolved called for %s with %s\n", tblName, getName());
943 if (0 == strcmp(getName(), tblName
)) return true; else return false;
945 bool TableImpl::pushPredicate(Predicate
*pred
)
948 PredicateImpl
*pImpl
= (PredicateImpl
*) pred
;
949 char tableName
[IDENTIFIER_LENGTH
];
950 Table::getTableNameAlone(pImpl
->getFldName1(), tableName
);
951 //printf("predicate tbl name %s\n", tableName);
953 //if predicate is of form t1.f1=t2.f1 then do not push here
954 if (0 != strcmp(pImpl
->getFldName2(),"")) return ret
;
956 if (0 == strcmp(getName(), tableName
))
959 //printf("PRABA::pushed predicate in tablehdl %s\n", getName());
964 void TableImpl::setPredicate(Predicate
*pred
)
966 if (NULL
== pred_
) { pred_
= pred
; return; }
967 Predicate
*curPred
= pred_
;
968 PredicateImpl
*newPred
= new PredicateImpl();
969 newPred
->setTerm(curPred
, OpAnd
, pred
);
970 newPred
->setTable(this);
974 void TableImpl::printPlan(int space
)
976 char spaceBuf
[IDENTIFIER_LENGTH
];
977 memset(spaceBuf
, 32, IDENTIFIER_LENGTH
);
978 spaceBuf
[space
] = '\0';
979 printf("%s <TABLE-NODE>\n", spaceBuf
);
980 printf("%s <NAME> %s </NAME>\n", spaceBuf
, getName());
981 printf("%s <ScanType> %s </ScanType>\n", spaceBuf
, ScanTypeNames
[scanType_
]);
982 PredicateImpl
*pred
= (PredicateImpl
*)pred_
;
983 if (pred
) pred
->print(space
+2);
984 printf("%s </TABLE-NODE>\n", spaceBuf
);