[Pkg-postgresql-public] Bug#894841: pg-repack: fix failing dep8 tests with postgresql 10.3
Nishanth Aravamudan
nish.aravamudan at canonical.com
Wed Apr 4 20:00:01 BST 2018
Package: pg-repack
Version: 1.4.2-1
Severity: normal
Tags: patch
User: ubuntu-devel at lists.ubuntu.com
Usertags: origin-ubuntu bionic ubuntu-patch
Dear Maintainer,
In Ubuntu, the attached patch was applied to fix DEP8 regressions with
Postgresql 10.3.
* debian/patches/always_qualify_relation_names.patch: Always qualify
relation names. Thanks to Masahiko Sawada <sawada.mshk at gmail.com>.
Thanks for considering the patch.
*** /tmp/tmpB3TGJW/pg-repack_1.4.2-1ubuntu1.debdiff
diff -Nru pg-repack-1.4.2/debian/patches/always_qualify_relation_names.patch pg-repack-1.4.2/debian/patches/always_qualify_relation_names.patch
--- pg-repack-1.4.2/debian/patches/always_qualify_relation_names.patch 1969-12-31 16:00:00.000000000 -0800
+++ pg-repack-1.4.2/debian/patches/always_qualify_relation_names.patch 2018-04-04 10:22:56.000000000 -0700
@@ -0,0 +1,2905 @@
+Description: 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.
+Author: Masahiko Sawada <sawada.mshk at gmail.com>
+Origin: upstream, https://github.com/reorg/pg_repack/pull/172
+Bug: https://github.com/reorg/pg_repack/issues/169
+Bug: https://github.com/reorg/pg_repack/issues/174
+Forwarded: not-needed
+Last-Update: 2018-04-04
+
+--- a/lib/pg_repack.sql.in
++++ b/lib/pg_repack.sql.in
+@@ -16,6 +16,30 @@
+ $$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,
+--- a/lib/repack.c
++++ b/lib/repack.c
+@@ -354,11 +354,30 @@
+ Oid nsp = get_rel_namespace(relid);
+ char *nspname;
+
++ /*
++ * Relation names given by PostgreSQL core are always
++ * 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 >= 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;
+ 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));
+ }
+--- a/regress/expected/repack.out
++++ b/regress/expected/repack.out
+@@ -1,14 +1,19 @@
+ -- 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 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)
+--- a/regress/expected/repack_1.out
++++ b/regress/expected/repack_1.out
+@@ -1,14 +1,19 @@
+ -- 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 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)
+--- a/regress/expected/repack_2.out
++++ b/regress/expected/repack_2.out
+@@ -1,14 +1,19 @@
+ -- 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 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)
+--- /dev/null
++++ b/regress/expected/repack_3.out
+@@ -0,0 +1,605 @@
++-- Test output file identifier.
++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)
++
++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"
+--- /dev/null
++++ b/regress/expected/repack_4.out
+@@ -0,0 +1,605 @@
++-- Test output file identifier.
++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)
++
++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"
+--- /dev/null
++++ b/regress/expected/repack_5.out
+@@ -0,0 +1,603 @@
++-- Test output file identifier.
++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)
++
++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"
+--- /dev/null
++++ b/regress/expected/repack_6.out
+@@ -0,0 +1,603 @@
++-- Test output file identifier.
++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)
++
++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"
+--- /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)
+--- a/regress/sql/repack.sql
++++ b/regress/sql/repack.sql
+@@ -1,13 +1,18 @@
+ -- 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 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;
+ --
+--- a/regress/expected/tablespace_2.out
++++ b/regress/expected/tablespace_2.out
+@@ -48,11 +48,11 @@
+ '_[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 pg_default WHERE (id > 0)
+- CREATE UNIQUE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) TABLESPACE pg_default
+- CREATE INDEX CONCURRENTLY index_OID ON testts1 USING btree (id) WITH (fillfactor='80') TABLESPACE pg_default
++ 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(
+@@ -60,11 +60,11 @@
+ '_[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
++ 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
diff -Nru pg-repack-1.4.2/debian/patches/series pg-repack-1.4.2/debian/patches/series
--- pg-repack-1.4.2/debian/patches/series 2017-10-14 02:24:16.000000000 -0700
+++ pg-repack-1.4.2/debian/patches/series 2018-04-04 10:22:56.000000000 -0700
@@ -1,3 +1,4 @@
libs
tablespace
tablespace-microrelease
+always_qualify_relation_names.patch
-- System Information:
Debian Release: buster/sid
APT prefers bionic
APT policy: (500, 'bionic')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 4.15.0-13-generic (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US:en (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
--
Nishanth Aravamudan
Ubuntu Server
Canonical Ltd
More information about the pkg-postgresql-public
mailing list