windows porting first phase- ported os layer, storage module to windows
[csql.git] / src / storage / TupleIterator.cxx
blobe3c5302ddd778f37885079d154162438c3d88523
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_);
35 keyPtr = (char*)predImpl->opAndValPtrForIndexField(def->fldName_, hIdxInfo->isUnique,op);
37 CINDEX *iptr = (CINDEX*) hIdxInfo->indexPtr;
38 TreeNode *fstNode=(TreeNode *)iptr->hashNodeChunk_;
39 if(fstNode!=NULL){
40 TreeNode *start = (TreeNode *)*((char**)((char*)fstNode + sizeof(TreeNode)));
41 tIter->set(start,(TreeNode*)iptr->hashNodeChunk_,procSlot);
42 }else{
43 tIter->set(NULL,(TreeNode*)iptr->hashNodeChunk_,procSlot);
45 tIter->setSearchKey(keyPtr, op);
46 if (hIdxInfo->isUnique) tIter->setUnique();
47 tIter->setFldOffset(hIdxInfo->fldOffset);
48 tIter->setTypeLength(hIdxInfo->type, hIdxInfo->compLength);
50 if(predImpl) predImpl->setIfNoLeftRight();
51 return OK;
53 DbRetVal TupleIterator::open()
55 PredicateImpl *predImpl = (PredicateImpl*) pred_;
56 if (fullTableScan == scanType_)
58 *cIter = ((Chunk*)chunkPtr_)->getIterator();
59 }else if (hashIndexScan == scanType_)
61 HashIndexInfo *hIdxInfo = (HashIndexInfo*)info;
62 bool isPtr = false;
63 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
64 int offset = hIdxInfo->fldOffset;
65 if(!keyBuffer) keyBuffer = (char*) malloc(hIdxInfo->compLength);
66 void *keyPtr = NULL;
67 char *keyBufferIter = keyBuffer;
68 while(iter.hasElement())
70 FieldDef *def = iter.nextElement();
71 //keyPtr = (void*)predImpl->valPtrForIndexField(def->fldName_,hIdxInfo->isUnique);
72 //TODO::PRABA::the below opt should be done for hash also
73 keyPtr = (void*)predImpl->valPtrForIndexField(def->fldName_,false);
74 if (NULL == keyPtr) {
75 printError(ErrSysFatal, "Fatal: Should not come here");
76 continue;
78 AllDataType::copyVal(keyBufferIter, keyPtr, def->type_, def->length_);
79 keyBufferIter = keyBufferIter + def->length_;
81 int bucketNo = HashIndex::computeHashBucket(hIdxInfo->type,
82 keyBuffer, hIdxInfo->noOfBuckets, hIdxInfo->compLength);
83 Bucket *bucket = &(hIdxInfo->buckets[bucketNo]);
84 HashIndexNode *head = (HashIndexNode*) bucket->bucketList_;
85 if (!head)
87 bIter->setHead(head);
88 return OK;
90 printDebug(DM_HashIndex, "open:head for bucket %x is :%x", bucket, head);
91 bIter->setHead(head);
92 }else if (treeIndexScan == scanType_)
94 HashIndexInfo *hIdxInfo = (HashIndexInfo*)info;
95 CINDEX *iptr = (CINDEX*) hIdxInfo->indexPtr;
96 TreeNode *fstNode=(TreeNode *)iptr->hashNodeChunk_;
97 if(fstNode!=NULL){
98 TreeNode *start = (TreeNode *)*((char**)((char*)fstNode + sizeof(TreeNode)));
99 tIter->set(start,(TreeNode*)iptr->hashNodeChunk_,procSlot);
100 }else{
101 tIter->set(NULL,(TreeNode*)iptr->hashNodeChunk_,procSlot);
103 if (hIdxInfo->isUnique) tIter->setUnique();
105 isClosed = false;
106 return OK;
109 //not returing previous tuple for all iterators and for tree iterator.
110 //it just decrements the nodeOffset for tree iterator.
111 void* TupleIterator::prev()
113 PredicateImpl *predImpl = (PredicateImpl*) pred_;
114 void *tuple = NULL;
115 if (treeIndexScan == scanType_)
117 if (NULL == tIter) return NULL;
118 tuple = tIter->prev();
119 predImpl->setTuple(tuple);
120 if(NULL == tuple) {
121 printDebug(DM_HashIndex, "prev::tuple is null");
123 //TODO::evaluate as it is done in next() before returning
125 return tuple;
128 void* TupleIterator::next()
130 PredicateImpl *predImpl = (PredicateImpl*) pred_;
131 void *tuple = NULL;
132 DbRetVal rv = OK;
133 if (fullTableScan == scanType_)
135 if (NULL == pred_)
137 //no predicates
138 return cIter->nextElement();
140 else
142 int offset=0;
143 bool isLargeSizeAllocator = cIter->isLargeSize();
144 void *val = predImpl->getValIfPointLookupOnInt(offset);
145 char *tup = NULL;
146 if (val != NULL) {
147 int value = *(int*)val;
148 if (isLargeSizeAllocator) {
149 while (true)
151 tup = (char*)cIter->nextElement();
152 if(NULL == tup) return NULL;
153 if (value == *((int*)(tup+offset))) break;
155 return tup;
156 }else {
157 tup = (char*)cIter->nextElementIntMatch(value, offset);
158 return tup;
161 val = predImpl->getVal1IfBetweenOnInt(offset);
162 if (val != NULL) {
163 void *val2 = predImpl->getVal2IfBetweenOnInt(offset);
164 int value1 = *(int*)val;
165 int value2 = *(int*)val2;
166 while (true)
168 if(isLargeSizeAllocator)
169 tup = (char*)cIter->nextElement();
170 else
171 tup = (char*)cIter->nextElementInt();
172 if(NULL == tup) return NULL;
173 if (*((int*)(tup+offset)) >= value1 &&
174 *((int*)(tup+offset)) <= value2) break;
176 return tup;
179 //evaluate till it succeeds
180 bool result = false;
181 while (!result)
183 if(isLargeSizeAllocator)
184 tuple = cIter->nextElement();
185 else
186 tuple = cIter->nextElementInt();
187 if(NULL == tuple) return NULL;
188 //predImpl->setTuple(tuple);
189 printDebug(DM_Table, "Evaluating the predicate from fullTableScan");
190 predImpl->evaluateForTable(result, (char*)tuple);
193 }else if (hashIndexScan == scanType_)
195 //evaluate till it succeeds
196 bool result = false;
197 while (!result)
199 HashIndexNode *node = bIter->next();
200 if (node == NULL) return NULL;
201 printDebug(DM_HashIndex, "next: returned HashIndexNode: %x", node);
202 tuple = node->ptrToTuple_;
203 if(NULL == tuple) {
204 printDebug(DM_HashIndex, "next::tuple is null");
205 return NULL;
208 //if (!predImpl->isSingleTerm()) {
209 printDebug(DM_HashIndex, "next: predicate has more than single term");
210 //predImpl->setTuple(tuple);
211 printDebug(DM_Table, "Evaluating the predicate from hashIndexScan: has more than one term");
212 predImpl->evaluateForTable(result, (char*)tuple);
213 //}
214 //else
215 // return tuple;
218 }else if (treeIndexScan == scanType_)
220 if (NULL == tIter) return NULL;
221 bool result = false;
222 while (!result)
224 tuple = tIter->next();
225 if(NULL == tuple) {
226 printDebug(DM_HashIndex, "next::tuple is null");
227 return NULL;
229 //predImpl->setTuple(tuple);
230 predImpl->evaluateForTable(result, (char*)tuple);
231 if(!result && (isBetween || isPointLook)) tIter->nextNode();
234 return tuple;
237 DbRetVal TupleIterator::close()
239 if (isClosed) return OK;
240 reset();
241 isClosed = true;
242 return OK;
245 void TupleIterator::reset()
247 DbRetVal rv = OK;
248 if (scanType_ == fullTableScan) {
249 if (cIter) *cIter = ((Chunk*)chunkPtr_)->getIterator();
251 else if (scanType_ == hashIndexScan) {
252 if(bIter) bIter->reset();
254 else if (scanType_ == treeIndexScan) { if(tIter) tIter->reset(); }