code reorg
[csql.git] / src / storage / TableImplModifyOp.cxx
blobd57f3dbaaeba4f707271fcfd34fe64d59d00e8e3
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 bool TableImpl::isFldNull(const char *name){
29 if (name[0] == '*') return false;
30 if ( strncasecmp(name,"COUNT",5) == 0 || strncasecmp(name,"AVG",3) == 0 ||
31 strncasecmp(name,"MIN",3) == 0 || strncasecmp(name,"MAX",3) == 0 ||
32 strncasecmp(name,"SUM",3) == 0 ) return false;
33 char fieldName[IDENTIFIER_LENGTH];
34 getFieldNameAlone((char*)name, fieldName);
35 int colpos = fldList_.getFieldPosition(fieldName);
36 if (-1 == colpos)
38 printError(ErrNotExists, "Field %s does not exist", name);
39 return false;
42 return isFldNull(colpos);
45 bool TableImpl::isFldNull(int colpos)
47 if (!curTuple_) return false;
48 if (colpos <1 || colpos > numFlds_) return false;
49 if (isIntUsedForNULL) {
50 int nullVal = *(int*)((char*)curTuple_ + (length_ - 4));
51 if (BITSET(nullVal, colpos-1)) return true;
53 else {
54 char *nullOffset = (char*)curTuple_ + (length_ - os::align(numFlds_));
55 if (nullOffset[colpos-1]) return true;
57 return false;
60 void TableImpl::resetNullinfo()
62 if (isIntUsedForNULL) {
63 iNullInfo =0;
65 else {
66 int i=0;
67 while(i < numFlds_) { cNullInfo[i++] = 0;}
71 DbRetVal TableImpl::markFldNull(char const* name)
73 DbRetVal rv = OK;
74 int colpos = fldList_.getFieldPosition(name);
75 if (-1 == colpos)
77 printError(ErrNotExists, "Field %s does not exist", name);
78 return ErrNotExists;
80 rv = markFldNull(colpos);
81 return rv;
84 DbRetVal TableImpl::markFldNull(int fldpos)
86 if (fldpos <1 || fldpos > numFlds_) return ErrBadArg;
87 if (isIntUsedForNULL) {
88 if (!BITSET(iNotNullInfo, fldpos-1)) SETBIT(iNullInfo, fldpos-1);
89 else {
90 printError(ErrNullViolation, "NOT NULL constraint violation");
91 return ErrNullViolation;
94 else {
95 if (!cNotNullInfo[fldpos-1]) cNullInfo[fldpos-1] = 1;
96 else {
97 printError(ErrNullViolation, "NOT NULL constraint violation");
98 return ErrNullViolation;
101 return OK;
104 void TableImpl::clearFldNull(const char *name)
106 int colpos = fldList_.getFieldPosition(name);
107 if (-1 == colpos)
109 printError(ErrNotExists, "Field %s does not exist", name);
110 return;
112 clearFldNull(colpos);
115 void TableImpl::clearFldNull(int colpos)
117 if (colpos <1 || colpos > numFlds_) return;
118 if (isIntUsedForNULL) CLEARBIT(iNullInfo, colpos-1);
119 else cNullInfo[colpos-1] = 0;
120 return;
123 DbRetVal TableImpl::insertTuple()
125 DbRetVal ret = getCheckpointMutex();
126 if (ret !=OK) return ret;
127 void *tptr = NULL;
128 int tries=0;
129 int totalTries = Conf::config.getMutexRetries();
130 while (tries < totalTries)
132 ret = OK;
133 tptr = ((Chunk*)chunkPtr_)->allocate(db_, &ret);
134 if (tptr !=NULL) break;
135 if (ret != ErrLockTimeOut)
137 sysDB_->releaseCheckpointMutex();
138 printError(ret, "Unable to allocate record from chunk");
139 return ret;
141 tries++;
143 if (NULL == tptr)
145 sysDB_->releaseCheckpointMutex();
146 printError(ret, "Unable to allocate record from chunk after %d retries", tries);
147 return ret;
149 curTuple_ = tptr;
150 if(isFkTbl){
151 TableImpl *fkTbl =NULL;
152 ListIterator tblIter = tblList.getIterator();
153 tblIter.reset();
154 while (tblIter.hasElement()){
155 fkTbl = (TableImpl *) tblIter.nextElement();
156 bool pkRec = isPkTableHasRecord(fkTbl->getName(),fkTbl,true);
157 if(!pkRec){
158 printError(ErrForeignKeyInsert, "Unable to insert into foreign Key table.Check PK table");
159 ((Chunk*)chunkPtr_)->free(db_, tptr);
160 sysDB_->releaseCheckpointMutex();
161 return ErrForeignKeyInsert;
164 tblIter.reset();
166 if (!loadFlag) {
167 //ret = lMgr_->getExclusiveLock(tptr, trans);
168 if (OK != tryExclusiveLock(tptr, trans))
170 ((Chunk*)chunkPtr_)->free(db_, tptr);
171 printError(ret, "Could not get lock for the insert tuple %x", tptr);
172 sysDB_->releaseCheckpointMutex();
173 return ErrLockTimeOut;
177 ret = copyValuesFromBindBuffer(tptr);
178 if (ret != OK)
180 printError(ret, "Unable to copy values from bind buffer");
181 if (!loadFlag) {
182 (*trans)->removeFromHasList(db_, tptr);
183 lMgr_->releaseLock(tptr);
186 FieldIterator fIter = fldList_.getIterator();
187 char *colPtr = (char*) curTuple_;
188 while (fIter.hasElement()) {
189 FieldDef *def = fIter.nextElement();
190 colPtr = (char *) curTuple_ + def->offset_;
191 if (def->type_ == typeVarchar) {
192 char *ptr = (char *) *(long *) colPtr;
193 if (ptr != 0L) ((Chunk *) vcChunkPtr_)->free(db_, ptr);
196 ((Chunk*)chunkPtr_)->free(db_, tptr);
197 sysDB_->releaseCheckpointMutex();
198 return ret;
200 int addSize = 0;
201 if (numFlds_ < 31)
203 addSize = 4;
204 *(int*)((char*)(tptr) + (length_-addSize)) = iNullInfo;
206 else
208 addSize = os::align(numFlds_);
209 os::memcpy(((char*)(tptr) + (length_-addSize)), cNullInfo, addSize);
212 //int tupleSize = length_ + addSize;
213 if (NULL != indexPtr_)
215 int i;
216 //it has index
217 for (i = 0; i < numIndexes_ ; i++)
219 ret = insertIndexNode(*trans, indexPtr_[i], idxInfo[i], tptr);
220 if (ret != OK) { printError(ret, "Error in inserting to index %x", tptr); break;}
222 if ( ret != OK)
224 for (int j = 0; j < i ; j++) {
225 printError(ErrWarning, "Undo:Deleting index node");
226 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
228 if (!loadFlag) {
229 (*trans)->removeFromHasList(db_, tptr);
230 lMgr_->releaseLock(tptr);
233 FieldIterator fIter = fldList_.getIterator();
234 char *colPtr = (char*) curTuple_;
235 while (fIter.hasElement()) {
236 FieldDef *def = fIter.nextElement();
237 colPtr = (char *) curTuple_ + def->offset_;
238 if (def->type_ == typeVarchar) {
239 char *ptr = (char *) *(long *) colPtr;
240 if (ptr != 0L) ((Chunk *) vcChunkPtr_)->free(db_, ptr);
243 ((Chunk*)chunkPtr_)->free(db_, tptr);
244 sysDB_->releaseCheckpointMutex();
245 return ret;
248 if (!loadFlag) {
249 //TODO: number of varchar fields to be stored as a member in TableImpl
250 int nVarchars = 0;
251 FieldIterator fIter = fldList_.getIterator();
252 while (fIter.hasElement()) {
253 FieldDef *def = fIter.nextElement();
254 if (def->type_ == typeVarchar) nVarchars++;
257 // the undo log for insert should contain
258 // tuple ptr + metadata Ptr + no of varchars + ptrs to varchars for insert opearation
259 int size = (3 + nVarchars) * sizeof(void *) + sizeof(int);
260 void *data = malloc(size);
261 char *ptr = (char *)data;
262 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
263 void *metaData = db_->getMetaDataPtr();
264 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
265 *(int *) ptr = nVarchars; ptr += sizeof(int);
266 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
267 fIter = fldList_.getIterator();
268 char *colPtr = (char*) curTuple_;
269 while (fIter.hasElement()) {
270 FieldDef *def = fIter.nextElement();
271 colPtr = (char *) curTuple_ + def->offset_;
272 if (def->type_ == typeVarchar) {
273 *(long *) ptr = (long)colPtr;
274 ptr += sizeof(void *);
277 ret = (*trans)->appendUndoLog(sysDB_, InsertOperation, data, size);
278 ::free(data);
280 if (ret != OK) {
281 printError(ret, "Unable to create undo log for %x %d", tptr, *(int*)tptr);
282 for (int j = 0; j < numIndexes_ ; j++) {
283 printError(ErrWarning, "Deleting index node");
284 deleteIndexNode(*trans, indexPtr_[j], idxInfo[j], tptr);
286 if (!loadFlag) {
287 (*trans)->removeFromHasList(db_, tptr);
288 lMgr_->releaseLock(tptr);
290 ((Chunk*)chunkPtr_)->free(db_, tptr);
292 sysDB_->releaseCheckpointMutex();
293 return ret;
296 DbRetVal TableImpl::deleteTuple()
298 if (NULL == curTuple_)
300 printError(ErrNotOpen, "Scan not open: No Current tuple");
301 return ErrNotOpen;
303 DbRetVal ret = getCheckpointMutex();
304 if (ret != OK) return ret;
305 if(isPkTbl){
306 TableImpl *fkTbl =NULL;
307 ListIterator tblIter = tblFkList.getIterator();
308 tblIter.reset();
309 while (tblIter.hasElement()){
310 fkTbl = (TableImpl *) tblIter.nextElement();
311 bool pkRec = isFkTableHasRecord(fkTbl->getName(),fkTbl);
312 if(pkRec){
313 printError(ErrForeignKeyDelete, "A Relation Exists. Delete from child table first");
314 sysDB_->releaseCheckpointMutex();
315 return ErrForeignKeyDelete;
318 tblIter.reset();
320 if (!loadFlag) {
321 //ret = lMgr_->getExclusiveLock(curTuple_, trans);
322 if (OK != tryExclusiveLock(curTuple_, trans))
324 printError(ret, "Could not get lock for the delete tuple %x",
325 curTuple_);
326 sysDB_->releaseCheckpointMutex();
327 return ErrLockTimeOut;
331 if (NULL != indexPtr_)
333 int i;
334 //it has index
335 for (i = 0; i < numIndexes_ ; i++)
337 ret = deleteIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
338 if (ret != OK) break;
340 if (i != numIndexes_ )
342 printError(ErrWarning, "Inserting back index node");
343 for (int j = 0; j < i ; j++)
344 insertIndexNode(*trans, indexPtr_[j], idxInfo[j], curTuple_);
345 if (!loadFlag) {
346 lMgr_->releaseLock(curTuple_);
347 (*trans)->removeFromHasList(db_, curTuple_);
349 printError(ret, "Unable to insert index node for tuple %x", curTuple_);
350 sysDB_->releaseCheckpointMutex();
351 return ret;
354 if (!loadFlag) {
355 // the undo log for delete should contain
356 // tupleptr + metadataPtr + nVarchars + varchar chunk ptr +
357 // ptrs to varchars + size and value pairs for varchars
359 //TODO: number of varchar fields to be stored as a member in TableImpl
360 void *tptr = curTuple_;
361 char *colPtr = (char *)curTuple_;
362 int nVarchars = 0;
363 int vcLenValPairSize = 0;
364 FieldIterator fIter = fldList_.getIterator();
365 while (fIter.hasElement()) {
366 FieldDef *def = fIter.nextElement();
367 colPtr = (char *) curTuple_ + def->offset_;
368 if (def->type_ == typeVarchar) {
369 nVarchars++;
370 if (* (long *) colPtr == 0L)
371 vcLenValPairSize = vcLenValPairSize + sizeof(int);
372 else vcLenValPairSize = vcLenValPairSize + sizeof(int) +
373 + os::align(strlen((char *) *(long *)colPtr) + 1);
376 int size = (3 + nVarchars) * sizeof(void *) + sizeof(int)
377 + vcLenValPairSize;
378 void *data = malloc(size);
379 char *ptr = (char *)data;
380 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
381 void *metaData = db_->getMetaDataPtr();
382 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
383 *(int *) ptr = nVarchars; ptr += sizeof(int);
384 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
385 fIter = fldList_.getIterator();
386 colPtr = (char*) curTuple_;
387 char *valLenPairPtr = ptr + nVarchars * sizeof(void *);
388 while (fIter.hasElement()) {
389 FieldDef *def = fIter.nextElement();
390 colPtr = (char *) curTuple_ + def->offset_;
391 int vcStrLen = 0;
392 if (def->type_ == typeVarchar) {
393 *(long *) ptr = (long )colPtr; ptr += sizeof(void *);
394 if (*(long *) colPtr == 0L) {
395 *(int *) valLenPairPtr = vcStrLen = 0;
396 valLenPairPtr += sizeof(int);
397 } else {
398 *(int *) valLenPairPtr = vcStrLen =
399 os::align(strlen((char *)*(long *)colPtr) + 1);
400 valLenPairPtr += sizeof(int);
401 strcpy(valLenPairPtr, (char *)*(long *)colPtr);
402 valLenPairPtr += vcStrLen;
406 ret = (*trans)->appendUndoLog(sysDB_, DeleteOperation, data, size);
407 ::free(data);
409 if (ret != OK) {
410 printError(ret, "Unable to create undo log for %x ", curTuple_);
411 for (int j = 0; j < numIndexes_ ; j++) {
412 printError(ErrWarning, "Inserting back index node");
413 insertIndexNode(*trans, indexPtr_[j], idxInfo[j], curTuple_);
415 if (!loadFlag) {
416 (*trans)->removeFromHasList(db_, curTuple_);
417 lMgr_->releaseLock(curTuple_);
421 FieldIterator fIter = fldList_.getIterator();
422 char *colPtr = (char*) curTuple_;
423 while (fIter.hasElement()) {
424 FieldDef *def = fIter.nextElement();
425 colPtr = (char *) curTuple_ + def->offset_;
426 if (def->type_ == typeVarchar) {
427 if (*(long *) colPtr != 0L) {
428 char *ptr = (char *) *(long *) colPtr;
429 ((Chunk *) vcChunkPtr_)->free(db_, ptr);
433 ((Chunk*)chunkPtr_)->free(db_, curTuple_);
434 iter->prev();
435 sysDB_->releaseCheckpointMutex();
436 return ret;
439 int TableImpl::deleteWhere()
441 DbRetVal ret = getCheckpointMutex();
442 if (ret !=OK) return ret;
444 int tuplesDeleted = 0;
445 DbRetVal rv = OK;
446 rv = execute();
447 if (rv !=OK) {
448 sysDB_->releaseCheckpointMutex();
449 return (int) rv;
451 while(true){
452 fetchNoBind( rv);
453 if (rv != OK) { tuplesDeleted = (int)rv; break; }
454 if (NULL == curTuple_) break;
455 rv = deleteTuple();
456 if (rv != OK) {
457 printError(rv, "Error: Could only delete %d tuples", tuplesDeleted);
458 closeScan();
459 sysDB_->releaseCheckpointMutex();
460 return (int) rv;
462 tuplesDeleted++;
464 closeScan();
465 sysDB_->releaseCheckpointMutex();
466 return tuplesDeleted;
469 int TableImpl::truncate()
471 //take exclusive lock on the table
472 //get the chunk ptr of the table
473 //traverse the tablechunks and free all the pages except the first one
474 //get the chunk ptr of all its indexes
475 //traverse the indexchunks and free all the pages except the first one
476 //release table lock
478 //TEMPORARY FIX
479 DbRetVal rv = OK;
480 Predicate* tmpPred = pred_;
481 pred_ = NULL;
482 isPlanCreated = false;
483 int tuplesDeleted = deleteWhere();
484 isPlanCreated = false;
485 pred_ = tmpPred;
486 return tuplesDeleted;
489 DbRetVal TableImpl::updateTuple()
491 if (NULL == curTuple_)
493 printError(ErrNotOpen, "Scan not open: No Current tuple");
494 return ErrNotOpen;
496 DbRetVal ret = getCheckpointMutex();
497 if (ret !=OK) return ret;
498 if(isFkTbl){
499 TableImpl *fkTbl =NULL;
500 ListIterator tblIter = tblList.getIterator();
501 tblIter.reset();
502 while (tblIter.hasElement()){
503 fkTbl = (TableImpl *) tblIter.nextElement();
504 bool pkRec = isPkTableHasRecord(fkTbl->getName(),fkTbl,false);
505 if(!pkRec){
506 printError(ErrForeignKeyInsert, "Unable to insert into foreign Key table.Check PK table");
507 sysDB_->releaseCheckpointMutex();
508 return ErrForeignKeyInsert;
511 tblIter.reset();
514 if (!loadFlag) {
515 //ret = lMgr_->getExclusiveLock(curTuple_, trans);
516 if (OK != tryExclusiveLock(curTuple_, trans))
518 printError(ret, "Could not get lock for the update tuple %x", curTuple_);
519 sysDB_->releaseCheckpointMutex();
520 return ErrLockTimeOut;
523 if (NULL != indexPtr_)
525 //it has index
526 //TODO::If it fails while updating index node, we have to undo all the updates
527 //on other indexes on the table.Currently it will leave the database in an
528 //inconsistent state.
529 for (int i = 0; i < numIndexes_ ; i++)
531 ret = updateIndexNode(*trans, indexPtr_[i], idxInfo[i], curTuple_);
532 if (ret != OK)
534 if (!loadFlag) {
535 lMgr_->releaseLock(curTuple_);
536 (*trans)->removeFromHasList(db_, curTuple_);
538 printError(ret, "Unable to update index node for tuple %x", curTuple_);
539 sysDB_->releaseCheckpointMutex();
540 return ret;
545 if (!loadFlag) {
546 // the undo log for update should contain
547 // tupleptr + tuple length + actual tuple + metadataPtr +
548 // nVarchars + varchar chunk ptr + ptrs to varchars +
549 // size and value pairs for varchars
551 //TODO: number of varchar fields to be stored as a member in TableImpl
552 void *tptr = curTuple_;
553 char *colPtr = (char *)curTuple_;
554 int nVarchars = 0;
555 int vcLenValPairSize = 0;
556 FieldIterator fIter = fldList_.getIterator();
557 while (fIter.hasElement()) {
558 FieldDef *def = fIter.nextElement();
559 colPtr = (char *) curTuple_ + def->offset_;
560 if (def->type_ == typeVarchar) {
561 nVarchars++;
562 if (* (long *) colPtr == 0L)
563 vcLenValPairSize = vcLenValPairSize + sizeof(int);
564 else vcLenValPairSize = vcLenValPairSize + sizeof(int) +
565 + os::align(strlen((char *) *(long *)colPtr) + 1);
568 int size = (3 + nVarchars) * sizeof(void *) + 2 * sizeof(int) +
569 vcLenValPairSize + length_;
570 void *data = malloc(size);
571 char *ptr = (char *) data;
572 *(long *) ptr = (long) tptr; ptr += sizeof(void *);
573 *(int *) ptr = length_; ptr += sizeof(int);
574 os::memcpy(ptr, tptr, length_); ptr += length_;
575 void *metaData = db_->getMetaDataPtr();
576 *(long *) ptr = (long) metaData; ptr += sizeof(void *);
577 *(int *) ptr = nVarchars; ptr += sizeof(int);
578 *(long *) ptr = (long) vcChunkPtr_; ptr += sizeof(void *);
579 fIter = fldList_.getIterator();
580 colPtr = (char*) curTuple_;
581 char *valLenPairPtr = ptr + nVarchars * sizeof(void *);
582 while (fIter.hasElement()) {
583 FieldDef *def = fIter.nextElement();
584 colPtr = (char *) curTuple_ + def->offset_;
585 int vcStrLen = 0;
586 if (def->type_ == typeVarchar) {
587 *(long *) ptr = (long)colPtr; ptr += sizeof(void *);
588 if (*(long *) colPtr == 0L) {
589 *(int *) valLenPairPtr = vcStrLen = 0;
590 valLenPairPtr += sizeof(int);
591 } else {
592 *(int *) valLenPairPtr = vcStrLen =
593 os::align(strlen((char *)*(long *)colPtr) + 1);
594 valLenPairPtr += sizeof(int);
595 strcpy(valLenPairPtr, (char *)*(long *)colPtr);
596 valLenPairPtr += vcStrLen;
600 ret = (*trans)->appendUndoLog(sysDB_, UpdateOperation, data, size);
601 ::free(data);
603 if (ret != OK) {
604 if (!loadFlag) {
605 lMgr_->releaseLock(curTuple_);
606 (*trans)->removeFromHasList(db_, curTuple_);
608 sysDB_->releaseCheckpointMutex();
609 return ret;
612 int addSize = 0;
613 int iNullVal=iNullInfo;
614 char *cNullVal = NULL;
615 if (numFlds_ > 32) {
616 addSize = os::align(numFlds_);
617 cNullVal = (char *) malloc(addSize);
618 os::memcpy(cNullVal, cNullInfo, addSize);
620 bool nullCharSet = false;
621 if (numFlds_ <= 32){
622 addSize=4;
623 if (!iNullVal)
624 iNullInfo = *(int*)((char*)(curTuple_) + (length_- addSize));
625 else
626 *(int*)((char*)(curTuple_) + (length_-addSize)) |= iNullInfo;
627 } else {
628 int i=0;
629 while(i < numFlds_) {
630 if(cNullInfo[i++]) { nullCharSet = true; break; }
632 char *null=(char*)(curTuple_) + (length_-addSize);
633 if (!nullCharSet) {
634 i=0;
635 while(i < numFlds_) {
636 if(null[i]) cNullInfo[i] = null[i];
637 i++;
639 } else {
640 i = 0;
641 while(i < numFlds_) {
642 if(cNullInfo[i]) { null[i] |= cNullInfo[i]; }
643 i++;
647 DbRetVal rv = copyValuesFromBindBuffer(curTuple_, false);
648 if (rv != OK && !loadFlag) {
649 lMgr_->releaseLock(curTuple_);
650 (*trans)->removeFromHasList(db_, curTuple_);
651 sysDB_->releaseCheckpointMutex();
652 return rv;
654 if (numFlds_ <= 32) {
655 if (!iNullVal) {
656 *(int*)((char*)(curTuple_) + (length_-addSize)) = iNullInfo;
657 iNullInfo=0;
658 } else iNullInfo=iNullVal;
659 } else {
660 int i = 0;
661 char *null=(char*)(curTuple_) + (length_-addSize);
662 if (!nullCharSet) {
663 os::memcpy(null, cNullInfo, addSize);
664 while (i < numFlds_) cNullInfo[i++] = 0;
665 } else os::memcpy(cNullInfo, cNullVal, addSize);
666 free(cNullVal); cNullVal = NULL;
668 sysDB_->releaseCheckpointMutex();
669 return OK;
672 long long TableImpl::getLastInsertedVal(DbRetVal &rv)
674 rv=OK;
675 return *(long long*)ptrToAuto;
678 void TableImpl::clearNullBit(int fldpos)
680 if (fldpos <1 || fldpos > numFlds_) return;
681 if (isIntUsedForNULL) CLEARBIT(iNullInfo, fldpos-1);
682 else cNullInfo[fldpos-1] = 0;
685 void TableImpl::setNullBit(int fldpos)
687 if (fldpos <1 || fldpos > numFlds_) return;
688 if (isIntUsedForNULL) SETBIT(iNullInfo, fldpos-1);
689 else cNullInfo[fldpos-1] = 1;
693 //-1 index not supported
694 DbRetVal TableImpl::insertIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
696 CINDEX *iptr = (CINDEX*)indexPtr;
697 DbRetVal ret = OK;
698 printDebug(DM_Table, "Inside insertIndexNode type %d", iptr->indexType_);
699 Index* idx = Index::getIndex(iptr->indexType_);
700 ret = idx->insert(this, tr, indexPtr, info, tuple,loadFlag);
701 return ret;
704 DbRetVal TableImpl::deleteIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
706 CINDEX *iptr = (CINDEX*)indexPtr;
707 DbRetVal ret = OK;
708 Index* idx = Index::getIndex(iptr->indexType_);
709 ret = idx->remove(this, tr, indexPtr, info, tuple, loadFlag);
710 return ret;
713 DbRetVal TableImpl::updateIndexNode(Transaction *tr, void *indexPtr, IndexInfo *info, void *tuple)
715 CINDEX *iptr = (CINDEX*)indexPtr;
716 DbRetVal ret = OK;
717 Index* idx = Index::getIndex(iptr->indexType_);
718 //TODO::currently it updates irrespective of whether the key changed or not
719 //because of this commenting the whole index update code. relook at it and uncomment
721 ret = idx->update(this, tr, indexPtr, info, tuple, loadFlag);
723 return ret;
726 bool TableImpl::isPkTableHasRecord(char *pkTableName, TableImpl *fkTbl,bool isInsert)
728 DbRetVal rv=OK;
729 bool isRecExist=false;
730 FieldNameList pkFieldList,fkFieldList;
731 void *tPkptr =NULL;
732 void *tFkptr = NULL;
733 void *chunkPk = NULL;
734 void *vcchunkPk = NULL;
735 CatalogTableTABLE cTable(sysDB_);
736 rv = cTable.getChunkAndTblPtr(pkTableName, chunkPk, tPkptr, vcchunkPk);
737 if ( OK != rv){return false;}
738 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tFkptr, vcchunkPk);
739 if ( OK != rv){return false;}
740 CatalogTableFK cFk(sysDB_);
741 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
742 if ( OK != rv){return false;}
743 int totFld = pkFieldList.size();
744 Condition *condition = new Condition[totFld];
745 char *pkFldName = NULL;
746 char *fkFldName = NULL;
747 FieldDef *def=NULL;
748 int i=0;
749 pkFieldList.resetIter();
750 fkFieldList.resetIter();
751 void *val=NULL;
752 while((pkFldName = pkFieldList.nextFieldName())!= NULL)
754 fkFldName = fkFieldList.nextFieldName();
755 FieldIterator fIter = fldList_.getIterator();
756 while (fIter.hasElement())
758 def = fIter.nextElement();
759 if (strcmp(def->fldName_, fkFldName) == 0)
761 if(NULL == def->bindVal_ && isInsert) { return true; }
762 if(NULL == def->bindVal_) {
763 if (def->type_ != typeVarchar)
764 val = (char*)curTuple_+ def->offset_;
765 else val = (void *) *(long *) ((char*)curTuple_+
766 def->offset_);
767 } else {
768 val = def->bindVal_;
770 if(def->type_==typeString)
771 condition[i].setTerm(pkFldName,OpEquals,&val);
772 else
773 condition[i].setTerm(pkFldName,OpEquals,val);
774 i++;
775 break;
779 pkFieldList.removeAll();
780 fkFieldList.removeAll();
781 Condition *cond = NULL;
782 if(i == 0 && !isInsert)return true;
783 if( i > 1){
784 cond = new Condition[i-1];
785 int totcon = i;
786 i=0;
787 int j=0;
788 for(j=0;j<totcon-1;j++)
790 if(j==0)
791 cond[j].setTerm(condition[i++].getPredicate(),OpAnd,condition[i++].getPredicate());
792 else
793 cond[j].setTerm(cond[j-1].getPredicate(), OpAnd, condition[i++].getPredicate());
795 fkTbl->setCondition(&cond[j-1]);
797 else{
798 fkTbl->setCondition(&condition[i-1]);
800 fkTbl->execute();
801 if(fkTbl->fetch()){
802 fkTbl->closeScan();
803 delete[] cond;
804 delete[] condition;
805 return true;
807 delete[] cond;
808 delete[] condition;
809 return false;
812 bool TableImpl::isFkTableHasRecord(char *pkTableName, TableImpl *fkTbl)
814 DbRetVal rv=OK;
815 FieldNameList pkFieldList,fkFieldList;
816 void *tPkptr =NULL;
817 void *tFkptr = NULL;
818 void *chunkPk = NULL;
819 void *vcchunkPk = NULL;
820 CatalogTableTABLE cTable(sysDB_);
821 rv = cTable.getChunkAndTblPtr(getName(), chunkPk, tPkptr, vcchunkPk);
822 if ( OK != rv){return false;}
823 rv = cTable.getChunkAndTblPtr(pkTableName, chunkPk, tFkptr, vcchunkPk);
824 if ( OK != rv){return false;}
825 CatalogTableFK cFk(sysDB_);
826 rv = cFk.getPkFkFieldInfo(tPkptr,tFkptr,pkFieldList,fkFieldList);
827 if ( OK != rv){return false;}
828 int totFld = pkFieldList.size();
829 Condition *condition = new Condition[totFld];
830 char *pkFldName = NULL;
831 char *fkFldName = NULL;
832 FieldDef *def=NULL;
833 int i=0;
834 pkFieldList.resetIter();
835 fkFieldList.resetIter();
836 while((pkFldName = pkFieldList.nextFieldName())!= NULL)
838 fkFldName = fkFieldList.nextFieldName();
839 FieldIterator fIter = fldList_.getIterator();
840 while (fIter.hasElement())
842 def = fIter.nextElement();
843 void *val = NULL;
844 if (def->type_ != typeVarchar)
845 val = (char*)curTuple_+ def->offset_;
846 else val = (void *) *(long *) ((char*)curTuple_+ def->offset_);
847 if (strcmp(def->fldName_, pkFldName) == 0)
849 if(def->type_==typeString)
850 condition[i].setTerm(fkFldName,OpEquals,&val);//((char*)curTuple_+def->offset_));
851 else
852 condition[i].setTerm(fkFldName,OpEquals,val);//((char*)curTuple_+def->offset_));
853 i++;
854 break;
858 pkFieldList.removeAll();
859 fkFieldList.removeAll();
860 if(i == 0 )return true;
861 Condition *cond = new Condition[i-1];
862 i=0;
863 int j=0;
864 for(j=0;j<totFld-1;j++)
866 if(j==0)
867 cond[j].setTerm(condition[i++].getPredicate(),OpAnd,condition[i++].getPredicate());
868 else
869 cond[j].setTerm(cond[j-1].getPredicate(), OpAnd, condition[i++].getPredicate());
871 if(totFld==1)
872 fkTbl->setCondition(&condition[totFld-1]);
873 else
874 fkTbl->setCondition(&cond[j-1]);
875 fkTbl->execute();
876 if(fkTbl->fetch()){
877 fkTbl->closeScan();
878 delete[] cond;
879 delete[] condition;
880 return true;
882 delete[] cond;
883 delete[] condition;
884 return false;