Removing dependency for Cache module in MMDB build
[csql.git] / src / storage / TupleIterator.cxx
blob5292707c13103b5c17382ddd21af6aa362a67aee
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<Table.h>
17 #include<Index.h>
18 #include<CatalogTables.h>
19 #include<Lock.h>
20 #include<Debug.h>
21 #include<TableImpl.h>
22 #include<PredicateImpl.h>
23 DbRetVal TupleIterator::setPlan()
25 PredicateImpl *predImpl = (PredicateImpl*) pred_;
26 if (treeIndexScan == scanType_)
28 HashIndexInfo *hIdxInfo = (HashIndexInfo*)info;
29 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
30 if(iter.hasElement())
32 FieldDef *def = iter.nextElement();
33 keyPtr = (char*)predImpl->valPtrForIndexField(def->fldName_, hIdxInfo->isUnique);
34 op = predImpl->opForIndexField(def->fldName_);
36 CINDEX *iptr = (CINDEX*) hIdxInfo->indexPtr;
37 TreeNode *fstNode=(TreeNode *)iptr->hashNodeChunk_;
38 if(fstNode!=NULL){
39 TreeNode *start = (TreeNode *)*((char**)((char*)fstNode + sizeof(TreeNode)));
40 tIter->set(start,(TreeNode*)iptr->hashNodeChunk_,procSlot);
41 }else{
42 tIter->set(NULL,(TreeNode*)iptr->hashNodeChunk_,procSlot);
44 tIter->setSearchKey(keyPtr, op);
45 if (hIdxInfo->isUnique) tIter->setUnique();
46 tIter->setFldOffset(hIdxInfo->fldOffset);
47 tIter->setTypeLength(hIdxInfo->type, hIdxInfo->compLength);
49 if(predImpl) predImpl->setIfNoLeftRight();
50 return OK;
52 DbRetVal TupleIterator::open()
54 PredicateImpl *predImpl = (PredicateImpl*) pred_;
55 if (fullTableScan == scanType_)
57 *cIter = ((Chunk*)chunkPtr_)->getIterator();
58 }else if (hashIndexScan == scanType_)
60 HashIndexInfo *hIdxInfo = (HashIndexInfo*)info;
61 bool isPtr = false;
62 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
63 int offset = hIdxInfo->fldOffset;
64 if(!keyBuffer) keyBuffer = (char*) malloc(hIdxInfo->compLength);
65 void *keyPtr = NULL;
66 char *keyBufferIter = keyBuffer;
67 while(iter.hasElement())
69 FieldDef *def = iter.nextElement();
70 //keyPtr = (void*)predImpl->valPtrForIndexField(def->fldName_,hIdxInfo->isUnique);
71 //TODO::PRABA::the below opt should be done for hash also
72 keyPtr = (void*)predImpl->valPtrForIndexField(def->fldName_,false);
73 AllDataType::copyVal(keyBufferIter, keyPtr, def->type_, def->length_);
74 keyBufferIter = keyBufferIter + def->length_;
76 int bucketNo = HashIndex::computeHashBucket(hIdxInfo->type,
77 keyBuffer, hIdxInfo->noOfBuckets, hIdxInfo->compLength);
78 Bucket *bucket = &(hIdxInfo->buckets[bucketNo]);
79 HashIndexNode *head = (HashIndexNode*) bucket->bucketList_;
80 if (!head)
82 bIter->setHead(head);
83 return OK;
85 printDebug(DM_HashIndex, "open:head for bucket %x is :%x", bucket, head);
86 bIter->setHead(head);
87 }else if (treeIndexScan == scanType_)
89 HashIndexInfo *hIdxInfo = (HashIndexInfo*)info;
90 CINDEX *iptr = (CINDEX*) hIdxInfo->indexPtr;
91 TreeNode *fstNode=(TreeNode *)iptr->hashNodeChunk_;
92 if(fstNode!=NULL){
93 TreeNode *start = (TreeNode *)*((char**)((char*)fstNode + sizeof(TreeNode)));
94 tIter->set(start,(TreeNode*)iptr->hashNodeChunk_,procSlot);
95 }else{
96 tIter->set(NULL,(TreeNode*)iptr->hashNodeChunk_,procSlot);
98 if (hIdxInfo->isUnique) tIter->setUnique();
100 isClosed = false;
101 return OK;
104 //not returing previous tuple for all iterators and for tree iterator.
105 //it just decrements the nodeOffset for tree iterator.
106 void* TupleIterator::prev()
108 PredicateImpl *predImpl = (PredicateImpl*) pred_;
109 void *tuple = NULL;
110 if (treeIndexScan == scanType_)
112 if (NULL == tIter) return NULL;
113 tuple = tIter->prev();
114 predImpl->setTuple(tuple);
115 if(NULL == tuple) {
116 printDebug(DM_HashIndex, "prev::tuple is null");
118 //TODO::evaluate as it is done in next() before returning
120 return tuple;
123 void* TupleIterator::next()
125 PredicateImpl *predImpl = (PredicateImpl*) pred_;
126 void *tuple = NULL;
127 DbRetVal rv = OK;
128 if (fullTableScan == scanType_)
130 if (NULL == pred_)
132 //no predicates
133 return cIter->nextElement();
135 else
137 int offset=0;
138 bool isLargeSizeAllocator = cIter->isLargeSize();
139 void *val = predImpl->getValIfPointLookupOnInt(offset);
140 char *tup = NULL;
141 if (val != NULL) {
142 int value = *(int*)val;
143 if (isLargeSizeAllocator) {
144 while (true)
146 tup = (char*)cIter->nextElement();
147 if(NULL == tup) return NULL;
148 if (value == *((int*)(tup+offset))) break;
150 return tup;
151 }else {
152 tup = (char*)cIter->nextElementIntMatch(value, offset);
153 return tup;
156 val = predImpl->getVal1IfBetweenOnInt(offset);
157 if (val != NULL) {
158 void *val2 = predImpl->getVal2IfBetweenOnInt(offset);
159 int value1 = *(int*)val;
160 int value2 = *(int*)val2;
161 while (true)
163 if(isLargeSizeAllocator)
164 tup = (char*)cIter->nextElement();
165 else
166 tup = (char*)cIter->nextElementInt();
167 if(NULL == tup) return NULL;
168 if (*((int*)(tup+offset)) >= value1 &&
169 *((int*)(tup+offset)) <= value2) break;
171 return tup;
174 //evaluate till it succeeds
175 bool result = false;
176 while (!result)
178 if(isLargeSizeAllocator)
179 tuple = cIter->nextElement();
180 else
181 tuple = cIter->nextElementInt();
182 if(NULL == tuple) return NULL;
183 //predImpl->setTuple(tuple);
184 printDebug(DM_Table, "Evaluating the predicate from fullTableScan");
185 predImpl->evaluateForTable(result, (char*)tuple);
188 }else if (hashIndexScan == scanType_)
190 //evaluate till it succeeds
191 bool result = false;
192 while (!result)
194 HashIndexNode *node = bIter->next();
195 if (node == NULL) return NULL;
196 printDebug(DM_HashIndex, "next: returned HashIndexNode: %x", node);
197 tuple = node->ptrToTuple_;
198 if(NULL == tuple) {
199 printDebug(DM_HashIndex, "next::tuple is null");
200 return NULL;
203 //if (!predImpl->isSingleTerm()) {
204 printDebug(DM_HashIndex, "next: predicate has more than single term");
205 //predImpl->setTuple(tuple);
206 printDebug(DM_Table, "Evaluating the predicate from hashIndexScan: has more than one term");
207 predImpl->evaluateForTable(result, (char*)tuple);
208 //}
209 //else
210 // return tuple;
213 }else if (treeIndexScan == scanType_)
215 if (NULL == tIter) return NULL;
216 bool result = false;
217 while (!result)
219 tuple = tIter->next();
220 if(NULL == tuple) {
221 printDebug(DM_HashIndex, "next::tuple is null");
222 return NULL;
224 //predImpl->setTuple(tuple);
225 predImpl->evaluateForTable(result, (char*)tuple);
226 if(!result && (isBetween || isPointLook)) tIter->nextNode();
229 return tuple;
232 DbRetVal TupleIterator::close()
234 if (isClosed) return OK;
235 reset();
236 isClosed = true;
237 return OK;
240 void TupleIterator::reset()
242 DbRetVal rv = OK;
243 if (scanType_ == fullTableScan) {
244 if (cIter) *cIter = ((Chunk*)chunkPtr_)->getIterator();
246 else if (scanType_ == hashIndexScan) {
247 if(bIter) bIter->reset();
249 else if (scanType_ == treeIndexScan) { if(tIter) tIter->reset(); }