mirror of
https://github.com/postgres/postgres.git
synced 2026-06-09 08:42:38 -04:00
Cover additional errors and corner conditions in repack.c
The coverage report shows that some error cases were not being tested;
add test cases for them.
While at it, move some recently added ones to the test_decoding suite:
the preventative check added in 43649b6a53 now causes servers with
wal_level=minimal to error out earlier than before.
Author: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Baji Shaik <baji.pgdev@gmail.com>
Discussion: https://postgr.es/m/ahiwD29RNfVT4tjQ@alvherre.pgsql
This commit is contained in:
parent
e2b35735b0
commit
2670cc298f
4 changed files with 154 additions and 99 deletions
|
|
@ -51,3 +51,53 @@ SELECT * FROM rpk_missing;
|
|||
(3 rows)
|
||||
|
||||
DROP TABLE rpk_missing;
|
||||
-- Error cases for concurrent mode
|
||||
-- Doesn't like partitioned tables
|
||||
CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a);
|
||||
REPACK (CONCURRENTLY) clstrpart;
|
||||
ERROR: REPACK (CONCURRENTLY) is not supported for partitioned tables
|
||||
HINT: Consider running the command on individual partitions.
|
||||
-- Disallowed in catalogs
|
||||
REPACK (CONCURRENTLY) pg_class;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "pg_class"
|
||||
HINT: REPACK (CONCURRENTLY) is not supported for catalog relations.
|
||||
-- Doesn't support TOAST tables directly
|
||||
CREATE TABLE repack_conc_toast (t text);
|
||||
SELECT reltoastrelid::regclass AS toast_rel
|
||||
FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
|
||||
\set VERBOSITY sqlstate
|
||||
REPACK (CONCURRENTLY) :toast_rel;
|
||||
ERROR: 0A000
|
||||
\set VERBOSITY default
|
||||
DROP TABLE repack_conc_toast;
|
||||
-- Only support permanent tables, temp and unlogged tables are not supported
|
||||
CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
|
||||
REPACK (CONCURRENTLY) repack_conc_temp;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_temp"
|
||||
HINT: REPACK (CONCURRENTLY) is only allowed for permanent relations.
|
||||
DROP TABLE repack_conc_temp;
|
||||
CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
|
||||
REPACK (CONCURRENTLY) repack_conc_unlogged;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_unlogged"
|
||||
HINT: REPACK (CONCURRENTLY) is only allowed for permanent relations.
|
||||
DROP TABLE repack_conc_unlogged;
|
||||
-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
|
||||
CREATE TABLE repack_conc_replident (i int PRIMARY KEY);
|
||||
ALTER TABLE repack_conc_replident REPLICA IDENTITY NOTHING;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
|
||||
DETAIL: REPACK (CONCURRENTLY) does not support tables with REPLICA IDENTITY NOTHING.
|
||||
-- Doesn't support tables without a primary key or replica identity index
|
||||
ALTER TABLE repack_conc_replident DROP CONSTRAINT repack_conc_replident_pkey;
|
||||
ALTER TABLE repack_conc_replident REPLICA IDENTITY DEFAULT;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
|
||||
HINT: Relation "repack_conc_replident" has no identity index.
|
||||
-- Doesn't support tables with deferrable primary keys
|
||||
ALTER TABLE repack_conc_replident ADD PRIMARY KEY (i) DEFERRABLE;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
|
||||
DETAIL: REPACK (CONCURRENTLY) does not support deferrable primary keys.
|
||||
HINT: Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity.
|
||||
-- clean up
|
||||
DROP TABLE repack_conc_replident, clstrpart;
|
||||
|
|
|
|||
|
|
@ -32,3 +32,46 @@ SELECT * FROM rpk_missing;
|
|||
REPACK (CONCURRENTLY) rpk_missing;
|
||||
SELECT * FROM rpk_missing;
|
||||
DROP TABLE rpk_missing;
|
||||
|
||||
-- Error cases for concurrent mode
|
||||
|
||||
-- Doesn't like partitioned tables
|
||||
CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a);
|
||||
REPACK (CONCURRENTLY) clstrpart;
|
||||
|
||||
-- Disallowed in catalogs
|
||||
REPACK (CONCURRENTLY) pg_class;
|
||||
|
||||
-- Doesn't support TOAST tables directly
|
||||
CREATE TABLE repack_conc_toast (t text);
|
||||
SELECT reltoastrelid::regclass AS toast_rel
|
||||
FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
|
||||
\set VERBOSITY sqlstate
|
||||
REPACK (CONCURRENTLY) :toast_rel;
|
||||
\set VERBOSITY default
|
||||
DROP TABLE repack_conc_toast;
|
||||
|
||||
-- Only support permanent tables, temp and unlogged tables are not supported
|
||||
CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
|
||||
REPACK (CONCURRENTLY) repack_conc_temp;
|
||||
DROP TABLE repack_conc_temp;
|
||||
CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
|
||||
REPACK (CONCURRENTLY) repack_conc_unlogged;
|
||||
DROP TABLE repack_conc_unlogged;
|
||||
|
||||
-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
|
||||
CREATE TABLE repack_conc_replident (i int PRIMARY KEY);
|
||||
ALTER TABLE repack_conc_replident REPLICA IDENTITY NOTHING;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
|
||||
-- Doesn't support tables without a primary key or replica identity index
|
||||
ALTER TABLE repack_conc_replident DROP CONSTRAINT repack_conc_replident_pkey;
|
||||
ALTER TABLE repack_conc_replident REPLICA IDENTITY DEFAULT;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
|
||||
-- Doesn't support tables with deferrable primary keys
|
||||
ALTER TABLE repack_conc_replident ADD PRIMARY KEY (i) DEFERRABLE;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
|
||||
-- clean up
|
||||
DROP TABLE repack_conc_replident, clstrpart;
|
||||
|
|
|
|||
|
|
@ -697,6 +697,39 @@ SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b;
|
|||
(4 rows)
|
||||
|
||||
COMMIT;
|
||||
-- verify some error cases
|
||||
CREATE TABLE clstr_table_one (id int, val text);
|
||||
CREATE TABLE clstr_table_two (id int, val text);
|
||||
CREATE INDEX clstr_idx_b ON clstr_table_two (id);
|
||||
CLUSTER clstr_table_one USING clstr_idx_b;
|
||||
ERROR: "clstr_idx_b" is not an index for table "clstr_table_one"
|
||||
CLUSTER clstr_table_one USING nonexistant;
|
||||
ERROR: index "nonexistant" for table "clstr_table_one" does not exist
|
||||
CREATE INDEX clstr_hash_idx ON clstr_table_one USING hash (id);
|
||||
CLUSTER clstr_table_one USING clstr_hash_idx;
|
||||
ERROR: cannot cluster on index "clstr_hash_idx" because access method does not support clustering
|
||||
CREATE INDEX clstr_partial_idx ON clstr_table_one (id) WHERE id > 0;
|
||||
CLUSTER clstr_table_one USING clstr_partial_idx;
|
||||
ERROR: cannot cluster on partial index "clstr_partial_idx"
|
||||
REPACK pg_class USING INDEX pg_class_oid_index;
|
||||
ERROR: permission denied: "pg_class" is a system catalog
|
||||
DETAIL: System catalogs can only be clustered by the index they're already clustered on, if any, unless "allow_system_table_mods" is enabled.
|
||||
DROP TABLE clstr_table_one, clstr_table_two;
|
||||
-- verify that CLUSTER/REPACK don't touch a NO DATA matview
|
||||
CREATE MATERIALIZED VIEW clstr_matview AS
|
||||
SELECT i FROM generate_series(1, 5) i
|
||||
WITH NO DATA;
|
||||
CREATE INDEX clstr_matview_idx ON clstr_matview (i);
|
||||
SELECT relfilenode FROM pg_class WHERE oid = 'clstr_matview'::regclass \gset
|
||||
CLUSTER clstr_matview USING clstr_matview_idx;
|
||||
REPACK clstr_matview USING INDEX clstr_matview_idx;
|
||||
SELECT relfilenode = :relfilenode FROM pg_class WHERE oid = 'clstr_matview'::regclass;
|
||||
?column?
|
||||
----------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
DROP MATERIALIZED VIEW clstr_matview;
|
||||
----------------------------------------------------------------------
|
||||
--
|
||||
-- REPACK
|
||||
|
|
@ -796,61 +829,7 @@ ORDER BY o.relname;
|
|||
clstr_3
|
||||
(2 rows)
|
||||
|
||||
--
|
||||
-- Check concurrent mode requirements
|
||||
--
|
||||
-- Disallowed in catalogs
|
||||
REPACK (CONCURRENTLY) pg_class;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "pg_class"
|
||||
HINT: REPACK (CONCURRENTLY) is not supported for catalog relations.
|
||||
-- Doesn't like partitioned tables
|
||||
REPACK (CONCURRENTLY) clstrpart;
|
||||
ERROR: REPACK (CONCURRENTLY) is not supported for partitioned tables
|
||||
HINT: Consider running the command on individual partitions.
|
||||
-- Doesn't support catalog tables
|
||||
REPACK (CONCURRENTLY) pg_class;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "pg_class"
|
||||
HINT: REPACK (CONCURRENTLY) is not supported for catalog relations.
|
||||
-- Only support permanent tables, temp and unlogged tables are not supported
|
||||
CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
|
||||
REPACK (CONCURRENTLY) repack_conc_temp;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_temp"
|
||||
HINT: REPACK (CONCURRENTLY) is only allowed for permanent relations.
|
||||
DROP TABLE repack_conc_temp;
|
||||
CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
|
||||
REPACK (CONCURRENTLY) repack_conc_unlogged;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_unlogged"
|
||||
HINT: REPACK (CONCURRENTLY) is only allowed for permanent relations.
|
||||
DROP TABLE repack_conc_unlogged;
|
||||
-- Doesn't support TOAST tables directly
|
||||
CREATE TABLE repack_conc_toast (t text);
|
||||
SELECT reltoastrelid::regclass AS toast_rel
|
||||
FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
|
||||
\set VERBOSITY sqlstate
|
||||
REPACK (CONCURRENTLY) :toast_rel;
|
||||
ERROR: 0A000
|
||||
\set VERBOSITY default
|
||||
DROP TABLE repack_conc_toast;
|
||||
-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
|
||||
CREATE TABLE repack_conc_replident (i int PRIMARY KEY);
|
||||
ALTER TABLE repack_conc_replident REPLICA IDENTITY NOTHING;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
|
||||
DETAIL: REPACK (CONCURRENTLY) does not support tables with REPLICA IDENTITY NOTHING.
|
||||
-- Doesn't support tables without a primary key or replica identity index
|
||||
ALTER TABLE repack_conc_replident DROP CONSTRAINT repack_conc_replident_pkey;
|
||||
ALTER TABLE repack_conc_replident REPLICA IDENTITY DEFAULT;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
|
||||
HINT: Relation "repack_conc_replident" has no identity index.
|
||||
-- Doesn't support tables with deferrable primary keys
|
||||
ALTER TABLE repack_conc_replident ADD PRIMARY KEY (i) DEFERRABLE;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
|
||||
DETAIL: REPACK (CONCURRENTLY) does not support deferrable primary keys.
|
||||
HINT: Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity.
|
||||
-- clean up
|
||||
DROP TABLE repack_conc_replident;
|
||||
DROP TABLE clustertest;
|
||||
DROP TABLE clstr_1;
|
||||
DROP TABLE clstr_2;
|
||||
|
|
|
|||
|
|
@ -328,6 +328,34 @@ EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b;
|
|||
SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b;
|
||||
COMMIT;
|
||||
|
||||
-- verify some error cases
|
||||
CREATE TABLE clstr_table_one (id int, val text);
|
||||
CREATE TABLE clstr_table_two (id int, val text);
|
||||
CREATE INDEX clstr_idx_b ON clstr_table_two (id);
|
||||
CLUSTER clstr_table_one USING clstr_idx_b;
|
||||
CLUSTER clstr_table_one USING nonexistant;
|
||||
|
||||
CREATE INDEX clstr_hash_idx ON clstr_table_one USING hash (id);
|
||||
CLUSTER clstr_table_one USING clstr_hash_idx;
|
||||
|
||||
CREATE INDEX clstr_partial_idx ON clstr_table_one (id) WHERE id > 0;
|
||||
CLUSTER clstr_table_one USING clstr_partial_idx;
|
||||
|
||||
REPACK pg_class USING INDEX pg_class_oid_index;
|
||||
|
||||
DROP TABLE clstr_table_one, clstr_table_two;
|
||||
|
||||
-- verify that CLUSTER/REPACK don't touch a NO DATA matview
|
||||
CREATE MATERIALIZED VIEW clstr_matview AS
|
||||
SELECT i FROM generate_series(1, 5) i
|
||||
WITH NO DATA;
|
||||
CREATE INDEX clstr_matview_idx ON clstr_matview (i);
|
||||
SELECT relfilenode FROM pg_class WHERE oid = 'clstr_matview'::regclass \gset
|
||||
CLUSTER clstr_matview USING clstr_matview_idx;
|
||||
REPACK clstr_matview USING INDEX clstr_matview_idx;
|
||||
SELECT relfilenode = :relfilenode FROM pg_class WHERE oid = 'clstr_matview'::regclass;
|
||||
DROP MATERIALIZED VIEW clstr_matview;
|
||||
|
||||
----------------------------------------------------------------------
|
||||
--
|
||||
-- REPACK
|
||||
|
|
@ -383,52 +411,7 @@ JOIN relnodes_new n ON o.relname = n.relname
|
|||
WHERE o.relfilenode <> n.relfilenode
|
||||
ORDER BY o.relname;
|
||||
|
||||
--
|
||||
-- Check concurrent mode requirements
|
||||
--
|
||||
|
||||
-- Disallowed in catalogs
|
||||
REPACK (CONCURRENTLY) pg_class;
|
||||
|
||||
-- Doesn't like partitioned tables
|
||||
REPACK (CONCURRENTLY) clstrpart;
|
||||
|
||||
-- Doesn't support catalog tables
|
||||
REPACK (CONCURRENTLY) pg_class;
|
||||
|
||||
-- Only support permanent tables, temp and unlogged tables are not supported
|
||||
CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
|
||||
REPACK (CONCURRENTLY) repack_conc_temp;
|
||||
DROP TABLE repack_conc_temp;
|
||||
CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
|
||||
REPACK (CONCURRENTLY) repack_conc_unlogged;
|
||||
DROP TABLE repack_conc_unlogged;
|
||||
|
||||
-- Doesn't support TOAST tables directly
|
||||
CREATE TABLE repack_conc_toast (t text);
|
||||
SELECT reltoastrelid::regclass AS toast_rel
|
||||
FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
|
||||
\set VERBOSITY sqlstate
|
||||
REPACK (CONCURRENTLY) :toast_rel;
|
||||
\set VERBOSITY default
|
||||
DROP TABLE repack_conc_toast;
|
||||
|
||||
-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
|
||||
CREATE TABLE repack_conc_replident (i int PRIMARY KEY);
|
||||
ALTER TABLE repack_conc_replident REPLICA IDENTITY NOTHING;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
|
||||
-- Doesn't support tables without a primary key or replica identity index
|
||||
ALTER TABLE repack_conc_replident DROP CONSTRAINT repack_conc_replident_pkey;
|
||||
ALTER TABLE repack_conc_replident REPLICA IDENTITY DEFAULT;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
|
||||
-- Doesn't support tables with deferrable primary keys
|
||||
ALTER TABLE repack_conc_replident ADD PRIMARY KEY (i) DEFERRABLE;
|
||||
REPACK (CONCURRENTLY) repack_conc_replident;
|
||||
|
||||
-- clean up
|
||||
DROP TABLE repack_conc_replident;
|
||||
DROP TABLE clustertest;
|
||||
DROP TABLE clstr_1;
|
||||
DROP TABLE clstr_2;
|
||||
|
|
|
|||
Loading…
Reference in a new issue