From acb427cf73b5e56bfa7594993ca41dff8088471e Mon Sep 17 00:00:00 2001 From: Mark Dilger Date: Fri, 1 Oct 2021 11:37:38 -0700 Subject: [PATCH v1] 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. --- 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 cc484d5b39..1a31ea4cb5 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -417,8 +417,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 ff97b618e6..9a8bd3b7cb 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -641,7 +641,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; @@ -789,8 +788,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) { @@ -13704,7 +13703,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 */ @@ -13735,8 +13733,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) @@ -13854,7 +13853,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 bf085aa93b..49cf637c4b 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1154,7 +1154,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; @@ -1181,7 +1180,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 e53d6e4885..143b05f10a 100644 --- a/src/test/regress/expected/brin.out +++ b/src/test/regress/expected/brin.out @@ -565,5 +565,35 @@ 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; diff --git a/src/test/regress/expected/btree_index.out b/src/test/regress/expected/btree_index.out index bc113a70b4..5a51037395 100644 --- a/src/test/regress/expected/btree_index.out +++ b/src/test/regress/expected/btree_index.out @@ -329,3 +329,31 @@ 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" 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 9364b88bc2..698aa0a493 100644 --- a/src/test/regress/expected/spgist.out +++ b/src/test/regress/expected/spgist.out @@ -65,3 +65,33 @@ DETAIL: Valid values are between "10" and "100". -- Modify fillfactor in existing index alter index spgist_point_idx set (fillfactor = 90); reindex index spgist_point_idx; +-- 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 3bd866d947..0b713eba95 100644 --- a/src/test/regress/sql/brin.sql +++ b/src/test/regress/sql/brin.sql @@ -507,5 +507,25 @@ 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 c60312db2d..700f1f1e32 100644 --- a/src/test/regress/sql/btree_index.sql +++ b/src/test/regress/sql/btree_index.sql @@ -172,3 +172,20 @@ 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); 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 c72cf42a33..1dbadad014 100644 --- a/src/test/regress/sql/spgist.sql +++ b/src/test/regress/sql/spgist.sql @@ -71,3 +71,21 @@ create index spgist_point_idx2 on spgist_point_tbl using spgist(p) with (fillfac -- Modify fillfactor in existing index alter index spgist_point_idx set (fillfactor = 90); reindex index spgist_point_idx; + +-- 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)