1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Create core infrastructure for KNNGIST.

This is a heavily revised version of builtin_knngist_core-0.9.  The
ordering operators are no longer mixed in with actual quals, which would
have confused not only humans but significant parts of the planner.
Instead, ordering operators are carried separately throughout planning and
execution.

Since the API for ambeginscan and amrescan functions had to be changed
anyway, this commit takes the opportunity to rationalize that a bit.
RelationGetIndexScan no longer forces a premature index_rescan call;
instead, callers of index_beginscan must call index_rescan too.  Aside from
making the AM-side initialization logic a bit less peculiar, this has the
advantage that we do not make a useless extra am_rescan call when there are
runtime key values.  AMs formerly could not assume that the key values
passed to amrescan were actually valid; now they can.

Teodor Sigaev and Tom Lane
This commit is contained in:
Tom Lane
2010-12-02 20:50:48 -05:00
parent d7e5d151da
commit d583f10b7e
40 changed files with 786 additions and 310 deletions

View File

@@ -57,22 +57,20 @@
/* ----------------
* RelationGetIndexScan -- Create and fill an IndexScanDesc.
*
* This routine creates an index scan structure and sets its contents
* up correctly. This routine calls AMrescan to set up the scan with
* the passed key.
* This routine creates an index scan structure and sets up initial
* contents for it.
*
* Parameters:
* indexRelation -- index relation for scan.
* nkeys -- count of scan keys.
* key -- array of scan keys to restrict the index scan.
* nkeys -- count of scan keys (index qual conditions).
* norderbys -- count of index order-by operators.
*
* Returns:
* An initialized IndexScanDesc.
* ----------------
*/
IndexScanDesc
RelationGetIndexScan(Relation indexRelation,
int nkeys, ScanKey key)
RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
{
IndexScanDesc scan;
@@ -82,15 +80,19 @@ RelationGetIndexScan(Relation indexRelation,
scan->indexRelation = indexRelation;
scan->xs_snapshot = SnapshotNow; /* may be set later */
scan->numberOfKeys = nkeys;
scan->numberOfOrderBys = norderbys;
/*
* We allocate the key space here, but the AM is responsible for actually
* filling it from the passed key array.
* We allocate key workspace here, but it won't get filled until amrescan.
*/
if (nkeys > 0)
scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
else
scan->keyData = NULL;
if (norderbys > 0)
scan->orderByData = (ScanKey) palloc(sizeof(ScanKeyData) * norderbys);
else
scan->orderByData = NULL;
/*
* During recovery we ignore killed tuples and don't bother to kill them
@@ -115,11 +117,6 @@ RelationGetIndexScan(Relation indexRelation,
scan->xs_next_hot = InvalidOffsetNumber;
scan->xs_prev_xmax = InvalidTransactionId;
/*
* Let the AM fill in the key and any opaque data it wants.
*/
index_rescan(scan, key);
return scan;
}
@@ -140,6 +137,8 @@ IndexScanEnd(IndexScanDesc scan)
{
if (scan->keyData != NULL)
pfree(scan->keyData);
if (scan->orderByData != NULL)
pfree(scan->orderByData);
pfree(scan);
}
@@ -286,7 +285,8 @@ systable_beginscan(Relation heapRelation,
}
sysscan->iscan = index_beginscan(heapRelation, irel,
snapshot, nkeys, key);
snapshot, nkeys, 0);
index_rescan(sysscan->iscan, key, nkeys, NULL, 0);
sysscan->scan = NULL;
}
else
@@ -450,7 +450,8 @@ systable_beginscan_ordered(Relation heapRelation,
}
sysscan->iscan = index_beginscan(heapRelation, indexRelation,
snapshot, nkeys, key);
snapshot, nkeys, 0);
index_rescan(sysscan->iscan, key, nkeys, NULL, 0);
sysscan->scan = NULL;
return sysscan;

View File

@@ -114,7 +114,7 @@ do { \
} while(0)
static IndexScanDesc index_beginscan_internal(Relation indexRelation,
int nkeys, ScanKey key);
int nkeys, int norderbys);
/* ----------------------------------------------------------------
@@ -213,11 +213,11 @@ IndexScanDesc
index_beginscan(Relation heapRelation,
Relation indexRelation,
Snapshot snapshot,
int nkeys, ScanKey key)
int nkeys, int norderbys)
{
IndexScanDesc scan;
scan = index_beginscan_internal(indexRelation, nkeys, key);
scan = index_beginscan_internal(indexRelation, nkeys, norderbys);
/*
* Save additional parameters into the scandesc. Everything else was set
@@ -238,11 +238,11 @@ index_beginscan(Relation heapRelation,
IndexScanDesc
index_beginscan_bitmap(Relation indexRelation,
Snapshot snapshot,
int nkeys, ScanKey key)
int nkeys)
{
IndexScanDesc scan;
scan = index_beginscan_internal(indexRelation, nkeys, key);
scan = index_beginscan_internal(indexRelation, nkeys, 0);
/*
* Save additional parameters into the scandesc. Everything else was set
@@ -258,7 +258,7 @@ index_beginscan_bitmap(Relation indexRelation,
*/
static IndexScanDesc
index_beginscan_internal(Relation indexRelation,
int nkeys, ScanKey key)
int nkeys, int norderbys)
{
IndexScanDesc scan;
FmgrInfo *procedure;
@@ -278,7 +278,7 @@ index_beginscan_internal(Relation indexRelation,
DatumGetPointer(FunctionCall3(procedure,
PointerGetDatum(indexRelation),
Int32GetDatum(nkeys),
PointerGetDatum(key)));
Int32GetDatum(norderbys)));
return scan;
}
@@ -286,23 +286,28 @@ index_beginscan_internal(Relation indexRelation,
/* ----------------
* index_rescan - (re)start a scan of an index
*
* The caller may specify a new set of scankeys (but the number of keys
* cannot change). To restart the scan without changing keys, pass NULL
* for the key array.
*
* Note that this is also called when first starting an indexscan;
* see RelationGetIndexScan. Keys *must* be passed in that case,
* unless scan->numberOfKeys is zero.
* During a restart, the caller may specify a new set of scankeys and/or
* orderbykeys; but the number of keys cannot differ from what index_beginscan
* was told. (Later we might relax that to "must not exceed", but currently
* the index AMs tend to assume that scan->numberOfKeys is what to believe.)
* To restart the scan without changing keys, pass NULL for the key arrays.
* (Of course, keys *must* be passed on the first call, unless
* scan->numberOfKeys is zero.)
* ----------------
*/
void
index_rescan(IndexScanDesc scan, ScanKey key)
index_rescan(IndexScanDesc scan,
ScanKey keys, int nkeys,
ScanKey orderbys, int norderbys)
{
FmgrInfo *procedure;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(amrescan);
Assert(nkeys == scan->numberOfKeys);
Assert(norderbys == scan->numberOfOrderBys);
/* Release any held pin on a heap page */
if (BufferIsValid(scan->xs_cbuf))
{
@@ -314,9 +319,12 @@ index_rescan(IndexScanDesc scan, ScanKey key)
scan->kill_prior_tuple = false; /* for safety */
FunctionCall2(procedure,
FunctionCall5(procedure,
PointerGetDatum(scan),
PointerGetDatum(key));
PointerGetDatum(keys),
Int32GetDatum(nkeys),
PointerGetDatum(orderbys),
Int32GetDatum(norderbys));
}
/* ----------------