From 68dc5925458b414ae6242cf71a11152507f13f09 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Mon, 20 Mar 2017 23:04:41 +0300 Subject: [PATCH 01/12] introduce option --parent-table (-I, stands for 'inheritance'), fix function repack_one_database(), introduce function repack.get_table_and_inheritors() --- bin/pg_repack.c | 69 +++++++++++++++++++++++++++++++++----------- lib/exports.txt | 40 +++++++++++++------------ lib/pg_repack.sql.in | 5 ++++ lib/repack.c | 41 ++++++++++++++++++++++++-- 4 files changed, 117 insertions(+), 38 deletions(-) diff --git a/bin/pg_repack.c b/bin/pg_repack.c index 36ceed8..db7aa01 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -109,7 +109,7 @@ const char *PROGRAM_VERSION = "unknown"; */ #define SQL_XID_SNAPSHOT_80300 \ "SELECT repack.array_accum(l.virtualtransaction) " \ - " FROM pg_locks AS l" \ + " FROM pg_locks AS l" \ " LEFT JOIN pg_stat_activity AS a " \ " ON l.pid = a.procpid " \ " LEFT JOIN pg_database AS d " \ @@ -174,7 +174,7 @@ typedef struct repack_index { Oid target_oid; /* target: OID */ const char *create_index; /* CREATE INDEX */ - index_status_t status; /* Track parallel build statuses. */ + index_status_t status; /* Track parallel build statuses. */ int worker_idx; /* which worker conn is handling */ } repack_index; @@ -238,6 +238,7 @@ static bool sqlstate_equals(PGresult *res, const char *state) static bool analyze = true; static bool alldb = false; static bool noorder = false; +static SimpleStringList parent_table_list = {NULL, NULL}; static SimpleStringList table_list = {NULL, NULL}; static SimpleStringList schema_list = {NULL, NULL}; static char *orderby = NULL; @@ -265,6 +266,7 @@ static pgut_option options[] = { { 'b', 'a', "all", &alldb }, { 'l', 't', "table", &table_list }, + { 'l', 'I', "parent-table", &parent_table_list }, { 'l', 'c', "schema", &schema_list }, { 'b', 'n', "no-order", &noorder }, { 'b', 'N', "dry-run", &dryrun }, @@ -306,12 +308,16 @@ main(int argc, char *argv[]) if (r_index.head && table_list.head) ereport(ERROR, (errcode(EINVAL), errmsg("cannot specify --index (-i) and --table (-t)"))); + if (r_index.head && parent_table_list.head) + ereport(ERROR, (errcode(EINVAL), + errmsg("cannot specify --index (-i) and --parent-table (-P)"))); else if (r_index.head && only_indexes) ereport(ERROR, (errcode(EINVAL), errmsg("cannot specify --index (-i) and --only-indexes (-x)"))); - else if (only_indexes && !table_list.head) + else if (only_indexes && !(table_list.head || parent_table_list.head)) ereport(ERROR, (errcode(EINVAL), - errmsg("cannot repack all indexes of database, specify the table(s) via --table (-t)"))); + errmsg("cannot repack all indexes of database, specify the table(s)" + "via --table (-t) or --parent-table (-P)"))); else if (alldb) ereport(ERROR, (errcode(EINVAL), errmsg("cannot repack specific index(es) in all databases"))); @@ -336,7 +342,7 @@ main(int argc, char *argv[]) } else { - if (schema_list.head && table_list.head) + if (schema_list.head && (table_list.head || parent_table_list.head)) ereport(ERROR, (errcode(EINVAL), errmsg("cannot repack specific table(s) in schema, use schema.table notation instead"))); @@ -346,7 +352,7 @@ main(int argc, char *argv[]) if (alldb) { - if (table_list.head) + if (table_list.head || parent_table_list.head) ereport(ERROR, (errcode(EINVAL), errmsg("cannot repack specific table(s) in all databases"))); @@ -602,15 +608,17 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize) SimpleStringListCell *cell; const char **params = NULL; int iparam = 0; + size_t num_parent_tables; size_t num_tables; size_t num_schemas; size_t num_params; + num_parent_tables = simple_string_list_size(parent_table_list); 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 + num_schemas + 1; + num_params = num_parent_tables + num_tables + num_schemas + 1; params = pgut_malloc(num_params * sizeof(char *)); initStringInfo(&sql); @@ -633,18 +641,42 @@ repack_one_database(const char *orderby, char *errbuf, size_t errsize) " WHERE "); params[iparam++] = tablespace; - if (num_tables) + if (num_tables || num_parent_tables) { - appendStringInfoString(&sql, "("); - for (cell = table_list.head; cell; cell = cell->next) + /* standalone tables */ + if (num_tables) { - /* Construct table name placeholders to be used by PQexecParams */ - appendStringInfo(&sql, "relid = $%d::regclass", iparam + 1); - params[iparam++] = cell->val; - if (cell->next) - appendStringInfoString(&sql, " OR "); + appendStringInfoString(&sql, "("); + for (cell = table_list.head; cell; cell = cell->next) + { + /* Construct table name placeholders to be used by PQexecParams */ + appendStringInfo(&sql, "relid = $%d::regclass", iparam + 1); + params[iparam++] = cell->val; + if (cell->next) + appendStringInfoString(&sql, " OR "); + } + appendStringInfoString(&sql, ")"); + } + + if (num_tables && num_parent_tables) + appendStringInfoString(&sql, " OR "); + + /* parent tables + inherited children */ + if (num_parent_tables) + { + appendStringInfoString(&sql, "("); + for (cell = parent_table_list.head; cell; cell = cell->next) + { + /* Construct table name placeholders to be used by PQexecParams */ + appendStringInfo(&sql, + "relid = ANY(repack.get_table_and_inheritors($%d::regclass))", + iparam + 1); + params[iparam++] = cell->val; + if (cell->next) + appendStringInfoString(&sql, " OR "); + } + appendStringInfoString(&sql, ")"); } - appendStringInfoString(&sql, ")"); } else if (num_schemas) { @@ -2008,7 +2040,7 @@ repack_all_indexes(char *errbuf, size_t errsize) initStringInfo(&sql); reconnect(ERROR); - assert(r_index.head || table_list.head); + assert(r_index.head || table_list.head || parent_table_list.head); if (!preliminary_checks(errbuf, errsize)) goto cleanup; @@ -2023,6 +2055,8 @@ repack_all_indexes(char *errbuf, size_t errsize) cell = r_index.head; } + + /* TODO: fix this also for parent_table_list */ else if (table_list.head) { appendStringInfoString(&sql, @@ -2087,6 +2121,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(" -I, --parent-table=TABLE repack specific parent table and its inheritors\n"); printf(" -c, --schema=SCHEMA repack tables in 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"); diff --git a/lib/exports.txt b/lib/exports.txt index ebc1092..b3bd953 100644 --- a/lib/exports.txt +++ b/lib/exports.txt @@ -1,19 +1,21 @@ -Pg_magic_func 1 -pg_finfo_repack_apply 2 -pg_finfo_repack_disable_autovacuum 3 -pg_finfo_repack_drop 4 -pg_finfo_repack_get_order_by 5 -pg_finfo_repack_indexdef 6 -pg_finfo_repack_swap 7 -pg_finfo_repack_trigger 8 -pg_finfo_repack_version 9 -pg_finfo_repack_index_swap 10 -repack_apply 11 -repack_disable_autovacuum 12 -repack_drop 13 -repack_get_order_by 14 -repack_indexdef 15 -repack_swap 16 -repack_trigger 17 -repack_version 18 -repack_index_swap 19 +Pg_magic_func 1 +pg_finfo_repack_apply 2 +pg_finfo_repack_disable_autovacuum 3 +pg_finfo_repack_drop 4 +pg_finfo_repack_get_order_by 5 +pg_finfo_repack_indexdef 6 +pg_finfo_repack_swap 7 +pg_finfo_repack_trigger 8 +pg_finfo_repack_version 9 +pg_finfo_repack_index_swap 10 +pg_finfo_repack_get_table_and_inheritors 11 +repack_apply 12 +repack_disable_autovacuum 13 +repack_drop 14 +repack_get_order_by 15 +repack_indexdef 16 +repack_swap 17 +repack_trigger 18 +repack_version 19 +repack_index_swap 20 +repack_get_table_and_inheritors 21 diff --git a/lib/pg_repack.sql.in b/lib/pg_repack.sql.in index d294548..13c95f5 100644 --- a/lib/pg_repack.sql.in +++ b/lib/pg_repack.sql.in @@ -254,3 +254,8 @@ LANGUAGE C VOLATILE STRICT; CREATE FUNCTION repack.repack_index_swap(oid) RETURNS void AS 'MODULE_PATHNAME', 'repack_index_swap' LANGUAGE C STABLE STRICT; + +CREATE FUNCTION repack.get_table_and_inheritors(regclass) RETURNS regclass[] AS +'MODULE_PATHNAME', 'repack_get_table_and_inheritors' +LANGUAGE C STABLE STRICT; + diff --git a/lib/repack.c b/lib/repack.c index 4e6711b..2355fe4 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -25,12 +25,14 @@ #include "catalog/pg_am.h" #endif +#include "catalog/pg_inherits_fn.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_type.h" #include "commands/tablecmds.h" #include "commands/trigger.h" #include "miscadmin.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -61,6 +63,7 @@ extern Datum PGUT_EXPORT repack_swap(PG_FUNCTION_ARGS); extern Datum PGUT_EXPORT repack_drop(PG_FUNCTION_ARGS); extern Datum PGUT_EXPORT repack_disable_autovacuum(PG_FUNCTION_ARGS); extern Datum PGUT_EXPORT repack_index_swap(PG_FUNCTION_ARGS); +extern Datum PGUT_EXPORT repack_get_table_and_inheritors(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(repack_version); PG_FUNCTION_INFO_V1(repack_trigger); @@ -71,6 +74,7 @@ PG_FUNCTION_INFO_V1(repack_swap); PG_FUNCTION_INFO_V1(repack_drop); PG_FUNCTION_INFO_V1(repack_disable_autovacuum); PG_FUNCTION_INFO_V1(repack_index_swap); +PG_FUNCTION_INFO_V1(repack_get_table_and_inheritors); static void repack_init(void); static SPIPlanPtr repack_prepare(const char *src, int nargs, Oid *argtypes); @@ -312,9 +316,9 @@ repack_apply(PG_FUNCTION_ARGS) * can delete all the rows we have processed at-once. */ if (i == 0) - appendStringInfoString(&sql_pop, pkid); + appendStringInfoString(&sql_pop, pkid); else - appendStringInfo(&sql_pop, ",%s", pkid); + appendStringInfo(&sql_pop, ",%s", pkid); pfree(pkid); } /* i must be > 0 (and hence we must have some rows to delete) @@ -1342,3 +1346,36 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId) PG_END_TRY(); } #endif + +Datum +repack_get_table_and_inheritors(PG_FUNCTION_ARGS) +{ + Oid parent = PG_GETARG_OID(0); + List *relations; + Datum *relations_array; + int relations_array_size; + ArrayType *result; + ListCell *lc; + int i; + + relations = find_all_inheritors(parent, NoLock, NULL); + + relations_array_size = list_length(relations); + if (relations_array_size == 0) + PG_RETURN_ARRAYTYPE_P(construct_empty_array(OIDOID)); + + relations_array = palloc(relations_array_size * sizeof(Datum)); + + i = 0; + foreach (lc, relations) + relations_array[i++] = ObjectIdGetDatum(lfirst_oid(lc)); + + result = construct_array(relations_array, + relations_array_size, + OIDOID, sizeof(Oid), + true, 'i'); + + pfree(relations_array); + + PG_RETURN_ARRAYTYPE_P(result); +} From 0e3ed0d5e141b74cbfe512b61fc24843a28146eb Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 22 Mar 2017 14:15:48 +0300 Subject: [PATCH 02/12] fix typos and formatting, implement -I in repack_all_indexes() --- bin/pg_repack.c | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/bin/pg_repack.c b/bin/pg_repack.c index db7aa01..2ef677e 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -310,14 +310,14 @@ main(int argc, char *argv[]) errmsg("cannot specify --index (-i) and --table (-t)"))); if (r_index.head && parent_table_list.head) ereport(ERROR, (errcode(EINVAL), - errmsg("cannot specify --index (-i) and --parent-table (-P)"))); + errmsg("cannot specify --index (-i) and --parent-table (-I)"))); else if (r_index.head && only_indexes) ereport(ERROR, (errcode(EINVAL), errmsg("cannot specify --index (-i) and --only-indexes (-x)"))); else if (only_indexes && !(table_list.head || parent_table_list.head)) ereport(ERROR, (errcode(EINVAL), errmsg("cannot repack all indexes of database, specify the table(s)" - "via --table (-t) or --parent-table (-P)"))); + "via --table (-t) or --parent-table (-I)"))); else if (alldb) ereport(ERROR, (errcode(EINVAL), errmsg("cannot repack specific index(es) in all databases"))); @@ -2032,7 +2032,7 @@ static bool repack_all_indexes(char *errbuf, size_t errsize) { bool ret = false; - PGresult *res = NULL; + PGresult *res = NULL; StringInfoData sql; SimpleStringListCell *cell = NULL; const char *params[1]; @@ -2055,9 +2055,7 @@ repack_all_indexes(char *errbuf, size_t errsize) cell = r_index.head; } - - /* TODO: fix this also for parent_table_list */ - else if (table_list.head) + else if (table_list.head || parent_table_list.head) { appendStringInfoString(&sql, "SELECT i.relname, idx.indexrelid, idx.indisvalid, idx.indrelid, $1::text, n.nspname" @@ -2065,6 +2063,39 @@ repack_all_indexes(char *errbuf, size_t errsize) " JOIN pg_namespace n ON n.oid = i.relnamespace" " WHERE idx.indrelid = $1::regclass ORDER BY indisvalid DESC, i.relname, n.nspname"); + for (cell = parent_table_list.head; cell; cell = cell->next) + { + int nchildren, i; + + params[0] = cell->val; + + /* find children of this parent table */ + res = execute_elevel("SELECT quote_ident(n.nspname) || '.' || quote_ident(c.relname)" + " FROM pg_class c JOIN pg_namespace n on n.oid = c.relnamespace" + " WHERE c.oid = ANY (repack.get_table_and_inheritors($1::regclass))" + " ORDER BY n.nspname, c.relname", 1, params, DEBUG2); + + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + elog(WARNING, "%s", PQerrorMessage(connection)); + continue; + } + + nchildren = PQntuples(res); + + if (nchildren == 0) + { + elog(WARNING, "relation \"%s\" does not exist", cell->val); + continue; + } + + /* append new tables to 'table_list' */ + for (i = 0; i < nchildren; i++) + simple_string_list_append(&table_list, getstr(res, i, 0)); + } + + CLEARPGRES(res); + cell = table_list.head; } @@ -2102,7 +2133,6 @@ repack_all_indexes(char *errbuf, size_t errsize) ret = true; cleanup: - CLEARPGRES(res); disconnect(); termStringInfo(&sql); return ret; From 6a51ed209d8e6c7b72f97cd8e7b56e80c73828d1 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 22 Mar 2017 15:04:27 +0300 Subject: [PATCH 03/12] add regression tests for '--parent-table' option --- regress/expected/repack.out | 59 +++++++++++++++++++++++++++++++++++++ regress/sql/repack.sql | 27 +++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/regress/expected/repack.out b/regress/expected/repack.out index 17e3666..1f9de83 100644 --- a/regress/expected/repack.out +++ b/regress/expected/repack.out @@ -403,3 +403,62 @@ 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; +-- +-- table inheritance check +-- +CREATE TABLE parent_a(val integer primary key); +CREATE TABLE child_a_1(val integer primary key) INHERITS(parent_a); +CREATE TABLE child_a_2(val integer primary key) INHERITS(parent_a); +CREATE TABLE parent_b(val integer primary key); +CREATE TABLE child_b_1(val integer primary key) INHERITS(parent_b); +CREATE TABLE child_b_2(val integer primary key) INHERITS(parent_b); +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table +ERROR: pg_repack failed with error: ERROR: relation "dummy_table" does not exist +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_index --index=dummy_index +ERROR: cannot specify --index (-i) and --parent-table (-I) +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --schema=dummy_schema +ERROR: cannot repack specific table(s) in schema, use schema.table notation instead +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --all +ERROR: cannot repack specific table(s) in all databases +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b +INFO: repacking table "parent_a" +INFO: repacking table "child_a_1" +INFO: repacking table "child_a_2" +INFO: repacking table "parent_b" +INFO: repacking table "child_b_1" +INFO: repacking table "child_b_2" +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b --only-indexes +INFO: repacking indexes of "public.child_a_1" +INFO: repacking index "public"."child_a_1_pkey" +INFO: repacking indexes of "public.child_a_2" +INFO: repacking index "public"."child_a_2_pkey" +INFO: repacking indexes of "public.parent_a" +INFO: repacking index "public"."parent_a_pkey" +INFO: repacking indexes of "public.child_b_1" +INFO: repacking index "public"."child_b_1_pkey" +INFO: repacking indexes of "public.child_b_2" +INFO: repacking index "public"."child_b_2_pkey" +INFO: repacking indexes of "public.parent_b" +INFO: repacking index "public"."parent_b_pkey" diff --git a/regress/sql/repack.sql b/regress/sql/repack.sql index e613d63..91f64ce 100644 --- a/regress/sql/repack.sql +++ b/regress/sql/repack.sql @@ -245,3 +245,30 @@ CREATE ROLE nosuper WITH LOGIN; -- => ERROR \! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check DROP ROLE IF EXISTS nosuper; + +-- +-- 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 --dbname=contrib_regression --parent-table=dummy_index --index=dummy_index +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --schema=dummy_schema +-- => ERROR +\! pg_repack --dbname=contrib_regression --parent-table=dummy_table --all +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b +-- => OK +\! pg_repack --dbname=contrib_regression --table=parent_a --parent-table=parent_b --only-indexes +-- => OK +\! pg_repack --dbname=contrib_regression --parent-table=parent_a --parent-table=parent_b --only-indexes + From 698d1ddfdd61e977074c57ff6918ff7c8eb7c471 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 22 Mar 2017 16:32:11 +0300 Subject: [PATCH 04/12] update docs --- doc/pg_repack.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/pg_repack.rst b/doc/pg_repack.rst index 2205cbb..04b8304 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 + -I, --parent-table=TABLE repack specific parent table and its inheritors -c, --schema=SCHEMA repack tables in specific schema only -s, --tablespace=TBLSPC move repacked tables to a new tablespace -S, --moveidx move repacked indexes to *TBLSPC* too @@ -158,6 +159,10 @@ Reorg Options reorganized by writing multiple ``-t`` switches. By default, all eligible tables in the target databases are reorganized. +``-I TABLE``, ``--parent-table=TABLE`` + Reorganize both the specified table(s) and its inheritors. Multiple + table hierarchies may be reorganized by writing multiple ``-I`` switches. + ``-c``, ``--schema`` Repack the tables in the specified schema(s) only. Multiple schemas may be repacked by writing multiple ``-c`` switches. May be used in @@ -197,7 +202,7 @@ Reorg Options ``-x``, ``--only-indexes`` Repack only the indexes of the specified table(s), which must be specified - with the ``--table`` option. + with the ``--table`` or ``--parent-table`` options. ``-T SECS``, ``--wait-timeout=SECS`` pg_repack needs to take an exclusive lock at the end of the @@ -227,7 +232,7 @@ Connection Options ^^^^^^^^^^^^^^^^^^ Options to connect to servers. You cannot use ``--all`` and ``--dbname`` or -``--table`` together. +``--table``/``--parent-table`` together. ``-a``, ``--all`` Reorganize all databases. From 5507a57d050f2b31a6707ee429d6cc59b0e1705a Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 22 Mar 2017 16:34:08 +0300 Subject: [PATCH 05/12] improve docs --- doc/pg_repack.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pg_repack.rst b/doc/pg_repack.rst index 04b8304..75f94dc 100644 --- a/doc/pg_repack.rst +++ b/doc/pg_repack.rst @@ -232,7 +232,7 @@ Connection Options ^^^^^^^^^^^^^^^^^^ Options to connect to servers. You cannot use ``--all`` and ``--dbname`` or -``--table``/``--parent-table`` together. +``--table`` or ``--parent-table`` together. ``-a``, ``--all`` Reorganize all databases. From 839aec7e710ae19c407c31d4e3ab9780ecd78507 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Fri, 24 Mar 2017 16:56:27 +0300 Subject: [PATCH 06/12] remove blank line --- lib/pg_repack.sql.in | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pg_repack.sql.in b/lib/pg_repack.sql.in index 13c95f5..46bacf4 100644 --- a/lib/pg_repack.sql.in +++ b/lib/pg_repack.sql.in @@ -258,4 +258,3 @@ LANGUAGE C STABLE STRICT; CREATE FUNCTION repack.get_table_and_inheritors(regclass) RETURNS regclass[] AS 'MODULE_PATHNAME', 'repack_get_table_and_inheritors' LANGUAGE C STABLE STRICT; - From 6d8ff6ba19e6285e8375716fe1bc064bbffd0e9d Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Fri, 24 Mar 2017 17:01:09 +0300 Subject: [PATCH 07/12] extend safety checks for -I --- bin/pg_repack.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/pg_repack.c b/bin/pg_repack.c index ac3da3e..36ac0b8 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -360,6 +360,11 @@ main(int argc, char *argv[]) (errcode(EINVAL), errmsg("cannot specify --table (-t) and --exclude-extension (-C)"))); + if (exclude_extension_list.head && parent_table_list.head) + ereport(ERROR, + (errcode(EINVAL), + errmsg("cannot specify --parent-table (-I) and --exclude-extension (-C)"))); + if (noorder) orderby = ""; From 48c42e1a87fc79c8677399f29ff8de4fffd05cdd Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Thu, 30 Mar 2017 14:09:59 +0300 Subject: [PATCH 08/12] fix regression tests for PostgreSQL <= 9.4 --- regress/expected/repack_3.out | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/regress/expected/repack_3.out b/regress/expected/repack_3.out index f800f07..6f95cd6 100644 --- a/regress/expected/repack_3.out +++ b/regress/expected/repack_3.out @@ -421,3 +421,62 @@ 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" From 7dca19d7e08a8c6b9ca69b0f59a0a31d00c31222 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 19 Apr 2017 14:09:30 +0300 Subject: [PATCH 09/12] add docs for repack_get_table_and_inheritors() --- lib/repack.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/repack.c b/lib/repack.c index a97b723..930fd56 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -1294,6 +1294,15 @@ repack_index_swap(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +/** + * @fn Datum get_table_and_inheritors(PG_FUNCTION_ARGS) + * @brief Return array containing Oids of parent table and its children. + * + * get_table_and_inheritors(table) + * + * @param table parent table. + * @retval regclass[] + */ Datum repack_get_table_and_inheritors(PG_FUNCTION_ARGS) { From 4df065891cc74a067df6920895d3692557405519 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 19 Apr 2017 14:14:26 +0300 Subject: [PATCH 10/12] add missing results to repack_1.out --- regress/expected/repack_1.out | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/regress/expected/repack_1.out b/regress/expected/repack_1.out index a7bbe2f..98360ee 100644 --- a/regress/expected/repack_1.out +++ b/regress/expected/repack_1.out @@ -472,3 +472,62 @@ 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" From 0901b82588a899a53665d2d6148ea6f14602c111 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 23 Apr 2017 21:22:54 +0300 Subject: [PATCH 11/12] acquire AccessShareLock on parent and children in repack_get_table_and_inheritors() --- lib/repack.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/repack.c b/lib/repack.c index 930fd56..073969c 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -32,6 +32,7 @@ #include "commands/tablecmds.h" #include "commands/trigger.h" #include "miscadmin.h" +#include "storage/lmgr.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -1314,7 +1315,14 @@ repack_get_table_and_inheritors(PG_FUNCTION_ARGS) ListCell *lc; int i; - relations = find_all_inheritors(parent, NoLock, NULL); + LockRelationOid(parent, AccessShareLock); + + /* Check that parent table exists */ + if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(parent))) + PG_RETURN_ARRAYTYPE_P(construct_empty_array(OIDOID)); + + /* Also check that children exist */ + relations = find_all_inheritors(parent, AccessShareLock, NULL); relations_array_size = list_length(relations); if (relations_array_size == 0) From 94679ee83a9d93f4d592d4da9635bf197962c960 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Mon, 24 Apr 2017 13:26:28 +0300 Subject: [PATCH 12/12] add a comment regarding AccessShareLocks in repack_get_table_and_inheritors() --- lib/repack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/repack.c b/lib/repack.c index 073969c..6ba7535 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -1298,6 +1298,7 @@ repack_index_swap(PG_FUNCTION_ARGS) /** * @fn Datum get_table_and_inheritors(PG_FUNCTION_ARGS) * @brief Return array containing Oids of parent table and its children. + * Note that this function does not release relation locks. * * get_table_and_inheritors(table) *