1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

Restructure indexscan API (index_beginscan, index_getnext) per

yesterday's proposal to pghackers.  Also remove unnecessary parameters
to heap_beginscan, heap_rescan.  I modified pg_proc.h to reflect the
new numbers of parameters for the AM interface routines, but did not
force an initdb because nothing actually looks at those fields.
This commit is contained in:
Tom Lane
2002-05-20 23:51:44 +00:00
parent c961474c96
commit 44fbe20d62
59 changed files with 834 additions and 1283 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.67 2002/02/19 20:11:13 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.68 2002/05/20 23:51:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -72,14 +72,10 @@ IndexNext(IndexScan *node)
IndexScanState *indexstate;
ExprContext *econtext;
ScanDirection direction;
Snapshot snapshot;
IndexScanDescPtr scanDescs;
IndexScanDesc scandesc;
Relation heapRelation;
RetrieveIndexResult result;
HeapTuple tuple;
TupleTableSlot *slot;
Buffer buffer = InvalidBuffer;
int numIndices;
bool bBackward;
int indexNumber;
@ -96,11 +92,9 @@ IndexNext(IndexScan *node)
else if (ScanDirectionIsBackward(direction))
direction = ForwardScanDirection;
}
snapshot = estate->es_snapshot;
scanstate = node->scan.scanstate;
indexstate = node->indxstate;
scanDescs = indexstate->iss_ScanDescs;
heapRelation = scanstate->css_currentRelation;
numIndices = indexstate->iss_NumIndices;
econtext = scanstate->cstate.cs_ExprContext;
slot = scanstate->css_ScanTupleSlot;
@ -142,8 +136,6 @@ IndexNext(IndexScan *node)
return slot;
}
tuple = &(indexstate->iss_htup);
/*
* ok, now that we have what we need, fetch an index tuple. if
* scanning this index succeeded then return the appropriate heap
@ -170,48 +162,37 @@ IndexNext(IndexScan *node)
while (indexNumber < numIndices)
{
scandesc = scanDescs[indexstate->iss_IndexPtr];
while ((result = index_getnext(scandesc, direction)) != NULL)
while ((tuple = index_getnext(scandesc, direction)) != NULL)
{
tuple->t_self = result->heap_iptr;
heap_fetch(heapRelation, snapshot, tuple, &buffer, scandesc);
pfree(result);
/*
* store the scanned tuple in the scan tuple slot of the
* scan state. Note: we pass 'false' because tuples
* returned by amgetnext are pointers onto disk pages and
* must not be pfree()'d.
*/
ExecStoreTuple(tuple, /* tuple to store */
slot, /* slot to store in */
scandesc->xs_cbuf, /* buffer containing tuple */
false); /* don't pfree */
if (tuple->t_data != NULL)
/*
* We must check to see if the current tuple was already
* matched by an earlier index, so we don't double-report
* it. We do this by passing the tuple through ExecQual
* and checking for failure with all previous
* qualifications.
*/
if (indexstate->iss_IndexPtr > 0)
{
bool prev_matches = false;
int prev_index;
List *qual;
/*
* store the scanned tuple in the scan tuple slot of the
* scan state. Eventually we will only do this and not
* return a tuple. Note: we pass 'false' because tuples
* returned by amgetnext are pointers onto disk pages and
* must not be pfree()'d.
*/
ExecStoreTuple(tuple, /* tuple to store */
slot, /* slot to store in */
buffer, /* buffer associated with tuple */
false); /* don't pfree */
/*
* At this point we have an extra pin on the buffer,
* because ExecStoreTuple incremented the pin count. Drop
* our local pin.
*/
ReleaseBuffer(buffer);
/*
* We must check to see if the current tuple was already
* matched by an earlier index, so we don't double-report
* it. We do this by passing the tuple through ExecQual
* and checking for failure with all previous
* qualifications.
*/
econtext->ecxt_scantuple = slot;
ResetExprContext(econtext);
qual = node->indxqualorig;
for (prev_index = 0; prev_index < indexstate->iss_IndexPtr;
for (prev_index = 0;
prev_index < indexstate->iss_IndexPtr;
prev_index++)
{
if (ExecQual((List *) lfirst(qual), econtext, false))
@ -221,12 +202,17 @@ IndexNext(IndexScan *node)
}
qual = lnext(qual);
}
if (!prev_matches)
return slot; /* OK to return tuple */
/* Duplicate tuple, so drop it and loop back for another */
ExecClearTuple(slot);
if (prev_matches)
{
/* Duplicate, so drop it and loop back for another */
ExecClearTuple(slot);
continue;
}
}
return slot; /* OK to return tuple */
}
if (indexNumber < numIndices)
{
indexNumber++;
@ -300,7 +286,6 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
EState *estate;
IndexScanState *indexstate;
ExprContext *econtext;
ScanDirection direction;
int numIndices;
IndexScanDescPtr scanDescs;
ScanKey *scanKeys;
@ -313,7 +298,6 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
indexstate = node->indxstate;
econtext = indexstate->iss_RuntimeContext; /* context for runtime
* keys */
direction = estate->es_direction;
numIndices = indexstate->iss_NumIndices;
scanDescs = indexstate->iss_ScanDescs;
scanKeys = indexstate->iss_ScanKeys;
@ -431,7 +415,7 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
IndexScanDesc scan = scanDescs[i];
ScanKey skey = scanKeys[i];
index_rescan(scan, direction, skey);
index_rescan(scan, skey);
}
}
@ -622,16 +606,14 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
int indexPtr;
ScanKey *scanKeys;
int *numScanKeys;
RelationPtr relationDescs;
RelationPtr indexDescs;
IndexScanDescPtr scanDescs;
int **runtimeKeyInfo;
bool have_runtime_keys;
List *rangeTable;
RangeTblEntry *rtentry;
Index relid;
Oid reloid;
Relation currentRelation;
ScanDirection direction;
/*
* assign execution state to node
@ -701,7 +683,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
*/
numScanKeys = (int *) palloc(numIndices * sizeof(int));
scanKeys = (ScanKey *) palloc(numIndices * sizeof(ScanKey));
relationDescs = (RelationPtr) palloc(numIndices * sizeof(Relation));
indexDescs = (RelationPtr) palloc(numIndices * sizeof(Relation));
scanDescs = (IndexScanDescPtr) palloc(numIndices * sizeof(IndexScanDesc));
/*
@ -1010,18 +992,11 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
pfree(runtimeKeyInfo);
}
/*
* get the range table and direction information from the execution
* state (these are needed to open the relations).
*/
rangeTable = estate->es_range_table;
direction = estate->es_direction;
/*
* open the base relation and acquire AccessShareLock on it.
*/
relid = node->scan.scanrelid;
rtentry = rt_fetch(relid, rangeTable);
rtentry = rt_fetch(relid, estate->es_range_table);
reloid = rtentry->relid;
currentRelation = heap_open(reloid, AccessShareLock);
@ -1049,24 +1024,16 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
{
Oid indexOid = (Oid) lfirsti(listscan);
if (indexOid != 0)
{
relationDescs[i] = index_open(indexOid);
/*
* Note: index_beginscan()'s second arg is a boolean indicating
* that the scan should be done in reverse. That is, if you pass
* it true, then the scan is backward.
*/
scanDescs[i] = index_beginscan(relationDescs[i],
false, /* see above comment */
numScanKeys[i],
scanKeys[i]);
}
indexDescs[i] = index_open(indexOid);
scanDescs[i] = index_beginscan(currentRelation,
indexDescs[i],
estate->es_snapshot,
numScanKeys[i],
scanKeys[i]);
listscan = lnext(listscan);
}
indexstate->iss_RelationDescs = relationDescs;
indexstate->iss_RelationDescs = indexDescs;
indexstate->iss_ScanDescs = scanDescs;
/*