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>
26 #include<AggTableImpl.h> //for AggType
28 void Table::getFieldNameAlone(char *fname
, char *name
) {
30 char *fullname
= fname
;
31 while(*fullname
!= '\0')
33 if (*fullname
== '.') { dotFound
= true; break; }
36 if (dotFound
) strcpy(name
, ++fullname
); else strcpy(name
, fname
);
39 void Table::getTableNameAlone(char *fname
, char *name
) {
42 bool dotFound
= false;
45 if (*name
== '.') { *name
='\0'; dotFound
= true; break; }
48 if (!dotFound
) strcpy(start
, "");
52 DbRetVal
TableImpl::bindFld(const char *name
, void *val
)
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
);
60 printError(ErrNotExists
, "Field %s does not exist", fieldName
);
66 bool TableImpl::isFldNull(const char *name
){
67 if (name
[0] == '*') return false;
68 char fieldName
[IDENTIFIER_LENGTH
];
69 getFieldNameAlone((char*)name
, fieldName
);
70 int colpos
= fldList_
.getFieldPosition(fieldName
);
73 printError(ErrNotExists
, "Field %s does not exist", name
);
77 return isFldNull(colpos
);
80 int TableImpl::getFldPos(char *name
)
82 return fldList_
.getFieldPosition(name
);
84 bool TableImpl::isFldNull(int colpos
)
86 if (!curTuple_
) return false;
87 if (colpos
<1 || colpos
> numFlds_
) return false;
88 if (isIntUsedForNULL
) {
89 int nullVal
= *(int*)((char*)curTuple_
+ (length_
- 4));
90 if (BITSET(nullVal
, colpos
)) return true;
93 char *nullOffset
= (char*)curTuple_
- os::align(numFlds_
);
94 if (nullOffset
[colpos
-1]) return true;
98 void TableImpl::resetNullinfo()
100 if (isIntUsedForNULL
) {
105 while(i
< numFlds_
) { cNullInfo
[0] = 0;}
108 DbRetVal
TableImpl::markFldNull(char const* name
)
111 int colpos
= fldList_
.getFieldPosition(name
);
114 printError(ErrNotExists
, "Field %s does not exist", name
);
117 rv
= markFldNull(colpos
);
121 DbRetVal
TableImpl::markFldNull(int fldpos
)
123 if (fldpos
<1 || fldpos
> numFlds_
) return ErrBadArg
;
124 bool isBitSet
= false;
125 if (isIntUsedForNULL
) {
126 if (!BITSET(iNotNullInfo
, fldpos
)) {
127 SETBIT(iNullInfo
, fldpos
);
131 printError(ErrNullViolation
, "NOT NULL constraint violation");
132 return ErrNullViolation
;
136 if (!BITSET(iNotNullInfo
, fldpos
)) cNullInfo
[fldpos
-1] = 1;
138 printError(ErrNullViolation
, "NOT NULL constraint violation");
139 return ErrNullViolation
;
145 void TableImpl::clearFldNull(const char *name
)
147 int colpos
= fldList_
.getFieldPosition(name
);
150 printError(ErrNotExists
, "Field %s does not exist", name
);
154 clearFldNull(colpos
);
157 void TableImpl::clearFldNull(int colpos
)
159 if (colpos
<1 || colpos
> numFlds_
) return;
160 if (isIntUsedForNULL
) {
161 CLEARBIT(iNullInfo
, colpos
);
164 cNullInfo
[colpos
-1] = 0;
168 bool TableImpl::hasIndex(char* fName
)
170 if (NULL
== indexPtr_
) return false;
171 for (int i
=0; i
< numIndexes_
; i
++)
173 HashIndexInfo
* info
= (HashIndexInfo
*) idxInfo
[i
];
174 FieldIterator iter
= info
->idxFldList
.getIterator();
175 if(iter
.hasElement())
177 FieldDef
*def
= iter
.nextElement();
178 if(strcmp(def
->fldName_
, fName
) == 0)
179 if(!iter
.hasElement())//neglet if it is composite index
185 void TableImpl::addPredicate(char *fName
, ComparisionOp op
, void *buf
)
187 //char fieldName[IDENTIFIER_LENGTH];
188 //Table::getFieldNameAlone(fName, fieldName);
189 PredicateImpl
*pred
= (PredicateImpl
*) pred_
;
190 PredicateImpl
*newPred
= new PredicateImpl();
191 newPred
->setTerm(fName
, op
, buf
);
192 if (NULL
== pred
) { pred_
= newPred
; return; }
193 PredicateImpl
*bothPred
= new PredicateImpl();
194 bothPred
->setTerm(pred
, OpAnd
, newPred
);
198 DbRetVal
TableImpl::optimize()
200 //table ptr is set in predicate because it needs to access the
201 //type and length to evaluate
204 PredicateImpl
*pred
= (PredicateImpl
*) pred_
;
205 pred
->setTable(this);
206 pred
->setProjectionList(NULL
);
207 pred
->setOffsetAndType();
212 DbRetVal
TableImpl::execute()
216 printError(ErrAlready
,"Scan already open:Close and re execute");
223 printError(ErrSysInternal
,"Unable to create the plan");
224 return ErrSysInternal
;
227 iter
= new TupleIterator(pred_
, scanType_
, idxInfo
[useIndex_
], chunkPtr_
, sysDB_
->procSlot
,isBetween
,isPointLook
);
228 else if (scanType_
== fullTableScan
)
229 iter
= new TupleIterator(pred_
, scanType_
, NULL
, chunkPtr_
, sysDB_
->procSlot
,isBetween
,isPointLook
);
232 printError(ErrSysFatal
,"Unable to create tuple iterator");//should never happen
238 printError(ret
,"Unable to open the iterator");
245 DbRetVal
TableImpl::createPlan()
248 //will do early return here. plan is generated only when setPredicate is called.
249 if (scanType_
== unknownScan
) return ErrSysFatal
; //this should never happen
256 FieldIterator fIter
= fldList_
.getIterator();
257 FieldDef
*def
= NULL
;
258 while ((def
= fIter
.nextElement())!= NULL
) {
259 if (NULL
!= def
->bindVal_
) bindList_
.append(def
);
261 numBindFlds_
= bindList_
.size();
262 bindListArray_
= (void **) malloc(numBindFlds_
* sizeof (void *));
265 ListIterator it
= bindList_
.getIterator();
266 while ((elem
= it
.nextElement()) != NULL
) bindListArray_
[i
++] = elem
;
268 //if there are no predicates then go for full scan
269 //if there are no indexes then go for full scan
270 if (NULL
== pred_
|| NULL
== indexPtr_
)
272 scanType_
= fullTableScan
;
273 isPlanCreated
= true;
276 if (NULL
!= indexPtr_
)
278 PredicateImpl
*pred
= (PredicateImpl
*)pred_
;
279 printDebug(DM_Predicate
, "predicate does not involve NOT , OR operator");
280 if (!pred
->isNotOrInvolved())
282 printDebug(DM_Predicate
, "predicate does not involve NOT , OR operator");
283 for (int i
=0; i
< numIndexes_
; i
++)
285 HashIndexInfo
* info
= (HashIndexInfo
*) idxInfo
[i
];
286 FieldIterator iter
= info
->idxFldList
.getIterator();
287 while(iter
.hasElement())
289 FieldDef
*def
= iter
.nextElement();
290 if (pred
->pointLookupInvolved(def
->fldName_
))
292 printDebug(DM_Predicate
, "point lookup involved for field %s",def
->fldName_
);
293 if(hashIndex
== info
->indType
) scanType_
= hashIndexScan
;
294 else scanType_
= treeIndexScan
;
295 isPlanCreated
= true;
299 else if (pred
->isBetweenInvolved(def
->fldName_
))
301 if (treeIndex
== info
->indType
)
303 scanType_
= treeIndexScan
;
304 isPlanCreated
= true;
307 break; //no composite index for tree index
310 else if (pred
->rangeQueryInvolved(def
->fldName_
))
312 printDebug(DM_Predicate
, "range lookup involved for field %s",def
->fldName_
);
313 if (treeIndex
== info
->indType
)
315 scanType_
= treeIndexScan
;
316 isPlanCreated
= true;
318 break; //no composite index for tree index
324 }//while iter.hasElement()
325 if (useIndex_
!= -1) return OK
;
329 scanType_
= fullTableScan
;
330 isPlanCreated
= true;
334 void* TableImpl::fetch()
337 if (NULL
== curTuple_
) return curTuple_
;
338 copyValuesToBindBuffer(curTuple_
);
341 void* TableImpl::fetch(DbRetVal
&rv
)
344 if (NULL
== curTuple_
) return curTuple_
;
345 copyValuesToBindBuffer(curTuple_
);
349 void* TableImpl::fetchNoBind()
353 printError(ErrNotOpen
,"Scan not open or Scan is closed\n");
356 void *prevTuple
= curTuple_
;
357 curTuple_
= iter
->next();
358 if (NULL
== curTuple_
)
362 DbRetVal lockRet
= OK
;
363 if ((*trans
)->isoLevel_
== READ_COMMITTED
)
365 //if iso level is read committed, operation duration lock is sufficent
366 //so release it here itself.
368 struct timeval timeout
;
369 timeout
.tv_sec
= Conf::config
.getMutexSecs();
370 timeout
.tv_usec
= Conf::config
.getMutexUSecs();
374 lockRet
= lMgr_
->isExclusiveLocked( curTuple_
, trans
, status
);
377 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
378 curTuple_
= prevTuple
;
383 if (tries
== 0) break;
384 os::select(0, 0, 0, 0, &timeout
);
389 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
390 curTuple_
= prevTuple
;
394 else if ((*trans
)->isoLevel_
== READ_REPEATABLE
) {
395 lockRet
= lMgr_
->getSharedLock(curTuple_
, trans
);
398 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
399 curTuple_
= prevTuple
;
407 void* TableImpl::fetchNoBind(DbRetVal
&rv
)
412 printError(ErrNotOpen
,"Scan not open or Scan is closed\n");
416 void *prevTuple
= curTuple_
;
417 curTuple_
= iter
->next();
418 if (NULL
== curTuple_
)
422 DbRetVal lockRet
= OK
;
423 if ((*trans
)->isoLevel_
== READ_REPEATABLE
) {
424 lockRet
= lMgr_
->getSharedLock(curTuple_
, trans
);
427 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
429 curTuple_
= prevTuple
;
434 else if ((*trans
)->isoLevel_
== READ_COMMITTED
)
436 //if iso level is read committed, operation duration lock is sufficent
437 //so release it here itself.
439 struct timeval timeout
;
440 timeout
.tv_sec
= Conf::config
.getMutexSecs();
441 timeout
.tv_usec
= Conf::config
.getMutexUSecs();
445 lockRet
= lMgr_
->isExclusiveLocked( curTuple_
, trans
, status
);
448 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
449 curTuple_
= prevTuple
;
455 if (tries
== 0) break;
456 os::select(0, 0, 0, 0, &timeout
);
461 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
462 curTuple_
= prevTuple
;
469 DbRetVal
TableImpl::fetchAgg(const char * fldName
, AggType aType
, void *buf
)
471 FieldInfo
*info
= new FieldInfo();
472 DbRetVal rv
= getFieldInfo(fldName
, info
);
473 if (OK
!= rv
) return rv
;
476 char *tuple
= (char*) fetchNoBind(rv
);
479 *(int*)buf
= 0; //assuming int. could create porting problems(64 |endian)
483 AllDataType::copyVal(buf
, (void*) (tuple
+info
->offset
), info
->type
, info
->length
);
485 tuple
= (char*) fetchNoBind(rv
);
486 if (NULL
== tuple
) break;
490 res
= AllDataType::compareVal(buf
, (void*) (tuple
+info
->offset
),
492 info
->type
, info
->length
);
493 if (res
) AllDataType::copyVal(buf
, (void*) (tuple
+info
->offset
),
494 info
->type
, info
->length
);
499 res
= AllDataType::compareVal(buf
, (void*) (tuple
+info
->offset
),
501 info
->type
, info
->length
);
502 if (res
) AllDataType::copyVal(buf
, (void*) (tuple
+info
->offset
),
503 info
->type
, info
->length
);
508 AllDataType::addVal(buf
, (void*) (tuple
+info
->offset
),
514 AllDataType::addVal(buf
, (void*) (tuple
+info
->offset
),
529 AllDataType::divVal(buf
, &count
,info
->type
);
534 (*(int*)buf
) = count
;
541 DbRetVal
TableImpl::insertTuple()
544 void *tptr
= ((Chunk
*)chunkPtr_
)->allocate(db_
, &ret
);
547 printError(ret
, "Unable to allocate record from chunk");
550 ret
= lMgr_
->getExclusiveLock(tptr
, trans
);
553 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
554 printError(ret
, "Could not get lock for the insert tuple %x", tptr
);
555 return ErrLockTimeOut
;
560 ret
= copyValuesFromBindBuffer(tptr
);
563 printError(ret
, "Unable to copy values from bind buffer");
564 (*trans
)->removeFromHasList(db_
, tptr
);
565 lMgr_
->releaseLock(tptr
);
566 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
573 *(int*)((char*)(tptr
) + (length_
-addSize
)) = iNullInfo
;
577 addSize
= os::align(numFlds_
);
578 os::memcpy(((char*)(tptr
) + (length_
-addSize
)), cNullInfo
, addSize
);
581 //int tupleSize = length_ + addSize;
582 if (NULL
!= indexPtr_
)
586 for (i
= 0; i
< numIndexes_
; i
++)
588 ret
= insertIndexNode(*trans
, indexPtr_
[i
], idxInfo
[i
], tptr
);
589 if (ret
!= OK
) { printError(ret
, "Error in inserting to index"); break;}
591 if (i
!= numIndexes_
)
593 for (int j
= 0; j
< i
; j
++) {
594 printError(ErrWarning
, "Deleting index node");
595 deleteIndexNode(*trans
, indexPtr_
[j
], idxInfo
[j
], tptr
);
597 lMgr_
->releaseLock(tptr
);
598 (*trans
)->removeFromHasList(db_
, tptr
);
599 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
601 //printError(ret, "Unable to insert index node for tuple %x ", tptr);
602 printError(ret
, "Unable to insert index node for tuple %x %d", tptr
, *(int*)tptr
);
607 ret
= (*trans
)->appendUndoLog(sysDB_
, InsertOperation
, tptr
, length_
);
609 printError(ret
, "Unable to create undo log for %x %d", tptr
, *(int*)tptr
);
610 for (int j
= 0; j
< numIndexes_
; j
++) {
611 printError(ErrWarning
, "Deleting index node");
612 deleteIndexNode(*trans
, indexPtr_
[j
], idxInfo
[j
], tptr
);
614 lMgr_
->releaseLock(tptr
);
615 (*trans
)->removeFromHasList(db_
, tptr
);
616 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
621 DbRetVal
TableImpl::deleteTuple()
623 if (NULL
== curTuple_
)
625 printError(ErrNotOpen
, "Scan not open: No Current tuple");
628 DbRetVal ret
= lMgr_
->getExclusiveLock(curTuple_
, trans
);
631 printError(ret
, "Could not get lock for the delete tuple %x", curTuple_
);
632 return ErrLockTimeOut
;
635 if (NULL
!= indexPtr_
)
639 for (i
= 0; i
< numIndexes_
; i
++)
641 ret
= deleteIndexNode(*trans
, indexPtr_
[i
], idxInfo
[i
], curTuple_
);
642 if (ret
!= OK
) break;
644 if (i
!= numIndexes_
)
646 for (int j
= 0; j
< i
; j
++)
647 insertIndexNode(*trans
, indexPtr_
[j
], idxInfo
[j
], curTuple_
);
648 lMgr_
->releaseLock(curTuple_
);
649 (*trans
)->removeFromHasList(db_
, curTuple_
);
650 printError(ret
, "Unable to insert index node for tuple %x", curTuple_
);
654 ((Chunk
*)chunkPtr_
)->free(db_
, curTuple_
);
656 ret
= (*trans
)->appendUndoLog(sysDB_
, DeleteOperation
, curTuple_
, length_
);
661 int TableImpl::deleteWhere()
663 int tuplesDeleted
= 0;
666 if (rv
!=OK
) return (int) rv
;
669 if (rv
!= OK
) { tuplesDeleted
= (int)rv
; break; }
670 if (NULL
== curTuple_
) break;
673 printError(rv
, "Error: Could only delete %d tuples", tuplesDeleted
);
680 return tuplesDeleted
;
683 int TableImpl::truncate()
685 //take exclusive lock on the table
686 //get the chunk ptr of the table
687 //traverse the tablechunks and free all the pages except the first one
688 //get the chunk ptr of all its indexes
689 //traverse the indexchunks and free all the pages except the first one
694 Predicate
* tmpPred
= pred_
;
696 isPlanCreated
= false;
697 int tuplesDeleted
= deleteWhere();
698 isPlanCreated
= false;
700 return tuplesDeleted
;
703 DbRetVal
TableImpl::updateTuple()
705 if (NULL
== curTuple_
)
707 printError(ErrNotOpen
, "Scan not open: No Current tuple");
710 DbRetVal ret
= lMgr_
->getExclusiveLock(curTuple_
, trans
);
713 printError(ret
, "Could not get lock for the update tuple %x", curTuple_
);
714 return ErrLockTimeOut
;
716 if (NULL
!= indexPtr_
)
719 //TODO::If it fails while updating index node, we have to undo all the updates
720 //on other indexes on the table.Currently it will leave the database in an
721 //inconsistent state.
722 for (int i
= 0; i
< numIndexes_
; i
++)
724 ret
= updateIndexNode(*trans
, indexPtr_
[i
], idxInfo
[i
], curTuple_
);
727 lMgr_
->releaseLock(curTuple_
);
728 (*trans
)->removeFromHasList(db_
, curTuple_
);
729 printError(ret
, "Unable to update index node for tuple %x", curTuple_
);
735 ret
= (*trans
)->appendUndoLog(sysDB_
, UpdateOperation
, curTuple_
, length_
);
736 if (ret
!= OK
) return ret
;
738 int iNullVal
=iNullInfo
;
742 iNullInfo
= *(int*)((char*)(curTuple_
) + (length_
- addSize
));
746 *(int*)((char*)(curTuple_
) + (length_
-addSize
)) |= iNullInfo
;
749 DbRetVal rv
= copyValuesFromBindBuffer(curTuple_
, false);
751 lMgr_
->releaseLock(curTuple_
);
752 (*trans
)->removeFromHasList(db_
, curTuple_
);
759 *(int*)((char*)(curTuple_
) + (length_
-addSize
)) = iNullInfo
;
762 else iNullInfo
=iNullVal
;
766 addSize
= os::align(numFlds_
);
767 //TODO::Do not do blind memcpy. It should OR each and every char
768 //os::memcpy(((char*)(curTuple_) + (length_-addSize)), cNullInfo, addSize);
774 void TableImpl::printInfo()
776 printf(" <TableName> %s </TableName>\n", tblName_
);
777 printf(" <TupleCount> %d </TupleCount>\n", numTuples());
778 printf(" <PagesUsed> %d </PagesUsed>\n", pagesUsed());
779 printf(" <SpaceUsed> %d </SpaceUsed>\n", spaceUsed());
780 printf(" <Indexes> %d <Indexes>\n", numIndexes_
);
781 printf(" <TupleLength> %d </TupleLength>\n", length_
);
782 printf(" <Fields> %d </Fields>\n", numFlds_
);
783 printf(" <Indexes>\n");
784 for (int i
=0; i
<numIndexes_
; i
++)
785 printf("<IndexName> %s </IndexName>\n", CatalogTableINDEX::getName(indexPtr_
[i
]));
786 printf(" </Indexes>\n");
790 DbRetVal
TableImpl::copyValuesFromBindBuffer(void *tuplePtr
, bool isInsert
)
792 //Iterate through the bind list and copy the value here
793 FieldIterator fIter
= fldList_
.getIterator();
794 char *colPtr
= (char*) tuplePtr
;
796 while (fIter
.hasElement())
798 FieldDef
*def
= fIter
.nextElement();
799 if (def
->isNull_
&& !def
->isDefault_
&& NULL
== def
->bindVal_
&& isInsert
)
801 printError(ErrNullViolation
, "NOT NULL constraint violation for field %s\n", def
->fldName_
);
802 return ErrNullViolation
;
804 if (def
->isDefault_
&& NULL
== def
->bindVal_
&& isInsert
)
806 void *dest
= AllDataType::alloc(def
->type_
, def
->length_
);
807 AllDataType::convert(typeString
, def
->defaultValueBuf_
, def
->type_
, dest
, def
->length_
);
808 AllDataType::copyVal(colPtr
, dest
, def
->type_
, def
->length_
);
809 colPtr
= colPtr
+ def
->length_
;
817 if (NULL
!= def
->bindVal_
)
819 if(!isInsert
&& isFldNull(fldpos
)){clearNullBit(fldpos
);}
820 strcpy((char*)colPtr
, (char*)def
->bindVal_
);
821 *(((char*)colPtr
) + (def
->length_
-1)) = '\0';
823 else if (!def
->isNull_
&& !def
->bindVal_
&& isInsert
) setNullBit(fldpos
);
824 colPtr
= colPtr
+ def
->length_
;
827 if (NULL
!= def
->bindVal_
)
829 if(!isInsert
&& isFldNull(fldpos
)){clearNullBit(fldpos
);}
830 DbRetVal rv
= AllDataType::strToValue(colPtr
, (char *) def
->bindVal_
, def
->type_
, def
->length_
);
831 if (rv
!= OK
) return ErrBadArg
;
833 else if (!def
->isNull_
&& isInsert
&& !def
->bindVal_
) setNullBit(fldpos
);
834 colPtr
= colPtr
+ def
->length_
;
837 if (NULL
!= def
->bindVal_
){
838 if(!isInsert
&& isFldNull(fldpos
)){clearNullBit(fldpos
);}
839 AllDataType::copyVal(colPtr
, def
->bindVal_
, def
->type_
);}
840 else { if (!def
->isNull_
&& isInsert
) setNullBit(fldpos
); }
841 colPtr
= colPtr
+ def
->length_
;
848 void TableImpl::clearNullBit(int fldpos
)
850 if (isIntUsedForNULL
){
851 CLEARBIT(iNullInfo
, fldpos
);}
853 cNullInfo
[fldpos
-1] = 0;
855 void TableImpl::setNullBit(int fldpos
)
857 if (isIntUsedForNULL
)
858 SETBIT(iNullInfo
, fldpos
);
860 cNullInfo
[fldpos
-1] = 1;
862 DbRetVal
TableImpl::copyValuesToBindBuffer(void *tuplePtr
)
864 //Iterate through the bind list and copy the value here
865 char *colPtr
= (char*) tuplePtr
;
866 FieldDef
*def
= NULL
;
867 for (int i
= 0; i
< numBindFlds_
; i
++) {
868 def
= (FieldDef
*) bindListArray_
[i
];
869 colPtr
= (char *) tuplePtr
+ def
->offset_
;
870 AllDataType::copyVal(def
->bindVal_
, colPtr
, def
->type_
, def
->length_
);
875 //-1 index not supported
876 DbRetVal
TableImpl::insertIndexNode(Transaction
*tr
, void *indexPtr
, IndexInfo
*info
, void *tuple
)
878 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
880 printDebug(DM_Table
, "Inside insertIndexNode type %d", iptr
->indexType_
);
881 Index
* idx
= Index::getIndex(iptr
->indexType_
);
882 ret
= idx
->insert(this, tr
, indexPtr
, info
, tuple
,undoFlag
);
886 DbRetVal
TableImpl::deleteIndexNode(Transaction
*tr
, void *indexPtr
, IndexInfo
*info
, void *tuple
)
888 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
890 Index
* idx
= Index::getIndex(iptr
->indexType_
);
891 ret
= idx
->remove(this, tr
, indexPtr
, info
, tuple
, undoFlag
);
894 void TableImpl::printSQLIndexString()
896 CatalogTableINDEXFIELD
cIndexField(sysDB_
);
897 char fName
[IDENTIFIER_LENGTH
];
898 char *fldName
= fName
;
900 for (int i
= 0; i
< numIndexes_
; i
++)
902 CINDEX
*iptr
= (CINDEX
*) indexPtr_
[i
];
903 printf("CREATE INDEX %s on %s ( ", iptr
->indName_
, getName());
905 cIndexField
.getFieldInfo(iptr
, fldList
);
906 FieldIterator fIter
= fldList
.getIterator();
907 bool firstFld
= true;
908 while(fIter
.hasElement())
910 FieldDef
*def
= fIter
.nextElement();
911 if (firstFld
) { printf(" %s ", def
->fldName_
); firstFld
= false; }
912 else printf(" ,%s ", def
->fldName_
);
915 if (iptr
->indexType_
== hashIndex
) printf(" HASH ");
916 else printf(" TREE ");
917 if (((HashIndexInfo
*) idxInfo
[i
])->isUnique
) printf(" UNIQUE;\n"); else printf(";\n");
922 DbRetVal
TableImpl::updateIndexNode(Transaction
*tr
, void *indexPtr
, IndexInfo
*info
, void *tuple
)
924 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
926 Index
* idx
= Index::getIndex(iptr
->indexType_
);
927 //TODO::currently it updates irrespective of whether the key changed or not
928 //because of this commenting the whole index update code. relook at it and uncomment
930 ret
= idx
->update(this, tr
, indexPtr
, info
, tuple
, undoFlag
);
936 void TableImpl::setTableInfo(char *name
, int tblid
, size_t length
,
937 int numFld
, int numIdx
, void *chunk
)
939 strcpy(tblName_
, name
);
943 numIndexes_
= numIdx
;
947 long TableImpl::spaceUsed()
949 Chunk
*chk
= (Chunk
*)chunkPtr_
;
950 long totSize
= chk
->getTotalDataNodes() * chk
->getSize();
951 totSize
= totSize
+ (chk
->totalPages() * sizeof (PageInfo
));
955 int TableImpl::pagesUsed()
957 Chunk
*chk
= (Chunk
*)chunkPtr_
;
958 return chk
->totalPages();
961 long TableImpl::numTuples()
963 return ((Chunk
*)chunkPtr_
)->getTotalDataNodes();
966 List
TableImpl::getFieldNameList()
969 FieldIterator fIter
= fldList_
.getIterator();
970 char fieldName
[IDENTIFIER_LENGTH
];
971 while (fIter
.hasElement())
973 FieldDef
*def
= fIter
.nextElement();
974 Identifier
*elem
= new Identifier();
975 Table::getFieldNameAlone(def
->fldName_
, fieldName
);
976 sprintf(elem
->name
, "%s.%s", getName(), fieldName
);
977 fldNameList
.append(elem
);
981 DbRetVal
TableImpl::close()
985 //printError(ErrNotOpen,"Scan not open");
987 //PRABA::when called multiple times it gives error
995 DbRetVal
TableImpl::closeScan()
997 //do not throw scan not open error
998 //this function will be called by table handle
1001 //PRABA::TEMP::otherwise fails.check with kishor
1007 DbRetVal
TableImpl::lock(bool shared
)
1013 ret = lMgr_->getSharedLock(chunkPtr_, NULL);
1015 ret = lMgr_->getExclusiveLock(chunkPtr_, NULL);
1018 printError(ret, "Could not exclusive lock on the table %x", chunkPtr_);
1020 //do not append for S to X upgrade
1021 if (!ProcessManager::hasLockList.exists(chunkPtr_))
1022 ProcessManager::hasLockList.append(chunkPtr_);
1027 DbRetVal
TableImpl::unlock()
1030 if (!ProcessManager::hasLockList.exists(chunkPtr_)) return OK;
1031 DbRetVal ret = lMgr_->releaseLock(chunkPtr_);
1034 printError(ret, "Could not release exclusive lock on the table %x", chunkPtr_);
1037 ProcessManager::hasLockList.remove(chunkPtr_);
1043 TableImpl::~TableImpl()
1045 if (NULL
!= iter
) { delete iter
; iter
= NULL
; }
1046 if (NULL
!= indexPtr_
) { delete[] indexPtr_
; indexPtr_
= NULL
; }
1047 if (NULL
!= idxInfo
)
1049 for (int i
= 0; i
< numIndexes_
; i
++) delete idxInfo
[i
];
1053 if (numFlds_
> 31 && cNullInfo
!= NULL
) { free(cNullInfo
); cNullInfo
= NULL
; }
1055 fldList_
.removeAll();
1059 void *TableImpl::getBindFldAddr(const char *name
)
1061 return fldList_
.getBindField(name
);
1063 bool TableImpl::isTableInvolved(char *tblName
)
1065 //printf("Table isTableInvolved called for %s with %s\n", tblName, getName());
1066 if (0 == strcmp(getName(), tblName
)) return true; else return false;
1068 bool TableImpl::pushPredicate(Predicate
*pred
)
1071 PredicateImpl
*pImpl
= (PredicateImpl
*) pred
;
1072 char tableName
[IDENTIFIER_LENGTH
];
1073 Table::getTableNameAlone(pImpl
->getFldName1(), tableName
);
1074 //printf("predicate tbl name %s\n", tableName);
1076 //if predicate is of form t1.f1=t2.f1 then do not push here
1077 if (0 != strcmp(pImpl
->getFldName2(),"")) return ret
;
1079 if (0 == strcmp(getName(), tableName
))
1082 //printf("PRABA::pushed predicate in tablehdl %s\n", getName());
1087 void TableImpl::setPredicate(Predicate
*pred
)
1089 if (NULL
== pred_
) { pred_
= pred
; return; }
1090 Predicate
*curPred
= pred_
;
1091 PredicateImpl
*newPred
= new PredicateImpl();
1092 newPred
->setTerm(curPred
, OpAnd
, pred
);
1093 newPred
->setTable(this);
1097 void TableImpl::printPlan(int space
)
1099 char spaceBuf
[IDENTIFIER_LENGTH
];
1100 memset(spaceBuf
, 32, IDENTIFIER_LENGTH
);
1101 spaceBuf
[space
] = '\0';
1102 printf("%s <TABLE-NODE>\n", spaceBuf
);
1103 printf("%s <NAME> %s </NAME>\n", spaceBuf
, getName());
1104 printf("%s <ScanType> %s </ScanType>\n", spaceBuf
, ScanTypeNames
[scanType_
]);
1105 PredicateImpl
*pred
= (PredicateImpl
*)pred_
;
1106 if (pred
) pred
->print(space
+2);
1107 printf("%s </TABLE-NODE>\n", spaceBuf
);