8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.45 2000/01/26 05:56:23 momjian Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.46 2000/02/05 23:19:44 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -124,7 +124,7 @@ IndexNext(IndexScan *node)
124
124
if (estate -> es_evTuple != NULL &&
125
125
estate -> es_evTuple [node -> scan .scanrelid - 1 ] != NULL )
126
126
{
127
- int iptr ;
127
+ List * qual ;
128
128
129
129
ExecClearTuple (slot );
130
130
if (estate -> es_evTupleNull [node -> scan .scanrelid - 1 ])
@@ -134,20 +134,23 @@ IndexNext(IndexScan *node)
134
134
slot -> val = estate -> es_evTuple [node -> scan .scanrelid - 1 ];
135
135
slot -> ttc_shouldFree = false;
136
136
137
- for (iptr = 0 ; iptr < numIndices ; iptr ++ )
137
+ scanstate -> cstate .cs_ExprContext -> ecxt_scantuple = slot ;
138
+
139
+ /* Does the tuple meet any of the OR'd indxqual conditions? */
140
+ foreach (qual , node -> indxqualorig )
138
141
{
139
- scanstate -> cstate .cs_ExprContext -> ecxt_scantuple = slot ;
140
- if (ExecQual (nth (iptr , node -> indxqualorig ),
142
+ if (ExecQual ((List * ) lfirst (qual ),
141
143
scanstate -> cstate .cs_ExprContext ,
142
144
false))
143
145
break ;
144
146
}
145
- if (iptr == numIndices ) /* would not be returned by indices */
147
+ if (qual == NIL ) /* would not be returned by indices */
146
148
slot -> val = NULL ;
147
149
148
150
/* Flag for the next call that no more tuples */
149
151
estate -> es_evTupleNull [node -> scan .scanrelid - 1 ] = true;
150
- return (slot );
152
+
153
+ return slot ;
151
154
}
152
155
153
156
tuple = & (indexstate -> iss_htup );
@@ -189,14 +192,14 @@ IndexNext(IndexScan *node)
189
192
{
190
193
bool prev_matches = false;
191
194
int prev_index ;
195
+ List * qual ;
192
196
193
- /* ----------------
197
+ /*
194
198
* store the scanned tuple in the scan tuple slot of
195
199
* the scan state. Eventually we will only do this and not
196
200
* return a tuple. Note: we pass 'false' because tuples
197
201
* returned by amgetnext are pointers onto disk pages and
198
202
* must not be pfree()'d.
199
- * ----------------
200
203
*/
201
204
ExecStoreTuple (tuple , /* tuple to store */
202
205
slot , /* slot to store in */
@@ -211,28 +214,29 @@ IndexNext(IndexScan *node)
211
214
ReleaseBuffer (buffer );
212
215
213
216
/*
214
- * We must check to see if the current tuple would have
215
- * been matched by an earlier index, so we don't double
216
- * report it. We do this by passing the tuple through
217
- * ExecQual and look for failure with all previous
218
- * qualifications.
217
+ * We must check to see if the current tuple was already
218
+ * matched by an earlier index, so we don't double-report it.
219
+ * We do this by passing the tuple through ExecQual and
220
+ * checking for failure with all previous qualifications.
219
221
*/
222
+ scanstate -> cstate .cs_ExprContext -> ecxt_scantuple = slot ;
223
+ qual = node -> indxqualorig ;
220
224
for (prev_index = 0 ; prev_index < indexstate -> iss_IndexPtr ;
221
225
prev_index ++ )
222
226
{
223
- scanstate -> cstate .cs_ExprContext -> ecxt_scantuple = slot ;
224
- if (ExecQual (nth (prev_index , node -> indxqualorig ),
227
+ if (ExecQual ((List * ) lfirst (qual ),
225
228
scanstate -> cstate .cs_ExprContext ,
226
229
false))
227
230
{
228
231
prev_matches = true;
229
232
break ;
230
233
}
234
+ qual = lnext (qual );
231
235
}
232
236
if (!prev_matches )
233
- return slot ;
234
- else
235
- ExecClearTuple (slot );
237
+ return slot ; /* OK to return tuple */
238
+ /* Duplicate tuple, so drop it and loop back for another */
239
+ ExecClearTuple (slot );
236
240
}
237
241
}
238
242
if (indexNumber < numIndices )
@@ -329,7 +333,6 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
329
333
scanDescs = indexstate -> iss_ScanDescs ;
330
334
scanKeys = indexstate -> iss_ScanKeys ;
331
335
runtimeKeyInfo = (Pointer * ) indexstate -> iss_RuntimeKeyInfo ;
332
- indxqual = node -> indxqual ;
333
336
numScanKeys = indexstate -> iss_NumScanKeys ;
334
337
indexstate -> iss_IndexPtr = -1 ;
335
338
if (ScanDirectionIsBackward (node -> indxorderdir ))
@@ -352,9 +355,11 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
352
355
/*
353
356
* get the index qualifications and recalculate the appropriate values
354
357
*/
358
+ indxqual = node -> indxqual ;
355
359
for (i = 0 ; i < numIndices ; i ++ )
356
360
{
357
- qual = nth (i , indxqual );
361
+ qual = lfirst (indxqual );
362
+ indxqual = lnext (indxqual );
358
363
n_keys = numScanKeys [i ];
359
364
scan_keys = (ScanKey ) scanKeys [i ];
360
365
@@ -672,7 +677,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
672
677
* ----------------
673
678
*/
674
679
indxid = node -> indxid ;
675
- indxqual = node -> indxqual ;
676
680
numIndices = length (indxid );
677
681
indexPtr = -1 ;
678
682
@@ -701,6 +705,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
701
705
* build the index scan keys from the index qualification
702
706
* ----------------
703
707
*/
708
+ indxqual = node -> indxqual ;
704
709
for (i = 0 ; i < numIndices ; i ++ )
705
710
{
706
711
int j ;
@@ -709,7 +714,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
709
714
ScanKey scan_keys ;
710
715
int * run_keys ;
711
716
712
- qual = nth (i , indxqual );
717
+ qual = lfirst (indxqual );
718
+ indxqual = lnext (indxqual );
713
719
n_keys = length (qual );
714
720
scan_keys = (n_keys <= 0 ) ? NULL :
715
721
(ScanKey ) palloc (n_keys * sizeof (ScanKeyData ));
@@ -743,8 +749,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
743
749
clause = nth (j , qual );
744
750
745
751
op = (Oper * ) clause -> oper ;
746
- if (!IsA (op , Oper ))
747
- elog (ERROR , "ExecInitIndexScan: op not an Oper !" );
752
+ if (!IsA (clause , Expr ) || ! IsA ( op , Oper ))
753
+ elog (ERROR , "ExecInitIndexScan: indxqual not an opclause !" );
748
754
749
755
opid = op -> opid ;
750
756
@@ -1066,9 +1072,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
1066
1072
*/
1067
1073
for (i = 0 ; i < numIndices ; i ++ )
1068
1074
{
1069
- Oid indexOid ;
1070
-
1071
- indexOid = (Oid ) nthi (i , indxid );
1075
+ Oid indexOid = (Oid ) nthi (i , indxid );
1072
1076
1073
1077
if (indexOid != 0 )
1074
1078
{
0 commit comments