Check if access methods support an INCLUDE clause.

Trying to create an hypothetical index with an INCLUDE clause on pg10- will
obviously fail with a syntax error.

Also add regression test for the INCLUDE clause on btree indexes.
This commit is contained in:
Julien Rouhaud 2021-02-04 00:16:30 +08:00
parent 119686936e
commit 3e3339b4b8
5 changed files with 96 additions and 1 deletions

View file

@ -44,7 +44,7 @@ ifeq ($(MAJORVERSION),10)
endif
ifneq ($(MAJORVERSION),$(filter $(MAJORVERSION), 9.2 9.3 9.4 9.5 9.6 10))
REGRESS += hypo_index_part
REGRESS += hypo_index_part hypo_include
endif
DEBUILD_ROOT = /tmp/$(EXTENSION)

55
expected/hypo_include.out Normal file
View file

@ -0,0 +1,55 @@
-- hypothetical indexes using INCLUDE keyword, pg11+
-- Remove all the hypothetical indexes if any
SELECT hypopg_reset();
hypopg_reset
--------------
(1 row)
-- Make sure stats and visibility map are up to date
VACUUM ANALYZE hypo;
-- Should not use hypothetical index
-- Create normal index
SELECT hypopg_create_index('CREATE INDEX ON hypo (id)');
hypopg_create_index
------------------------------
(13719,<13719>btree_hypo_id)
(1 row)
-- Should use hypothetical index using a regular Index Scan
SELECT COUNT(*) FROM do_explain('SELECT val FROM hypo WHERE id = 1') e
WHERE e ~ 'Index Scan.*<\d+>btree_hypo.*';
count
-------
1
(1 row)
-- Remove all the hypothetical indexes
SELECT hypopg_reset();
hypopg_reset
--------------
(1 row)
-- Create INCLUDE index
SELECT hypopg_create_index('CREATE INDEX ON hypo (id) INCLUDE (val)');
hypopg_create_index
----------------------------------
(13719,<13719>btree_hypo_id_val)
(1 row)
-- Should use hypothetical index using an Index Only Scan
SELECT COUNT(*) FROM do_explain('SELECT val FROM hypo WHERE id = 1') e
WHERE e ~ 'Index Only Scan.*<\d+>btree_hypo.*';
count
-------
1
(1 row)
-- Deparse the index DDL
SELECT hypopg_get_indexdef(indexrelid) FROM hypopg();
hypopg_get_indexdef
------------------------------------------------------------
CREATE INDEX ON public.hypo USING btree (id) INCLUDE (val)
(1 row)

View file

@ -173,6 +173,7 @@ hypo_newIndex(Oid relid, char *accessMethod, int nkeycolumns, int ninccolumns,
entry->amcanorder = amroutine->amcanorder;
#if PG_VERSION_NUM >= 110000
entry->amcanparallel = amroutine->amcanparallel;
entry->amcaninclude = amroutine->amcaninclude;
#endif
#else
/* Up to 9.5, all information is available in the pg_am tuple */
@ -443,6 +444,14 @@ hypo_index_store_parsetree(IndexStmt *node, const char *queryString)
errmsg("hypopg: access method \"%s\" does not support multicolumn indexes",
node->accessMethod)));
#if PG_VERSION_NUM >= 110000
if (node-> indexIncludingParams != NIL && !entry->amcaninclude)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("hypopg: access method \"%s\" does not support included columns",
node->accessMethod)));
#endif
entry->unique = node->unique;
entry->ncolumns = nkeycolumns + ninccolumns;
entry->nkeycolumns = nkeycolumns;

View file

@ -95,6 +95,8 @@ typedef struct hypoIndex
bool amhasgetbitmap; /* does AM have amgetbitmap interface? */
#if PG_VERSION_NUM >= 110000
bool amcanparallel; /* does AM support parallel scan? */
bool amcaninclude; /* does AM support columns included with clause
INCLUDE? */
#endif
bool amcanunique; /* does AM support UNIQUE indexes? */
bool amcanmulticol; /* does AM support multi-column indexes? */

29
test/sql/hypo_include.sql Normal file
View file

@ -0,0 +1,29 @@
-- hypothetical indexes using INCLUDE keyword, pg11+
-- Remove all the hypothetical indexes if any
SELECT hypopg_reset();
-- Make sure stats and visibility map are up to date
VACUUM ANALYZE hypo;
-- Should not use hypothetical index
-- Create normal index
SELECT hypopg_create_index('CREATE INDEX ON hypo (id)');
-- Should use hypothetical index using a regular Index Scan
SELECT COUNT(*) FROM do_explain('SELECT val FROM hypo WHERE id = 1') e
WHERE e ~ 'Index Scan.*<\d+>btree_hypo.*';
-- Remove all the hypothetical indexes
SELECT hypopg_reset();
-- Create INCLUDE index
SELECT hypopg_create_index('CREATE INDEX ON hypo (id) INCLUDE (val)');
-- Should use hypothetical index using an Index Only Scan
SELECT COUNT(*) FROM do_explain('SELECT val FROM hypo WHERE id = 1') e
WHERE e ~ 'Index Only Scan.*<\d+>btree_hypo.*';
-- Deparse the index DDL
SELECT hypopg_get_indexdef(indexrelid) FROM hypopg();