From 92da8666b6fa248a40b5835de9a7f3b320e46d7a Mon Sep 17 00:00:00 2001 From: Mark Dilger Date: Tue, 21 Dec 2021 11:07:26 -0800 Subject: [PATCH v3] Reject storage options in toast namespace in views CREATE VEW was silently ignoring storage options in the toast namespace. It seems better to reject them. Do that. While at it, add test coverage of storage options used in other CREATE statments. --- doc/src/sgml/ref/create_index.sgml | 8 ++- src/backend/access/common/reloptions.c | 30 +++++++++- src/backend/commands/createas.c | 3 +- src/backend/commands/tablecmds.c | 15 ++--- src/backend/tcop/utility.c | 3 +- src/include/access/reloptions.h | 3 +- src/test/regress/expected/brin.out | 30 ++++++++++ src/test/regress/expected/btree_index.out | 28 ++++++++++ src/test/regress/expected/create_view.out | 6 ++ src/test/regress/expected/gin.out | 30 ++++++++++ src/test/regress/expected/gist.out | 30 ++++++++++ src/test/regress/expected/hash_index.out | 30 ++++++++++ src/test/regress/expected/matview.out | 68 +++++++++++++++++++++++ src/test/regress/expected/spgist.out | 30 ++++++++++ src/test/regress/sql/brin.sql | 20 +++++++ src/test/regress/sql/btree_index.sql | 17 ++++++ src/test/regress/sql/create_view.sql | 4 ++ src/test/regress/sql/gin.sql | 20 +++++++ src/test/regress/sql/gist.sql | 20 +++++++ src/test/regress/sql/hash_index.sql | 18 ++++++ src/test/regress/sql/matview.sql | 56 +++++++++++++++++++ src/test/regress/sql/spgist.sql | 18 ++++++ 22 files changed, 472 insertions(+), 15 deletions(-) diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index 89a4d746f6..17f7332115 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -420,8 +420,12 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - The other index methods use fillfactor in different but roughly - analogous ways; the default fillfactor varies between methods. + Other built-in index methods which use fillfactor use it in different but + roughly analogous ways; the default fillfactor varies between methods. + + + The built-in BRIN and GIN index + methods do not use fillfactor. diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index b5602f5323..0f8d12332f 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -543,6 +543,8 @@ static relopt_string stringRelOpts[] = {{NULL}} }; +static const char *heapNsps[] = HEAP_RELOPT_NAMESPACES; + static relopt_gen **relOpts = NULL; static bits32 last_assigned_kind = RELOPT_KIND_LAST_DEFAULT; @@ -1147,7 +1149,7 @@ add_local_string_reloption(local_relopts *relopts, const char *name, */ Datum transformRelOptions(Datum oldOptions, List *defList, const char *namspace, - char *validnsps[], bool acceptOidsOff, bool isReset) + const char *validnsps[], bool acceptOidsOff, bool isReset) { Datum result; ArrayBuildState *astate; @@ -1316,6 +1318,32 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace, return result; } +/* + * Get the default list of reloption namespaces accepted for the given relkind, + * or NULL if the relkind accepts no namespace qualified reloptions. + */ +const char ** +reloptNsps(char relkind) +{ + switch (relkind) + { + case RELKIND_MATVIEW: + case RELKIND_PARTITIONED_TABLE: + case RELKIND_RELATION: + case RELKIND_TOASTVALUE: + return heapNsps; + case RELKIND_COMPOSITE_TYPE: + case RELKIND_FOREIGN_TABLE: + case RELKIND_INDEX: + case RELKIND_PARTITIONED_INDEX: + case RELKIND_SEQUENCE: + case RELKIND_VIEW: + return NULL; + default: + Assert(false); + } + return NULL; /* keep compiler quiet */ +} /* * Convert the text-array format of reloptions into a List of DefElem. diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 0982851715..5450948357 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -88,7 +88,6 @@ create_ctas_internal(List *attrList, IntoClause *into) bool is_matview; char relkind; Datum toast_options; - static char *validnsps[] = HEAP_RELOPT_NAMESPACES; ObjectAddress intoRelationAddr; /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ @@ -127,7 +126,7 @@ create_ctas_internal(List *attrList, IntoClause *into) toast_options = transformRelOptions((Datum) 0, create->options, "toast", - validnsps, + reloptNsps(RELKIND_RELATION), true, false); (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index bf42587e38..75fe2e4a8c 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -646,7 +646,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *listptr; AttrNumber attnum; bool partitioned; - static char *validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; LOCKMODE parentLockmode; @@ -794,8 +793,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, /* * Parse and validate reloptions, if any. */ - reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps, - true, false); + reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, + reloptNsps(relkind), true, false); switch (relkind) { @@ -13836,7 +13835,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Datum repl_val[Natts_pg_class]; bool repl_null[Natts_pg_class]; bool repl_repl[Natts_pg_class]; - static char *validnsps[] = HEAP_RELOPT_NAMESPACES; if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ @@ -13867,8 +13865,9 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, /* Generate new proposed reloptions (text array) */ newOptions = transformRelOptions(isnull ? (Datum) 0 : datum, - defList, NULL, validnsps, false, - operation == AT_ResetRelOptions); + defList, NULL, + reloptNsps(rel->rd_rel->relkind), + false, operation == AT_ResetRelOptions); /* Validate */ switch (rel->rd_rel->relkind) @@ -13986,7 +13985,9 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, } newOptions = transformRelOptions(isnull ? (Datum) 0 : datum, - defList, "toast", validnsps, false, + defList, "toast", + reloptNsps(RELKIND_TOASTVALUE), + false, operation == AT_ResetRelOptions); (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 1fbc387d47..3a58b29959 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1155,7 +1155,6 @@ ProcessUtilitySlow(ParseState *pstate, { CreateStmt *cstmt = (CreateStmt *) stmt; Datum toast_options; - static char *validnsps[] = HEAP_RELOPT_NAMESPACES; /* Remember transformed RangeVar for LIKE */ table_rv = cstmt->relation; @@ -1182,7 +1181,7 @@ ProcessUtilitySlow(ParseState *pstate, toast_options = transformRelOptions((Datum) 0, cstmt->options, "toast", - validnsps, + reloptNsps(RELKIND_TOASTVALUE), true, false); (void) heap_reloptions(RELKIND_TOASTVALUE, diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index 7c5fbeb517..88d3a8f093 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -220,8 +220,9 @@ extern void add_local_string_reloption(local_relopts *opts, const char *name, fill_string_relopt filler, int offset); extern Datum transformRelOptions(Datum oldOptions, List *defList, - const char *namspace, char *validnsps[], + const char *namspace, const char *validnsps[], bool acceptOidsOff, bool isReset); +extern const char **reloptNsps(char relkind); extern List *untransformRelOptions(Datum options); extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, amoptions_function amoptions); diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out index 2d03d8e134..f46590d1f0 100644 --- a/src/test/regress/expected/brin.out +++ b/src/test/regress/expected/brin.out @@ -565,6 +565,36 @@ SELECT * FROM brintest_3 WHERE b < '0'; ---+---+---+--- (0 rows) +-- Test supported storage parameters +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (autosummarize=true,pages_per_range=40); +-- Test unsupported storage parameters +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (deduplicate_items=on); -- from btree +ERROR: unrecognized parameter "deduplicate_items" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (fastupdate=on); -- from gin +ERROR: unrecognized parameter "fastupdate" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (gin_pending_list_limit=1000); -- from gin +ERROR: unrecognized parameter "gin_pending_list_limit" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (fillfactor=30); -- from gist +ERROR: unrecognized parameter "fillfactor" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (buffering=on); -- from gist +ERROR: unrecognized parameter "buffering" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (parallel_workers=5); -- from heap +ERROR: unrecognized parameter "parallel_workers" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (seq_page_cost=1.0); -- from tablespace +ERROR: unrecognized parameter "seq_page_cost" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (random_page_cost=4.0); -- from tablespace +ERROR: unrecognized parameter "random_page_cost" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (effective_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "effective_io_concurrency" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (maintenance_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "maintenance_io_concurrency" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (toast.vacuum_index_cleanup=auto); -- from toast +ERROR: unrecognized parameter namespace "toast" +-- Test nonsense storage parameters +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (nonsense); +ERROR: unrecognized parameter "nonsense" +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (toast.nonsense); +ERROR: unrecognized parameter namespace "toast" DROP TABLE brintest_3; RESET enable_seqscan; -- Test handling of index predicates - updating attributes in predicates diff --git a/src/test/regress/expected/btree_index.out b/src/test/regress/expected/btree_index.out index c43e023716..7720515a6a 100644 --- a/src/test/regress/expected/btree_index.out +++ b/src/test/regress/expected/btree_index.out @@ -329,6 +329,34 @@ INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,1000) i; -- Test unsupported btree opclass parameters create index on btree_tall_tbl (id int4_ops(foo=1)); ERROR: operator class int4_ops has no options +-- Test unsupported storage parameters +create index on btree_tall_tbl (id) with (pages_per_range=40); -- from brin +ERROR: unrecognized parameter "pages_per_range" +create index on btree_tall_tbl (id) with (autosummarize=true); -- from brin +ERROR: unrecognized parameter "autosummarize" +create index on btree_tall_tbl (id) with (fastupdate=on); -- from gin +ERROR: unrecognized parameter "fastupdate" +create index on btree_tall_tbl (id) with (gin_pending_list_limit=1000); -- from gin +ERROR: unrecognized parameter "gin_pending_list_limit" +create index on btree_tall_tbl (id) with (buffering=on); -- from gist +ERROR: unrecognized parameter "buffering" +create index on btree_tall_tbl (id) with (parallel_workers=5); -- from heap +ERROR: unrecognized parameter "parallel_workers" +create index on btree_tall_tbl (id) with (seq_page_cost=1.0); -- from tablespace +ERROR: unrecognized parameter "seq_page_cost" +create index on btree_tall_tbl (id) with (random_page_cost=4.0); -- from tablespace +ERROR: unrecognized parameter "random_page_cost" +create index on btree_tall_tbl (id) with (effective_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "effective_io_concurrency" +create index on btree_tall_tbl (id) with (maintenance_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "maintenance_io_concurrency" +create index on btree_tall_tbl (id) with (toast.vacuum_index_cleanup=auto); -- from toast +ERROR: unrecognized parameter namespace "toast" +-- Test nonsense storage parameters +create index on btree_tall_tbl (id) with (nonsense); +ERROR: unrecognized parameter "nonsense" +create index on btree_tall_tbl (id) with (toast.nonsense); +ERROR: unrecognized parameter namespace "toast" -- Test case of ALTER INDEX with abuse of column names for indexes. -- This grammar is not officially supported, but the parser allows it. CREATE INDEX btree_tall_idx2 ON btree_tall_tbl (id); diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out index f50ef76685..ab7b0d98d8 100644 --- a/src/test/regress/expected/create_view.out +++ b/src/test/regress/expected/create_view.out @@ -267,6 +267,12 @@ ERROR: invalid value for boolean option "security_barrier": 100 CREATE VIEW mysecview6 WITH (invalid_option) -- Error AS SELECT * FROM tbl1 WHERE a < 100; ERROR: unrecognized parameter "invalid_option" +CREATE VIEW mysecview7 WITH (toast.vacuum_index_cleanup=OFF) -- Error + AS SELECT * FROM tbl1 WHERE a < 100; +ERROR: unrecognized parameter namespace "toast" +CREATE VIEW mysecview8 WITH (nonsense.instanity) -- Error + AS SELECT * FROM tbl1 WHERE a < 100; +ERROR: unrecognized parameter namespace "nonsense" SELECT relname, relkind, reloptions FROM pg_class WHERE oid in ('mysecview1'::regclass, 'mysecview2'::regclass, 'mysecview3'::regclass, 'mysecview4'::regclass) diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out index 6402e89c7f..c95ac0a151 100644 --- a/src/test/regress/expected/gin.out +++ b/src/test/regress/expected/gin.out @@ -287,4 +287,34 @@ select count(*) from t_gin_test_tbl where j @> '{}'::int[]; reset enable_seqscan; reset enable_bitmapscan; +-- Test supported storage parameters +create index on t_gin_test_tbl using gin(i, j) with (fastupdate=on, gin_pending_list_limit=1000); +-- Test unsupported storage parameters +create index on t_gin_test_tbl using gin(i, j) with (pages_per_range=40); -- from brin +ERROR: unrecognized parameter "pages_per_range" +create index on t_gin_test_tbl using gin(i, j) with (autosummarize=true); -- from brin +ERROR: unrecognized parameter "autosummarize" +create index on t_gin_test_tbl using gin(i, j) with (deduplicate_items=on); -- from btree +ERROR: unrecognized parameter "deduplicate_items" +create index on t_gin_test_tbl using gin(i, j) with (fillfactor=30); -- from gist +ERROR: unrecognized parameter "fillfactor" +create index on t_gin_test_tbl using gin(i, j) with (buffering=on); -- from gist +ERROR: unrecognized parameter "buffering" +create index on t_gin_test_tbl using gin(i, j) with (parallel_workers=5); -- from heap +ERROR: unrecognized parameter "parallel_workers" +create index on t_gin_test_tbl using gin(i, j) with (seq_page_cost=1.0); -- from tablespace +ERROR: unrecognized parameter "seq_page_cost" +create index on t_gin_test_tbl using gin(i, j) with (random_page_cost=4.0); -- from tablespace +ERROR: unrecognized parameter "random_page_cost" +create index on t_gin_test_tbl using gin(i, j) with (effective_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "effective_io_concurrency" +create index on t_gin_test_tbl using gin(i, j) with (maintenance_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "maintenance_io_concurrency" +create index on t_gin_test_tbl using gin(i, j) with (toast.vacuum_index_cleanup=auto); -- from toast +ERROR: unrecognized parameter namespace "toast" +-- Test nonsense storage parameters +create index on t_gin_test_tbl using gin(i, j) with (nonsense); +ERROR: unrecognized parameter "nonsense" +create index on t_gin_test_tbl using gin(i, j) with (toast.nonsense); +ERROR: unrecognized parameter namespace "toast" drop table t_gin_test_tbl; diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index 90edb4061d..3f4ad53819 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -316,4 +316,34 @@ drop index gist_tbl_multi_index; reset enable_seqscan; reset enable_bitmapscan; reset enable_indexonlyscan; +-- Test supported storage parameters +create index on gist_tbl using gist (p, c) with (fillfactor=30, buffering=on); +-- Test unsupported storage parameters +create index on gist_tbl using gist (p, c) with (pages_per_range=40); -- from brin +ERROR: unrecognized parameter "pages_per_range" +create index on gist_tbl using gist (p, c) with (autosummarize=true); -- from brin +ERROR: unrecognized parameter "autosummarize" +create index on gist_tbl using gist (p, c) with (deduplicate_items=on); -- from btree +ERROR: unrecognized parameter "deduplicate_items" +create index on gist_tbl using gist (p, c) with (fastupdate=on); -- from gin +ERROR: unrecognized parameter "fastupdate" +create index on gist_tbl using gist (p, c) with (gin_pending_list_limit=1000); -- from gin +ERROR: unrecognized parameter "gin_pending_list_limit" +create index on gist_tbl using gist (p, c) with (parallel_workers=5); -- from heap +ERROR: unrecognized parameter "parallel_workers" +create index on gist_tbl using gist (p, c) with (seq_page_cost=1.0); -- from tablespace +ERROR: unrecognized parameter "seq_page_cost" +create index on gist_tbl using gist (p, c) with (random_page_cost=4.0); -- from tablespace +ERROR: unrecognized parameter "random_page_cost" +create index on gist_tbl using gist (p, c) with (effective_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "effective_io_concurrency" +create index on gist_tbl using gist (p, c) with (maintenance_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "maintenance_io_concurrency" +create index on gist_tbl using gist (p, c) with (toast.vacuum_index_cleanup=auto); -- from toast +ERROR: unrecognized parameter namespace "toast" +-- Test nonsense storage parameters +create index on gist_tbl using gist (p, c) with (nonsense); +ERROR: unrecognized parameter "nonsense" +create index on gist_tbl using gist (p, c) with (toast.nonsense); +ERROR: unrecognized parameter namespace "toast" drop table gist_tbl; diff --git a/src/test/regress/expected/hash_index.out b/src/test/regress/expected/hash_index.out index e23de21b41..b1c2ca0d6f 100644 --- a/src/test/regress/expected/hash_index.out +++ b/src/test/regress/expected/hash_index.out @@ -241,3 +241,33 @@ CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) WITH (fillfactor=101); ERROR: value 101 out of bounds for option "fillfactor" DETAIL: Valid values are between "10" and "100". +-- Test unsupported storage parameters +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (autosummarize=true); -- from brin +ERROR: unrecognized parameter "autosummarize" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (pages_per_range=40); -- from brin +ERROR: unrecognized parameter "pages_per_range" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (deduplicate_items=on); -- from btree +ERROR: unrecognized parameter "deduplicate_items" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (fastupdate=on); -- from gin +ERROR: unrecognized parameter "fastupdate" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (gin_pending_list_limit=1000); -- from gin +ERROR: unrecognized parameter "gin_pending_list_limit" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (buffering=on); -- from gist +ERROR: unrecognized parameter "buffering" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (parallel_workers=5); -- from heap +ERROR: unrecognized parameter "parallel_workers" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (seq_page_cost=1.0); -- from tablespace +ERROR: unrecognized parameter "seq_page_cost" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (random_page_cost=4.0); -- from tablespace +ERROR: unrecognized parameter "random_page_cost" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (effective_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "effective_io_concurrency" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (maintenance_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "maintenance_io_concurrency" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (toast.vacuum_index_cleanup=auto); -- from toast +ERROR: unrecognized parameter namespace "toast" +-- Test nonsense storage parameters +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (nonsense); +ERROR: unrecognized parameter "nonsense" +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (toast.nonsense); +ERROR: unrecognized parameter namespace "toast" diff --git a/src/test/regress/expected/matview.out b/src/test/regress/expected/matview.out index 313c72a268..6782c606d5 100644 --- a/src/test/regress/expected/matview.out +++ b/src/test/regress/expected/matview.out @@ -676,3 +676,71 @@ NOTICE: relation "matview_ine_tab" already exists, skipping (0 rows) DROP MATERIALIZED VIEW matview_ine_tab; +-- Test supported storage parameters +CREATE MATERIALIZED VIEW matview_opts + WITH (toast.vacuum_index_cleanup=auto, fillfactor=30, parallel_workers=5) + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +DROP MATERIALIZED VIEW matview_opts; +-- Test supported toast storage parameters with materialzed views lacking +-- toastable columns +CREATE MATERIALIZED VIEW matview_opts WITH (toast.vacuum_index_cleanup=auto) + AS SELECT gs AS i FROM generate_series(1,100) gs; +DROP MATERIALIZED VIEW matview_opts; +-- Test unsupported toast storage parameters with materialzed views lacking +-- toastable columns +CREATE MATERIALIZED VIEW matview_uns_opts WITH (toast.no_such_option) + AS SELECT gs AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "no_such_option" +-- Test the interaction of supported storage parameters with delayed population +CREATE MATERIALIZED VIEW matview_opts + WITH (toast.vacuum_index_cleanup=auto, fillfactor=30, parallel_workers=5) + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs + WITH NO DATA; +REFRESH MATERIALIZED VIEW matview_opts; +SELECT rel.reloptions, toast.reloptions AS toastoptions + FROM pg_class rel LEFT JOIN pg_class toast ON rel.reltoastrelid = toast.oid + WHERE rel.relname = 'matview_opts'; + reloptions | toastoptions +------------------------------------+----------------------------- + {fillfactor=30,parallel_workers=5} | {vacuum_index_cleanup=auto} +(1 row) + +DROP MATERIALIZED VIEW matview_opts; +-- Test unsupported storage parameters +CREATE MATERIALIZED VIEW matview_uns_opts WITH (pages_per_range=40) -- from brin + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "pages_per_range" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (autosummarize=true) -- from brin + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "autosummarize" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (deduplicate_items=true) -- from btree + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "deduplicate_items" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (fastupdate=on) -- from gin + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "fastupdate" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (gin_pending_list_limit=1000) -- from gin + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "gin_pending_list_limit" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (buffering=on) -- from gist + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "buffering" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (seq_page_cost=1.0) -- from tablespace + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "seq_page_cost" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (random_page_cost=4.0) -- from tablespace + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "random_page_cost" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (effective_io_concurrency=5) -- from tablespace + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "effective_io_concurrency" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (maintenance_io_concurrency=5) -- from tablespace + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "maintenance_io_concurrency" +-- Test nonsense storage parameters +CREATE MATERIALIZED VIEW matview_uns_opts WITH (nonsense) + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "nonsense" +CREATE MATERIALIZED VIEW matview_uns_opts WITH (toast.nonsense) + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +ERROR: unrecognized parameter "nonsense" diff --git a/src/test/regress/expected/spgist.out b/src/test/regress/expected/spgist.out index 1688e0e0a3..e40ec7c5ce 100644 --- a/src/test/regress/expected/spgist.out +++ b/src/test/regress/expected/spgist.out @@ -86,3 +86,33 @@ select * from spgist_domain_tbl where f1 = 'fo'; fo (1 row) +-- Test unsupported storage parameters +create index on spgist_point_tbl using spgist(p) with (pages_per_range=40); -- from brin +ERROR: unrecognized parameter "pages_per_range" +create index on spgist_point_tbl using spgist(p) with (autosummarize=true); -- from brin +ERROR: unrecognized parameter "autosummarize" +create index on spgist_point_tbl using spgist(p) with (deduplicate_items=on); -- from btree +ERROR: unrecognized parameter "deduplicate_items" +create index on spgist_point_tbl using spgist(p) with (fastupdate=on); -- from gin +ERROR: unrecognized parameter "fastupdate" +create index on spgist_point_tbl using spgist(p) with (gin_pending_list_limit=1000); -- from gin +ERROR: unrecognized parameter "gin_pending_list_limit" +create index on spgist_point_tbl using spgist(p) with (buffering=on); -- from gist +ERROR: unrecognized parameter "buffering" +create index on spgist_point_tbl using spgist(p) with (parallel_workers=5); -- from heap +ERROR: unrecognized parameter "parallel_workers" +create index on spgist_point_tbl using spgist(p) with (seq_page_cost=1.0); -- from tablespace +ERROR: unrecognized parameter "seq_page_cost" +create index on spgist_point_tbl using spgist(p) with (random_page_cost=4.0); -- from tablespace +ERROR: unrecognized parameter "random_page_cost" +create index on spgist_point_tbl using spgist(p) with (effective_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "effective_io_concurrency" +create index on spgist_point_tbl using spgist(p) with (maintenance_io_concurrency=5); -- from tablespace +ERROR: unrecognized parameter "maintenance_io_concurrency" +create index on spgist_point_tbl using spgist(p) with (toast.vacuum_index_cleanup=auto); -- from toast +ERROR: unrecognized parameter namespace "toast" +-- Test nonsense storage parameters +create index on spgist_point_tbl using spgist(p) with (nonsense); +ERROR: unrecognized parameter "nonsense" +create index on spgist_point_tbl using spgist(p) with (toast.nonsense); +ERROR: unrecognized parameter namespace "toast" diff --git a/src/test/regress/sql/brin.sql b/src/test/regress/sql/brin.sql index e12f3a0df9..a6acd61e32 100644 --- a/src/test/regress/sql/brin.sql +++ b/src/test/regress/sql/brin.sql @@ -507,6 +507,26 @@ SELECT * FROM brintest_3 WHERE b < '0'; SELECT * FROM brintest_3 WHERE b < '0'; +-- Test supported storage parameters +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (autosummarize=true,pages_per_range=40); + +-- Test unsupported storage parameters +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (deduplicate_items=on); -- from btree +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (fastupdate=on); -- from gin +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (gin_pending_list_limit=1000); -- from gin +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (fillfactor=30); -- from gist +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (buffering=on); -- from gist +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (parallel_workers=5); -- from heap +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (seq_page_cost=1.0); -- from tablespace +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (random_page_cost=4.0); -- from tablespace +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (effective_io_concurrency=5); -- from tablespace +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (maintenance_io_concurrency=5); -- from tablespace +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (toast.vacuum_index_cleanup=auto); -- from toast + +-- Test nonsense storage parameters +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (nonsense); +CREATE INDEX ON brintest_3 USING brin (b, c) WITH (toast.nonsense); + DROP TABLE brintest_3; RESET enable_seqscan; diff --git a/src/test/regress/sql/btree_index.sql b/src/test/regress/sql/btree_index.sql index c34502249f..0aad5464f6 100644 --- a/src/test/regress/sql/btree_index.sql +++ b/src/test/regress/sql/btree_index.sql @@ -173,6 +173,23 @@ INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,1000) i; -- Test unsupported btree opclass parameters create index on btree_tall_tbl (id int4_ops(foo=1)); +-- Test unsupported storage parameters +create index on btree_tall_tbl (id) with (pages_per_range=40); -- from brin +create index on btree_tall_tbl (id) with (autosummarize=true); -- from brin +create index on btree_tall_tbl (id) with (fastupdate=on); -- from gin +create index on btree_tall_tbl (id) with (gin_pending_list_limit=1000); -- from gin +create index on btree_tall_tbl (id) with (buffering=on); -- from gist +create index on btree_tall_tbl (id) with (parallel_workers=5); -- from heap +create index on btree_tall_tbl (id) with (seq_page_cost=1.0); -- from tablespace +create index on btree_tall_tbl (id) with (random_page_cost=4.0); -- from tablespace +create index on btree_tall_tbl (id) with (effective_io_concurrency=5); -- from tablespace +create index on btree_tall_tbl (id) with (maintenance_io_concurrency=5); -- from tablespace +create index on btree_tall_tbl (id) with (toast.vacuum_index_cleanup=auto); -- from toast + +-- Test nonsense storage parameters +create index on btree_tall_tbl (id) with (nonsense); +create index on btree_tall_tbl (id) with (toast.nonsense); + -- Test case of ALTER INDEX with abuse of column names for indexes. -- This grammar is not officially supported, but the parser allows it. CREATE INDEX btree_tall_idx2 ON btree_tall_tbl (id); diff --git a/src/test/regress/sql/create_view.sql b/src/test/regress/sql/create_view.sql index bdda56e8de..3ac2ec091a 100644 --- a/src/test/regress/sql/create_view.sql +++ b/src/test/regress/sql/create_view.sql @@ -218,6 +218,10 @@ CREATE VIEW mysecview5 WITH (security_barrier=100) -- Error AS SELECT * FROM tbl1 WHERE a > 100; CREATE VIEW mysecview6 WITH (invalid_option) -- Error AS SELECT * FROM tbl1 WHERE a < 100; +CREATE VIEW mysecview7 WITH (toast.vacuum_index_cleanup=OFF) -- Error + AS SELECT * FROM tbl1 WHERE a < 100; +CREATE VIEW mysecview8 WITH (nonsense.instanity) -- Error + AS SELECT * FROM tbl1 WHERE a < 100; SELECT relname, relkind, reloptions FROM pg_class WHERE oid in ('mysecview1'::regclass, 'mysecview2'::regclass, 'mysecview3'::regclass, 'mysecview4'::regclass) diff --git a/src/test/regress/sql/gin.sql b/src/test/regress/sql/gin.sql index 5194afcc1f..18ece42a36 100644 --- a/src/test/regress/sql/gin.sql +++ b/src/test/regress/sql/gin.sql @@ -170,4 +170,24 @@ select count(*) from t_gin_test_tbl where j @> '{}'::int[]; reset enable_seqscan; reset enable_bitmapscan; +-- Test supported storage parameters +create index on t_gin_test_tbl using gin(i, j) with (fastupdate=on, gin_pending_list_limit=1000); + +-- Test unsupported storage parameters +create index on t_gin_test_tbl using gin(i, j) with (pages_per_range=40); -- from brin +create index on t_gin_test_tbl using gin(i, j) with (autosummarize=true); -- from brin +create index on t_gin_test_tbl using gin(i, j) with (deduplicate_items=on); -- from btree +create index on t_gin_test_tbl using gin(i, j) with (fillfactor=30); -- from gist +create index on t_gin_test_tbl using gin(i, j) with (buffering=on); -- from gist +create index on t_gin_test_tbl using gin(i, j) with (parallel_workers=5); -- from heap +create index on t_gin_test_tbl using gin(i, j) with (seq_page_cost=1.0); -- from tablespace +create index on t_gin_test_tbl using gin(i, j) with (random_page_cost=4.0); -- from tablespace +create index on t_gin_test_tbl using gin(i, j) with (effective_io_concurrency=5); -- from tablespace +create index on t_gin_test_tbl using gin(i, j) with (maintenance_io_concurrency=5); -- from tablespace +create index on t_gin_test_tbl using gin(i, j) with (toast.vacuum_index_cleanup=auto); -- from toast + +-- Test nonsense storage parameters +create index on t_gin_test_tbl using gin(i, j) with (nonsense); +create index on t_gin_test_tbl using gin(i, j) with (toast.nonsense); + drop table t_gin_test_tbl; diff --git a/src/test/regress/sql/gist.sql b/src/test/regress/sql/gist.sql index b9d398ea94..3973221126 100644 --- a/src/test/regress/sql/gist.sql +++ b/src/test/regress/sql/gist.sql @@ -147,4 +147,24 @@ reset enable_seqscan; reset enable_bitmapscan; reset enable_indexonlyscan; +-- Test supported storage parameters +create index on gist_tbl using gist (p, c) with (fillfactor=30, buffering=on); + +-- Test unsupported storage parameters +create index on gist_tbl using gist (p, c) with (pages_per_range=40); -- from brin +create index on gist_tbl using gist (p, c) with (autosummarize=true); -- from brin +create index on gist_tbl using gist (p, c) with (deduplicate_items=on); -- from btree +create index on gist_tbl using gist (p, c) with (fastupdate=on); -- from gin +create index on gist_tbl using gist (p, c) with (gin_pending_list_limit=1000); -- from gin +create index on gist_tbl using gist (p, c) with (parallel_workers=5); -- from heap +create index on gist_tbl using gist (p, c) with (seq_page_cost=1.0); -- from tablespace +create index on gist_tbl using gist (p, c) with (random_page_cost=4.0); -- from tablespace +create index on gist_tbl using gist (p, c) with (effective_io_concurrency=5); -- from tablespace +create index on gist_tbl using gist (p, c) with (maintenance_io_concurrency=5); -- from tablespace +create index on gist_tbl using gist (p, c) with (toast.vacuum_index_cleanup=auto); -- from toast + +-- Test nonsense storage parameters +create index on gist_tbl using gist (p, c) with (nonsense); +create index on gist_tbl using gist (p, c) with (toast.nonsense); + drop table gist_tbl; diff --git a/src/test/regress/sql/hash_index.sql b/src/test/regress/sql/hash_index.sql index 4d1aa020a9..b7fcb8b58c 100644 --- a/src/test/regress/sql/hash_index.sql +++ b/src/test/regress/sql/hash_index.sql @@ -202,3 +202,21 @@ CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) WITH (fillfactor=9); CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) WITH (fillfactor=101); + +-- Test unsupported storage parameters +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (autosummarize=true); -- from brin +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (pages_per_range=40); -- from brin +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (deduplicate_items=on); -- from btree +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (fastupdate=on); -- from gin +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (gin_pending_list_limit=1000); -- from gin +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (buffering=on); -- from gist +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (parallel_workers=5); -- from heap +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (seq_page_cost=1.0); -- from tablespace +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (random_page_cost=4.0); -- from tablespace +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (effective_io_concurrency=5); -- from tablespace +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (maintenance_io_concurrency=5); -- from tablespace +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (toast.vacuum_index_cleanup=auto); -- from toast + +-- Test nonsense storage parameters +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (nonsense); +CREATE INDEX ON hash_f8_heap USING hash (random) WITH (toast.nonsense); diff --git a/src/test/regress/sql/matview.sql b/src/test/regress/sql/matview.sql index 68b9ccfd45..21f023e684 100644 --- a/src/test/regress/sql/matview.sql +++ b/src/test/regress/sql/matview.sql @@ -295,3 +295,59 @@ EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) CREATE MATERIALIZED VIEW IF NOT EXISTS matview_ine_tab AS SELECT 1 / 0 WITH NO DATA; -- ok DROP MATERIALIZED VIEW matview_ine_tab; + +-- Test supported storage parameters +CREATE MATERIALIZED VIEW matview_opts + WITH (toast.vacuum_index_cleanup=auto, fillfactor=30, parallel_workers=5) + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +DROP MATERIALIZED VIEW matview_opts; + +-- Test supported toast storage parameters with materialzed views lacking +-- toastable columns +CREATE MATERIALIZED VIEW matview_opts WITH (toast.vacuum_index_cleanup=auto) + AS SELECT gs AS i FROM generate_series(1,100) gs; +DROP MATERIALIZED VIEW matview_opts; + +-- Test unsupported toast storage parameters with materialzed views lacking +-- toastable columns +CREATE MATERIALIZED VIEW matview_uns_opts WITH (toast.no_such_option) + AS SELECT gs AS i FROM generate_series(1,100) gs; + +-- Test the interaction of supported storage parameters with delayed population +CREATE MATERIALIZED VIEW matview_opts + WITH (toast.vacuum_index_cleanup=auto, fillfactor=30, parallel_workers=5) + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs + WITH NO DATA; +REFRESH MATERIALIZED VIEW matview_opts; +SELECT rel.reloptions, toast.reloptions AS toastoptions + FROM pg_class rel LEFT JOIN pg_class toast ON rel.reltoastrelid = toast.oid + WHERE rel.relname = 'matview_opts'; +DROP MATERIALIZED VIEW matview_opts; + +-- Test unsupported storage parameters +CREATE MATERIALIZED VIEW matview_uns_opts WITH (pages_per_range=40) -- from brin + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (autosummarize=true) -- from brin + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (deduplicate_items=true) -- from btree + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (fastupdate=on) -- from gin + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (gin_pending_list_limit=1000) -- from gin + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (buffering=on) -- from gist + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (seq_page_cost=1.0) -- from tablespace + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (random_page_cost=4.0) -- from tablespace + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (effective_io_concurrency=5) -- from tablespace + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (maintenance_io_concurrency=5) -- from tablespace + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; + +-- Test nonsense storage parameters +CREATE MATERIALIZED VIEW matview_uns_opts WITH (nonsense) + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; +CREATE MATERIALIZED VIEW matview_uns_opts WITH (toast.nonsense) + AS SELECT gs, gs::text AS i FROM generate_series(1,100) gs; diff --git a/src/test/regress/sql/spgist.sql b/src/test/regress/sql/spgist.sql index 7644f344a9..e8f1a65138 100644 --- a/src/test/regress/sql/spgist.sql +++ b/src/test/regress/sql/spgist.sql @@ -80,3 +80,21 @@ insert into spgist_domain_tbl values('fee'), ('fi'), ('fo'), ('fum'); explain (costs off) select * from spgist_domain_tbl where f1 = 'fo'; select * from spgist_domain_tbl where f1 = 'fo'; + +-- Test unsupported storage parameters +create index on spgist_point_tbl using spgist(p) with (pages_per_range=40); -- from brin +create index on spgist_point_tbl using spgist(p) with (autosummarize=true); -- from brin +create index on spgist_point_tbl using spgist(p) with (deduplicate_items=on); -- from btree +create index on spgist_point_tbl using spgist(p) with (fastupdate=on); -- from gin +create index on spgist_point_tbl using spgist(p) with (gin_pending_list_limit=1000); -- from gin +create index on spgist_point_tbl using spgist(p) with (buffering=on); -- from gist +create index on spgist_point_tbl using spgist(p) with (parallel_workers=5); -- from heap +create index on spgist_point_tbl using spgist(p) with (seq_page_cost=1.0); -- from tablespace +create index on spgist_point_tbl using spgist(p) with (random_page_cost=4.0); -- from tablespace +create index on spgist_point_tbl using spgist(p) with (effective_io_concurrency=5); -- from tablespace +create index on spgist_point_tbl using spgist(p) with (maintenance_io_concurrency=5); -- from tablespace +create index on spgist_point_tbl using spgist(p) with (toast.vacuum_index_cleanup=auto); -- from toast + +-- Test nonsense storage parameters +create index on spgist_point_tbl using spgist(p) with (nonsense); +create index on spgist_point_tbl using spgist(p) with (toast.nonsense); -- 2.21.1 (Apple Git-122.3)