From 7166a0ee8cecf11bab626adcbab55fdd03da8990 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Fri, 13 Oct 2017 09:16:37 +0100 Subject: [PATCH 1/8] Preparing release 1.4.2 --- META.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/META.json b/META.json index 9ab89fd..ad0425b 100644 --- a/META.json +++ b/META.json @@ -2,7 +2,7 @@ "name": "pg_repack", "abstract": "PostgreSQL module for data reorganization", "description": "Reorganize tables in PostgreSQL databases with minimal locks", - "version": "1.4.1", + "version": "1.4.2", "maintainer": [ "Beena Emerson ", "Josh Kupershmidt ", @@ -15,7 +15,7 @@ "provides": { "pg_repack": { "file": "lib/pg_repack.sql", - "version": "1.4.1", + "version": "1.4.2", "abstract": "Reorganize tables in PostgreSQL databases with minimal locks" } }, From fdad0b87a2c61d1ff02a6c423af4545a87193a8e Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 17 Oct 2017 18:03:07 +0900 Subject: [PATCH 2/8] Fix Japanese doc. --- doc/pg_repack_jp.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/pg_repack_jp.rst b/doc/pg_repack_jp.rst index 0c7e931..f129c45 100644 --- a/doc/pg_repack_jp.rst +++ b/doc/pg_repack_jp.rst @@ -871,8 +871,7 @@ ACCESS EXCLUSIVEロックを取得します。その他のステップでは、A * pg_repack 1.4.2 * PostgreSQL 10をサポートしました (issue #120) - * エラー「DROP INDEX CONCURRENTLY cannot run inside a transaction block」が発生する事象を - 修正しました (issue #129) + * エラー「DROP INDEX CONCURRENTLY cannot run inside a transaction block」が発生する事象を修正しました (issue #129) .. * pg_repack 1.4.1 .. * fixed broken ``--order-by`` option (issue #138) From 4fa4f8945ed6ef0f9122f685a5d2d63ed623fb4a Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 17 Oct 2017 12:11:28 +0900 Subject: [PATCH 3/8] Fix change logs of version 1.4.1 and 1.4.2. --- doc/pg_repack_jp.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/pg_repack_jp.rst b/doc/pg_repack_jp.rst index f129c45..7161762 100644 --- a/doc/pg_repack_jp.rst +++ b/doc/pg_repack_jp.rst @@ -864,12 +864,13 @@ ACCESS EXCLUSIVEロックを取得します。その他のステップでは、A リリースノート --------------- + .. * pg_repack 1.4.2 .. * added PostgreSQL 10 support (issue #120) -.. * fixed error DROP INDEX CONCURRENTLY cannot run inside a transaction block - (issue #129) +.. * fixed error DROP INDEX CONCURRENTLY cannot run inside a transaction block (issue #129) * pg_repack 1.4.2 + * PostgreSQL 10をサポートしました (issue #120) * エラー「DROP INDEX CONCURRENTLY cannot run inside a transaction block」が発生する事象を修正しました (issue #129) @@ -877,6 +878,7 @@ ACCESS EXCLUSIVEロックを取得します。その他のステップでは、A .. * fixed broken ``--order-by`` option (issue #138) * pg_repack 1.4.1 + * 壊れていた ``--order-by`` オプションを修正しました (issue #138) .. * pg_repack 1.4 From bf61feefc4140041bcb2a473c72d4ef67f74b2c5 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 17 Oct 2017 12:16:44 +0900 Subject: [PATCH 4/8] Fix Japanese doc. --- doc/pg_repack_jp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pg_repack_jp.rst b/doc/pg_repack_jp.rst index 7161762..1a5a735 100644 --- a/doc/pg_repack_jp.rst +++ b/doc/pg_repack_jp.rst @@ -879,7 +879,7 @@ ACCESS EXCLUSIVEロックを取得します。その他のステップでは、A * pg_repack 1.4.1 - * 壊れていた ``--order-by`` オプションを修正しました (issue #138) + * 壊れていた ``--order-by`` オプションを修正しました (issue #138) .. * pg_repack 1.4 .. * added support for PostgreSQL 9.6 From 2f6196d6546dc884c4b907bd80388f632ab4694f Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Fri, 9 Mar 2018 10:53:43 +0900 Subject: [PATCH 5/8] Always qualify relation names. Due to change at PostgreSQL 10.3, 9.6.8, 9.5.12, 9.4.17 and 9.3.22, relation names passed by PostgreSQL function such as pg_get_indexdef_string() are schema-qualified, which could be cause of a parse error. --- lib/repack.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/repack.c b/lib/repack.c index 43f7e80..801ff8d 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -354,11 +354,27 @@ get_relation_name(Oid relid) Oid nsp = get_rel_namespace(relid); char *nspname; + /* + * Relation names given by PostgreSQL core are always + * qualified since some minor releases. + */ +#if ((PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 100003) || \ + (PG_VERSION_NUM >= 90600 && PG_VERSION_NUM < 90608) || \ + (PG_VERSION_NUM >= 90500 && PG_VERSION_NUM < 90512) || \ + (PG_VERSION_NUM >= 90400 && PG_VERSION_NUM < 90417) || \ + (PG_VERSION_NUM >= 90300 && PG_VERSION_NUM < 90322)) /* Qualify the name if not visible in search path */ if (RelationIsVisible(relid)) nspname = NULL; else nspname = get_namespace_name(nsp); +#else + /* Qualify the name */ + if (OidIsValid(nsp)) + nspname = get_namespace_name(nsp); + else + nspname = NULL; +#endif return quote_qualified_identifier(nspname, get_rel_name(relid)); } From a0fe223f8b59b8109b208a3ecb56dc969abb2eaa Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Fri, 9 Mar 2018 11:00:42 +0900 Subject: [PATCH 6/8] Forgot to add expected files of regression tests. --- regress/expected/repack_3.out | 600 ++++++++++++++++++++++++++++++ regress/expected/tablespace_2.out | 234 ++++++++++++ 2 files changed, 834 insertions(+) create mode 100644 regress/expected/repack_3.out create mode 100644 regress/expected/tablespace_2.out diff --git a/regress/expected/repack_3.out b/regress/expected/repack_3.out new file mode 100644 index 0000000..cb1dfb3 --- /dev/null +++ b/regress/expected/repack_3.out @@ -0,0 +1,600 @@ +-- Test output file identifier. +SELECT CASE + WHEN split_part(version(), ' ', 2) ~ '^(10)' + THEN 'repack_2.out' + WHEN split_part(version(), ' ', 2) ~ '^(9\.6|9\.5)' + THEN 'repack.out' + WHEN split_part(version(), ' ', 2) ~ '^(9\.4|9\.3|9\.2|9\.1)' + THEN 'repack_1.out' + ELSE version() +END AS testfile; + testfile +-------------- + repack_2.out +(1 row) + +SET client_min_messages = warning; +-- +-- create table. +-- +CREATE TABLE tbl_cluster ( + col1 int, + "time" timestamp, + ","")" text, + PRIMARY KEY (","")", col1) WITH (fillfactor = 75) +) WITH (fillfactor = 70); +CREATE INDEX ","") cluster" ON tbl_cluster ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75); +ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; +CREATE TABLE tbl_only_pkey ( + col1 int PRIMARY KEY, + ","")" text +); +CREATE TABLE tbl_only_ckey ( + col1 int, + col2 timestamp, + ","")" text +) WITH (fillfactor = 70); +CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); +ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; +CREATE TABLE tbl_gistkey ( + id integer PRIMARY KEY, + c circle +); +CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c); +ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle; +CREATE TABLE tbl_with_dropped_column ( + d1 text, + c1 text, + id integer PRIMARY KEY, + d2 text, + c2 text, + d3 text +); +ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75); +ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey; +CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75); +CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1); +CREATE TABLE tbl_with_dropped_toast ( + i integer, + j integer, + t text, + PRIMARY KEY (i, j) +); +ALTER TABLE tbl_with_dropped_toast CLUSTER ON tbl_with_dropped_toast_pkey; +CREATE TABLE tbl_badindex ( + id integer PRIMARY KEY, + n integer +); +CREATE TABLE tbl_idxopts ( + i integer PRIMARY KEY, + t text +); +CREATE INDEX idxopts_t ON tbl_idxopts (t DESC NULLS LAST) WHERE (t != 'aaa'); +-- Use this table to play with attribute options too +ALTER TABLE tbl_idxopts ALTER i SET STATISTICS 1; +ALTER TABLE tbl_idxopts ALTER t SET (n_distinct = -0.5); +CREATE TABLE tbl_with_toast ( + i integer PRIMARY KEY, + c text +); +ALTER TABLE tbl_with_toast SET (AUTOVACUUM_VACUUM_SCALE_FACTOR = 30, AUTOVACUUM_VACUUM_THRESHOLD = 300); +ALTER TABLE tbl_with_toast SET (TOAST.AUTOVACUUM_VACUUM_SCALE_FACTOR = 40, TOAST.AUTOVACUUM_VACUUM_THRESHOLD = 400); +CREATE TABLE tbl_with_mod_column_storage ( + id integer PRIMARY KEY, + c text +); +ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; +CREATE TABLE tbl_order (c int primary key); +-- +-- insert data +-- +INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin'); +INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king'); +INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker'); +INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen'); +INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); +INSERT INTO tbl_only_pkey VALUES(1, 'abc'); +INSERT INTO tbl_only_pkey VALUES(2, 'def'); +INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc'); +INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def'); +INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>'); +INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>'); +INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 2, 'd2', 'c2', 'd3'); +INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 1, 'd2', 'c2', 'd3'); +ALTER TABLE tbl_with_dropped_column DROP COLUMN d1; +ALTER TABLE tbl_with_dropped_column DROP COLUMN d2; +ALTER TABLE tbl_with_dropped_column DROP COLUMN d3; +ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text; +CREATE VIEW view_for_dropped_column AS + SELECT * FROM tbl_with_dropped_column; +INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc'); +INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); +ALTER TABLE tbl_with_dropped_toast DROP COLUMN t; +INSERT INTO tbl_badindex VALUES(1, 10); +INSERT INTO tbl_badindex VALUES(2, 10); +-- insert data that is always stored into the toast table if column type is extended. +SELECT setseed(0); INSERT INTO tbl_with_mod_column_storage SELECT 1, array_to_string(ARRAY(SELECT chr((random() * (127 - 32) + 32)::int) FROM generate_series(1, 3 * 1024) code), ''); + setseed +--------- + +(1 row) + +-- This will fail. Silence the message as it's different across PG versions. +SET client_min_messages = fatal; +CREATE UNIQUE INDEX CONCURRENTLY idx_badindex_n ON tbl_badindex (n); +SET client_min_messages = warning; +INSERT INTO tbl_idxopts VALUES (0, 'abc'), (1, 'aaa'), (2, NULL), (3, 'bbb'); +-- Insert no-ordered data +INSERT INTO tbl_order SELECT generate_series(100, 51, -1); +CLUSTER tbl_order USING tbl_order_pkey; +INSERT INTO tbl_order SELECT generate_series(50, 1, -1); +-- +-- before +-- +SELECT * FROM tbl_with_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 2 | c2 | + c1 | 1 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 2 | c2 | + c1 | 1 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +-- +-- do repack +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster +INFO: repacking table "tbl_cluster" +\! pg_repack --dbname=contrib_regression --table=tbl_badindex +INFO: repacking table "tbl_badindex" +WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) +\! pg_repack --dbname=contrib_regression +INFO: repacking table "tbl_cluster" +INFO: repacking table "tbl_only_pkey" +INFO: repacking table "tbl_gistkey" +INFO: repacking table "tbl_with_dropped_column" +INFO: repacking table "tbl_with_dropped_toast" +INFO: repacking table "tbl_badindex" +WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) +INFO: repacking table "tbl_idxopts" +INFO: repacking table "tbl_with_toast" +INFO: repacking table "tbl_with_mod_column_storage" +INFO: repacking table "tbl_order" +-- +-- after +-- +\d tbl_cluster + Table "public.tbl_cluster" + Column | Type | Collation | Nullable | Default +--------+-----------------------------+-----------+----------+--------- + col1 | integer | | not null | + time | timestamp without time zone | | | + ,") | text | | not null | +Indexes: + "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) WITH (fillfactor='75') + ",") cluster" btree ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor='75') CLUSTER + +\d tbl_gistkey + Table "public.tbl_gistkey" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + id | integer | | not null | + c | circle | | | +Indexes: + "tbl_gistkey_pkey" PRIMARY KEY, btree (id) + "cidx_circle" gist (c) CLUSTER + +\d tbl_only_ckey + Table "public.tbl_only_ckey" + Column | Type | Collation | Nullable | Default +--------+-----------------------------+-----------+----------+--------- + col1 | integer | | | + col2 | timestamp without time zone | | | + ,") | text | | | +Indexes: + "cidx_only_ckey" btree (col2, ","")") CLUSTER + +\d tbl_only_pkey + Table "public.tbl_only_pkey" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + col1 | integer | | not null | + ,") | text | | | +Indexes: + "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) + +\d tbl_with_dropped_column + Table "public.tbl_with_dropped_column" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + c1 | text | | | + id | integer | | not null | + c2 | text | | | + c3 | text | | | +Indexes: + "tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) WITH (fillfactor='75') CLUSTER + "idx_c1c2" btree (c1, c2) WITH (fillfactor='75') + "idx_c2c1" btree (c2, c1) + +\d tbl_with_dropped_toast + Table "public.tbl_with_dropped_toast" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + i | integer | | not null | + j | integer | | not null | +Indexes: + "tbl_with_dropped_toast_pkey" PRIMARY KEY, btree (i, j) CLUSTER + +\d tbl_idxopts + Table "public.tbl_idxopts" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + i | integer | | not null | + t | text | | | +Indexes: + "tbl_idxopts_pkey" PRIMARY KEY, btree (i) + "idxopts_t" btree (t DESC NULLS LAST) WHERE t <> 'aaa'::text + +SELECT col1, to_char("time", 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster ORDER BY 1, 2; + col1 | to_char | ,") +------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + 1 | 2008-12-31 10:00:00 | admin + 2 | 2008-01-01 00:00:00 | king + 3 | 2008-03-04 12:00:00 | joker + 4 | 2008-03-05 15:00:00 | queen + 5 | 2008-01-01 00:30:00 | 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488471.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146186757248575675626141415406703029969945094998952478811655512094373648528093231902305582067974820101084674923265015312343266903322886650672254668921837971227047131660367861588019049986537379859389467650347506576050756618348129606100947602187190325083145829523959832997789824508288714463832917347224163984587855397667958063818353666110843173780894378316102088305524901670023520711144288695990956365797087168498072899493296484283020786408603988738697537582317317831395992983007838702877053913369563312103707264019249106768231199288375641141422016742752102372994270831059898459475987664288897796147837958390228854852903576033852808064381972344661059689722872865264153822664698420021195484155278441181286534507035191650016689294415480846071277143999762926834629577438361895110127148638746976545982451788550975379013880664961911962222957110555242923723192197738262561631468842032853716682938649611917049738836395495938 +(5 rows) + +SELECT * FROM tbl_only_ckey ORDER BY 1; + col1 | col2 | ,") +------+--------------------------+----- + 1 | Tue Jan 01 00:00:00 2008 | abc + 2 | Fri Feb 01 00:00:00 2008 | def +(2 rows) + +SELECT * FROM tbl_only_pkey ORDER BY 1; + col1 | ,") +------+----- + 1 | abc + 2 | def +(2 rows) + +SELECT * FROM tbl_gistkey ORDER BY 1; + id | c +----+----------- + 1 | <(1,2),3> + 2 | <(4,5),6> +(2 rows) + +SET enable_seqscan = on; +SET enable_indexscan = off; +SELECT * FROM tbl_with_dropped_column ; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column ORDER BY 1, 2; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +SET enable_seqscan = off; +SET enable_indexscan = on; +SELECT * FROM tbl_with_dropped_column ORDER BY 1, 2; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +RESET enable_seqscan; +RESET enable_indexscan; +-- check if storage option for both table and TOAST table didn't go away. +SELECT CASE relkind + WHEN 'r' THEN relname + WHEN 't' THEN 'toast_table' + END as table, + reloptions +FROM pg_class +WHERE relname = 'tbl_with_toast' OR relname = 'pg_toast_' || 'tbl_with_toast'::regclass::oid +ORDER BY 1; + table | reloptions +----------------+--------------------------------------------------------------------- + tbl_with_toast | {autovacuum_vacuum_scale_factor=30,autovacuum_vacuum_threshold=300} + toast_table | {autovacuum_vacuum_scale_factor=40,autovacuum_vacuum_threshold=400} +(2 rows) + +SELECT pg_relation_size(reltoastrelid) = 0 as check_toast_rel_size FROM pg_class WHERE relname = 'tbl_with_mod_column_storage'; + check_toast_rel_size +---------------------- + t +(1 row) + +-- +-- check broken links or orphan toast relations +-- +SELECT oid, relname + FROM pg_class + WHERE relkind = 't' + AND oid NOT IN (SELECT reltoastrelid FROM pg_class WHERE relkind = 'r'); + oid | relname +-----+--------- +(0 rows) + +SELECT oid, relname + FROM pg_class + WHERE relkind = 'r' + AND reltoastrelid <> 0 + AND reltoastrelid NOT IN (SELECT oid FROM pg_class WHERE relkind = 't'); + oid | relname +-----+--------- +(0 rows) + +-- check columns options +SELECT attname, attstattarget, attoptions +FROM pg_attribute +WHERE attrelid = 'tbl_idxopts'::regclass +AND attnum > 0 +ORDER BY attnum; + attname | attstattarget | attoptions +---------+---------------+------------------- + i | 1 | + t | -1 | {n_distinct=-0.5} +(2 rows) + +-- +-- NOT NULL UNIQUE +-- +CREATE TABLE tbl_nn (col1 int NOT NULL, col2 int NOT NULL); +CREATE TABLE tbl_uk (col1 int NOT NULL, col2 int , UNIQUE(col1, col2)); +CREATE TABLE tbl_nn_uk (col1 int NOT NULL, col2 int NOT NULL, UNIQUE(col1, col2)); +CREATE TABLE tbl_pk_uk (col1 int NOT NULL, col2 int NOT NULL, PRIMARY KEY(col1, col2), UNIQUE(col2, col1)); +CREATE TABLE tbl_nn_puk (col1 int NOT NULL, col2 int NOT NULL); +CREATE UNIQUE INDEX tbl_nn_puk_pcol1_idx ON tbl_nn_puk(col1) WHERE col1 < 10; +\! pg_repack --dbname=contrib_regression --table=tbl_nn +WARNING: relation "tbl_nn" must have a primary key or not-null unique keys +-- => WARNING +\! pg_repack --dbname=contrib_regression --table=tbl_uk +WARNING: relation "tbl_uk" must have a primary key or not-null unique keys +-- => WARNING +\! pg_repack --dbname=contrib_regression --table=tbl_nn_uk +INFO: repacking table "tbl_nn_uk" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_pk_uk +INFO: repacking table "tbl_pk_uk" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_pk_uk --only-indexes +INFO: repacking indexes of "tbl_pk_uk" +INFO: repacking index "public"."tbl_pk_uk_col2_col1_key" +INFO: repacking index "public"."tbl_pk_uk_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_nn_puk +WARNING: relation "tbl_nn_puk" must have a primary key or not-null unique keys +-- => WARNING +-- +-- Triggers handling +-- +CREATE FUNCTION trgtest() RETURNS trigger AS +$$BEGIN RETURN NEW; END$$ +LANGUAGE plpgsql; +CREATE TABLE trg1 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger_1 AFTER UPDATE ON trg1 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg1 +INFO: repacking table "trg1" +CREATE TABLE trg2 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger AFTER UPDATE ON trg2 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg2 +INFO: repacking table "trg2" +WARNING: the table "trg2" already has a trigger called "repack_trigger" +DETAIL: The trigger was probably installed during a previous attempt to run pg_repack on the table which was interrupted and for some reason failed to clean up the temporary objects. Please drop the trigger or drop and recreate the pg_repack extension altogether to remove all the temporary objects left over. +CREATE TABLE trg3 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger_1 BEFORE UPDATE ON trg3 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg3 +INFO: repacking table "trg3" +-- +-- Table re-organization using specific column +-- +-- reorganize table using cluster key. Sort in ascending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order +INFO: repacking table "tbl_order" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + ctid | c +--------+---- + (0,1) | 1 + (0,2) | 2 + (0,3) | 3 + (0,4) | 4 + (0,5) | 5 + (0,6) | 6 + (0,7) | 7 + (0,8) | 8 + (0,9) | 9 + (0,10) | 10 +(10 rows) + +-- reorganize table using specific column order. Sort in descending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order -o "c DESC" +INFO: repacking table "tbl_order" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + ctid | c +--------+----- + (0,1) | 100 + (0,2) | 99 + (0,3) | 98 + (0,4) | 97 + (0,5) | 96 + (0,6) | 95 + (0,7) | 94 + (0,8) | 93 + (0,9) | 92 + (0,10) | 91 +(10 rows) + +-- +-- Dry run +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --dry-run +INFO: Dry run enabled, not executing repack +INFO: repacking table "tbl_cluster" +-- Test --schema +-- +CREATE SCHEMA test_schema1; +CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); +CREATE SCHEMA test_schema2; +CREATE TABLE test_schema2.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema2.tbl2 (id INTEGER PRIMARY KEY); +-- => OK +\! pg_repack --dbname=contrib_regression --schema=test_schema1 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +-- => OK +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +INFO: repacking table "test_schema2.tbl1" +INFO: repacking table "test_schema2.tbl2" +-- => ERROR +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --table=tbl1 +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --all --schema=test_schema1 +ERROR: cannot repack specific schema(s) in all databases +-- +-- don't kill backend +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-kill-backend +INFO: repacking table "tbl_cluster" +-- +-- no superuser check +-- +DROP ROLE IF EXISTS nosuper; +CREATE ROLE nosuper WITH LOGIN; +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-superuser-check +INFO: repacking table "tbl_cluster" +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper +ERROR: pg_repack failed with error: You must be a superuser to use pg_repack +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check +ERROR: pg_repack failed with error: ERROR: permission denied for schema repack +LINE 1: select repack.version(), repack.version_sql() + ^ +DROP ROLE IF EXISTS nosuper; +-- +-- exclude extension check +-- +CREATE SCHEMA exclude_extension_schema; +CREATE TABLE exclude_extension_schema.tbl(val integer primary key); +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension +ERROR: cannot specify --table (-t) and --exclude-extension (-C) +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension -x +ERROR: cannot specify --only-indexes (-x) and --exclude-extension (-C) +-- => ERROR +\! pg_repack --dbname=contrib_regression --index=dummy_index --exclude-extension=dummy_extension +ERROR: cannot specify --index (-i) and --exclude-extension (-C) +-- => OK +\! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension +INFO: repacking table "exclude_extension_schema.tbl" +-- => OK +\! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension --exclude-extension=dummy_extension +INFO: repacking table "exclude_extension_schema.tbl" +-- +-- table inheritance check +-- +CREATE TABLE parent_a(val integer primary key); +CREATE TABLE child_a_1(val integer primary key) INHERITS(parent_a); +CREATE TABLE child_a_2(val integer primary key) INHERITS(parent_a); +CREATE TABLE parent_b(val integer primary key); +CREATE TABLE child_b_1(val integer primary key) INHERITS(parent_b); +CREATE TABLE child_b_2(val integer primary key) INHERITS(parent_b); +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table +ERROR: pg_repack failed with error: ERROR: relation "dummy_table" does not exist +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_index --index=dummy_index +ERROR: cannot specify --index (-i) and --parent-table (-I) +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --schema=dummy_schema +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --all +ERROR: cannot repack specific table(s) in all databases +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "child_a_1" +INFO: repacking table "child_a_2" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "public.child_a_1" +INFO: repacking index "public"."child_a_1_pkey" +INFO: repacking indexes of "public.child_a_2" +INFO: repacking index "public"."child_a_2_pkey" +INFO: repacking indexes of "public.parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" diff --git a/regress/expected/tablespace_2.out b/regress/expected/tablespace_2.out new file mode 100644 index 0000000..dcc5542 --- /dev/null +++ b/regress/expected/tablespace_2.out @@ -0,0 +1,234 @@ +SET client_min_messages = warning; +-- +-- Tablespace features tests +-- +-- Note: in order to pass this test you must create a tablespace called 'testts' +-- +SELECT spcname FROM pg_tablespace WHERE spcname = 'testts'; + spcname +--------- + testts +(1 row) + +-- If the query above failed you must create the 'testts' tablespace; +CREATE TABLE testts1 (id serial primary key, data text); +CREATE INDEX testts1_partial_idx on testts1 (id) where (id > 0); +CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); +INSERT INTO testts1 (data) values ('a'); +INSERT INTO testts1 (data) values ('b'); +INSERT INTO testts1 (data) values ('c'); +-- check the indexes definitions +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, false), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +---------------------------------------------------------------------------------------------------------- + CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE pg_default WHERE (id > 0) + CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE pg_default + CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE pg_default +(3 rows) + +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', false), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +--------------------------------------------------------------------------------------------------- + CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo WHERE (id > 0) + CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo + CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor='80') TABLESPACE foo +(3 rows) + +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, true), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +--------------------------------------------------------------------------------------------------------------------- + CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE pg_default WHERE (id > 0) + CREATE UNIQUE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE pg_default + CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE pg_default +(3 rows) + +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', true), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +-------------------------------------------------------------------------------------------------------------- + CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE foo WHERE (id > 0) + CREATE UNIQUE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) TABLESPACE foo + CREATE INDEX CONCURRENTLY index_OID ON public.testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE foo +(3 rows) + +-- can move the tablespace from default +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts +INFO: repacking table "testts1" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- + testts1 | testts +(1 row) + +SELECT * from testts1 order by id; + id | data +----+------ + 1 | a + 2 | b + 3 | c +(3 rows) + +-- tablespace stays where it is +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 +INFO: repacking table "testts1" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- + testts1 | testts +(1 row) + +-- can move the ts back to default +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 -s pg_default +INFO: repacking table "testts1" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- +(0 rows) + +-- can move the table together with the indexes +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts --moveidx +INFO: repacking table "testts1" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------------------+--------- + testts1 | testts + testts1_partial_idx | testts + testts1_pkey | testts + testts1_with_idx | testts +(4 rows) + +-- can't specify --moveidx without --tablespace +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 --moveidx +ERROR: cannot specify --moveidx (-S) without --tablespace (-s) +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 -S +ERROR: cannot specify --moveidx (-S) without --tablespace (-s) +-- not broken with order +\! pg_repack --dbname=contrib_regression -o id --table=testts1 --tablespace pg_default --moveidx +INFO: repacking table "testts1" +--move all indexes of the table to a tablespace +\! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=testts +INFO: repacking indexes of "testts1" +INFO: repacking index "public"."testts1_partial_idx" +INFO: repacking index "public"."testts1_pkey" +INFO: repacking index "public"."testts1_with_idx" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------------------+--------- + testts1_partial_idx | testts + testts1_pkey | testts + testts1_with_idx | testts +(3 rows) + +--all indexes of tablespace remain in same tablespace +\! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes +INFO: repacking indexes of "testts1" +INFO: repacking index "public"."testts1_partial_idx" +INFO: repacking index "public"."testts1_pkey" +INFO: repacking index "public"."testts1_with_idx" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------------------+--------- + testts1_partial_idx | testts + testts1_pkey | testts + testts1_with_idx | testts +(3 rows) + +--move all indexes of the table to pg_default +\! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=pg_default +INFO: repacking indexes of "testts1" +INFO: repacking index "public"."testts1_partial_idx" +INFO: repacking index "public"."testts1_pkey" +INFO: repacking index "public"."testts1_with_idx" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- +(0 rows) + +--move one index to a tablespace +\! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=testts +INFO: repacking index "public"."testts1_pkey" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +--------------+--------- + testts1_pkey | testts +(1 row) + +--index tablespace stays as is +\! pg_repack --dbname=contrib_regression --index=testts1_pkey +INFO: repacking index "public"."testts1_pkey" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +--------------+--------- + testts1_pkey | testts +(1 row) + +--move index to pg_default +\! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=pg_default +INFO: repacking index "public"."testts1_pkey" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- +(0 rows) + +--using multiple --index option +\! pg_repack --dbname=contrib_regression --index=testts1_pkey --index=testts1_with_idx --tablespace=testts +INFO: repacking index "public"."testts1_pkey" +INFO: repacking index "public"."testts1_with_idx" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +------------------+--------- + testts1_pkey | testts + testts1_with_idx | testts +(2 rows) + +--using --indexes-only and --index option together +\! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --index=testts1_pkey +ERROR: cannot specify --index (-i) and --table (-t) From 64c22ffc5f12b76b2b63c4ac3fcc588395e728d3 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Fri, 9 Mar 2018 13:43:04 +0900 Subject: [PATCH 7/8] Add expected files for regression tests. Due to compatibility break by the recent PostgreSQL core code changes we need to split expected files into each minor releases rather than each major releases. Now the mapping between PostgreSQL version and expected file is complicated as follows. * version 10 * >= 10.3 : repack_3.out, tablespace_2.out * < 10.3 : repack_2.out, tablespace.out * version 9.6 * >= 9.6.8 : repack_4.out, tablespace_2.out * < 9.6.8 : repack.out, tablespace.out * version 9.5 * >= 9.5.12 : repack_4.out, tablespace_2.out * < 9.5.12 : repack.out, tablespace_1.out * version 9.4 * >= 9.4.17 : repack_5.out, tablespace_2.out * < 9.4.17 : repack_1.out, tablespace_1.out * version 9.3 * >= 9.3.22 : repack_6.out, tablespace_3.out * < 9.3.22 : repack_1.out, tablespace_1.out * version 9.2 : repack_1.out, tablespace_1.out * version 9.1 : repack_1.out, tablespace_1.out --- lib/repack.c | 7 +- regress/expected/repack.out | 74 +++- regress/expected/repack_1.out | 74 +++- regress/expected/repack_2.out | 74 +++- regress/expected/repack_3.out | 76 +++- regress/expected/repack_4.out | 654 ++++++++++++++++++++++++++++++ regress/expected/repack_5.out | 652 +++++++++++++++++++++++++++++ regress/expected/repack_6.out | 652 +++++++++++++++++++++++++++++ regress/expected/tablespace_3.out | 234 +++++++++++ regress/sql/repack.sql | 73 +++- 10 files changed, 2518 insertions(+), 52 deletions(-) create mode 100644 regress/expected/repack_4.out create mode 100644 regress/expected/repack_5.out create mode 100644 regress/expected/repack_6.out create mode 100644 regress/expected/tablespace_3.out diff --git a/lib/repack.c b/lib/repack.c index 801ff8d..036e310 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -356,13 +356,16 @@ get_relation_name(Oid relid) /* * Relation names given by PostgreSQL core are always - * qualified since some minor releases. + * qualified since some minor releases. Note that this change + * doesn't introduce to PostgreSQL 9.2 and 9.1 releases. */ #if ((PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 100003) || \ (PG_VERSION_NUM >= 90600 && PG_VERSION_NUM < 90608) || \ (PG_VERSION_NUM >= 90500 && PG_VERSION_NUM < 90512) || \ (PG_VERSION_NUM >= 90400 && PG_VERSION_NUM < 90417) || \ - (PG_VERSION_NUM >= 90300 && PG_VERSION_NUM < 90322)) + (PG_VERSION_NUM >= 90300 && PG_VERSION_NUM < 90322) || \ + (PG_VERSION_NUM >= 90200 && PG_VERSION_NUM < 90300) || \ + (PG_VERSION_NUM >= 90100 && PG_VERSION_NUM < 90200)) /* Qualify the name if not visible in search path */ if (RelationIsVisible(relid)) nspname = NULL; diff --git a/regress/expected/repack.out b/regress/expected/repack.out index 25d4751..8001c1d 100644 --- a/regress/expected/repack.out +++ b/regress/expected/repack.out @@ -1,14 +1,68 @@ +-- Setup function to get version number. +-- This function returns a value same as PG_VERSION_NUM. +CREATE OR REPLACE FUNCTION version_num() RETURNS int AS +$$ +DECLARE + version_int int[]; + version_str text; +BEGIN + SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; + IF array_length(version_int, 1) = 2 THEN -- version 10 or higher + SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; + ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower + SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; + ELSE + RAISE 'invalid version'; + END IF; + RETURN version_str::int; +END; +$$ +LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT CASE - WHEN split_part(version(), ' ', 2) ~ '^(10)' - THEN 'repack_2.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.6|9\.5)' - THEN 'repack.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.4|9\.3|9\.2|9\.1)' - THEN 'repack_1.out' - ELSE version() -END AS testfile; - testfile +SELECT + CASE + WHEN version_num >= 100000 THEN -- PostgreSQL 10 + CASE + WHEN version_num >= 100003 THEN + 'repack_3.out' + ELSE + 'repack_2.out' + END + WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 + CASE + WHEN version_num >= 90608 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 + CASE + WHEN version_num >= 90512 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 + CASE + WHEN version_num >= 90417 THEN + 'repack_5.out' + ELSE + 'repack_1.out' + END + WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 + CASE + WHEN version_num >= 90322 THEN + 'repack_5.out' + ELSE + 'repack_6.out' + END + WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 + 'repack_1.out' + WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 + 'repack_1.out' + END +FROM version_num() as version_num; + case ------------ repack.out (1 row) diff --git a/regress/expected/repack_1.out b/regress/expected/repack_1.out index 595aab6..48690cb 100644 --- a/regress/expected/repack_1.out +++ b/regress/expected/repack_1.out @@ -1,14 +1,68 @@ +-- Setup function to get version number. +-- This function returns a value same as PG_VERSION_NUM. +CREATE OR REPLACE FUNCTION version_num() RETURNS int AS +$$ +DECLARE + version_int int[]; + version_str text; +BEGIN + SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; + IF array_length(version_int, 1) = 2 THEN -- version 10 or higher + SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; + ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower + SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; + ELSE + RAISE 'invalid version'; + END IF; + RETURN version_str::int; +END; +$$ +LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT CASE - WHEN split_part(version(), ' ', 2) ~ '^(10)' - THEN 'repack_2.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.6|9\.5)' - THEN 'repack.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.4|9\.3|9\.2|9\.1)' - THEN 'repack_1.out' - ELSE version() -END AS testfile; - testfile +SELECT + CASE + WHEN version_num >= 100000 THEN -- PostgreSQL 10 + CASE + WHEN version_num >= 100003 THEN + 'repack_3.out' + ELSE + 'repack_2.out' + END + WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 + CASE + WHEN version_num >= 90608 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 + CASE + WHEN version_num >= 90512 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 + CASE + WHEN version_num >= 90417 THEN + 'repack_5.out' + ELSE + 'repack_1.out' + END + WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 + CASE + WHEN version_num >= 90322 THEN + 'repack_5.out' + ELSE + 'repack_6.out' + END + WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 + 'repack_1.out' + WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 + 'repack_1.out' + END +FROM version_num() as version_num; + case -------------- repack_1.out (1 row) diff --git a/regress/expected/repack_2.out b/regress/expected/repack_2.out index 3b5d72e..1637dd6 100644 --- a/regress/expected/repack_2.out +++ b/regress/expected/repack_2.out @@ -1,14 +1,68 @@ +-- Setup function to get version number. +-- This function returns a value same as PG_VERSION_NUM. +CREATE OR REPLACE FUNCTION version_num() RETURNS int AS +$$ +DECLARE + version_int int[]; + version_str text; +BEGIN + SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; + IF array_length(version_int, 1) = 2 THEN -- version 10 or higher + SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; + ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower + SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; + ELSE + RAISE 'invalid version'; + END IF; + RETURN version_str::int; +END; +$$ +LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT CASE - WHEN split_part(version(), ' ', 2) ~ '^(10)' - THEN 'repack_2.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.6|9\.5)' - THEN 'repack.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.4|9\.3|9\.2|9\.1)' - THEN 'repack_1.out' - ELSE version() -END AS testfile; - testfile +SELECT + CASE + WHEN version_num >= 100000 THEN -- PostgreSQL 10 + CASE + WHEN version_num >= 100003 THEN + 'repack_3.out' + ELSE + 'repack_2.out' + END + WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 + CASE + WHEN version_num >= 90608 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 + CASE + WHEN version_num >= 90512 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 + CASE + WHEN version_num >= 90417 THEN + 'repack_5.out' + ELSE + 'repack_1.out' + END + WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 + CASE + WHEN version_num >= 90322 THEN + 'repack_5.out' + ELSE + 'repack_6.out' + END + WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 + 'repack_1.out' + WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 + 'repack_1.out' + END +FROM version_num() as version_num; + case -------------- repack_2.out (1 row) diff --git a/regress/expected/repack_3.out b/regress/expected/repack_3.out index cb1dfb3..4a23973 100644 --- a/regress/expected/repack_3.out +++ b/regress/expected/repack_3.out @@ -1,16 +1,70 @@ +-- Setup function to get version number. +-- This function returns a value same as PG_VERSION_NUM. +CREATE OR REPLACE FUNCTION version_num() RETURNS int AS +$$ +DECLARE + version_int int[]; + version_str text; +BEGIN + SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; + IF array_length(version_int, 1) = 2 THEN -- version 10 or higher + SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; + ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower + SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; + ELSE + RAISE 'invalid version'; + END IF; + RETURN version_str::int; +END; +$$ +LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT CASE - WHEN split_part(version(), ' ', 2) ~ '^(10)' - THEN 'repack_2.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.6|9\.5)' - THEN 'repack.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.4|9\.3|9\.2|9\.1)' - THEN 'repack_1.out' - ELSE version() -END AS testfile; - testfile +SELECT + CASE + WHEN version_num >= 100000 THEN -- PostgreSQL 10 + CASE + WHEN version_num >= 100003 THEN + 'repack_3.out' + ELSE + 'repack_2.out' + END + WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 + CASE + WHEN version_num >= 90608 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 + CASE + WHEN version_num >= 90512 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 + CASE + WHEN version_num >= 90417 THEN + 'repack_5.out' + ELSE + 'repack_1.out' + END + WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 + CASE + WHEN version_num >= 90322 THEN + 'repack_5.out' + ELSE + 'repack_6.out' + END + WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 + 'repack_1.out' + WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 + 'repack_1.out' + END +FROM version_num() as version_num; + case -------------- - repack_2.out + repack_3.out (1 row) SET client_min_messages = warning; diff --git a/regress/expected/repack_4.out b/regress/expected/repack_4.out new file mode 100644 index 0000000..099d1ad --- /dev/null +++ b/regress/expected/repack_4.out @@ -0,0 +1,654 @@ +-- Setup function to get version number. +-- This function returns a value same as PG_VERSION_NUM. +CREATE OR REPLACE FUNCTION version_num() RETURNS int AS +$$ +DECLARE + version_int int[]; + version_str text; +BEGIN + SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; + IF array_length(version_int, 1) = 2 THEN -- version 10 or higher + SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; + ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower + SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; + ELSE + RAISE 'invalid version'; + END IF; + RETURN version_str::int; +END; +$$ +LANGUAGE plpgsql IMMUTABLE STRICT; +-- Test output file identifier. +SELECT + CASE + WHEN version_num >= 100000 THEN -- PostgreSQL 10 + CASE + WHEN version_num >= 100003 THEN + 'repack_3.out' + ELSE + 'repack_2.out' + END + WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 + CASE + WHEN version_num >= 90608 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 + CASE + WHEN version_num >= 90512 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 + CASE + WHEN version_num >= 90417 THEN + 'repack_5.out' + ELSE + 'repack_1.out' + END + WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 + CASE + WHEN version_num >= 90322 THEN + 'repack_5.out' + ELSE + 'repack_6.out' + END + WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 + 'repack_1.out' + WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 + 'repack_1.out' + END +FROM version_num() as version_num; + case +-------------- + repack_4.out +(1 row) + +SET client_min_messages = warning; +-- +-- create table. +-- +CREATE TABLE tbl_cluster ( + col1 int, + "time" timestamp, + ","")" text, + PRIMARY KEY (","")", col1) WITH (fillfactor = 75) +) WITH (fillfactor = 70); +CREATE INDEX ","") cluster" ON tbl_cluster ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75); +ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; +CREATE TABLE tbl_only_pkey ( + col1 int PRIMARY KEY, + ","")" text +); +CREATE TABLE tbl_only_ckey ( + col1 int, + col2 timestamp, + ","")" text +) WITH (fillfactor = 70); +CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); +ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; +CREATE TABLE tbl_gistkey ( + id integer PRIMARY KEY, + c circle +); +CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c); +ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle; +CREATE TABLE tbl_with_dropped_column ( + d1 text, + c1 text, + id integer PRIMARY KEY, + d2 text, + c2 text, + d3 text +); +ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75); +ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey; +CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75); +CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1); +CREATE TABLE tbl_with_dropped_toast ( + i integer, + j integer, + t text, + PRIMARY KEY (i, j) +); +ALTER TABLE tbl_with_dropped_toast CLUSTER ON tbl_with_dropped_toast_pkey; +CREATE TABLE tbl_badindex ( + id integer PRIMARY KEY, + n integer +); +CREATE TABLE tbl_idxopts ( + i integer PRIMARY KEY, + t text +); +CREATE INDEX idxopts_t ON tbl_idxopts (t DESC NULLS LAST) WHERE (t != 'aaa'); +-- Use this table to play with attribute options too +ALTER TABLE tbl_idxopts ALTER i SET STATISTICS 1; +ALTER TABLE tbl_idxopts ALTER t SET (n_distinct = -0.5); +CREATE TABLE tbl_with_toast ( + i integer PRIMARY KEY, + c text +); +ALTER TABLE tbl_with_toast SET (AUTOVACUUM_VACUUM_SCALE_FACTOR = 30, AUTOVACUUM_VACUUM_THRESHOLD = 300); +ALTER TABLE tbl_with_toast SET (TOAST.AUTOVACUUM_VACUUM_SCALE_FACTOR = 40, TOAST.AUTOVACUUM_VACUUM_THRESHOLD = 400); +CREATE TABLE tbl_with_mod_column_storage ( + id integer PRIMARY KEY, + c text +); +ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; +CREATE TABLE tbl_order (c int primary key); +-- +-- insert data +-- +INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin'); +INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king'); +INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker'); +INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen'); +INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); +INSERT INTO tbl_only_pkey VALUES(1, 'abc'); +INSERT INTO tbl_only_pkey VALUES(2, 'def'); +INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc'); +INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def'); +INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>'); +INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>'); +INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 2, 'd2', 'c2', 'd3'); +INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 1, 'd2', 'c2', 'd3'); +ALTER TABLE tbl_with_dropped_column DROP COLUMN d1; +ALTER TABLE tbl_with_dropped_column DROP COLUMN d2; +ALTER TABLE tbl_with_dropped_column DROP COLUMN d3; +ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text; +CREATE VIEW view_for_dropped_column AS + SELECT * FROM tbl_with_dropped_column; +INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc'); +INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); +ALTER TABLE tbl_with_dropped_toast DROP COLUMN t; +INSERT INTO tbl_badindex VALUES(1, 10); +INSERT INTO tbl_badindex VALUES(2, 10); +-- insert data that is always stored into the toast table if column type is extended. +SELECT setseed(0); INSERT INTO tbl_with_mod_column_storage SELECT 1, array_to_string(ARRAY(SELECT chr((random() * (127 - 32) + 32)::int) FROM generate_series(1, 3 * 1024) code), ''); + setseed +--------- + +(1 row) + +-- This will fail. Silence the message as it's different across PG versions. +SET client_min_messages = fatal; +CREATE UNIQUE INDEX CONCURRENTLY idx_badindex_n ON tbl_badindex (n); +SET client_min_messages = warning; +INSERT INTO tbl_idxopts VALUES (0, 'abc'), (1, 'aaa'), (2, NULL), (3, 'bbb'); +-- Insert no-ordered data +INSERT INTO tbl_order SELECT generate_series(100, 51, -1); +CLUSTER tbl_order USING tbl_order_pkey; +INSERT INTO tbl_order SELECT generate_series(50, 1, -1); +-- +-- before +-- +SELECT * FROM tbl_with_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 2 | c2 | + c1 | 1 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 2 | c2 | + c1 | 1 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +-- +-- do repack +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster +INFO: repacking table "tbl_cluster" +\! pg_repack --dbname=contrib_regression --table=tbl_badindex +INFO: repacking table "tbl_badindex" +WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) +\! pg_repack --dbname=contrib_regression +INFO: repacking table "tbl_cluster" +INFO: repacking table "tbl_only_pkey" +INFO: repacking table "tbl_gistkey" +INFO: repacking table "tbl_with_dropped_column" +INFO: repacking table "tbl_with_dropped_toast" +INFO: repacking table "tbl_badindex" +WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) +INFO: repacking table "tbl_idxopts" +INFO: repacking table "tbl_with_toast" +INFO: repacking table "tbl_with_mod_column_storage" +INFO: repacking table "tbl_order" +-- +-- after +-- +\d tbl_cluster + Table "public.tbl_cluster" + Column | Type | Modifiers +--------+-----------------------------+----------- + col1 | integer | not null + time | timestamp without time zone | + ,") | text | not null +Indexes: + "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) WITH (fillfactor='75') + ",") cluster" btree ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor='75') CLUSTER + +\d tbl_gistkey + Table "public.tbl_gistkey" + Column | Type | Modifiers +--------+---------+----------- + id | integer | not null + c | circle | +Indexes: + "tbl_gistkey_pkey" PRIMARY KEY, btree (id) + "cidx_circle" gist (c) CLUSTER + +\d tbl_only_ckey + Table "public.tbl_only_ckey" + Column | Type | Modifiers +--------+-----------------------------+----------- + col1 | integer | + col2 | timestamp without time zone | + ,") | text | +Indexes: + "cidx_only_ckey" btree (col2, ","")") CLUSTER + +\d tbl_only_pkey + Table "public.tbl_only_pkey" + Column | Type | Modifiers +--------+---------+----------- + col1 | integer | not null + ,") | text | +Indexes: + "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) + +\d tbl_with_dropped_column +Table "public.tbl_with_dropped_column" + Column | Type | Modifiers +--------+---------+----------- + c1 | text | + id | integer | not null + c2 | text | + c3 | text | +Indexes: + "tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) WITH (fillfactor='75') CLUSTER + "idx_c1c2" btree (c1, c2) WITH (fillfactor='75') + "idx_c2c1" btree (c2, c1) + +\d tbl_with_dropped_toast +Table "public.tbl_with_dropped_toast" + Column | Type | Modifiers +--------+---------+----------- + i | integer | not null + j | integer | not null +Indexes: + "tbl_with_dropped_toast_pkey" PRIMARY KEY, btree (i, j) CLUSTER + +\d tbl_idxopts + Table "public.tbl_idxopts" + Column | Type | Modifiers +--------+---------+----------- + i | integer | not null + t | text | +Indexes: + "tbl_idxopts_pkey" PRIMARY KEY, btree (i) + "idxopts_t" btree (t DESC NULLS LAST) WHERE t <> 'aaa'::text + +SELECT col1, to_char("time", 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster ORDER BY 1, 2; + col1 | to_char | ,") +------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + 1 | 2008-12-31 10:00:00 | admin + 2 | 2008-01-01 00:00:00 | king + 3 | 2008-03-04 12:00:00 | joker + 4 | 2008-03-05 15:00:00 | queen + 5 | 2008-01-01 00:30:00 | 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488471.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146186757248575675626141415406703029969945094998952478811655512094373648528093231902305582067974820101084674923265015312343266903322886650672254668921837971227047131660367861588019049986537379859389467650347506576050756618348129606100947602187190325083145829523959832997789824508288714463832917347224163984587855397667958063818353666110843173780894378316102088305524901670023520711144288695990956365797087168498072899493296484283020786408603988738697537582317317831395992983007838702877053913369563312103707264019249106768231199288375641141422016742752102372994270831059898459475987664288897796147837958390228854852903576033852808064381972344661059689722872865264153822664698420021195484155278441181286534507035191650016689294415480846071277143999762926834629577438361895110127148638746976545982451788550975379013880664961911962222957110555242923723192197738262561631468842032853716682938649611917049738836395495938 +(5 rows) + +SELECT * FROM tbl_only_ckey ORDER BY 1; + col1 | col2 | ,") +------+--------------------------+----- + 1 | Tue Jan 01 00:00:00 2008 | abc + 2 | Fri Feb 01 00:00:00 2008 | def +(2 rows) + +SELECT * FROM tbl_only_pkey ORDER BY 1; + col1 | ,") +------+----- + 1 | abc + 2 | def +(2 rows) + +SELECT * FROM tbl_gistkey ORDER BY 1; + id | c +----+----------- + 1 | <(1,2),3> + 2 | <(4,5),6> +(2 rows) + +SET enable_seqscan = on; +SET enable_indexscan = off; +SELECT * FROM tbl_with_dropped_column ; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column ORDER BY 1, 2; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +SET enable_seqscan = off; +SET enable_indexscan = on; +SELECT * FROM tbl_with_dropped_column ORDER BY 1, 2; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +RESET enable_seqscan; +RESET enable_indexscan; +-- check if storage option for both table and TOAST table didn't go away. +SELECT CASE relkind + WHEN 'r' THEN relname + WHEN 't' THEN 'toast_table' + END as table, + reloptions +FROM pg_class +WHERE relname = 'tbl_with_toast' OR relname = 'pg_toast_' || 'tbl_with_toast'::regclass::oid +ORDER BY 1; + table | reloptions +----------------+--------------------------------------------------------------------- + tbl_with_toast | {autovacuum_vacuum_scale_factor=30,autovacuum_vacuum_threshold=300} + toast_table | {autovacuum_vacuum_scale_factor=40,autovacuum_vacuum_threshold=400} +(2 rows) + +SELECT pg_relation_size(reltoastrelid) = 0 as check_toast_rel_size FROM pg_class WHERE relname = 'tbl_with_mod_column_storage'; + check_toast_rel_size +---------------------- + t +(1 row) + +-- +-- check broken links or orphan toast relations +-- +SELECT oid, relname + FROM pg_class + WHERE relkind = 't' + AND oid NOT IN (SELECT reltoastrelid FROM pg_class WHERE relkind = 'r'); + oid | relname +-----+--------- +(0 rows) + +SELECT oid, relname + FROM pg_class + WHERE relkind = 'r' + AND reltoastrelid <> 0 + AND reltoastrelid NOT IN (SELECT oid FROM pg_class WHERE relkind = 't'); + oid | relname +-----+--------- +(0 rows) + +-- check columns options +SELECT attname, attstattarget, attoptions +FROM pg_attribute +WHERE attrelid = 'tbl_idxopts'::regclass +AND attnum > 0 +ORDER BY attnum; + attname | attstattarget | attoptions +---------+---------------+------------------- + i | 1 | + t | -1 | {n_distinct=-0.5} +(2 rows) + +-- +-- NOT NULL UNIQUE +-- +CREATE TABLE tbl_nn (col1 int NOT NULL, col2 int NOT NULL); +CREATE TABLE tbl_uk (col1 int NOT NULL, col2 int , UNIQUE(col1, col2)); +CREATE TABLE tbl_nn_uk (col1 int NOT NULL, col2 int NOT NULL, UNIQUE(col1, col2)); +CREATE TABLE tbl_pk_uk (col1 int NOT NULL, col2 int NOT NULL, PRIMARY KEY(col1, col2), UNIQUE(col2, col1)); +CREATE TABLE tbl_nn_puk (col1 int NOT NULL, col2 int NOT NULL); +CREATE UNIQUE INDEX tbl_nn_puk_pcol1_idx ON tbl_nn_puk(col1) WHERE col1 < 10; +\! pg_repack --dbname=contrib_regression --table=tbl_nn +WARNING: relation "tbl_nn" must have a primary key or not-null unique keys +-- => WARNING +\! pg_repack --dbname=contrib_regression --table=tbl_uk +WARNING: relation "tbl_uk" must have a primary key or not-null unique keys +-- => WARNING +\! pg_repack --dbname=contrib_regression --table=tbl_nn_uk +INFO: repacking table "tbl_nn_uk" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_pk_uk +INFO: repacking table "tbl_pk_uk" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_pk_uk --only-indexes +INFO: repacking indexes of "tbl_pk_uk" +INFO: repacking index "public"."tbl_pk_uk_col2_col1_key" +INFO: repacking index "public"."tbl_pk_uk_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_nn_puk +WARNING: relation "tbl_nn_puk" must have a primary key or not-null unique keys +-- => WARNING +-- +-- Triggers handling +-- +CREATE FUNCTION trgtest() RETURNS trigger AS +$$BEGIN RETURN NEW; END$$ +LANGUAGE plpgsql; +CREATE TABLE trg1 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger_1 AFTER UPDATE ON trg1 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg1 +INFO: repacking table "trg1" +CREATE TABLE trg2 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger AFTER UPDATE ON trg2 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg2 +INFO: repacking table "trg2" +WARNING: the table "trg2" already has a trigger called "repack_trigger" +DETAIL: The trigger was probably installed during a previous attempt to run pg_repack on the table which was interrupted and for some reason failed to clean up the temporary objects. Please drop the trigger or drop and recreate the pg_repack extension altogether to remove all the temporary objects left over. +CREATE TABLE trg3 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger_1 BEFORE UPDATE ON trg3 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg3 +INFO: repacking table "trg3" +-- +-- Table re-organization using specific column +-- +-- reorganize table using cluster key. Sort in ascending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order +INFO: repacking table "tbl_order" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + ctid | c +--------+---- + (0,1) | 1 + (0,2) | 2 + (0,3) | 3 + (0,4) | 4 + (0,5) | 5 + (0,6) | 6 + (0,7) | 7 + (0,8) | 8 + (0,9) | 9 + (0,10) | 10 +(10 rows) + +-- reorganize table using specific column order. Sort in descending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order -o "c DESC" +INFO: repacking table "tbl_order" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + ctid | c +--------+----- + (0,1) | 100 + (0,2) | 99 + (0,3) | 98 + (0,4) | 97 + (0,5) | 96 + (0,6) | 95 + (0,7) | 94 + (0,8) | 93 + (0,9) | 92 + (0,10) | 91 +(10 rows) + +-- +-- Dry run +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --dry-run +INFO: Dry run enabled, not executing repack +INFO: repacking table "tbl_cluster" +-- Test --schema +-- +CREATE SCHEMA test_schema1; +CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); +CREATE SCHEMA test_schema2; +CREATE TABLE test_schema2.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema2.tbl2 (id INTEGER PRIMARY KEY); +-- => OK +\! pg_repack --dbname=contrib_regression --schema=test_schema1 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +-- => OK +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +INFO: repacking table "test_schema2.tbl1" +INFO: repacking table "test_schema2.tbl2" +-- => ERROR +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --table=tbl1 +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --all --schema=test_schema1 +ERROR: cannot repack specific schema(s) in all databases +-- +-- don't kill backend +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-kill-backend +INFO: repacking table "tbl_cluster" +-- +-- no superuser check +-- +DROP ROLE IF EXISTS nosuper; +CREATE ROLE nosuper WITH LOGIN; +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-superuser-check +INFO: repacking table "tbl_cluster" +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper +ERROR: pg_repack failed with error: You must be a superuser to use pg_repack +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check +ERROR: pg_repack failed with error: ERROR: permission denied for schema repack +LINE 1: select repack.version(), repack.version_sql() + ^ +DROP ROLE IF EXISTS nosuper; +-- +-- exclude extension check +-- +CREATE SCHEMA exclude_extension_schema; +CREATE TABLE exclude_extension_schema.tbl(val integer primary key); +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension +ERROR: cannot specify --table (-t) and --exclude-extension (-C) +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension -x +ERROR: cannot specify --only-indexes (-x) and --exclude-extension (-C) +-- => ERROR +\! pg_repack --dbname=contrib_regression --index=dummy_index --exclude-extension=dummy_extension +ERROR: cannot specify --index (-i) and --exclude-extension (-C) +-- => OK +\! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension +INFO: repacking table "exclude_extension_schema.tbl" +-- => OK +\! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension --exclude-extension=dummy_extension +INFO: repacking table "exclude_extension_schema.tbl" +-- +-- table inheritance check +-- +CREATE TABLE parent_a(val integer primary key); +CREATE TABLE child_a_1(val integer primary key) INHERITS(parent_a); +CREATE TABLE child_a_2(val integer primary key) INHERITS(parent_a); +CREATE TABLE parent_b(val integer primary key); +CREATE TABLE child_b_1(val integer primary key) INHERITS(parent_b); +CREATE TABLE child_b_2(val integer primary key) INHERITS(parent_b); +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table +ERROR: pg_repack failed with error: ERROR: relation "dummy_table" does not exist +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_index --index=dummy_index +ERROR: cannot specify --index (-i) and --parent-table (-I) +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --schema=dummy_schema +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --all +ERROR: cannot repack specific table(s) in all databases +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "child_a_1" +INFO: repacking table "child_a_2" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "public.child_a_1" +INFO: repacking index "public"."child_a_1_pkey" +INFO: repacking indexes of "public.child_a_2" +INFO: repacking index "public"."child_a_2_pkey" +INFO: repacking indexes of "public.parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" diff --git a/regress/expected/repack_5.out b/regress/expected/repack_5.out new file mode 100644 index 0000000..f266ca1 --- /dev/null +++ b/regress/expected/repack_5.out @@ -0,0 +1,652 @@ +-- Setup function to get version number. +-- This function returns a value same as PG_VERSION_NUM. +CREATE OR REPLACE FUNCTION version_num() RETURNS int AS +$$ +DECLARE + version_int int[]; + version_str text; +BEGIN + SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; + IF array_length(version_int, 1) = 2 THEN -- version 10 or higher + SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; + ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower + SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; + ELSE + RAISE 'invalid version'; + END IF; + RETURN version_str::int; +END; +$$ +LANGUAGE plpgsql IMMUTABLE STRICT; +-- Test output file identifier. +SELECT + CASE + WHEN version_num >= 100000 THEN -- PostgreSQL 10 + CASE + WHEN version_num >= 100003 THEN + 'repack_3.out' + ELSE + 'repack_2.out' + END + WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 + CASE + WHEN version_num >= 90608 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 + CASE + WHEN version_num >= 90512 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 + CASE + WHEN version_num >= 90417 THEN + 'repack_5.out' + ELSE + 'repack_1.out' + END + WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 + CASE + WHEN version_num >= 90322 THEN + 'repack_5.out' + ELSE + 'repack_6.out' + END + WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 + 'repack_1.out' + WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 + 'repack_1.out' + END +FROM version_num() as version_num; + case +-------------- + repack_5.out +(1 row) + +SET client_min_messages = warning; +-- +-- create table. +-- +CREATE TABLE tbl_cluster ( + col1 int, + "time" timestamp, + ","")" text, + PRIMARY KEY (","")", col1) WITH (fillfactor = 75) +) WITH (fillfactor = 70); +CREATE INDEX ","") cluster" ON tbl_cluster ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75); +ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; +CREATE TABLE tbl_only_pkey ( + col1 int PRIMARY KEY, + ","")" text +); +CREATE TABLE tbl_only_ckey ( + col1 int, + col2 timestamp, + ","")" text +) WITH (fillfactor = 70); +CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); +ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; +CREATE TABLE tbl_gistkey ( + id integer PRIMARY KEY, + c circle +); +CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c); +ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle; +CREATE TABLE tbl_with_dropped_column ( + d1 text, + c1 text, + id integer PRIMARY KEY, + d2 text, + c2 text, + d3 text +); +ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75); +ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey; +CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75); +CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1); +CREATE TABLE tbl_with_dropped_toast ( + i integer, + j integer, + t text, + PRIMARY KEY (i, j) +); +ALTER TABLE tbl_with_dropped_toast CLUSTER ON tbl_with_dropped_toast_pkey; +CREATE TABLE tbl_badindex ( + id integer PRIMARY KEY, + n integer +); +CREATE TABLE tbl_idxopts ( + i integer PRIMARY KEY, + t text +); +CREATE INDEX idxopts_t ON tbl_idxopts (t DESC NULLS LAST) WHERE (t != 'aaa'); +-- Use this table to play with attribute options too +ALTER TABLE tbl_idxopts ALTER i SET STATISTICS 1; +ALTER TABLE tbl_idxopts ALTER t SET (n_distinct = -0.5); +CREATE TABLE tbl_with_toast ( + i integer PRIMARY KEY, + c text +); +ALTER TABLE tbl_with_toast SET (AUTOVACUUM_VACUUM_SCALE_FACTOR = 30, AUTOVACUUM_VACUUM_THRESHOLD = 300); +ALTER TABLE tbl_with_toast SET (TOAST.AUTOVACUUM_VACUUM_SCALE_FACTOR = 40, TOAST.AUTOVACUUM_VACUUM_THRESHOLD = 400); +CREATE TABLE tbl_with_mod_column_storage ( + id integer PRIMARY KEY, + c text +); +ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; +CREATE TABLE tbl_order (c int primary key); +-- +-- insert data +-- +INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin'); +INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king'); +INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker'); +INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen'); +INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); +INSERT INTO tbl_only_pkey VALUES(1, 'abc'); +INSERT INTO tbl_only_pkey VALUES(2, 'def'); +INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc'); +INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def'); +INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>'); +INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>'); +INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 2, 'd2', 'c2', 'd3'); +INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 1, 'd2', 'c2', 'd3'); +ALTER TABLE tbl_with_dropped_column DROP COLUMN d1; +ALTER TABLE tbl_with_dropped_column DROP COLUMN d2; +ALTER TABLE tbl_with_dropped_column DROP COLUMN d3; +ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text; +CREATE VIEW view_for_dropped_column AS + SELECT * FROM tbl_with_dropped_column; +INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc'); +INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); +ALTER TABLE tbl_with_dropped_toast DROP COLUMN t; +INSERT INTO tbl_badindex VALUES(1, 10); +INSERT INTO tbl_badindex VALUES(2, 10); +-- insert data that is always stored into the toast table if column type is extended. +SELECT setseed(0); INSERT INTO tbl_with_mod_column_storage SELECT 1, array_to_string(ARRAY(SELECT chr((random() * (127 - 32) + 32)::int) FROM generate_series(1, 3 * 1024) code), ''); + setseed +--------- + +(1 row) + +-- This will fail. Silence the message as it's different across PG versions. +SET client_min_messages = fatal; +CREATE UNIQUE INDEX CONCURRENTLY idx_badindex_n ON tbl_badindex (n); +SET client_min_messages = warning; +INSERT INTO tbl_idxopts VALUES (0, 'abc'), (1, 'aaa'), (2, NULL), (3, 'bbb'); +-- Insert no-ordered data +INSERT INTO tbl_order SELECT generate_series(100, 51, -1); +CLUSTER tbl_order USING tbl_order_pkey; +INSERT INTO tbl_order SELECT generate_series(50, 1, -1); +-- +-- before +-- +SELECT * FROM tbl_with_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 2 | c2 | + c1 | 1 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 2 | c2 | + c1 | 1 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +-- +-- do repack +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster +INFO: repacking table "tbl_cluster" +\! pg_repack --dbname=contrib_regression --table=tbl_badindex +INFO: repacking table "tbl_badindex" +WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) +\! pg_repack --dbname=contrib_regression +INFO: repacking table "tbl_cluster" +INFO: repacking table "tbl_only_pkey" +INFO: repacking table "tbl_gistkey" +INFO: repacking table "tbl_with_dropped_column" +INFO: repacking table "tbl_with_dropped_toast" +INFO: repacking table "tbl_badindex" +WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON public.tbl_badindex USING btree (n) +INFO: repacking table "tbl_idxopts" +INFO: repacking table "tbl_with_toast" +INFO: repacking table "tbl_with_mod_column_storage" +INFO: repacking table "tbl_order" +-- +-- after +-- +\d tbl_cluster + Table "public.tbl_cluster" + Column | Type | Modifiers +--------+-----------------------------+----------- + col1 | integer | not null + time | timestamp without time zone | + ,") | text | not null +Indexes: + "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) WITH (fillfactor='75') + ",") cluster" btree ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor='75') CLUSTER + +\d tbl_gistkey + Table "public.tbl_gistkey" + Column | Type | Modifiers +--------+---------+----------- + id | integer | not null + c | circle | +Indexes: + "tbl_gistkey_pkey" PRIMARY KEY, btree (id) + "cidx_circle" gist (c) CLUSTER + +\d tbl_only_ckey + Table "public.tbl_only_ckey" + Column | Type | Modifiers +--------+-----------------------------+----------- + col1 | integer | + col2 | timestamp without time zone | + ,") | text | +Indexes: + "cidx_only_ckey" btree (col2, ","")") CLUSTER + +\d tbl_only_pkey + Table "public.tbl_only_pkey" + Column | Type | Modifiers +--------+---------+----------- + col1 | integer | not null + ,") | text | +Indexes: + "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) + +\d tbl_with_dropped_column +Table "public.tbl_with_dropped_column" + Column | Type | Modifiers +--------+---------+----------- + c1 | text | + id | integer | not null + c2 | text | + c3 | text | +Indexes: + "tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) WITH (fillfactor='75') CLUSTER + "idx_c1c2" btree (c1, c2) WITH (fillfactor='75') + "idx_c2c1" btree (c2, c1) + +\d tbl_with_dropped_toast +Table "public.tbl_with_dropped_toast" + Column | Type | Modifiers +--------+---------+----------- + i | integer | not null + j | integer | not null +Indexes: + "tbl_with_dropped_toast_pkey" PRIMARY KEY, btree (i, j) CLUSTER + +\d tbl_idxopts + Table "public.tbl_idxopts" + Column | Type | Modifiers +--------+---------+----------- + i | integer | not null + t | text | +Indexes: + "tbl_idxopts_pkey" PRIMARY KEY, btree (i) + "idxopts_t" btree (t DESC NULLS LAST) WHERE t <> 'aaa'::text + +SELECT col1, to_char("time", 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster ORDER BY 1, 2; + col1 | to_char | ,") +------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + 1 | 2008-12-31 10:00:00 | admin + 2 | 2008-01-01 00:00:00 | king + 3 | 2008-03-04 12:00:00 | joker + 4 | 2008-03-05 15:00:00 | queen + 5 | 2008-01-01 00:30:00 | 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488471.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146186757248575675626141415406703029969945094998952478811655512094373648528093231902305582067974820101084674923265015312343266903322886650672254668921837971227047131660367861588019049986537379859389467650347506576050756618348129606100947602187190325083145829523959832997789824508288714463832917347224163984587855397667958063818353666110843173780894378316102088305524901670023520711144288695990956365797087168498072899493296484283020786408603988738697537582317317831395992983007838702877053913369563312103707264019249106768231199288375641141422016742752102372994270831059898459475987664288897796147837958390228854852903576033852808064381972344661059689722872865264153822664698420021195484155278441181286534507035191650016689294415480846071277143999762926834629577438361895110127148638746976545982451788550975379013880664961911962222957110555242923723192197738262561631468842032853716682938649611917049738836395495938 +(5 rows) + +SELECT * FROM tbl_only_ckey ORDER BY 1; + col1 | col2 | ,") +------+--------------------------+----- + 1 | Tue Jan 01 00:00:00 2008 | abc + 2 | Fri Feb 01 00:00:00 2008 | def +(2 rows) + +SELECT * FROM tbl_only_pkey ORDER BY 1; + col1 | ,") +------+----- + 1 | abc + 2 | def +(2 rows) + +SELECT * FROM tbl_gistkey ORDER BY 1; + id | c +----+----------- + 1 | <(1,2),3> + 2 | <(4,5),6> +(2 rows) + +SET enable_seqscan = on; +SET enable_indexscan = off; +SELECT * FROM tbl_with_dropped_column ; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column ORDER BY 1, 2; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +SET enable_seqscan = off; +SET enable_indexscan = on; +SELECT * FROM tbl_with_dropped_column ORDER BY 1, 2; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +RESET enable_seqscan; +RESET enable_indexscan; +-- check if storage option for both table and TOAST table didn't go away. +SELECT CASE relkind + WHEN 'r' THEN relname + WHEN 't' THEN 'toast_table' + END as table, + reloptions +FROM pg_class +WHERE relname = 'tbl_with_toast' OR relname = 'pg_toast_' || 'tbl_with_toast'::regclass::oid +ORDER BY 1; + table | reloptions +----------------+--------------------------------------------------------------------- + tbl_with_toast | {autovacuum_vacuum_scale_factor=30,autovacuum_vacuum_threshold=300} + toast_table | {autovacuum_vacuum_scale_factor=40,autovacuum_vacuum_threshold=400} +(2 rows) + +SELECT pg_relation_size(reltoastrelid) = 0 as check_toast_rel_size FROM pg_class WHERE relname = 'tbl_with_mod_column_storage'; + check_toast_rel_size +---------------------- + t +(1 row) + +-- +-- check broken links or orphan toast relations +-- +SELECT oid, relname + FROM pg_class + WHERE relkind = 't' + AND oid NOT IN (SELECT reltoastrelid FROM pg_class WHERE relkind = 'r'); + oid | relname +-----+--------- +(0 rows) + +SELECT oid, relname + FROM pg_class + WHERE relkind = 'r' + AND reltoastrelid <> 0 + AND reltoastrelid NOT IN (SELECT oid FROM pg_class WHERE relkind = 't'); + oid | relname +-----+--------- +(0 rows) + +-- check columns options +SELECT attname, attstattarget, attoptions +FROM pg_attribute +WHERE attrelid = 'tbl_idxopts'::regclass +AND attnum > 0 +ORDER BY attnum; + attname | attstattarget | attoptions +---------+---------------+------------------- + i | 1 | + t | -1 | {n_distinct=-0.5} +(2 rows) + +-- +-- NOT NULL UNIQUE +-- +CREATE TABLE tbl_nn (col1 int NOT NULL, col2 int NOT NULL); +CREATE TABLE tbl_uk (col1 int NOT NULL, col2 int , UNIQUE(col1, col2)); +CREATE TABLE tbl_nn_uk (col1 int NOT NULL, col2 int NOT NULL, UNIQUE(col1, col2)); +CREATE TABLE tbl_pk_uk (col1 int NOT NULL, col2 int NOT NULL, PRIMARY KEY(col1, col2), UNIQUE(col2, col1)); +CREATE TABLE tbl_nn_puk (col1 int NOT NULL, col2 int NOT NULL); +CREATE UNIQUE INDEX tbl_nn_puk_pcol1_idx ON tbl_nn_puk(col1) WHERE col1 < 10; +\! pg_repack --dbname=contrib_regression --table=tbl_nn +WARNING: relation "tbl_nn" must have a primary key or not-null unique keys +-- => WARNING +\! pg_repack --dbname=contrib_regression --table=tbl_uk +WARNING: relation "tbl_uk" must have a primary key or not-null unique keys +-- => WARNING +\! pg_repack --dbname=contrib_regression --table=tbl_nn_uk +INFO: repacking table "tbl_nn_uk" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_pk_uk +INFO: repacking table "tbl_pk_uk" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_pk_uk --only-indexes +INFO: repacking indexes of "tbl_pk_uk" +INFO: repacking index "public"."tbl_pk_uk_col2_col1_key" +INFO: repacking index "public"."tbl_pk_uk_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_nn_puk +WARNING: relation "tbl_nn_puk" must have a primary key or not-null unique keys +-- => WARNING +-- +-- Triggers handling +-- +CREATE FUNCTION trgtest() RETURNS trigger AS +$$BEGIN RETURN NEW; END$$ +LANGUAGE plpgsql; +CREATE TABLE trg1 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger_1 AFTER UPDATE ON trg1 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg1 +INFO: repacking table "trg1" +CREATE TABLE trg2 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger AFTER UPDATE ON trg2 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg2 +INFO: repacking table "trg2" +WARNING: the table "trg2" already has a trigger called "repack_trigger" +DETAIL: The trigger was probably installed during a previous attempt to run pg_repack on the table which was interrupted and for some reason failed to clean up the temporary objects. Please drop the trigger or drop and recreate the pg_repack extension altogether to remove all the temporary objects left over. +CREATE TABLE trg3 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger_1 BEFORE UPDATE ON trg3 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg3 +INFO: repacking table "trg3" +-- +-- Table re-organization using specific column +-- +-- reorganize table using cluster key. Sort in ascending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order +INFO: repacking table "tbl_order" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + ctid | c +--------+---- + (0,1) | 1 + (0,2) | 2 + (0,3) | 3 + (0,4) | 4 + (0,5) | 5 + (0,6) | 6 + (0,7) | 7 + (0,8) | 8 + (0,9) | 9 + (0,10) | 10 +(10 rows) + +-- reorganize table using specific column order. Sort in descending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order -o "c DESC" +INFO: repacking table "tbl_order" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + ctid | c +--------+----- + (0,1) | 100 + (0,2) | 99 + (0,3) | 98 + (0,4) | 97 + (0,5) | 96 + (0,6) | 95 + (0,7) | 94 + (0,8) | 93 + (0,9) | 92 + (0,10) | 91 +(10 rows) + +-- +-- Dry run +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --dry-run +INFO: Dry run enabled, not executing repack +INFO: repacking table "tbl_cluster" +-- Test --schema +-- +CREATE SCHEMA test_schema1; +CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); +CREATE SCHEMA test_schema2; +CREATE TABLE test_schema2.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema2.tbl2 (id INTEGER PRIMARY KEY); +-- => OK +\! pg_repack --dbname=contrib_regression --schema=test_schema1 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +-- => OK +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +INFO: repacking table "test_schema2.tbl1" +INFO: repacking table "test_schema2.tbl2" +-- => ERROR +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --table=tbl1 +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --all --schema=test_schema1 +ERROR: cannot repack specific schema(s) in all databases +-- +-- don't kill backend +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-kill-backend +INFO: repacking table "tbl_cluster" +-- +-- no superuser check +-- +DROP ROLE IF EXISTS nosuper; +CREATE ROLE nosuper WITH LOGIN; +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-superuser-check +INFO: repacking table "tbl_cluster" +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper +ERROR: pg_repack failed with error: You must be a superuser to use pg_repack +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check +ERROR: pg_repack failed with error: ERROR: permission denied for schema repack +DROP ROLE IF EXISTS nosuper; +-- +-- exclude extension check +-- +CREATE SCHEMA exclude_extension_schema; +CREATE TABLE exclude_extension_schema.tbl(val integer primary key); +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension +ERROR: cannot specify --table (-t) and --exclude-extension (-C) +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension -x +ERROR: cannot specify --only-indexes (-x) and --exclude-extension (-C) +-- => ERROR +\! pg_repack --dbname=contrib_regression --index=dummy_index --exclude-extension=dummy_extension +ERROR: cannot specify --index (-i) and --exclude-extension (-C) +-- => OK +\! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension +INFO: repacking table "exclude_extension_schema.tbl" +-- => OK +\! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension --exclude-extension=dummy_extension +INFO: repacking table "exclude_extension_schema.tbl" +-- +-- table inheritance check +-- +CREATE TABLE parent_a(val integer primary key); +CREATE TABLE child_a_1(val integer primary key) INHERITS(parent_a); +CREATE TABLE child_a_2(val integer primary key) INHERITS(parent_a); +CREATE TABLE parent_b(val integer primary key); +CREATE TABLE child_b_1(val integer primary key) INHERITS(parent_b); +CREATE TABLE child_b_2(val integer primary key) INHERITS(parent_b); +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table +ERROR: pg_repack failed with error: ERROR: relation "dummy_table" does not exist +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_index --index=dummy_index +ERROR: cannot specify --index (-i) and --parent-table (-I) +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --schema=dummy_schema +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --all +ERROR: cannot repack specific table(s) in all databases +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "child_a_1" +INFO: repacking table "child_a_2" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "public.child_a_1" +INFO: repacking index "public"."child_a_1_pkey" +INFO: repacking indexes of "public.child_a_2" +INFO: repacking index "public"."child_a_2_pkey" +INFO: repacking indexes of "public.parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" diff --git a/regress/expected/repack_6.out b/regress/expected/repack_6.out new file mode 100644 index 0000000..eb084a1 --- /dev/null +++ b/regress/expected/repack_6.out @@ -0,0 +1,652 @@ +-- Setup function to get version number. +-- This function returns a value same as PG_VERSION_NUM. +CREATE OR REPLACE FUNCTION version_num() RETURNS int AS +$$ +DECLARE + version_int int[]; + version_str text; +BEGIN + SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; + IF array_length(version_int, 1) = 2 THEN -- version 10 or higher + SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; + ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower + SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; + ELSE + RAISE 'invalid version'; + END IF; + RETURN version_str::int; +END; +$$ +LANGUAGE plpgsql IMMUTABLE STRICT; +-- Test output file identifier. +SELECT + CASE + WHEN version_num >= 100000 THEN -- PostgreSQL 10 + CASE + WHEN version_num >= 100003 THEN + 'repack_3.out' + ELSE + 'repack_2.out' + END + WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 + CASE + WHEN version_num >= 90608 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 + CASE + WHEN version_num >= 90512 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 + CASE + WHEN version_num >= 90417 THEN + 'repack_5.out' + ELSE + 'repack_1.out' + END + WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 + CASE + WHEN version_num >= 90322 THEN + 'repack_5.out' + ELSE + 'repack_6.out' + END + WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 + 'repack_1.out' + WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 + 'repack_1.out' + END +FROM version_num() as version_num; + case +-------------- + repack_6.out +(1 row) + +SET client_min_messages = warning; +-- +-- create table. +-- +CREATE TABLE tbl_cluster ( + col1 int, + "time" timestamp, + ","")" text, + PRIMARY KEY (","")", col1) WITH (fillfactor = 75) +) WITH (fillfactor = 70); +CREATE INDEX ","") cluster" ON tbl_cluster ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75); +ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; +CREATE TABLE tbl_only_pkey ( + col1 int PRIMARY KEY, + ","")" text +); +CREATE TABLE tbl_only_ckey ( + col1 int, + col2 timestamp, + ","")" text +) WITH (fillfactor = 70); +CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); +ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; +CREATE TABLE tbl_gistkey ( + id integer PRIMARY KEY, + c circle +); +CREATE INDEX cidx_circle ON tbl_gistkey USING gist (c); +ALTER TABLE tbl_gistkey CLUSTER ON cidx_circle; +CREATE TABLE tbl_with_dropped_column ( + d1 text, + c1 text, + id integer PRIMARY KEY, + d2 text, + c2 text, + d3 text +); +ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75); +ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey; +CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75); +CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1); +CREATE TABLE tbl_with_dropped_toast ( + i integer, + j integer, + t text, + PRIMARY KEY (i, j) +); +ALTER TABLE tbl_with_dropped_toast CLUSTER ON tbl_with_dropped_toast_pkey; +CREATE TABLE tbl_badindex ( + id integer PRIMARY KEY, + n integer +); +CREATE TABLE tbl_idxopts ( + i integer PRIMARY KEY, + t text +); +CREATE INDEX idxopts_t ON tbl_idxopts (t DESC NULLS LAST) WHERE (t != 'aaa'); +-- Use this table to play with attribute options too +ALTER TABLE tbl_idxopts ALTER i SET STATISTICS 1; +ALTER TABLE tbl_idxopts ALTER t SET (n_distinct = -0.5); +CREATE TABLE tbl_with_toast ( + i integer PRIMARY KEY, + c text +); +ALTER TABLE tbl_with_toast SET (AUTOVACUUM_VACUUM_SCALE_FACTOR = 30, AUTOVACUUM_VACUUM_THRESHOLD = 300); +ALTER TABLE tbl_with_toast SET (TOAST.AUTOVACUUM_VACUUM_SCALE_FACTOR = 40, TOAST.AUTOVACUUM_VACUUM_THRESHOLD = 400); +CREATE TABLE tbl_with_mod_column_storage ( + id integer PRIMARY KEY, + c text +); +ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; +CREATE TABLE tbl_order (c int primary key); +-- +-- insert data +-- +INSERT INTO tbl_cluster VALUES(1, '2008-12-31 10:00:00', 'admin'); +INSERT INTO tbl_cluster VALUES(2, '2008-01-01 00:00:00', 'king'); +INSERT INTO tbl_cluster VALUES(3, '2008-03-04 12:00:00', 'joker'); +INSERT INTO tbl_cluster VALUES(4, '2008-03-05 15:00:00', 'queen'); +INSERT INTO tbl_cluster VALUES(5, '2008-01-01 00:30:00', sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); +INSERT INTO tbl_only_pkey VALUES(1, 'abc'); +INSERT INTO tbl_only_pkey VALUES(2, 'def'); +INSERT INTO tbl_only_ckey VALUES(1, '2008-01-01 00:00:00', 'abc'); +INSERT INTO tbl_only_ckey VALUES(2, '2008-02-01 00:00:00', 'def'); +INSERT INTO tbl_gistkey VALUES(1, '<(1,2),3>'); +INSERT INTO tbl_gistkey VALUES(2, '<(4,5),6>'); +INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 2, 'd2', 'c2', 'd3'); +INSERT INTO tbl_with_dropped_column VALUES('d1', 'c1', 1, 'd2', 'c2', 'd3'); +ALTER TABLE tbl_with_dropped_column DROP COLUMN d1; +ALTER TABLE tbl_with_dropped_column DROP COLUMN d2; +ALTER TABLE tbl_with_dropped_column DROP COLUMN d3; +ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text; +CREATE VIEW view_for_dropped_column AS + SELECT * FROM tbl_with_dropped_column; +INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc'); +INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text); +ALTER TABLE tbl_with_dropped_toast DROP COLUMN t; +INSERT INTO tbl_badindex VALUES(1, 10); +INSERT INTO tbl_badindex VALUES(2, 10); +-- insert data that is always stored into the toast table if column type is extended. +SELECT setseed(0); INSERT INTO tbl_with_mod_column_storage SELECT 1, array_to_string(ARRAY(SELECT chr((random() * (127 - 32) + 32)::int) FROM generate_series(1, 3 * 1024) code), ''); + setseed +--------- + +(1 row) + +-- This will fail. Silence the message as it's different across PG versions. +SET client_min_messages = fatal; +CREATE UNIQUE INDEX CONCURRENTLY idx_badindex_n ON tbl_badindex (n); +SET client_min_messages = warning; +INSERT INTO tbl_idxopts VALUES (0, 'abc'), (1, 'aaa'), (2, NULL), (3, 'bbb'); +-- Insert no-ordered data +INSERT INTO tbl_order SELECT generate_series(100, 51, -1); +CLUSTER tbl_order USING tbl_order_pkey; +INSERT INTO tbl_order SELECT generate_series(50, 1, -1); +-- +-- before +-- +SELECT * FROM tbl_with_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 2 | c2 | + c1 | 1 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 2 | c2 | + c1 | 1 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +-- +-- do repack +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster +INFO: repacking table "tbl_cluster" +\! pg_repack --dbname=contrib_regression --table=tbl_badindex +INFO: repacking table "tbl_badindex" +WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON tbl_badindex USING btree (n) +\! pg_repack --dbname=contrib_regression +INFO: repacking table "tbl_cluster" +INFO: repacking table "tbl_only_pkey" +INFO: repacking table "tbl_gistkey" +INFO: repacking table "tbl_with_dropped_column" +INFO: repacking table "tbl_with_dropped_toast" +INFO: repacking table "tbl_badindex" +WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON tbl_badindex USING btree (n) +INFO: repacking table "tbl_idxopts" +INFO: repacking table "tbl_with_toast" +INFO: repacking table "tbl_with_mod_column_storage" +INFO: repacking table "tbl_order" +-- +-- after +-- +\d tbl_cluster + Table "public.tbl_cluster" + Column | Type | Modifiers +--------+-----------------------------+----------- + col1 | integer | not null + time | timestamp without time zone | + ,") | text | not null +Indexes: + "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) WITH (fillfactor=75) + ",") cluster" btree ("time", length(","")"), ","")" text_pattern_ops) WITH (fillfactor=75) CLUSTER + +\d tbl_gistkey + Table "public.tbl_gistkey" + Column | Type | Modifiers +--------+---------+----------- + id | integer | not null + c | circle | +Indexes: + "tbl_gistkey_pkey" PRIMARY KEY, btree (id) + "cidx_circle" gist (c) CLUSTER + +\d tbl_only_ckey + Table "public.tbl_only_ckey" + Column | Type | Modifiers +--------+-----------------------------+----------- + col1 | integer | + col2 | timestamp without time zone | + ,") | text | +Indexes: + "cidx_only_ckey" btree (col2, ","")") CLUSTER + +\d tbl_only_pkey + Table "public.tbl_only_pkey" + Column | Type | Modifiers +--------+---------+----------- + col1 | integer | not null + ,") | text | +Indexes: + "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) + +\d tbl_with_dropped_column +Table "public.tbl_with_dropped_column" + Column | Type | Modifiers +--------+---------+----------- + c1 | text | + id | integer | not null + c2 | text | + c3 | text | +Indexes: + "tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) WITH (fillfactor=75) CLUSTER + "idx_c1c2" btree (c1, c2) WITH (fillfactor=75) + "idx_c2c1" btree (c2, c1) + +\d tbl_with_dropped_toast +Table "public.tbl_with_dropped_toast" + Column | Type | Modifiers +--------+---------+----------- + i | integer | not null + j | integer | not null +Indexes: + "tbl_with_dropped_toast_pkey" PRIMARY KEY, btree (i, j) CLUSTER + +\d tbl_idxopts + Table "public.tbl_idxopts" + Column | Type | Modifiers +--------+---------+----------- + i | integer | not null + t | text | +Indexes: + "tbl_idxopts_pkey" PRIMARY KEY, btree (i) + "idxopts_t" btree (t DESC NULLS LAST) WHERE t <> 'aaa'::text + +SELECT col1, to_char("time", 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster ORDER BY 1, 2; + col1 | to_char | ,") +------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + 1 | 2008-12-31 10:00:00 | admin + 2 | 2008-01-01 00:00:00 | king + 3 | 2008-03-04 12:00:00 | joker + 4 | 2008-03-05 15:00:00 | queen + 5 | 2008-01-01 00:30:00 | 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488471.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146186757248575675626141415406703029969945094998952478811655512094373648528093231902305582067974820101084674923265015312343266903322886650672254668921837971227047131660367861588019049986537379859389467650347506576050756618348129606100947602187190325083145829523959832997789824508288714463832917347224163984587855397667958063818353666110843173780894378316102088305524901670023520711144288695990956365797087168498072899493296484283020786408603988738697537582317317831395992983007838702877053913369563312103707264019249106768231199288375641141422016742752102372994270831059898459475987664288897796147837958390228854852903576033852808064381972344661059689722872865264153822664698420021195484155278441181286534507035191650016689294415480846071277143999762926834629577438361895110127148638746976545982451788550975379013880664961911962222957110555242923723192197738262561631468842032853716682938649611917049738836395495938 +(5 rows) + +SELECT * FROM tbl_only_ckey ORDER BY 1; + col1 | col2 | ,") +------+--------------------------+----- + 1 | Tue Jan 01 00:00:00 2008 | abc + 2 | Fri Feb 01 00:00:00 2008 | def +(2 rows) + +SELECT * FROM tbl_only_pkey ORDER BY 1; + col1 | ,") +------+----- + 1 | abc + 2 | def +(2 rows) + +SELECT * FROM tbl_gistkey ORDER BY 1; + id | c +----+----------- + 1 | <(1,2),3> + 2 | <(4,5),6> +(2 rows) + +SET enable_seqscan = on; +SET enable_indexscan = off; +SELECT * FROM tbl_with_dropped_column ; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column ORDER BY 1, 2; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +SET enable_seqscan = off; +SET enable_indexscan = on; +SELECT * FROM tbl_with_dropped_column ORDER BY 1, 2; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM view_for_dropped_column; + c1 | id | c2 | c3 +----+----+----+---- + c1 | 1 | c2 | + c1 | 2 | c2 | +(2 rows) + +SELECT * FROM tbl_with_dropped_toast; + i | j +---+---- + 1 | 10 + 2 | 20 +(2 rows) + +RESET enable_seqscan; +RESET enable_indexscan; +-- check if storage option for both table and TOAST table didn't go away. +SELECT CASE relkind + WHEN 'r' THEN relname + WHEN 't' THEN 'toast_table' + END as table, + reloptions +FROM pg_class +WHERE relname = 'tbl_with_toast' OR relname = 'pg_toast_' || 'tbl_with_toast'::regclass::oid +ORDER BY 1; + table | reloptions +----------------+--------------------------------------------------------------------- + tbl_with_toast | {autovacuum_vacuum_scale_factor=30,autovacuum_vacuum_threshold=300} + toast_table | {autovacuum_vacuum_scale_factor=40,autovacuum_vacuum_threshold=400} +(2 rows) + +SELECT pg_relation_size(reltoastrelid) = 0 as check_toast_rel_size FROM pg_class WHERE relname = 'tbl_with_mod_column_storage'; + check_toast_rel_size +---------------------- + t +(1 row) + +-- +-- check broken links or orphan toast relations +-- +SELECT oid, relname + FROM pg_class + WHERE relkind = 't' + AND oid NOT IN (SELECT reltoastrelid FROM pg_class WHERE relkind = 'r'); + oid | relname +-----+--------- +(0 rows) + +SELECT oid, relname + FROM pg_class + WHERE relkind = 'r' + AND reltoastrelid <> 0 + AND reltoastrelid NOT IN (SELECT oid FROM pg_class WHERE relkind = 't'); + oid | relname +-----+--------- +(0 rows) + +-- check columns options +SELECT attname, attstattarget, attoptions +FROM pg_attribute +WHERE attrelid = 'tbl_idxopts'::regclass +AND attnum > 0 +ORDER BY attnum; + attname | attstattarget | attoptions +---------+---------------+------------------- + i | 1 | + t | -1 | {n_distinct=-0.5} +(2 rows) + +-- +-- NOT NULL UNIQUE +-- +CREATE TABLE tbl_nn (col1 int NOT NULL, col2 int NOT NULL); +CREATE TABLE tbl_uk (col1 int NOT NULL, col2 int , UNIQUE(col1, col2)); +CREATE TABLE tbl_nn_uk (col1 int NOT NULL, col2 int NOT NULL, UNIQUE(col1, col2)); +CREATE TABLE tbl_pk_uk (col1 int NOT NULL, col2 int NOT NULL, PRIMARY KEY(col1, col2), UNIQUE(col2, col1)); +CREATE TABLE tbl_nn_puk (col1 int NOT NULL, col2 int NOT NULL); +CREATE UNIQUE INDEX tbl_nn_puk_pcol1_idx ON tbl_nn_puk(col1) WHERE col1 < 10; +\! pg_repack --dbname=contrib_regression --table=tbl_nn +WARNING: relation "tbl_nn" must have a primary key or not-null unique keys +-- => WARNING +\! pg_repack --dbname=contrib_regression --table=tbl_uk +WARNING: relation "tbl_uk" must have a primary key or not-null unique keys +-- => WARNING +\! pg_repack --dbname=contrib_regression --table=tbl_nn_uk +INFO: repacking table "tbl_nn_uk" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_pk_uk +INFO: repacking table "tbl_pk_uk" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_pk_uk --only-indexes +INFO: repacking indexes of "tbl_pk_uk" +INFO: repacking index "public"."tbl_pk_uk_col2_col1_key" +INFO: repacking index "public"."tbl_pk_uk_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_nn_puk +WARNING: relation "tbl_nn_puk" must have a primary key or not-null unique keys +-- => WARNING +-- +-- Triggers handling +-- +CREATE FUNCTION trgtest() RETURNS trigger AS +$$BEGIN RETURN NEW; END$$ +LANGUAGE plpgsql; +CREATE TABLE trg1 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger_1 AFTER UPDATE ON trg1 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg1 +INFO: repacking table "trg1" +CREATE TABLE trg2 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger AFTER UPDATE ON trg2 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg2 +INFO: repacking table "trg2" +WARNING: the table "trg2" already has a trigger called "repack_trigger" +DETAIL: The trigger was probably installed during a previous attempt to run pg_repack on the table which was interrupted and for some reason failed to clean up the temporary objects. Please drop the trigger or drop and recreate the pg_repack extension altogether to remove all the temporary objects left over. +CREATE TABLE trg3 (id integer PRIMARY KEY); +CREATE TRIGGER repack_trigger_1 BEFORE UPDATE ON trg3 FOR EACH ROW EXECUTE PROCEDURE trgtest(); +\! pg_repack --dbname=contrib_regression --table=trg3 +INFO: repacking table "trg3" +-- +-- Table re-organization using specific column +-- +-- reorganize table using cluster key. Sort in ascending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order +INFO: repacking table "tbl_order" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + ctid | c +--------+---- + (0,1) | 1 + (0,2) | 2 + (0,3) | 3 + (0,4) | 4 + (0,5) | 5 + (0,6) | 6 + (0,7) | 7 + (0,8) | 8 + (0,9) | 9 + (0,10) | 10 +(10 rows) + +-- reorganize table using specific column order. Sort in descending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order -o "c DESC" +INFO: repacking table "tbl_order" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + ctid | c +--------+----- + (0,1) | 100 + (0,2) | 99 + (0,3) | 98 + (0,4) | 97 + (0,5) | 96 + (0,6) | 95 + (0,7) | 94 + (0,8) | 93 + (0,9) | 92 + (0,10) | 91 +(10 rows) + +-- +-- Dry run +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --dry-run +INFO: Dry run enabled, not executing repack +INFO: repacking table "tbl_cluster" +-- Test --schema +-- +CREATE SCHEMA test_schema1; +CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); +CREATE SCHEMA test_schema2; +CREATE TABLE test_schema2.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema2.tbl2 (id INTEGER PRIMARY KEY); +-- => OK +\! pg_repack --dbname=contrib_regression --schema=test_schema1 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +-- => OK +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +INFO: repacking table "test_schema2.tbl1" +INFO: repacking table "test_schema2.tbl2" +-- => ERROR +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --table=tbl1 +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --all --schema=test_schema1 +ERROR: cannot repack specific schema(s) in all databases +-- +-- don't kill backend +-- +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-kill-backend +INFO: repacking table "tbl_cluster" +-- +-- no superuser check +-- +DROP ROLE IF EXISTS nosuper; +CREATE ROLE nosuper WITH LOGIN; +-- => OK +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --no-superuser-check +INFO: repacking table "tbl_cluster" +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper +ERROR: pg_repack failed with error: You must be a superuser to use pg_repack +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check +ERROR: pg_repack failed with error: ERROR: permission denied for schema repack +DROP ROLE IF EXISTS nosuper; +-- +-- exclude extension check +-- +CREATE SCHEMA exclude_extension_schema; +CREATE TABLE exclude_extension_schema.tbl(val integer primary key); +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension +ERROR: cannot specify --table (-t) and --exclude-extension (-C) +-- => ERROR +\! pg_repack --dbname=contrib_regression --table=dummy_table --exclude-extension=dummy_extension -x +ERROR: cannot specify --only-indexes (-x) and --exclude-extension (-C) +-- => ERROR +\! pg_repack --dbname=contrib_regression --index=dummy_index --exclude-extension=dummy_extension +ERROR: cannot specify --index (-i) and --exclude-extension (-C) +-- => OK +\! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension +INFO: repacking table "exclude_extension_schema.tbl" +-- => OK +\! pg_repack --dbname=contrib_regression --schema=exclude_extension_schema --exclude-extension=dummy_extension --exclude-extension=dummy_extension +INFO: repacking table "exclude_extension_schema.tbl" +-- +-- table inheritance check +-- +CREATE TABLE parent_a(val integer primary key); +CREATE TABLE child_a_1(val integer primary key) INHERITS(parent_a); +CREATE TABLE child_a_2(val integer primary key) INHERITS(parent_a); +CREATE TABLE parent_b(val integer primary key); +CREATE TABLE child_b_1(val integer primary key) INHERITS(parent_b); +CREATE TABLE child_b_2(val integer primary key) INHERITS(parent_b); +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table +ERROR: pg_repack failed with error: ERROR: relation "dummy_table" does not exist +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_index --index=dummy_index +ERROR: cannot specify --index (-i) and --parent-table (-I) +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --schema=dummy_schema +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --all +ERROR: cannot repack specific table(s) in all databases +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "child_a_1" +INFO: repacking table "child_a_2" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "public.child_a_1" +INFO: repacking index "public"."child_a_1_pkey" +INFO: repacking indexes of "public.child_a_2" +INFO: repacking index "public"."child_a_2_pkey" +INFO: repacking indexes of "public.parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" diff --git a/regress/expected/tablespace_3.out b/regress/expected/tablespace_3.out new file mode 100644 index 0000000..ef0424e --- /dev/null +++ b/regress/expected/tablespace_3.out @@ -0,0 +1,234 @@ +SET client_min_messages = warning; +-- +-- Tablespace features tests +-- +-- Note: in order to pass this test you must create a tablespace called 'testts' +-- +SELECT spcname FROM pg_tablespace WHERE spcname = 'testts'; + spcname +--------- + testts +(1 row) + +-- If the query above failed you must create the 'testts' tablespace; +CREATE TABLE testts1 (id serial primary key, data text); +CREATE INDEX testts1_partial_idx on testts1 (id) where (id > 0); +CREATE INDEX testts1_with_idx on testts1 (id) with (fillfactor=80); +INSERT INTO testts1 (data) values ('a'); +INSERT INTO testts1 (data) values ('b'); +INSERT INTO testts1 (data) values ('c'); +-- check the indexes definitions +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, false), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +---------------------------------------------------------------------------------- + CREATE INDEX index_OID ON repack.table_OID USING btree (id) WHERE (id > 0) + CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) + CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor=80) +(3 rows) + +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', false), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +------------------------------------------------------------------------------------------------- + CREATE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo WHERE (id > 0) + CREATE UNIQUE INDEX index_OID ON repack.table_OID USING btree (id) TABLESPACE foo + CREATE INDEX index_OID ON repack.table_OID USING btree (id) WITH (fillfactor=80) TABLESPACE foo +(3 rows) + +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, NULL, true), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +-------------------------------------------------------------------------------------- + CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WHERE (id > 0) + CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) + CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor=80) +(3 rows) + +SELECT regexp_replace( + repack.repack_indexdef(indexrelid, 'testts1'::regclass, 'foo', true), + '_[0-9]+', '_OID', 'g') +FROM pg_index i join pg_class c ON c.oid = indexrelid +WHERE indrelid = 'testts1'::regclass ORDER BY relname; + regexp_replace +----------------------------------------------------------------------------------------------------- + CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE foo WHERE (id > 0) + CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE foo + CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor=80) TABLESPACE foo +(3 rows) + +-- can move the tablespace from default +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts +INFO: repacking table "testts1" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- + testts1 | testts +(1 row) + +SELECT * from testts1 order by id; + id | data +----+------ + 1 | a + 2 | b + 3 | c +(3 rows) + +-- tablespace stays where it is +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 +INFO: repacking table "testts1" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- + testts1 | testts +(1 row) + +-- can move the ts back to default +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 -s pg_default +INFO: repacking table "testts1" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- +(0 rows) + +-- can move the table together with the indexes +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 --tablespace testts --moveidx +INFO: repacking table "testts1" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------------------+--------- + testts1 | testts + testts1_partial_idx | testts + testts1_pkey | testts + testts1_with_idx | testts +(4 rows) + +-- can't specify --moveidx without --tablespace +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 --moveidx +ERROR: cannot specify --moveidx (-S) without --tablespace (-s) +\! pg_repack --dbname=contrib_regression --no-order --table=testts1 -S +ERROR: cannot specify --moveidx (-S) without --tablespace (-s) +-- not broken with order +\! pg_repack --dbname=contrib_regression -o id --table=testts1 --tablespace pg_default --moveidx +INFO: repacking table "testts1" +--move all indexes of the table to a tablespace +\! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=testts +INFO: repacking indexes of "testts1" +INFO: repacking index "public"."testts1_partial_idx" +INFO: repacking index "public"."testts1_pkey" +INFO: repacking index "public"."testts1_with_idx" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------------------+--------- + testts1_partial_idx | testts + testts1_pkey | testts + testts1_with_idx | testts +(3 rows) + +--all indexes of tablespace remain in same tablespace +\! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes +INFO: repacking indexes of "testts1" +INFO: repacking index "public"."testts1_partial_idx" +INFO: repacking index "public"."testts1_pkey" +INFO: repacking index "public"."testts1_with_idx" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------------------+--------- + testts1_partial_idx | testts + testts1_pkey | testts + testts1_with_idx | testts +(3 rows) + +--move all indexes of the table to pg_default +\! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --tablespace=pg_default +INFO: repacking indexes of "testts1" +INFO: repacking index "public"."testts1_partial_idx" +INFO: repacking index "public"."testts1_pkey" +INFO: repacking index "public"."testts1_with_idx" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- +(0 rows) + +--move one index to a tablespace +\! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=testts +INFO: repacking index "public"."testts1_pkey" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +--------------+--------- + testts1_pkey | testts +(1 row) + +--index tablespace stays as is +\! pg_repack --dbname=contrib_regression --index=testts1_pkey +INFO: repacking index "public"."testts1_pkey" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +--------------+--------- + testts1_pkey | testts +(1 row) + +--move index to pg_default +\! pg_repack --dbname=contrib_regression --index=testts1_pkey --tablespace=pg_default +INFO: repacking index "public"."testts1_pkey" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +---------+--------- +(0 rows) + +--using multiple --index option +\! pg_repack --dbname=contrib_regression --index=testts1_pkey --index=testts1_with_idx --tablespace=testts +INFO: repacking index "public"."testts1_pkey" +INFO: repacking index "public"."testts1_with_idx" +SELECT relname, spcname +FROM pg_class JOIN pg_tablespace ts ON ts.oid = reltablespace +WHERE relname ~ '^testts1' +ORDER BY relname; + relname | spcname +------------------+--------- + testts1_pkey | testts + testts1_with_idx | testts +(2 rows) + +--using --indexes-only and --index option together +\! pg_repack --dbname=contrib_regression --table=testts1 --only-indexes --index=testts1_pkey +ERROR: cannot specify --index (-i) and --table (-t) diff --git a/regress/sql/repack.sql b/regress/sql/repack.sql index f79022e..3f73daf 100644 --- a/regress/sql/repack.sql +++ b/regress/sql/repack.sql @@ -1,13 +1,68 @@ +-- Setup function to get version number. +-- This function returns a value same as PG_VERSION_NUM. +CREATE OR REPLACE FUNCTION version_num() RETURNS int AS +$$ +DECLARE + version_int int[]; + version_str text; +BEGIN + SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; + IF array_length(version_int, 1) = 2 THEN -- version 10 or higher + SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; + ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower + SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; + ELSE + RAISE 'invalid version'; + END IF; + RETURN version_str::int; +END; +$$ +LANGUAGE plpgsql IMMUTABLE STRICT; + -- Test output file identifier. -SELECT CASE - WHEN split_part(version(), ' ', 2) ~ '^(10)' - THEN 'repack_2.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.6|9\.5)' - THEN 'repack.out' - WHEN split_part(version(), ' ', 2) ~ '^(9\.4|9\.3|9\.2|9\.1)' - THEN 'repack_1.out' - ELSE version() -END AS testfile; +SELECT + CASE + WHEN version_num >= 100000 THEN -- PostgreSQL 10 + CASE + WHEN version_num >= 100003 THEN + 'repack_3.out' + ELSE + 'repack_2.out' + END + WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 + CASE + WHEN version_num >= 90608 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 + CASE + WHEN version_num >= 90512 THEN + 'repack_4.out' + ELSE + 'repack.out' + END + WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 + CASE + WHEN version_num >= 90417 THEN + 'repack_5.out' + ELSE + 'repack_1.out' + END + WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 + CASE + WHEN version_num >= 90322 THEN + 'repack_5.out' + ELSE + 'repack_6.out' + END + WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 + 'repack_1.out' + WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 + 'repack_1.out' + END +FROM version_num() as version_num; SET client_min_messages = warning; -- From 2fd0eb050a2256a4454ecc48f2b23cc5551cb04b Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Fri, 9 Mar 2018 13:03:36 +0000 Subject: [PATCH 8/8] A more compact way to verify the identity of the test files --- lib/pg_repack.sql.in | 24 +++++++++++ regress/expected/repack.out | 79 +++++++---------------------------- regress/expected/repack_1.out | 79 +++++++---------------------------- regress/expected/repack_2.out | 79 +++++++---------------------------- regress/expected/repack_3.out | 79 +++++++---------------------------- regress/expected/repack_4.out | 79 +++++++---------------------------- regress/expected/repack_5.out | 79 +++++++---------------------------- regress/expected/repack_6.out | 79 +++++++---------------------------- regress/sql/repack.sql | 78 +++++++--------------------------- 9 files changed, 143 insertions(+), 512 deletions(-) diff --git a/lib/pg_repack.sql.in b/lib/pg_repack.sql.in index 249547c..8a68b60 100644 --- a/lib/pg_repack.sql.in +++ b/lib/pg_repack.sql.in @@ -16,6 +16,30 @@ CREATE FUNCTION repack.version_sql() RETURNS text AS $$SELECT 'pg_repack REPACK_VERSION'::text$$ LANGUAGE SQL IMMUTABLE STRICT; +CREATE FUNCTION repack.pg_version(version_str text DEFAULT NULL) RETURNS integer +AS $$ + -- Return the server version number in a format similar to PG_VERSION_NUM. + -- Call with no argument for the server version, pass an argument for testing + select (case + when array_length(tokens, 1) = 2 then + to_char(tokens[1], 'FM00') || + '00' || to_char(tokens[2], 'FM00') + when array_length(tokens, 1) = 3 then + to_char(tokens[1], 'FM00') || + to_char(tokens[2], 'FM00') || + to_char(tokens[3], 'FM00') + else + -- This will raise an error which we can read + 'unexpected version string: ' || coalesce($1, version()) + end)::int + from ( + select string_to_array(substring( + split_part(coalesce($1, version()), ' ', 2) + from '\d+\.\d+(?:\.\d+)?'), '.')::int[] + ) as x (tokens); +$$ +LANGUAGE SQL IMMUTABLE; + CREATE AGGREGATE repack.array_accum ( sfunc = array_append, basetype = anyelement, diff --git a/regress/expected/repack.out b/regress/expected/repack.out index 8001c1d..3306ab0 100644 --- a/regress/expected/repack.out +++ b/regress/expected/repack.out @@ -1,68 +1,19 @@ --- Setup function to get version number. --- This function returns a value same as PG_VERSION_NUM. -CREATE OR REPLACE FUNCTION version_num() RETURNS int AS -$$ -DECLARE - version_int int[]; - version_str text; -BEGIN - SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; - IF array_length(version_int, 1) = 2 THEN -- version 10 or higher - SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; - ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower - SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; - ELSE - RAISE 'invalid version'; - END IF; - RETURN version_str::int; -END; -$$ -LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT - CASE - WHEN version_num >= 100000 THEN -- PostgreSQL 10 - CASE - WHEN version_num >= 100003 THEN - 'repack_3.out' - ELSE - 'repack_2.out' - END - WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 - CASE - WHEN version_num >= 90608 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 - CASE - WHEN version_num >= 90512 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 - CASE - WHEN version_num >= 90417 THEN - 'repack_5.out' - ELSE - 'repack_1.out' - END - WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 - CASE - WHEN version_num >= 90322 THEN - 'repack_5.out' - ELSE - 'repack_6.out' - END - WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 - 'repack_1.out' - WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 - 'repack_1.out' - END -FROM version_num() as version_num; - case +select filename from (values + ( 90100, 90300, 'repack_1.out'), + ( 90300, 90322, 'repack_6.out'), + ( 90322, 90400, 'repack_5.out'), + ( 90400, 90417, 'repack_1.out'), + ( 90417, 90500, 'repack_5.out'), + ( 90500, 90512, 'repack.out'), + ( 90512, 90600, 'repack_4.out'), + ( 90600, 90608, 'repack.out'), + ( 90608, 100000, 'repack_4.out'), + (100000, 100003, 'repack_2.out'), + (100003, 110000, 'repack_3.out') +) as x (min, max, filename) +where min <= repack.pg_version() and repack.pg_version() < max; + filename ------------ repack.out (1 row) diff --git a/regress/expected/repack_1.out b/regress/expected/repack_1.out index 48690cb..df04ca8 100644 --- a/regress/expected/repack_1.out +++ b/regress/expected/repack_1.out @@ -1,68 +1,19 @@ --- Setup function to get version number. --- This function returns a value same as PG_VERSION_NUM. -CREATE OR REPLACE FUNCTION version_num() RETURNS int AS -$$ -DECLARE - version_int int[]; - version_str text; -BEGIN - SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; - IF array_length(version_int, 1) = 2 THEN -- version 10 or higher - SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; - ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower - SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; - ELSE - RAISE 'invalid version'; - END IF; - RETURN version_str::int; -END; -$$ -LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT - CASE - WHEN version_num >= 100000 THEN -- PostgreSQL 10 - CASE - WHEN version_num >= 100003 THEN - 'repack_3.out' - ELSE - 'repack_2.out' - END - WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 - CASE - WHEN version_num >= 90608 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 - CASE - WHEN version_num >= 90512 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 - CASE - WHEN version_num >= 90417 THEN - 'repack_5.out' - ELSE - 'repack_1.out' - END - WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 - CASE - WHEN version_num >= 90322 THEN - 'repack_5.out' - ELSE - 'repack_6.out' - END - WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 - 'repack_1.out' - WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 - 'repack_1.out' - END -FROM version_num() as version_num; - case +select filename from (values + ( 90100, 90300, 'repack_1.out'), + ( 90300, 90322, 'repack_6.out'), + ( 90322, 90400, 'repack_5.out'), + ( 90400, 90417, 'repack_1.out'), + ( 90417, 90500, 'repack_5.out'), + ( 90500, 90512, 'repack.out'), + ( 90512, 90600, 'repack_4.out'), + ( 90600, 90608, 'repack.out'), + ( 90608, 100000, 'repack_4.out'), + (100000, 100003, 'repack_2.out'), + (100003, 110000, 'repack_3.out') +) as x (min, max, filename) +where min <= repack.pg_version() and repack.pg_version() < max; + filename -------------- repack_1.out (1 row) diff --git a/regress/expected/repack_2.out b/regress/expected/repack_2.out index 1637dd6..0654079 100644 --- a/regress/expected/repack_2.out +++ b/regress/expected/repack_2.out @@ -1,68 +1,19 @@ --- Setup function to get version number. --- This function returns a value same as PG_VERSION_NUM. -CREATE OR REPLACE FUNCTION version_num() RETURNS int AS -$$ -DECLARE - version_int int[]; - version_str text; -BEGIN - SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; - IF array_length(version_int, 1) = 2 THEN -- version 10 or higher - SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; - ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower - SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; - ELSE - RAISE 'invalid version'; - END IF; - RETURN version_str::int; -END; -$$ -LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT - CASE - WHEN version_num >= 100000 THEN -- PostgreSQL 10 - CASE - WHEN version_num >= 100003 THEN - 'repack_3.out' - ELSE - 'repack_2.out' - END - WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 - CASE - WHEN version_num >= 90608 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 - CASE - WHEN version_num >= 90512 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 - CASE - WHEN version_num >= 90417 THEN - 'repack_5.out' - ELSE - 'repack_1.out' - END - WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 - CASE - WHEN version_num >= 90322 THEN - 'repack_5.out' - ELSE - 'repack_6.out' - END - WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 - 'repack_1.out' - WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 - 'repack_1.out' - END -FROM version_num() as version_num; - case +select filename from (values + ( 90100, 90300, 'repack_1.out'), + ( 90300, 90322, 'repack_6.out'), + ( 90322, 90400, 'repack_5.out'), + ( 90400, 90417, 'repack_1.out'), + ( 90417, 90500, 'repack_5.out'), + ( 90500, 90512, 'repack.out'), + ( 90512, 90600, 'repack_4.out'), + ( 90600, 90608, 'repack.out'), + ( 90608, 100000, 'repack_4.out'), + (100000, 100003, 'repack_2.out'), + (100003, 110000, 'repack_3.out') +) as x (min, max, filename) +where min <= repack.pg_version() and repack.pg_version() < max; + filename -------------- repack_2.out (1 row) diff --git a/regress/expected/repack_3.out b/regress/expected/repack_3.out index 4a23973..fea2c29 100644 --- a/regress/expected/repack_3.out +++ b/regress/expected/repack_3.out @@ -1,68 +1,19 @@ --- Setup function to get version number. --- This function returns a value same as PG_VERSION_NUM. -CREATE OR REPLACE FUNCTION version_num() RETURNS int AS -$$ -DECLARE - version_int int[]; - version_str text; -BEGIN - SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; - IF array_length(version_int, 1) = 2 THEN -- version 10 or higher - SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; - ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower - SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; - ELSE - RAISE 'invalid version'; - END IF; - RETURN version_str::int; -END; -$$ -LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT - CASE - WHEN version_num >= 100000 THEN -- PostgreSQL 10 - CASE - WHEN version_num >= 100003 THEN - 'repack_3.out' - ELSE - 'repack_2.out' - END - WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 - CASE - WHEN version_num >= 90608 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 - CASE - WHEN version_num >= 90512 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 - CASE - WHEN version_num >= 90417 THEN - 'repack_5.out' - ELSE - 'repack_1.out' - END - WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 - CASE - WHEN version_num >= 90322 THEN - 'repack_5.out' - ELSE - 'repack_6.out' - END - WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 - 'repack_1.out' - WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 - 'repack_1.out' - END -FROM version_num() as version_num; - case +select filename from (values + ( 90100, 90300, 'repack_1.out'), + ( 90300, 90322, 'repack_6.out'), + ( 90322, 90400, 'repack_5.out'), + ( 90400, 90417, 'repack_1.out'), + ( 90417, 90500, 'repack_5.out'), + ( 90500, 90512, 'repack.out'), + ( 90512, 90600, 'repack_4.out'), + ( 90600, 90608, 'repack.out'), + ( 90608, 100000, 'repack_4.out'), + (100000, 100003, 'repack_2.out'), + (100003, 110000, 'repack_3.out') +) as x (min, max, filename) +where min <= repack.pg_version() and repack.pg_version() < max; + filename -------------- repack_3.out (1 row) diff --git a/regress/expected/repack_4.out b/regress/expected/repack_4.out index 099d1ad..62a137e 100644 --- a/regress/expected/repack_4.out +++ b/regress/expected/repack_4.out @@ -1,68 +1,19 @@ --- Setup function to get version number. --- This function returns a value same as PG_VERSION_NUM. -CREATE OR REPLACE FUNCTION version_num() RETURNS int AS -$$ -DECLARE - version_int int[]; - version_str text; -BEGIN - SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; - IF array_length(version_int, 1) = 2 THEN -- version 10 or higher - SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; - ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower - SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; - ELSE - RAISE 'invalid version'; - END IF; - RETURN version_str::int; -END; -$$ -LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT - CASE - WHEN version_num >= 100000 THEN -- PostgreSQL 10 - CASE - WHEN version_num >= 100003 THEN - 'repack_3.out' - ELSE - 'repack_2.out' - END - WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 - CASE - WHEN version_num >= 90608 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 - CASE - WHEN version_num >= 90512 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 - CASE - WHEN version_num >= 90417 THEN - 'repack_5.out' - ELSE - 'repack_1.out' - END - WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 - CASE - WHEN version_num >= 90322 THEN - 'repack_5.out' - ELSE - 'repack_6.out' - END - WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 - 'repack_1.out' - WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 - 'repack_1.out' - END -FROM version_num() as version_num; - case +select filename from (values + ( 90100, 90300, 'repack_1.out'), + ( 90300, 90322, 'repack_6.out'), + ( 90322, 90400, 'repack_5.out'), + ( 90400, 90417, 'repack_1.out'), + ( 90417, 90500, 'repack_5.out'), + ( 90500, 90512, 'repack.out'), + ( 90512, 90600, 'repack_4.out'), + ( 90600, 90608, 'repack.out'), + ( 90608, 100000, 'repack_4.out'), + (100000, 100003, 'repack_2.out'), + (100003, 110000, 'repack_3.out') +) as x (min, max, filename) +where min <= repack.pg_version() and repack.pg_version() < max; + filename -------------- repack_4.out (1 row) diff --git a/regress/expected/repack_5.out b/regress/expected/repack_5.out index f266ca1..d64771f 100644 --- a/regress/expected/repack_5.out +++ b/regress/expected/repack_5.out @@ -1,68 +1,19 @@ --- Setup function to get version number. --- This function returns a value same as PG_VERSION_NUM. -CREATE OR REPLACE FUNCTION version_num() RETURNS int AS -$$ -DECLARE - version_int int[]; - version_str text; -BEGIN - SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; - IF array_length(version_int, 1) = 2 THEN -- version 10 or higher - SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; - ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower - SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; - ELSE - RAISE 'invalid version'; - END IF; - RETURN version_str::int; -END; -$$ -LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT - CASE - WHEN version_num >= 100000 THEN -- PostgreSQL 10 - CASE - WHEN version_num >= 100003 THEN - 'repack_3.out' - ELSE - 'repack_2.out' - END - WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 - CASE - WHEN version_num >= 90608 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 - CASE - WHEN version_num >= 90512 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 - CASE - WHEN version_num >= 90417 THEN - 'repack_5.out' - ELSE - 'repack_1.out' - END - WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 - CASE - WHEN version_num >= 90322 THEN - 'repack_5.out' - ELSE - 'repack_6.out' - END - WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 - 'repack_1.out' - WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 - 'repack_1.out' - END -FROM version_num() as version_num; - case +select filename from (values + ( 90100, 90300, 'repack_1.out'), + ( 90300, 90322, 'repack_6.out'), + ( 90322, 90400, 'repack_5.out'), + ( 90400, 90417, 'repack_1.out'), + ( 90417, 90500, 'repack_5.out'), + ( 90500, 90512, 'repack.out'), + ( 90512, 90600, 'repack_4.out'), + ( 90600, 90608, 'repack.out'), + ( 90608, 100000, 'repack_4.out'), + (100000, 100003, 'repack_2.out'), + (100003, 110000, 'repack_3.out') +) as x (min, max, filename) +where min <= repack.pg_version() and repack.pg_version() < max; + filename -------------- repack_5.out (1 row) diff --git a/regress/expected/repack_6.out b/regress/expected/repack_6.out index eb084a1..3d57ffb 100644 --- a/regress/expected/repack_6.out +++ b/regress/expected/repack_6.out @@ -1,68 +1,19 @@ --- Setup function to get version number. --- This function returns a value same as PG_VERSION_NUM. -CREATE OR REPLACE FUNCTION version_num() RETURNS int AS -$$ -DECLARE - version_int int[]; - version_str text; -BEGIN - SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; - IF array_length(version_int, 1) = 2 THEN -- version 10 or higher - SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; - ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower - SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; - ELSE - RAISE 'invalid version'; - END IF; - RETURN version_str::int; -END; -$$ -LANGUAGE plpgsql IMMUTABLE STRICT; -- Test output file identifier. -SELECT - CASE - WHEN version_num >= 100000 THEN -- PostgreSQL 10 - CASE - WHEN version_num >= 100003 THEN - 'repack_3.out' - ELSE - 'repack_2.out' - END - WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 - CASE - WHEN version_num >= 90608 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 - CASE - WHEN version_num >= 90512 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 - CASE - WHEN version_num >= 90417 THEN - 'repack_5.out' - ELSE - 'repack_1.out' - END - WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 - CASE - WHEN version_num >= 90322 THEN - 'repack_5.out' - ELSE - 'repack_6.out' - END - WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 - 'repack_1.out' - WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 - 'repack_1.out' - END -FROM version_num() as version_num; - case +select filename from (values + ( 90100, 90300, 'repack_1.out'), + ( 90300, 90322, 'repack_6.out'), + ( 90322, 90400, 'repack_5.out'), + ( 90400, 90417, 'repack_1.out'), + ( 90417, 90500, 'repack_5.out'), + ( 90500, 90512, 'repack.out'), + ( 90512, 90600, 'repack_4.out'), + ( 90600, 90608, 'repack.out'), + ( 90608, 100000, 'repack_4.out'), + (100000, 100003, 'repack_2.out'), + (100003, 110000, 'repack_3.out') +) as x (min, max, filename) +where min <= repack.pg_version() and repack.pg_version() < max; + filename -------------- repack_6.out (1 row) diff --git a/regress/sql/repack.sql b/regress/sql/repack.sql index 3f73daf..cdb35bd 100644 --- a/regress/sql/repack.sql +++ b/regress/sql/repack.sql @@ -1,68 +1,18 @@ --- Setup function to get version number. --- This function returns a value same as PG_VERSION_NUM. -CREATE OR REPLACE FUNCTION version_num() RETURNS int AS -$$ -DECLARE - version_int int[]; - version_str text; -BEGIN - SELECT string_to_array(split_part(version(), ' ', 2), '.')::int[] INTO version_int; - IF array_length(version_int, 1) = 2 THEN -- version 10 or higher - SELECT to_char(version_int[1], 'FM00') || '00' || to_char(version_int[2], 'FM00') INTO version_str; - ELSIF array_length(version_int, 1) = 3 THEN --version 9.6 or lower - SELECT to_char(version_int[1], 'FM00') || to_char(version_int[2], 'FM00') || to_char(version_int[3], 'FM00') INTO version_str; - ELSE - RAISE 'invalid version'; - END IF; - RETURN version_str::int; -END; -$$ -LANGUAGE plpgsql IMMUTABLE STRICT; - -- Test output file identifier. -SELECT - CASE - WHEN version_num >= 100000 THEN -- PostgreSQL 10 - CASE - WHEN version_num >= 100003 THEN - 'repack_3.out' - ELSE - 'repack_2.out' - END - WHEN version_num >= 90600 THEN -- PostgrSQL 9.6 - CASE - WHEN version_num >= 90608 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90500 THEN -- PostgreSQL 9.5 - CASE - WHEN version_num >= 90512 THEN - 'repack_4.out' - ELSE - 'repack.out' - END - WHEN version_num >= 90400 THEN -- PostgreSQL 9.4 - CASE - WHEN version_num >= 90417 THEN - 'repack_5.out' - ELSE - 'repack_1.out' - END - WHEN version_num >= 90300 THEN -- PostgreSQL 9.3 - CASE - WHEN version_num >= 90322 THEN - 'repack_5.out' - ELSE - 'repack_6.out' - END - WHEN version_num >= 90200 THEN -- PostgreSQL 9.2 - 'repack_1.out' - WHEN version_num >= 90100 THEN -- PostgreSQL 9.1 - 'repack_1.out' - END -FROM version_num() as version_num; +select filename from (values + ( 90100, 90300, 'repack_1.out'), + ( 90300, 90322, 'repack_6.out'), + ( 90322, 90400, 'repack_5.out'), + ( 90400, 90417, 'repack_1.out'), + ( 90417, 90500, 'repack_5.out'), + ( 90500, 90512, 'repack.out'), + ( 90512, 90600, 'repack_4.out'), + ( 90600, 90608, 'repack.out'), + ( 90608, 100000, 'repack_4.out'), + (100000, 100003, 'repack_2.out'), + (100003, 110000, 'repack_3.out') +) as x (min, max, filename) +where min <= repack.pg_version() and repack.pg_version() < max; SET client_min_messages = warning; --