diff --git a/bin/pg_repack.c b/bin/pg_repack.c index 46bdeb0..2be03cd 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -772,6 +772,7 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize) for (i = 0; i < num; i++) { repack_table table; + StringInfoData copy_sql; const char *create_table_1; const char *create_table_2; const char *tablespace; @@ -814,17 +815,27 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize) table.sql_pop = getstr(res, i, c++); tablespace = getstr(res, i, c++); + /* Craft CREATE TABLE SQL */ resetStringInfo(&sql); appendStringInfoString(&sql, create_table_1); appendStringInfoString(&sql, tablespace); appendStringInfoString(&sql, create_table_2); + + /* Always append WITH NO DATA to CREATE TABLE SQL*/ + appendStringInfoString(&sql, " WITH NO DATA"); + table.create_table = sql.data; + + /* Craft Copy SQL */ + initStringInfo(©_sql); + appendStringInfoString(©_sql, table.copy_data); if (!orderby) + { if (ckey != NULL) { /* CLUSTER mode */ - appendStringInfoString(&sql, " ORDER BY "); - appendStringInfoString(&sql, ckey); + appendStringInfoString(©_sql, " ORDER BY "); + appendStringInfoString(©_sql, ckey); } /* else, VACUUM FULL mode (non-clustered tables) */ @@ -836,13 +847,10 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize) else { /* User specified ORDER BY */ - appendStringInfoString(&sql, " ORDER BY "); - appendStringInfoString(&sql, orderby); + appendStringInfoString(©_sql, " ORDER BY "); + appendStringInfoString(©_sql, orderby); } - - /* Always append WITH NOT DATA */ - appendStringInfoString(&sql, " WITH NO DATA"); - table.create_table = sql.data; + table.copy_data = copy_sql.data; repack_one_table(&table, orderby); } diff --git a/regress/expected/repack.out b/regress/expected/repack.out index 5934f65..7417f48 100644 --- a/regress/expected/repack.out +++ b/regress/expected/repack.out @@ -69,6 +69,7 @@ CREATE TABLE tbl_with_mod_column_storage ( c text ); ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; +CREATE TABLE tbl_order (c int primary key); -- -- insert data -- @@ -103,6 +104,10 @@ 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 -- @@ -146,6 +151,7 @@ WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON tbl_badin 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 -- @@ -257,8 +263,8 @@ SET enable_indexscan = off; SELECT * FROM tbl_with_dropped_column ; c1 | id | c2 | c3 ----+----+----+---- - c1 | 2 | c2 | c1 | 1 | c2 | + c1 | 2 | c2 | (2 rows) SELECT * FROM view_for_dropped_column ORDER BY 1, 2; @@ -287,8 +293,8 @@ SELECT * FROM tbl_with_dropped_column ORDER BY 1, 2; SELECT * FROM view_for_dropped_column; c1 | id | c2 | c3 ----+----+----+---- - c1 | 2 | c2 | c1 | 1 | c2 | + c1 | 2 | c2 | (2 rows) SELECT * FROM tbl_with_dropped_toast; @@ -402,6 +408,45 @@ 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 -- diff --git a/regress/expected/repack_1.out b/regress/expected/repack_1.out index 98360ee..62fc8dd 100644 --- a/regress/expected/repack_1.out +++ b/regress/expected/repack_1.out @@ -69,6 +69,7 @@ CREATE TABLE tbl_with_mod_column_storage ( c text ); ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; +CREATE TABLE tbl_order (c int primary key); -- -- insert data -- @@ -103,6 +104,10 @@ 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 -- @@ -146,6 +151,7 @@ WARNING: skipping invalid index: CREATE UNIQUE INDEX idx_badindex_n ON tbl_badin 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 -- @@ -257,8 +263,8 @@ SET enable_indexscan = off; SELECT * FROM tbl_with_dropped_column ; c1 | id | c2 | c3 ----+----+----+---- - c1 | 2 | c2 | c1 | 1 | c2 | + c1 | 2 | c2 | (2 rows) SELECT * FROM view_for_dropped_column ORDER BY 1, 2; @@ -287,8 +293,8 @@ SELECT * FROM tbl_with_dropped_column ORDER BY 1, 2; SELECT * FROM view_for_dropped_column; c1 | id | c2 | c3 ----+----+----+---- - c1 | 2 | c2 | c1 | 1 | c2 | + c1 | 2 | c2 | (2 rows) SELECT * FROM tbl_with_dropped_toast; @@ -402,6 +408,45 @@ 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 -- diff --git a/regress/sql/repack.sql b/regress/sql/repack.sql index 9f58c09..ce7c386 100644 --- a/regress/sql/repack.sql +++ b/regress/sql/repack.sql @@ -81,6 +81,7 @@ CREATE TABLE tbl_with_mod_column_storage ( ); ALTER TABLE tbl_with_mod_column_storage ALTER c SET STORAGE MAIN; +CREATE TABLE tbl_order (c int primary key); -- -- insert data -- @@ -126,6 +127,10 @@ 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 -- @@ -241,6 +246,19 @@ 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 +-- +-- Table re-organization using specific column +-- + +-- reorganize table using cluster key. Sort in ascending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + +-- reorganize table using specific column order. Sort in descending order. +\! pg_repack --dbname=contrib_regression --table=tbl_order -o "c DESC" +SELECT ctid, c FROM tbl_order WHERE ctid <= '(0,10)'; + + -- -- Dry run --