From 1a10df904921c1389e8d99ac3dc80c3ad3a2ed28 Mon Sep 17 00:00:00 2001 From: Steeve Lennmark Date: Tue, 15 Oct 2013 10:56:34 +0200 Subject: [PATCH 1/6] Add support for repacking an entire schema This adds the option -c (--schema). --- bin/pg_repack.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/bin/pg_repack.c b/bin/pg_repack.c index f266539..2ca5567 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -219,6 +219,7 @@ static bool analyze = true; static bool alldb = false; static bool noorder = false; static SimpleStringList table_list = {NULL, NULL}; +static SimpleStringList schema_list = {NULL, NULL}; static char *orderby = NULL; static char *tablespace = NULL; static bool moveidx = false; @@ -239,6 +240,7 @@ static pgut_option options[] = { { 'b', 'a', "all", &alldb }, { 'l', 't', "table", &table_list }, + { 'l', 'c', "schema", &schema_list }, { 'b', 'n', "no-order", &noorder }, { 's', 'o', "order-by", &orderby }, { 's', 's', "tablespace", &tablespace }, @@ -312,6 +314,10 @@ main(int argc, char *argv[]) ereport(ERROR, (errcode(EINVAL), errmsg("cannot repack specific table(s) in all databases"))); + if (schema_list.head) + ereport(ERROR, + (errcode(EINVAL), + errmsg("cannot repack specific schema(s) in all databases"))); repack_all_databases(orderby); } else @@ -555,12 +561,14 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize) const char **params = NULL; int iparam = 0; size_t num_tables; + size_t num_schemas; size_t num_params; num_tables = simple_string_list_size(table_list); + num_schemas = simple_string_list_size(schema_list); /* 1st param is the user-specified tablespace */ - num_params = num_tables + 1; + num_params = num_tables + num_schemas + 1; params = pgut_malloc(num_params * sizeof(char *)); initStringInfo(&sql); @@ -596,6 +604,19 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize) } appendStringInfoString(&sql, ")"); } + else if (num_schemas) + { + appendStringInfoString(&sql, "schemaname IN ("); + for (cell = schema_list.head; cell; cell = cell->next) + { + /* Construct schema name placeholders to be used by PQexecParams */ + appendStringInfo(&sql, "$%d", iparam + 1); + params[iparam++] = cell->val; + if (cell->next) + appendStringInfoString(&sql, ", "); + } + appendStringInfoString(&sql, ")"); + } else { appendStringInfoString(&sql, "pkid IS NOT NULL"); @@ -1895,6 +1916,7 @@ pgut_help(bool details) printf("Options:\n"); printf(" -a, --all repack all databases\n"); printf(" -t, --table=TABLE repack specific table only\n"); + printf(" -c, --schema=SCHEMA repack specific schema only\n"); printf(" -s, --tablespace=TBLSPC move repacked tables to a new tablespace\n"); printf(" -S, --moveidx move repacked indexes to TBLSPC too\n"); printf(" -o, --order-by=COLUMNS order by columns instead of cluster keys\n"); From e16472419fddba01438d8cfc5838402d574bfaf9 Mon Sep 17 00:00:00 2001 From: Steeve Lennmark Date: Wed, 22 Jan 2014 14:55:07 +0100 Subject: [PATCH 2/6] Fix regression while refactoring patch --- bin/pg_repack.c | 1 + lib/pg_repack.sql.in | 1 + 2 files changed, 2 insertions(+) diff --git a/bin/pg_repack.c b/bin/pg_repack.c index 2ca5567..14eb640 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -658,6 +658,7 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize) table.target_oid = getoid(res, i, c++); table.target_toast = getoid(res, i, c++); table.target_tidx = getoid(res, i, c++); + c++; // Skip schemaname table.pkid = getoid(res, i, c++); table.ckid = getoid(res, i, c++); diff --git a/lib/pg_repack.sql.in b/lib/pg_repack.sql.in index eb42436..52bfaaa 100644 --- a/lib/pg_repack.sql.in +++ b/lib/pg_repack.sql.in @@ -173,6 +173,7 @@ CREATE VIEW repack.tables AS R.oid AS relid, R.reltoastrelid AS reltoastrelid, CASE WHEN R.reltoastrelid = 0 THEN 0 ELSE (SELECT reltoastidxid FROM pg_class WHERE oid = R.reltoastrelid) END AS reltoastidxid, + N.nspname AS schemaname, PK.indexrelid AS pkid, CK.indexrelid AS ckid, repack.get_create_index_type(PK.indexrelid, 'repack.pk_' || R.oid) AS create_pktype, From c2fa3a02effec05c62679d4a81df7a8c302c76b0 Mon Sep 17 00:00:00 2001 From: Steeve Lennmark Date: Fri, 24 Jan 2014 15:14:16 +0100 Subject: [PATCH 3/6] Add documentation for --schema --- doc/pg_repack.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/pg_repack.rst b/doc/pg_repack.rst index ccc4978..540749c 100644 --- a/doc/pg_repack.rst +++ b/doc/pg_repack.rst @@ -117,6 +117,7 @@ The following options can be specified in ``OPTIONS``. Options: -a, --all repack all databases -t, --table=TABLE repack specific table only + -c, --schema=SCHEMA repack specific schema only -s, --tablespace=TBLSPC move repacked tables to a new tablespace -S, --moveidx move repacked indexes to *TBLSPC* too -o, --order-by=COLUMNS order by columns instead of cluster keys @@ -154,6 +155,11 @@ Reorg Options reorganized by writing multiple ``-t`` switches. By default, all eligible tables in the target databases are reorganized. +``-c``, ``--schema`` + Repack the specified schema(s) only. Multiple schemas may be repacked + by writing multiple ``-c`` switches. May be used in conjunction with + ``--tablespace`` to move tables and indexes to a different tablespace. + ``-o COLUMNS [,...]``, ``--order-by=COLUMNS [,...]`` Perform an online CLUSTER ordered by the specified columns. @@ -443,6 +449,7 @@ Releases * Bugfix: correctly handle key indexes with options such as DESC, NULL FIRST/LAST, COLLATE (pg_repack issue #3). * More helpful program output and error messages. + * Added ``--schema`` to repack only specific schema. * pg_repack 1.1.8 From e7b6719256eacf11952c07f51312cb1a7879dd27 Mon Sep 17 00:00:00 2001 From: Steeve Lennmark Date: Thu, 30 Jan 2014 12:19:21 +0000 Subject: [PATCH 4/6] Add test for --schema (-c) --- regress/expected/repack.out | 9 +++++++++ regress/sql/repack.sql | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/regress/expected/repack.out b/regress/expected/repack.out index 18488bb..624fd70 100644 --- a/regress/expected/repack.out +++ b/regress/expected/repack.out @@ -352,3 +352,12 @@ CREATE TABLE trg4 (id integer PRIMARY KEY); CREATE TRIGGER zzzzzz AFTER UPDATE ON trg4 FOR EACH ROW EXECUTE PROCEDURE trgtest(); \! pg_repack --dbname=contrib_regression --table=trg4 INFO: repacking table "trg4" +-- +-- Repack single schema +-- +CREATE SCHEMA only_this_schema; +CREATE TABLE only_this_schema.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE only_this_schema.tbl2 (id INTEGER PRIMARY KEY); +\! pg_repack --dbname=contrib_regression --schema=only_this_schema +INFO: repacking table "only_this_schema.tbl1" +INFO: repacking table "only_this_schema.tbl2" diff --git a/regress/sql/repack.sql b/regress/sql/repack.sql index e460c2d..b55c5a8 100644 --- a/regress/sql/repack.sql +++ b/regress/sql/repack.sql @@ -206,3 +206,11 @@ CREATE TRIGGER z_repack_trigges BEFORE UPDATE ON trg3 FOR EACH ROW EXECUTE PROCE CREATE TABLE trg4 (id integer PRIMARY KEY); CREATE TRIGGER zzzzzz AFTER UPDATE ON trg4 FOR EACH ROW EXECUTE PROCEDURE trgtest(); \! pg_repack --dbname=contrib_regression --table=trg4 + +-- +-- Repack single schema +-- +CREATE SCHEMA only_this_schema; +CREATE TABLE only_this_schema.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE only_this_schema.tbl2 (id INTEGER PRIMARY KEY); +\! pg_repack --dbname=contrib_regression --schema=only_this_schema From 9b381f5b85469a7184fddeb434f84977ee2c145a Mon Sep 17 00:00:00 2001 From: Steeve Lennmark Date: Thu, 30 Jan 2014 12:27:32 +0000 Subject: [PATCH 5/6] Add second test that tests multiple --schema args --- regress/expected/repack.out | 23 +++++++++++++++++------ regress/sql/repack.sql | 16 ++++++++++++---- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/regress/expected/repack.out b/regress/expected/repack.out index 624fd70..2ca7b39 100644 --- a/regress/expected/repack.out +++ b/regress/expected/repack.out @@ -355,9 +355,20 @@ INFO: repacking table "trg4" -- -- Repack single schema -- -CREATE SCHEMA only_this_schema; -CREATE TABLE only_this_schema.tbl1 (id INTEGER PRIMARY KEY); -CREATE TABLE only_this_schema.tbl2 (id INTEGER PRIMARY KEY); -\! pg_repack --dbname=contrib_regression --schema=only_this_schema -INFO: repacking table "only_this_schema.tbl1" -INFO: repacking table "only_this_schema.tbl2" +CREATE SCHEMA test_schema1; +CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); +\! pg_repack --dbname=contrib_regression --schema=test_schema1 +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +-- +-- Repack two schemas +-- +CREATE SCHEMA test_schema2; +CREATE TABLE test_schema2.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema2.tbl2 (id INTEGER PRIMARY KEY); +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 +INFO: repacking table "test_schema2.tbl1" +INFO: repacking table "test_schema1.tbl1" +INFO: repacking table "test_schema1.tbl2" +INFO: repacking table "test_schema2.tbl2" diff --git a/regress/sql/repack.sql b/regress/sql/repack.sql index b55c5a8..875f50c 100644 --- a/regress/sql/repack.sql +++ b/regress/sql/repack.sql @@ -210,7 +210,15 @@ CREATE TRIGGER zzzzzz AFTER UPDATE ON trg4 FOR EACH ROW EXECUTE PROCEDURE trgtes -- -- Repack single schema -- -CREATE SCHEMA only_this_schema; -CREATE TABLE only_this_schema.tbl1 (id INTEGER PRIMARY KEY); -CREATE TABLE only_this_schema.tbl2 (id INTEGER PRIMARY KEY); -\! pg_repack --dbname=contrib_regression --schema=only_this_schema +CREATE SCHEMA test_schema1; +CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); +\! pg_repack --dbname=contrib_regression --schema=test_schema1 + +-- +-- Repack two schemas +-- +CREATE SCHEMA test_schema2; +CREATE TABLE test_schema2.tbl1 (id INTEGER PRIMARY KEY); +CREATE TABLE test_schema2.tbl2 (id INTEGER PRIMARY KEY); +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 From f094795178f2ee29e42cec4c7ef66cf5fcdd8c0a Mon Sep 17 00:00:00 2001 From: Steeve Lennmark Date: Fri, 31 Jan 2014 08:22:12 +0000 Subject: [PATCH 6/6] Clean up tests and fix regression It was possible to specify both --schema and --table which probably -should- be legal but would need some code to be rewritten. This patch adds a check that both can't be specified and returns an error telling the user to use schema.table notation instead. A regression test checking this behaviour was added. --- bin/pg_repack.c | 5 +++++ regress/expected/repack.out | 23 ++++++++++++++--------- regress/sql/repack.sql | 14 ++++++++------ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/bin/pg_repack.c b/bin/pg_repack.c index 14eb640..34337a6 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -305,6 +305,11 @@ main(int argc, char *argv[]) } else { + if (schema_list.head && table_list.head) + ereport(ERROR, + (errcode(EINVAL), + errmsg("cannot repack specific table(s) in schema, use schema.table notation instead"))); + if (noorder) orderby = ""; diff --git a/regress/expected/repack.out b/regress/expected/repack.out index 2ca7b39..e282fb5 100644 --- a/regress/expected/repack.out +++ b/regress/expected/repack.out @@ -353,22 +353,27 @@ CREATE TRIGGER zzzzzz AFTER UPDATE ON trg4 FOR EACH ROW EXECUTE PROCEDURE trgtes \! pg_repack --dbname=contrib_regression --table=trg4 INFO: repacking table "trg4" -- --- Repack single schema +-- Test --schema -- CREATE SCHEMA test_schema1; CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); -\! pg_repack --dbname=contrib_regression --schema=test_schema1 -INFO: repacking table "test_schema1.tbl1" -INFO: repacking table "test_schema1.tbl2" --- --- Repack two schemas --- CREATE SCHEMA test_schema2; CREATE TABLE test_schema2.tbl1 (id INTEGER PRIMARY KEY); CREATE TABLE test_schema2.tbl2 (id INTEGER PRIMARY KEY); -\! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 -INFO: repacking table "test_schema2.tbl1" +-- => 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_schema2.tbl1" INFO: repacking table "test_schema2.tbl2" +INFO: repacking table "test_schema1.tbl2" +INFO: repacking table "test_schema1.tbl1" +-- => 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 diff --git a/regress/sql/repack.sql b/regress/sql/repack.sql index 875f50c..88500ea 100644 --- a/regress/sql/repack.sql +++ b/regress/sql/repack.sql @@ -208,17 +208,19 @@ CREATE TRIGGER zzzzzz AFTER UPDATE ON trg4 FOR EACH ROW EXECUTE PROCEDURE trgtes \! pg_repack --dbname=contrib_regression --table=trg4 -- --- Repack single schema +-- Test --schema -- CREATE SCHEMA test_schema1; CREATE TABLE test_schema1.tbl1 (id INTEGER PRIMARY KEY); CREATE TABLE test_schema1.tbl2 (id INTEGER PRIMARY KEY); -\! pg_repack --dbname=contrib_regression --schema=test_schema1 - --- --- Repack two schemas --- 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 +-- => OK \! pg_repack --dbname=contrib_regression --schema=test_schema1 --schema=test_schema2 +-- => ERROR +\! pg_repack --dbname=contrib_regression --schema=test_schema1 --table=tbl1 +-- => ERROR +\! pg_repack --dbname=contrib_regression --all --schema=test_schema1