mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Change the planner to allow indexscan qualification clauses to use
nonconsecutive columns of a multicolumn index, as per discussion around mid-May (pghackers thread "Best way to scan on-disk bitmaps"). This turns out to require only minimal changes in btree, and so far as I can see none at all in GiST. btcostestimate did need some work, but its original assumption that index selectivity == heap selectivity was quite bogus even before this.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.82 2005/05/27 23:31:20 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.83 2005/06/13 23:14:48 tgl Exp $
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
* index_open - open an index relation by relation OID
|
||||
@@ -25,7 +25,6 @@
|
||||
* index_getmulti - get multiple tuples from a scan
|
||||
* index_bulk_delete - bulk deletion of index tuples
|
||||
* index_vacuum_cleanup - post-deletion cleanup of an index
|
||||
* index_cost_estimator - fetch amcostestimate procedure OID
|
||||
* index_getprocid - get a support procedure OID
|
||||
* index_getprocinfo - get a support procedure's lookup info
|
||||
*
|
||||
@@ -718,27 +717,6 @@ index_vacuum_cleanup(Relation indexRelation,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* index_cost_estimator
|
||||
*
|
||||
* Fetch the amcostestimate procedure OID for an index.
|
||||
*
|
||||
* We could combine fetching and calling the procedure,
|
||||
* as index_insert does for example; but that would require
|
||||
* importing a bunch of planner/optimizer stuff into this file.
|
||||
* ----------------
|
||||
*/
|
||||
RegProcedure
|
||||
index_cost_estimator(Relation indexRelation)
|
||||
{
|
||||
FmgrInfo *procedure;
|
||||
|
||||
RELATION_CHECKS;
|
||||
GET_REL_PROCEDURE(amcostestimate);
|
||||
|
||||
return procedure->fn_oid;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* index_getprocid
|
||||
*
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.91 2005/03/29 00:16:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.92 2005/06/13 23:14:48 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -594,15 +594,17 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
||||
}
|
||||
|
||||
/*
|
||||
* Done if that was the last attribute.
|
||||
* Done if that was the last attribute, or if next key
|
||||
* is not in sequence (implying no boundary key is available
|
||||
* for the next attribute).
|
||||
*/
|
||||
if (i >= so->numberOfKeys)
|
||||
if (i >= so->numberOfKeys ||
|
||||
cur->sk_attno != curattr + 1)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Reset for next attr, which should be in sequence.
|
||||
* Reset for next attr.
|
||||
*/
|
||||
Assert(cur->sk_attno == curattr + 1);
|
||||
curattr = cur->sk_attno;
|
||||
chosen = NULL;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.62 2004/12/31 21:59:22 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.63 2005/06/13 23:14:48 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -190,7 +190,9 @@ _bt_formitem(IndexTuple itup)
|
||||
* matched to continue the scan. In general, numberOfRequiredKeys is equal
|
||||
* to the number of keys for leading attributes with "=" keys, plus the
|
||||
* key(s) for the first non "=" attribute, which can be seen to be correct
|
||||
* by considering the above example.
|
||||
* by considering the above example. Note in particular that if there are no
|
||||
* keys for a given attribute, the keys for subsequent attributes can never
|
||||
* be required; for instance "WHERE y = 4" requires a full-index scan.
|
||||
*
|
||||
* If possible, redundant keys are eliminated: we keep only the tightest
|
||||
* >/>= bound and the tightest </<= bound, and if there's an = key then
|
||||
@@ -248,8 +250,8 @@ _bt_preprocess_keys(IndexScanDesc scan)
|
||||
outkeys = so->keyData;
|
||||
cur = &inkeys[0];
|
||||
/* we check that input keys are correctly ordered */
|
||||
if (cur->sk_attno != 1)
|
||||
elog(ERROR, "key(s) for attribute 1 missed");
|
||||
if (cur->sk_attno < 1)
|
||||
elog(ERROR, "btree index keys must be ordered by attribute");
|
||||
|
||||
/* We can short-circuit most of the work if there's just one key */
|
||||
if (numberOfKeys == 1)
|
||||
@@ -270,7 +272,8 @@ _bt_preprocess_keys(IndexScanDesc scan)
|
||||
}
|
||||
memcpy(outkeys, inkeys, sizeof(ScanKeyData));
|
||||
so->numberOfKeys = 1;
|
||||
so->numberOfRequiredKeys = 1;
|
||||
if (cur->sk_attno == 1)
|
||||
so->numberOfRequiredKeys = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -324,8 +327,8 @@ _bt_preprocess_keys(IndexScanDesc scan)
|
||||
int priorNumberOfEqualCols = numberOfEqualCols;
|
||||
|
||||
/* check input keys are correctly ordered */
|
||||
if (i < numberOfKeys && cur->sk_attno != attno + 1)
|
||||
elog(ERROR, "key(s) for attribute %d missed", attno + 1);
|
||||
if (i < numberOfKeys && cur->sk_attno < attno)
|
||||
elog(ERROR, "btree index keys must be ordered by attribute");
|
||||
|
||||
/*
|
||||
* If = has been specified, no other key will be used. In case
|
||||
|
||||
Reference in New Issue
Block a user