diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-12-18 15:49:00 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-12-18 15:50:37 -0500 |
commit | 3695a555136a6d179cac8ae48d5f90171d5b30e9 (patch) | |
tree | efb7fb5afb3dea1292c9a50635b53215cc548e64 /src | |
parent | 19d223171801dda36f84e24dc89c9fbab1ababad (diff) | |
download | postgresql-3695a555136a6d179cac8ae48d5f90171d5b30e9.tar.gz postgresql-3695a555136a6d179cac8ae48d5f90171d5b30e9.zip |
Replace simple constant pg_am.amcanreturn with an AM support function.
The need for this was debated when we put in the index-only-scan feature,
but at the time we had no near-term expectation of having AMs that could
support such scans for only some indexes; so we kept it simple. However,
the SP-GiST AM forces the issue, so let's fix it.
This patch only installs the new API; no behavior actually changes.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/index/indexam.c | 22 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtree.c | 11 | ||||
-rw-r--r-- | src/backend/access/spgist/spgscan.c | 7 | ||||
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 4 | ||||
-rw-r--r-- | src/backend/optimizer/util/plancat.c | 2 | ||||
-rw-r--r-- | src/include/access/genam.h | 1 | ||||
-rw-r--r-- | src/include/access/nbtree.h | 1 | ||||
-rw-r--r-- | src/include/access/spgist.h | 1 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_am.h | 52 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.h | 4 | ||||
-rw-r--r-- | src/include/nodes/relation.h | 2 | ||||
-rw-r--r-- | src/include/utils/rel.h | 1 |
13 files changed, 79 insertions, 31 deletions
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 6d423a7d682..e5fb5183897 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -26,6 +26,7 @@ * index_getbitmap - get all tuples from a scan * index_bulk_delete - bulk deletion of index tuples * index_vacuum_cleanup - post-deletion cleanup of an index + * index_can_return - does index support index-only scans? * index_getprocid - get a support procedure OID * index_getprocinfo - get a support procedure's lookup info * @@ -712,6 +713,27 @@ index_vacuum_cleanup(IndexVacuumInfo *info, } /* ---------------- + * index_can_return - does index support index-only scans? + * ---------------- + */ +bool +index_can_return(Relation indexRelation) +{ + FmgrInfo *procedure; + + RELATION_CHECKS; + + /* amcanreturn is optional; assume FALSE if not provided by AM */ + if (!RegProcedureIsValid(indexRelation->rd_am->amcanreturn)) + return false; + + GET_REL_PROCEDURE(amcanreturn); + + return DatumGetBool(FunctionCall1(procedure, + PointerGetDatum(indexRelation))); +} + +/* ---------------- * index_getprocid * * Index access methods typically require support routines that are diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index f3a1d256a05..13c05525179 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -1091,3 +1091,14 @@ restart: goto restart; } } + +/* + * btcanreturn() -- Check whether btree indexes support index-only scans. + * + * btrees always do, so this is trivial. + */ +Datum +btcanreturn(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(true); +} diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c index ac309649682..748265ecba7 100644 --- a/src/backend/access/spgist/spgscan.c +++ b/src/backend/access/spgist/spgscan.c @@ -559,3 +559,10 @@ spggettuple(PG_FUNCTION_ARGS) PG_RETURN_BOOL(false); } + +Datum +spgcanreturn(PG_FUNCTION_ARGS) +{ + /* Not implemented yet */ + PG_RETURN_BOOL(false); +} diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 74bc7ac7c63..fa6749a2f9c 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -1075,10 +1075,10 @@ check_index_only(RelOptInfo *rel, IndexOptInfo *index) ListCell *lc; int i; - /* Index-only scans must be enabled, and AM must be capable of it */ + /* Index-only scans must be enabled, and index must be capable of them */ if (!enable_indexonlyscan) return false; - if (!index->amcanreturn) + if (!index->canreturn) return false; /* diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index de629e93c9a..77080192efd 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -212,8 +212,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, info->relam = indexRelation->rd_rel->relam; info->amcostestimate = indexRelation->rd_am->amcostestimate; + info->canreturn = index_can_return(indexRelation); info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop; - info->amcanreturn = indexRelation->rd_am->amcanreturn; info->amoptionalkey = indexRelation->rd_am->amoptionalkey; info->amsearcharray = indexRelation->rd_am->amsearcharray; info->amsearchnulls = indexRelation->rd_am->amsearchnulls; diff --git a/src/include/access/genam.h b/src/include/access/genam.h index dd62680dd54..48ebf1986c9 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -156,6 +156,7 @@ extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info, void *callback_state); extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); +extern bool index_can_return(Relation indexRelation); extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum); extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum, diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 9a751ce1004..3a3ff61e571 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -607,6 +607,7 @@ extern Datum btmarkpos(PG_FUNCTION_ARGS); extern Datum btrestrpos(PG_FUNCTION_ARGS); extern Datum btbulkdelete(PG_FUNCTION_ARGS); extern Datum btvacuumcleanup(PG_FUNCTION_ARGS); +extern Datum btcanreturn(PG_FUNCTION_ARGS); extern Datum btoptions(PG_FUNCTION_ARGS); /* diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h index aa655a31402..df6fec6cf45 100644 --- a/src/include/access/spgist.h +++ b/src/include/access/spgist.h @@ -182,6 +182,7 @@ extern Datum spgmarkpos(PG_FUNCTION_ARGS); extern Datum spgrestrpos(PG_FUNCTION_ARGS); extern Datum spggetbitmap(PG_FUNCTION_ARGS); extern Datum spggettuple(PG_FUNCTION_ARGS); +extern Datum spgcanreturn(PG_FUNCTION_ARGS); /* spgutils.c */ extern Datum spgoptions(PG_FUNCTION_ARGS); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index fd424fa8d0c..8bb4c5c58cd 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201112172 +#define CATALOG_VERSION_NO 201112181 #endif diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index 6fdd1d5b052..2289a8e6435 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -45,7 +45,6 @@ CATALOG(pg_am,2601) bool amcanbackward; /* does AM support backward scan? */ bool amcanunique; /* does AM support UNIQUE indexes? */ bool amcanmulticol; /* does AM support multi-column indexes? */ - bool amcanreturn; /* can AM return IndexTuples? */ bool amoptionalkey; /* can query omit key for the first column? */ bool amsearcharray; /* can AM handle ScalarArrayOpExpr quals? */ bool amsearchnulls; /* can AM search for NULL/NOT NULL entries? */ @@ -65,6 +64,7 @@ CATALOG(pg_am,2601) regproc ambuildempty; /* "build empty index" function */ regproc ambulkdelete; /* bulk-delete function */ regproc amvacuumcleanup; /* post-VACUUM cleanup function */ + regproc amcanreturn; /* can indexscan return IndexTuples? */ regproc amcostestimate; /* estimate cost of an indexscan */ regproc amoptions; /* parse AM-specific parameters */ } FormData_pg_am; @@ -89,26 +89,26 @@ typedef FormData_pg_am *Form_pg_am; #define Anum_pg_am_amcanbackward 6 #define Anum_pg_am_amcanunique 7 #define Anum_pg_am_amcanmulticol 8 -#define Anum_pg_am_amcanreturn 9 -#define Anum_pg_am_amoptionalkey 10 -#define Anum_pg_am_amsearcharray 11 -#define Anum_pg_am_amsearchnulls 12 -#define Anum_pg_am_amstorage 13 -#define Anum_pg_am_amclusterable 14 -#define Anum_pg_am_ampredlocks 15 -#define Anum_pg_am_amkeytype 16 -#define Anum_pg_am_aminsert 17 -#define Anum_pg_am_ambeginscan 18 -#define Anum_pg_am_amgettuple 19 -#define Anum_pg_am_amgetbitmap 20 -#define Anum_pg_am_amrescan 21 -#define Anum_pg_am_amendscan 22 -#define Anum_pg_am_ammarkpos 23 -#define Anum_pg_am_amrestrpos 24 -#define Anum_pg_am_ambuild 25 -#define Anum_pg_am_ambuildempty 26 -#define Anum_pg_am_ambulkdelete 27 -#define Anum_pg_am_amvacuumcleanup 28 +#define Anum_pg_am_amoptionalkey 9 +#define Anum_pg_am_amsearcharray 10 +#define Anum_pg_am_amsearchnulls 11 +#define Anum_pg_am_amstorage 12 +#define Anum_pg_am_amclusterable 13 +#define Anum_pg_am_ampredlocks 14 +#define Anum_pg_am_amkeytype 15 +#define Anum_pg_am_aminsert 16 +#define Anum_pg_am_ambeginscan 17 +#define Anum_pg_am_amgettuple 18 +#define Anum_pg_am_amgetbitmap 19 +#define Anum_pg_am_amrescan 20 +#define Anum_pg_am_amendscan 21 +#define Anum_pg_am_ammarkpos 22 +#define Anum_pg_am_amrestrpos 23 +#define Anum_pg_am_ambuild 24 +#define Anum_pg_am_ambuildempty 25 +#define Anum_pg_am_ambulkdelete 26 +#define Anum_pg_am_amvacuumcleanup 27 +#define Anum_pg_am_amcanreturn 28 #define Anum_pg_am_amcostestimate 29 #define Anum_pg_am_amoptions 30 @@ -117,19 +117,19 @@ typedef FormData_pg_am *Form_pg_am; * ---------------- */ -DATA(insert OID = 403 ( btree 5 2 t f t t t t t t t f t t 0 btinsert btbeginscan btgettuple btgetbitmap btrescan btendscan btmarkpos btrestrpos btbuild btbuildempty btbulkdelete btvacuumcleanup btcostestimate btoptions )); +DATA(insert OID = 403 ( btree 5 2 t f t t t t t t f t t 0 btinsert btbeginscan btgettuple btgetbitmap btrescan btendscan btmarkpos btrestrpos btbuild btbuildempty btbulkdelete btvacuumcleanup btcanreturn btcostestimate btoptions )); DESCR("b-tree index access method"); #define BTREE_AM_OID 403 -DATA(insert OID = 405 ( hash 1 1 f f t f f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions )); +DATA(insert OID = 405 ( hash 1 1 f f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup - hashcostestimate hashoptions )); DESCR("hash index access method"); #define HASH_AM_OID 405 -DATA(insert OID = 783 ( gist 0 8 f t f f t f t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions )); +DATA(insert OID = 783 ( gist 0 8 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup - gistcostestimate gistoptions )); DESCR("GiST index access method"); #define GIST_AM_OID 783 -DATA(insert OID = 2742 ( gin 0 5 f f f f t f t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup gincostestimate ginoptions )); +DATA(insert OID = 2742 ( gin 0 5 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions )); DESCR("GIN index access method"); #define GIN_AM_OID 2742 -DATA(insert OID = 4000 ( spgist 0 5 f f f f f f f f f f f f 0 spginsert spgbeginscan spggettuple spggetbitmap spgrescan spgendscan spgmarkpos spgrestrpos spgbuild spgbuildempty spgbulkdelete spgvacuumcleanup spgcostestimate spgoptions )); +DATA(insert OID = 4000 ( spgist 0 5 f f f f f f f f f f f 0 spginsert spgbeginscan spggettuple spggetbitmap spgrescan spgendscan spgmarkpos spgrestrpos spgbuild spgbuildempty spgbulkdelete spgvacuumcleanup spgcanreturn spgcostestimate spgoptions )); DESCR("SP-GiST index access method"); #define SPGIST_AM_OID 4000 diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 6da3b421ae3..60e9feb2e32 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -546,6 +546,8 @@ DATA(insert OID = 332 ( btbulkdelete PGNSP PGUID 12 1 0 0 0 f f f t f v 4 0 DESCR("btree(internal)"); DATA(insert OID = 972 ( btvacuumcleanup PGNSP PGUID 12 1 0 0 0 f f f t f v 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ btvacuumcleanup _null_ _null_ _null_ )); DESCR("btree(internal)"); +DATA(insert OID = 276 ( btcanreturn PGNSP PGUID 12 1 0 0 0 f f f t f s 1 0 16 "2281" _null_ _null_ _null_ _null_ btcanreturn _null_ _null_ _null_ )); +DESCR("btree(internal)"); DATA(insert OID = 1268 ( btcostestimate PGNSP PGUID 12 1 0 0 0 f f f t f v 9 0 2278 "2281 2281 2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ btcostestimate _null_ _null_ _null_ )); DESCR("btree(internal)"); DATA(insert OID = 2785 ( btoptions PGNSP PGUID 12 1 0 0 0 f f f t f s 2 0 17 "1009 16" _null_ _null_ _null_ _null_ btoptions _null_ _null_ _null_ )); @@ -4506,6 +4508,8 @@ DATA(insert OID = 4011 ( spgbulkdelete PGNSP PGUID 12 1 0 0 0 f f f t f v 4 DESCR("spgist(internal)"); DATA(insert OID = 4012 ( spgvacuumcleanup PGNSP PGUID 12 1 0 0 0 f f f t f v 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ spgvacuumcleanup _null_ _null_ _null_ )); DESCR("spgist(internal)"); +DATA(insert OID = 4032 ( spgcanreturn PGNSP PGUID 12 1 0 0 0 f f f t f s 1 0 16 "2281" _null_ _null_ _null_ _null_ spgcanreturn _null_ _null_ _null_ )); +DESCR("spgist(internal)"); DATA(insert OID = 4013 ( spgcostestimate PGNSP PGUID 12 1 0 0 0 f f f t f v 9 0 2278 "2281 2281 2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ _null_ spgcostestimate _null_ _null_ _null_ )); DESCR("spgist(internal)"); DATA(insert OID = 4014 ( spgoptions PGNSP PGUID 12 1 0 0 0 f f f t f s 2 0 17 "1009 16" _null_ _null_ _null_ _null_ spgoptions _null_ _null_ _null_ )); diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index a400960a272..74c060b9b66 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -490,8 +490,8 @@ typedef struct IndexOptInfo bool unique; /* true if a unique index */ bool immediate; /* is uniqueness enforced immediately? */ bool hypothetical; /* true if index doesn't really exist */ + bool canreturn; /* can index return IndexTuples? */ bool amcanorderbyop; /* does AM support order by operator result? */ - bool amcanreturn; /* can AM return IndexTuples? */ bool amoptionalkey; /* can query omit key for the first column? */ bool amsearcharray; /* can AM handle ScalarArrayOpExpr quals? */ bool amsearchnulls; /* can AM search for NULL/NOT NULL entries? */ diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 173dc16a253..70d16eb01e4 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -64,6 +64,7 @@ typedef struct RelationAmInfo FmgrInfo ambuildempty; FmgrInfo ambulkdelete; FmgrInfo amvacuumcleanup; + FmgrInfo amcanreturn; FmgrInfo amcostestimate; FmgrInfo amoptions; } RelationAmInfo; |