Fix for Bug # 2483638
[csql.git] / src / storage / TupleIterator.cxx
blobba8e87adbcaf40c48ec8721e90209c2847b975c0
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::open()
26 if (fullTableScan == scanType_)
28 cIter = new ChunkIterator();
29 *cIter = ((Chunk*)chunkPtr_)->getIterator();
30 }else if (hashIndexScan == scanType_)
32 HashIndexInfo *hIdxInfo = (HashIndexInfo*)info;
33 PredicateImpl *predImpl = (PredicateImpl*) pred_;
34 bool isPtr = false;
35 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
36 char *keyBuffer;
37 int offset = hIdxInfo->fldOffset;
38 keyBuffer = (char*) malloc(hIdxInfo->compLength);
39 void *keyStartBuffer = (void*) keyBuffer, *keyPtr;
40 while(iter.hasElement())
42 FieldDef def = iter.nextElement();
43 keyPtr = (void*)predImpl->valPtrForIndexField(def.fldName_);
44 AllDataType::copyVal(keyBuffer, keyPtr, def.type_, def.length_);
45 keyBuffer = keyBuffer + AllDataType::size(def.type_, def.length_);
47 int bucketNo = 0;
48 if (hIdxInfo->type == typeComposite)
49 bucketNo = HashIndex::computeHashBucket(hIdxInfo->type,
50 (char *)keyStartBuffer, hIdxInfo->noOfBuckets, hIdxInfo->compLength);
51 else bucketNo = HashIndex::computeHashBucket(hIdxInfo->type,
52 keyStartBuffer, hIdxInfo->noOfBuckets, hIdxInfo->compLength);
53 free(keyStartBuffer);
54 Bucket *bucket = &(hIdxInfo->buckets[bucketNo]);
55 int ret = bucket->mutex_.getLock(procSlot);
56 if (ret != 0)
58 printError(ErrLockTimeOut,"Unable to acquire bucket Mutex for bucket %d",bucketNo);
59 return ErrLockTimeOut;
61 HashIndexNode *head = (HashIndexNode*) bucket->bucketList_;
62 if (!head)
64 bucket->mutex_.releaseLock(procSlot);
65 bIter = NULL ;
66 return OK;
68 printDebug(DM_HashIndex, "open:head for bucket %x is :%x", bucket, head);
69 bIter = new BucketIter(head);
70 bucket->mutex_.releaseLock(procSlot);
71 }else if (treeIndexScan == scanType_)
73 HashIndexInfo *hIdxInfo = (HashIndexInfo*)info;
74 PredicateImpl *predImpl = (PredicateImpl*) pred_;
75 bool isPtr = false;
76 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
77 void *keyPtr; ComparisionOp op;
78 if(iter.hasElement())
80 FieldDef def = iter.nextElement();
81 keyPtr = (void*)predImpl->valPtrForIndexField(def.fldName_);
82 op = predImpl->opForIndexField(def.fldName_);
83 //TODO::remove this predicate term as it is pushed to tree iter
85 CINDEX *iptr = (CINDEX*) hIdxInfo->indexPtr;
86 tIter = new TreeIter((TreeNode*)iptr->hashNodeChunk_);
87 tIter->setSearchKey(keyPtr, op);
88 tIter->setFldOffset(hIdxInfo->fldOffset);
89 tIter->setTypeLength(hIdxInfo->type, hIdxInfo->compLength);
91 return OK;
94 //not returing previous tuple for all iterators and for tree iterator.
95 //it just decrements the nodeOffset for tree iterator.
96 void* TupleIterator::prev()
98 PredicateImpl *predImpl = (PredicateImpl*) pred_;
99 void *tuple = NULL;
100 if (treeIndexScan == scanType_)
102 if (NULL == tIter) return NULL;
103 tuple = tIter->prev();
104 predImpl->setTuple(tuple);
105 if(NULL == tuple) {
106 printDebug(DM_HashIndex, "prev::tuple is null");
109 return tuple;
112 void* TupleIterator::next()
114 PredicateImpl *predImpl = (PredicateImpl*) pred_;
115 void *tuple = NULL;
116 DbRetVal rv = OK;
117 if (fullTableScan == scanType_)
120 if (NULL == pred_ )
122 //no predicates
123 return cIter->nextElement();
125 else
127 //evaluate till it succeeds
128 bool result = false;
129 while (!result)
131 tuple = cIter->nextElement();
132 if(NULL == tuple) return NULL;
133 predImpl->setTuple(tuple);
134 printDebug(DM_Table, "Evaluating the predicate from fullTableScan");
135 rv = predImpl->evaluate(result);
136 if (rv != OK) return NULL;
139 }else if (hashIndexScan == scanType_)
141 if (NULL == bIter)
143 //if there are no nodes in bucket bIter will be null
144 return NULL;
146 //evaluate till it succeeds
147 bool result = false;
148 while (!result)
150 HashIndexNode *node = bIter->next();
151 if (node == NULL) return NULL;
152 printDebug(DM_HashIndex, "next: returned HashIndexNode: %x", node);
153 tuple = node->ptrToTuple_;
154 if(NULL == tuple) {
155 printDebug(DM_HashIndex, "next::tuple is null");
156 return NULL;
159 //if (!predImpl->isSingleTerm()) {
160 printDebug(DM_HashIndex, "next: predicate has more than single term");
161 predImpl->setTuple(tuple);
162 printDebug(DM_Table, "Evaluating the predicate from hashIndexScan: has more than one term");
163 rv = predImpl->evaluate(result);
164 if (rv != OK) return NULL;
165 //}
166 //else
167 // return tuple;
170 }else if (treeIndexScan == scanType_)
172 if (NULL == tIter) return NULL;
173 bool result = false;
174 while (!result)
176 tuple = tIter->next();
177 if(NULL == tuple) {
178 printDebug(DM_HashIndex, "next::tuple is null");
179 return NULL;
181 predImpl->setTuple(tuple);
182 rv = predImpl->evaluate(result);
183 if (rv != OK) return NULL;
186 return tuple;
189 DbRetVal TupleIterator::close()
191 if (scanType_ == fullTableScan)
193 delete cIter;
194 cIter = NULL;
195 } else if (scanType_ == hashIndexScan)
197 delete bIter;
198 bIter = NULL;
199 } else if (scanType_ == treeIndexScan)
201 delete tIter;
202 tIter = NULL;
205 scanType_ = unknownScan;
206 return OK;