[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