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 ***************************************************************************/
18 #include<CatalogTables.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();
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_
;
40 TreeNode
*start
= (TreeNode
*)*((char**)((char*)fstNode
+ sizeof(TreeNode
)));
41 tIter
->set(start
,(TreeNode
*)iptr
->hashNodeChunk_
,procSlot
);
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();
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
;
63 FieldIterator iter
= hIdxInfo
->idxFldList
.getIterator();
64 int offset
= hIdxInfo
->fldOffset
;
65 if(!keyBuffer
) keyBuffer
= (char*) malloc(hIdxInfo
->compLength
);
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);
75 printError(ErrSysFatal
, "Fatal: Should not come here");
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_
;
90 printDebug(DM_HashIndex
, "open:head for bucket %x is :%x", bucket
, head
);
92 }else if (treeIndexScan
== scanType_
)
94 HashIndexInfo
*hIdxInfo
= (HashIndexInfo
*)info
;
95 CINDEX
*iptr
= (CINDEX
*) hIdxInfo
->indexPtr
;
96 TreeNode
*fstNode
=(TreeNode
*)iptr
->hashNodeChunk_
;
98 TreeNode
*start
= (TreeNode
*)*((char**)((char*)fstNode
+ sizeof(TreeNode
)));
99 tIter
->set(start
,(TreeNode
*)iptr
->hashNodeChunk_
,procSlot
);
101 tIter
->set(NULL
,(TreeNode
*)iptr
->hashNodeChunk_
,procSlot
);
103 if (hIdxInfo
->isUnique
) tIter
->setUnique();
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_
;
115 if (treeIndexScan
== scanType_
)
117 if (NULL
== tIter
) return NULL
;
118 tuple
= tIter
->prev();
119 predImpl
->setTuple(tuple
);
121 printDebug(DM_HashIndex
, "prev::tuple is null");
123 //TODO::evaluate as it is done in next() before returning
128 void* TupleIterator::next()
130 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
133 if (fullTableScan
== scanType_
)
138 return cIter
->nextElement();
143 bool isLargeSizeAllocator
= cIter
->isLargeSize();
144 void *val
= predImpl
->getValIfPointLookupOnInt(offset
);
147 int value
= *(int*)val
;
148 if (isLargeSizeAllocator
) {
151 tup
= (char*)cIter
->nextElement();
152 if(NULL
== tup
) return NULL
;
153 if (value
== *((int*)(tup
+offset
))) break;
157 tup
= (char*)cIter
->nextElementIntMatch(value
, offset
);
161 val
= predImpl
->getVal1IfBetweenOnInt(offset
);
163 void *val2
= predImpl
->getVal2IfBetweenOnInt(offset
);
164 int value1
= *(int*)val
;
165 int value2
= *(int*)val2
;
168 if(isLargeSizeAllocator
)
169 tup
= (char*)cIter
->nextElement();
171 tup
= (char*)cIter
->nextElementInt();
172 if(NULL
== tup
) return NULL
;
173 if (*((int*)(tup
+offset
)) >= value1
&&
174 *((int*)(tup
+offset
)) <= value2
) break;
179 //evaluate till it succeeds
183 if(isLargeSizeAllocator
)
184 tuple
= cIter
->nextElement();
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
199 HashIndexNode
*node
= bIter
->next();
200 if (node
== NULL
) return NULL
;
201 printDebug(DM_HashIndex
, "next: returned HashIndexNode: %x", node
);
202 tuple
= node
->ptrToTuple_
;
204 printDebug(DM_HashIndex
, "next::tuple is 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
);
218 }else if (treeIndexScan
== scanType_
)
220 if (NULL
== tIter
) return NULL
;
224 tuple
= tIter
->next();
226 printDebug(DM_HashIndex
, "next::tuple is null");
229 //predImpl->setTuple(tuple);
230 predImpl
->evaluateForTable(result
, (char*)tuple
);
231 if(!result
&& (isBetween
|| isPointLook
)) tIter
->nextNode();
237 DbRetVal
TupleIterator::close()
239 if (isClosed
) return OK
;
245 void TupleIterator::reset()
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(); }