Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0a2e5cd

Browse files
committed
Allow index use with OR clauses.
1 parent0668aa8 commit0a2e5cd

File tree

9 files changed

+287
-316
lines changed

9 files changed

+287
-316
lines changed

‎src/backend/executor/execQual.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.33 1998/06/15 19:28:19 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.34 1998/08/01 22:12:02 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1349,8 +1349,6 @@ ExecQual(List *qual, ExprContext *econtext)
13491349

13501350
foreach(clause,qual)
13511351
{
1352-
1353-
13541352
result=ExecQualClause((Node*)lfirst(clause),econtext);
13551353
if (result== true)
13561354
break;

‎src/backend/executor/nodeIndexscan.c

Lines changed: 118 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.19 1998/07/27 19:37:57 vadim Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.20 1998/08/01 22:12:04 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -87,15 +87,15 @@ IndexNext(IndexScan *node)
8787
IndexScanState*indexstate;
8888
ScanDirectiondirection;
8989
Snapshotsnapshot;
90-
intindexPtr;
9190
IndexScanDescPtrscanDescs;
9291
IndexScanDescscandesc;
9392
RelationheapRelation;
9493
RetrieveIndexResultresult;
9594
HeapTupletuple;
9695
TupleTableSlot*slot;
9796
Bufferbuffer=InvalidBuffer;
98-
97+
intnumIndices;
98+
9999
/* ----------------
100100
*extract necessary information from index scan node
101101
* ----------------
@@ -105,54 +105,66 @@ IndexNext(IndexScan *node)
105105
snapshot=estate->es_snapshot;
106106
scanstate=node->scan.scanstate;
107107
indexstate=node->indxstate;
108-
indexPtr=indexstate->iss_IndexPtr;
109108
scanDescs=indexstate->iss_ScanDescs;
110-
scandesc=scanDescs[indexPtr];
111109
heapRelation=scanstate->css_currentRelation;
112-
110+
numIndices=indexstate->iss_NumIndices;
113111
slot=scanstate->css_ScanTupleSlot;
114112

115113
/* ----------------
116114
*ok, now that we have what we need, fetch an index tuple.
117-
* ----------------
118-
*/
119-
120-
/* ----------------
121115
*if scanning this index succeeded then return the
122116
*appropriate heap tuple.. else return NULL.
123117
* ----------------
124118
*/
125-
while ((result=index_getnext(scandesc,direction))!=NULL)
119+
while (indexstate->iss_IndexPtr<numIndices)
126120
{
127-
tuple=heap_fetch(heapRelation,snapshot,
128-
&result->heap_iptr,&buffer);
129-
/* be tidy */
130-
pfree(result);
131-
132-
if (tuple!=NULL)
133-
{
134-
/* ----------------
135-
*store the scanned tuple in the scan tuple slot of
136-
*the scan state. Eventually we will only do this and not
137-
*return a tuple. Note: we pass 'false' because tuples
138-
*returned by amgetnext are pointers onto disk pages and
139-
*were not created with palloc() and so should not be pfree()'d.
140-
* ----------------
141-
*/
142-
ExecStoreTuple(tuple,/* tuple to store */
143-
slot,/* slot to store in */
144-
buffer,/* buffer associated with tuple */
145-
false);/* don't pfree */
146-
147-
returnslot;
148-
}
149-
else
121+
scandesc=scanDescs[indexstate->iss_IndexPtr];
122+
while ((result=index_getnext(scandesc,direction))!=NULL)
150123
{
124+
tuple=heap_fetch(heapRelation,snapshot,
125+
&result->heap_iptr,&buffer);
126+
/* be tidy */
127+
pfree(result);
128+
129+
if (tuple!=NULL)
130+
{
131+
boolprev_matches= false;
132+
intprev_index;
133+
134+
/* ----------------
135+
*store the scanned tuple in the scan tuple slot of
136+
*the scan state. Eventually we will only do this and not
137+
*return a tuple. Note: we pass 'false' because tuples
138+
*returned by amgetnext are pointers onto disk pages and
139+
*were not created with palloc() and so should not be pfree()'d.
140+
* ----------------
141+
*/
142+
ExecStoreTuple(tuple,/* tuple to store */
143+
slot,/* slot to store in */
144+
buffer,/* buffer associated with tuple */
145+
false);/* don't pfree */
146+
147+
for (prev_index=0;prev_index<indexstate->iss_IndexPtr;
148+
prev_index++)
149+
{
150+
if (ExecQual(nth(prev_index,node->indxqual),
151+
scanstate->cstate.cs_ExprContext))
152+
{
153+
prev_matches= true;
154+
break;
155+
}
156+
}
157+
if (!prev_matches)
158+
returnslot;
159+
else
160+
ExecClearTuple(slot);
161+
}
151162
if (BufferIsValid(buffer))
152163
ReleaseBuffer(buffer);
153164
}
165+
if (indexstate->iss_IndexPtr<numIndices)
166+
indexstate->iss_IndexPtr++;
154167
}
155-
156168
/* ----------------
157169
*if we get here it means the index scan failed so we
158170
*are at the end of the scan..
@@ -218,7 +230,6 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
218230
inti;
219231

220232
Pointer*runtimeKeyInfo;
221-
intindexPtr;
222233
int*numScanKeys;
223234
List*indxqual;
224235
List*qual;
@@ -238,69 +249,62 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
238249
numIndices=indexstate->iss_NumIndices;
239250
scanDescs=indexstate->iss_ScanDescs;
240251
scanKeys=indexstate->iss_ScanKeys;
241-
242252
runtimeKeyInfo= (Pointer*)indexstate->iss_RuntimeKeyInfo;
253+
indxqual=node->indxqual;
254+
numScanKeys=indexstate->iss_NumScanKeys;
255+
indexstate->iss_IndexPtr=0;
256+
257+
/* it's possible in subselects */
258+
if (exprCtxt==NULL)
259+
exprCtxt=node->scan.scanstate->cstate.cs_ExprContext;
243260

244-
if (runtimeKeyInfo!=NULL)
245-
{
246-
247-
/*
248-
* get the index qualifications and recalculate the appropriate
249-
* values
250-
*/
251-
indexPtr=indexstate->iss_IndexPtr;
252-
indxqual=node->indxqual;
253-
qual=nth(indexPtr,indxqual);
254-
numScanKeys=indexstate->iss_NumScanKeys;
255-
n_keys=numScanKeys[indexPtr];
256-
run_keys= (int*)runtimeKeyInfo[indexPtr];
257-
scan_keys= (ScanKey)scanKeys[indexPtr];
261+
if (exprCtxt!=NULL)
262+
node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple=
263+
exprCtxt->ecxt_outertuple;
258264

259-
/* it's possible in subselects */
260-
if (exprCtxt==NULL)
261-
exprCtxt=node->scan.scanstate->cstate.cs_ExprContext;
262-
263-
for (j=0;j<n_keys;j++)
265+
/*
266+
* get the index qualifications and recalculate the appropriate
267+
* values
268+
*/
269+
for (i=0;i<numIndices;i++)
270+
{
271+
if (runtimeKeyInfo&&runtimeKeyInfo[i]!=NULL)
264272
{
265-
266-
/*
267-
* If we have a run-time key, then extract the run-time
268-
* expression and evaluate it with respect to the current
269-
* outer tuple. We then stick the result into the scan key.
270-
*/
271-
if (run_keys[j]!=NO_OP)
273+
qual=nth(i,indxqual);
274+
n_keys=numScanKeys[i];
275+
run_keys= (int*)runtimeKeyInfo[i];
276+
scan_keys= (ScanKey)scanKeys[i];
277+
278+
for (j=0;j<n_keys;j++)
272279
{
273-
clause=nth(j,qual);
274-
scanexpr= (run_keys[j]==RIGHT_OP) ?
275-
(Node*)get_rightop(clause) : (Node*)get_leftop(clause);
276-
277280
/*
278-
* pass in isDone but ignore it. We don't iterate in
279-
* quals
281+
* If we have a run-time key, then extract the run-time
282+
* expression and evaluate it with respect to the current
283+
* outer tuple. We then stick the result into the scan key.
280284
*/
281-
scanvalue= (Datum)
282-
ExecEvalExpr(scanexpr,exprCtxt,&isNull,&isDone);
283-
scan_keys[j].sk_argument=scanvalue;
284-
if (isNull)
285-
scan_keys[j].sk_flags |=SK_ISNULL;
286-
else
287-
scan_keys[j].sk_flags &= ~SK_ISNULL;
285+
if (run_keys[j]!=NO_OP)
286+
{
287+
clause=nth(j,qual);
288+
scanexpr= (run_keys[j]==RIGHT_OP) ?
289+
(Node*)get_rightop(clause) : (Node*)get_leftop(clause);
290+
291+
/*
292+
* pass in isDone but ignore it. We don't iterate in
293+
* quals
294+
*/
295+
scanvalue= (Datum)
296+
ExecEvalExpr(scanexpr,exprCtxt,&isNull,&isDone);
297+
scan_keys[j].sk_argument=scanvalue;
298+
if (isNull)
299+
scan_keys[j].sk_flags |=SK_ISNULL;
300+
else
301+
scan_keys[j].sk_flags &= ~SK_ISNULL;
302+
}
288303
}
304+
sdesc=scanDescs[i];
305+
skey=scanKeys[i];
306+
index_rescan(sdesc,direction,skey);
289307
}
290-
}
291-
292-
/*
293-
* rescans all indices
294-
*
295-
* note: AMrescan assumes only one scan key. This may have to change if
296-
* we ever decide to support multiple keys.
297-
*/
298-
for (i=0;i<numIndices;i++)
299-
{
300-
sdesc=scanDescs[i];
301-
skey=scanKeys[i];
302-
index_rescan(sdesc,direction,skey);
303-
}
304308

305309
/* ----------------
306310
*perhaps return something meaningful
@@ -322,19 +326,23 @@ ExecEndIndexScan(IndexScan *node)
322326
{
323327
CommonScanState*scanstate;
324328
IndexScanState*indexstate;
329+
Pointer*runtimeKeyInfo;
325330
ScanKey*scanKeys;
331+
int*numScanKeys;
326332
intnumIndices;
327333
inti;
328334

329335
scanstate=node->scan.scanstate;
330336
indexstate=node->indxstate;
331-
337+
runtimeKeyInfo= (Pointer*)indexstate->iss_RuntimeKeyInfo;
338+
332339
/* ----------------
333340
*extract information from the node
334341
* ----------------
335342
*/
336343
numIndices=indexstate->iss_NumIndices;
337344
scanKeys=indexstate->iss_ScanKeys;
345+
numScanKeys=indexstate->iss_NumScanKeys;
338346

339347
/* ----------------
340348
*Free the projection info and the scan attribute info
@@ -362,7 +370,24 @@ ExecEndIndexScan(IndexScan *node)
362370
if (scanKeys[i]!=NULL)
363371
pfree(scanKeys[i]);
364372
}
373+
pfree(scanKeys);
374+
pfree(numScanKeys);
375+
376+
if (runtimeKeyInfo)
377+
{
378+
for (i=0;i<numIndices;i++)
379+
{
380+
List*qual;
381+
intn_keys;
365382

383+
qual=nth(i,indxqual);
384+
n_keys=length(qual);
385+
if (n_keys>0)
386+
pfree(runtimeKeyInfo[i]);
387+
}
388+
pfree(runtimeKeyInfo);
389+
}
390+
366391
/* ----------------
367392
*clear out tuple table slots
368393
* ----------------
@@ -430,7 +455,7 @@ ExecIndexRestrPos(IndexScan *node)
430455

431456
/* ----------------------------------------------------------------
432457
*ExecInitIndexScan
433-
*
458+
*
434459
*Initializes the index scan's state information, creates
435460
*scan keys, and opens the base and index relations.
436461
*
@@ -886,20 +911,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
886911
if (have_runtime_keys)
887912
indexstate->iss_RuntimeKeyInfo= (Pointer)runtimeKeyInfo;
888913
else
889-
{
890914
indexstate->iss_RuntimeKeyInfo=NULL;
891-
for (i=0;i<numIndices;i++)
892-
{
893-
List*qual;
894-
intn_keys;
895-
896-
qual=nth(i,indxqual);
897-
n_keys=length(qual);
898-
if (n_keys>0)
899-
pfree(runtimeKeyInfo[i]);
900-
}
901-
pfree(runtimeKeyInfo);
902-
}
903915

904916
/* ----------------
905917
*get the range table and direction information
@@ -991,6 +1003,5 @@ int
9911003
ExecCountSlotsIndexScan(IndexScan*node)
9921004
{
9931005
returnExecCountSlotsNode(outerPlan((Plan*)node))+
994-
ExecCountSlotsNode(innerPlan((Plan*)node))+
995-
INDEXSCAN_NSLOTS;
1006+
ExecCountSlotsNode(innerPlan((Plan*)node))+INDEXSCAN_NSLOTS;
9961007
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp