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 DbRetVal
TableImpl::bindFld(const char *name
, void *val
)
29 //set it in the field list
30 DbRetVal rv
= fldList_
.updateBindVal(name
, val
);
32 printError(ErrNotExists
, "Field %s does not exist", name
);
37 bool TableImpl::isFldNull(const char *name
){
40 bool TableImpl::isFldNull(int colpos
)
44 void TableImpl::markFldNull(char const* name
)
48 void TableImpl::markFldNull(int fldpos
)
54 void TableImpl::clearFldNull(const char *name)
58 void TableImpl::clearFldNull(int colpos)
64 DbRetVal
TableImpl::execute()
68 printError(ErrAlready
,"Scan already open:Close and re execute");
71 //table ptr is set in predicate because it needs to access the
72 //type and length to evaluate
75 PredicateImpl
*pred
= (PredicateImpl
*) pred_
;
83 printError(ErrSysInternal
,"Unable to create the plan");
84 return ErrSysInternal
;
86 iter
= new TupleIterator(pred_
, scanType_
, idxInfo
, chunkPtr_
);
90 printError(ErrSysInternal
,"Unable to open the iterator");
91 return ErrSysInternal
;
97 DbRetVal
TableImpl::createPlan()
100 //if there are no predicates then go for full scan
101 //if there are no indexes then go for full scan
102 if (NULL
== pred_
|| NULL
== indexPtr_
)
104 scanType_
= fullTableScan
;
107 if (NULL
!= indexPtr_
)
109 //Note:numIndexes_ == 0 is handled above. for this case indexPtr_ is null
110 if (numIndexes_
== 1) {
111 //check predicate, whether it has field name and == operator
112 //and does not have OR, NOT operator
113 char *fName
= ((SingleFieldHashIndexInfo
*)idxInfo
)->fldName
;
114 PredicateImpl
*pred
= (PredicateImpl
*)pred_
;
115 if (pred
->pointLookupInvolved(fName
))
117 scanType_
= hashIndexScan
;
123 scanType_
= fullTableScan
;
133 scanType_
= fullTableScan
;
137 void* TableImpl::fetch()
140 if (NULL
== curTuple_
) return curTuple_
;
141 copyValuesToBindBuffer(curTuple_
);
145 void* TableImpl::fetchNoBind()
149 printError(ErrNotOpen
,"Scan not open or Scan is closed\n");
152 curTuple_
= iter
->next();
153 if (NULL
== curTuple_
)
157 DbRetVal lockRet
= OK
;
158 if ((*trans
)->isoLevel_
== READ_REPEATABLE
) {
159 lockRet
= lMgr_
->getSharedLock(curTuple_
, trans
);
162 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
167 else if ((*trans
)->isoLevel_
== READ_COMMITTED
)
169 //if iso level is read committed, operation duration lock is sufficent
170 //so release it here itself.
172 struct timeval timeout
;
173 timeout
.tv_sec
= Conf::config
.getMutexSecs();
174 timeout
.tv_usec
= Conf::config
.getMutexUSecs();
178 lockRet
= lMgr_
->isExclusiveLocked( curTuple_
, trans
, status
);
181 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
186 if (tries
== 0) break;
187 os::select(0, 0, 0, 0, &timeout
);
192 printError(lockRet
, "Unable to get the lock for the tuple %x", curTuple_
);
199 DbRetVal
TableImpl::insertTuple()
201 void *tptr
= ((Chunk
*)chunkPtr_
)->allocate(db_
);
204 printError(ErrNoMemory
, "Unable to allocate memory to store tuple");
207 DbRetVal ret
= lMgr_
->getExclusiveLock(tptr
, trans
);
210 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
211 printError(ret
, "Could not get lock for the insert tuple %x", tptr
);
214 int tupleSize
= fldList_
.getTupleSize ();
217 ret
= copyValuesFromBindBuffer(tptr
);
220 printError(ret
, "Unable to copy values from bind buffer");
221 lMgr_
->releaseLock(tptr
);
222 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
225 if (NULL
!= indexPtr_
)
229 for (i
= 0; i
< numIndexes_
; i
++)
231 ret
= insertIndexNode(*trans
, indexPtr_
[i
], tptr
);
232 if (ret
!= OK
) break;
234 if (i
!= numIndexes_
)
236 for (int j
= 0; j
< i
; j
++)
237 deleteIndexNode(*trans
, indexPtr_
[j
], tptr
);
238 lMgr_
->releaseLock(tptr
);
239 ((Chunk
*)chunkPtr_
)->free(db_
, tptr
);
240 printError(ret
, "Unable to insert index node for tuple %x", tptr
);
245 (*trans
)->appendUndoLog(sysDB_
, InsertOperation
, tptr
, tupleSize
);
249 DbRetVal
TableImpl::deleteTuple()
251 if (NULL
== curTuple_
)
253 printError(ErrNotOpen
, "Scan not open: No Current tuple");
256 DbRetVal ret
= lMgr_
->getExclusiveLock(curTuple_
, trans
);
259 printError(ret
, "Could not get lock for the delete tuple %x", curTuple_
);
263 if (NULL
!= indexPtr_
)
267 for (i
= 0; i
< numIndexes_
; i
++)
269 ret
= deleteIndexNode(*trans
, indexPtr_
[i
], curTuple_
);
270 if (ret
!= OK
) break;
272 if (i
!= numIndexes_
)
274 for (int j
= 0; j
< i
; j
++)
275 insertIndexNode(*trans
, indexPtr_
[j
], curTuple_
);
276 lMgr_
->releaseLock(curTuple_
);
277 printError(ret
, "Unable to insert index node for tuple %x", curTuple_
);
281 ((Chunk
*)chunkPtr_
)->free(db_
, curTuple_
);
282 (*trans
)->appendUndoLog(sysDB_
, DeleteOperation
, curTuple_
, fldList_
.getTupleSize());
286 DbRetVal
TableImpl::updateTuple()
288 if (NULL
== curTuple_
)
290 printError(ErrNotOpen
, "Scan not open: No Current tuple");
293 DbRetVal ret
= lMgr_
->getExclusiveLock(curTuple_
, trans
);
296 printError(ret
, "Could not get lock for the update tuple %x", curTuple_
);
299 if (NULL
!= indexPtr_
)
302 //TODO::If it fails while updating index node, we have to undo all the updates
303 //on other indexes on the table.Currently it will leave the database in an
304 //inconsistent state.
305 for (int i
= 0; i
< numIndexes_
; i
++)
307 ret
= updateIndexNode(*trans
, indexPtr_
[i
], curTuple_
);
310 lMgr_
->releaseLock(curTuple_
);
311 printError(ret
, "Unable to update index node for tuple %x", curTuple_
);
316 (*trans
)->appendUndoLog(sysDB_
, UpdateOperation
, curTuple_
, fldList_
.getTupleSize());
317 return copyValuesFromBindBuffer(curTuple_
);
320 DbRetVal
TableImpl::copyValuesFromBindBuffer(void *tuplePtr
)
322 //Iterate through the bind list and copy the value here
323 FieldIterator fIter
= fldList_
.getIterator();
324 char *colPtr
= (char*) tuplePtr
;
325 while (fIter
.hasElement())
327 FieldDef def
= fIter
.nextElement();
331 if (NULL
!= def
.bindVal_
)
333 strcpy((char*)colPtr
, (char*)def
.bindVal_
);
334 *(((char*)colPtr
) + (def
.length_
-1)) = '\0';
336 colPtr
= colPtr
+ os::align(def
.length_
);
339 if (NULL
!= def
.bindVal_
)
340 os::memcpy((char*)colPtr
, (char*)def
.bindVal_
, def
.length_
);
341 colPtr
= colPtr
+ os::align(def
.length_
);
344 if (NULL
!= def
.bindVal_
)
345 AllDataType::copyVal(colPtr
, def
.bindVal_
, def
.type_
);
346 colPtr
= colPtr
+ os::align(AllDataType::size(def
.type_
));
353 DbRetVal
TableImpl::copyValuesToBindBuffer(void *tuplePtr
)
355 //Iterate through the bind list and copy the value here
356 FieldIterator fIter
= fldList_
.getIterator();
357 char *colPtr
= (char*) tuplePtr
;
358 while (fIter
.hasElement())
360 FieldDef def
= fIter
.nextElement();
364 if (NULL
!= def
.bindVal_
)
365 strcpy((char*)def
.bindVal_
, (char*)colPtr
);
366 colPtr
= colPtr
+ os::align(def
.length_
);
369 if (NULL
!= def
.bindVal_
)
370 os::memcpy((char*)def
.bindVal_
, (char*)colPtr
, def
.length_
);
371 colPtr
= colPtr
+ os::align(def
.length_
);
374 if (NULL
!= def
.bindVal_
)
375 AllDataType::copyVal(def
.bindVal_
, colPtr
, def
.type_
);
376 colPtr
= colPtr
+ os::align(AllDataType::size(def
.type_
));
383 //-1 index not supported
384 DbRetVal
TableImpl::insertIndexNode(Transaction
*tr
, void *indexPtr
, void *tuple
)
386 INDEX
*iptr
= (INDEX
*)indexPtr
;
388 Index
* idx
= Index::getIndex(iptr
->indexType_
);
389 if (idx
== NULL
) printf("It is here :PRABA\n");
390 ret
= idx
->insert(this, tr
, indexPtr
, tuple
);
394 DbRetVal
TableImpl::deleteIndexNode(Transaction
*tr
, void *indexPtr
, void *tuple
)
396 INDEX
*iptr
= (INDEX
*)indexPtr
;
398 //CatalogTableINDEX::getMutex(indexPtr);
399 Index
* idx
= Index::getIndex(iptr
->indexType_
);
400 ret
= idx
->remove(this, tr
, indexPtr
, tuple
);
401 //CatalogTableINDEX::releaseMutex(indexPtr);
406 DbRetVal
TableImpl::updateIndexNode(Transaction
*tr
, void *indexPtr
, void *tuple
)
408 INDEX
*iptr
= (INDEX
*)indexPtr
;
410 //CatalogTableINDEX::getMutex(indexPtr);
411 Index
* idx
= Index::getIndex(iptr
->indexType_
);
412 ret
= idx
->update(this, tr
, indexPtr
, tuple
);
413 //CatalogTableINDEX::releaseMutex(indexPtr);
419 DbRetVal
TableImpl::close()
423 printError(ErrNotOpen
,"Scan not open");
432 TableImpl::~TableImpl()
434 if (NULL
!= iter
) { delete iter
; iter
= NULL
; }
435 if (NULL
!= idxInfo
) { delete idxInfo
; idxInfo
= NULL
; }
436 if (NULL
!= indexPtr_
) { delete[] indexPtr_
; indexPtr_
= NULL
; }
437 fldList_
.removeAll();
440 void TableImpl::setTableInfo(char *name
, int tblid
, size_t length
,
441 int numFld
, int numIdx
, void *chunk
)
443 strcpy(tblName_
, name
);
447 numIndexes_
= numIdx
;
451 long TableImpl::spaceUsed()
453 Chunk
*chk
= (Chunk
*)chunkPtr_
;
454 long totSize
= chk
->getTotalDataNodes() * chk
->getSize();
455 totSize
= totSize
+ (chk
->totalPages() * sizeof (PageInfo
));
459 long TableImpl::numTuples()
461 return ((Chunk
*)chunkPtr_
)->getTotalDataNodes();
464 List
TableImpl::getFieldNameList()
467 FieldIterator fIter
= fldList_
.getIterator();
468 while (fIter
.hasElement())
470 FieldDef def
= fIter
.nextElement();
471 Identifier
*elem
= new Identifier();
472 strcpy(elem
->name
, def
.fldName_
);
473 fldNameList
.append(elem
);