Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
fail-fast: false
matrix:
pg_version: ["11", "12", "13", "14", "15", "16", "17", "18"]
from_version: ["2.2", "2.3"]
from_version: ["2.3", "2.4"]
steps:
- uses: actions/checkout@v6
- name: Remove default PostgreSQL
Expand Down
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,19 @@ DATA = pgl_ddl_deploy--1.0.sql pgl_ddl_deploy--1.0--1.1.sql \
pgl_ddl_deploy--2.0.sql pgl_ddl_deploy--2.0--2.1.sql \
pgl_ddl_deploy--2.1.sql pgl_ddl_deploy--2.1--2.2.sql \
pgl_ddl_deploy--2.2.sql pgl_ddl_deploy--2.2--2.3.sql \
pgl_ddl_deploy--2.3.sql
MODULES = pgl_ddl_deploy ddl_deparse
pgl_ddl_deploy--2.3.sql pgl_ddl_deploy--2.3--2.4.sql \
pgl_ddl_deploy--2.4.sql
MODULES = ddl_deparse
MODULE_big = pgl_ddl_deploy
OBJS = postgres_deparse.11.o \
postgres_deparse.12.o \
postgres_deparse.13.o \
postgres_deparse.14.o \
postgres_deparse.15.o \
postgres_deparse.16.o \
postgres_deparse.17.o \
postgres_deparse.18.o \
pgl_ddl_deploy.o

REGRESS := 01_create_ext 02_setup 03_add_configs 04_deploy 04_deploy_update \
05_allowed 06_multi 07_edges 08_ignored \
Expand Down Expand Up @@ -52,7 +63,8 @@ REGRESS := 01_create_ext 02_setup 03_add_configs 04_deploy 04_deploy_update \
54_new_setup \
55_raise_message \
56_1_6_features \
57_native_features
57_2_4_features \
99_native_features
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ https://innovation.enova.com/pursuing-postgres-ddl-replication/

# <a name="release_notes"></a>Release Notes

### Release 2.3
### Release 2.4
Summary of changes:
* Support for Postgres 17 & 18
* Support for replicating index DDL
* Prevent DDL that internally touches toast tables from being silently dropped

### Release 2.2
Summary of changes:
Expand Down Expand Up @@ -356,6 +357,11 @@ SQL statement with a single node `parsetree`) will be eligible for propagation.
be maintained by DDL replication. Thus only `ALTER TABLE`
statements are permitted here. This option is incompatible with
`include_schema_regex`.
- `include_indexes`: if true, will replicate `CREATE INDEX`/`ALTER INDEX`/`DROP INDEX`
statements. This can be undesirable if the replica is intended to have different
configuration from the primary. Also, indexes cannot be created with `CREATE INDEX CONCURRENTLY`
and will therefore potentially block operations on the table, which can be problematic
if the replica is in active read usage.
- `queue_subscriber_failures`: if true, DDL will be allowed to fail on subscriber
without breaking replication, and queued for retry using function
`pgl_ddl_deploy.retry_all_subscriber_logs()`. This is useful for example if you
Expand Down
12 changes: 6 additions & 6 deletions ddl_deparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ get_altertable_subcmdinfo(PG_FUNCTION_ARGS)
strtype = "ADD OIDS";
break;
case AT_AddOidsRecurse:
strtype = "ADD OIDS (and recurse)";
strtype = "ADD OIDS";
break;
#endif
#if PG_VERSION_NUM >= 120000 && PG_VERSION_NUM < 180000
Expand All @@ -119,19 +119,19 @@ get_altertable_subcmdinfo(PG_FUNCTION_ARGS)
#endif
#if PG_VERSION_NUM < 160000
case AT_AddColumnRecurse:
strtype = "ADD COLUMN (and recurse)";
strtype = "ADD COLUMN";
break;
case AT_DropColumnRecurse:
strtype = "DROP COLUMN (and recurse)";
strtype = "DROP COLUMN";
break;
case AT_AddConstraintRecurse:
strtype = "ADD CONSTRAINT (and recurse)";
strtype = "ADD CONSTRAINT";
break;
case AT_ValidateConstraintRecurse:
strtype = "VALIDATE CONSTRAINT (and recurse)";
strtype = "VALIDATE CONSTRAINT";
break;
case AT_DropConstraintRecurse:
strtype = "DROP CONSTRAINT (and recurse)";
strtype = "DROP CONSTRAINT";
break;
#endif
#if PG_VERSION_NUM >= 170000
Expand Down
7 changes: 7 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
pgl-ddl-deploy (2.4.0-1) unstable; urgency=medium

* Support for replicating index DDL
* Prevent DDL that internally touches toast tables from being silently dropped

-- Jacob Burroughs <jburroughs@instructure.com> Wed, 17 Jun 2026 13:12:22 -0500

pgl-ddl-deploy (2.3.0-1) unstable; urgency=medium

* Support for Postgres 16
Expand Down
528 changes: 264 additions & 264 deletions expected/05_allowed.out

Large diffs are not rendered by default.

72 changes: 36 additions & 36 deletions expected/06_multi.out
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ WARNING: Unhandled deployment logged in pgl_ddl_deploy.unhandled
WARNING: Unhandled deployment logged in pgl_ddl_deploy.unhandled
DROP TABLE
SELECT set_name, ddl_sql_raw, ddl_sql_sent FROM pgl_ddl_deploy.events ORDER BY id DESC LIMIT 10;
set_name | ddl_sql_raw | ddl_sql_sent
----------+-----------------------------+-----------------------------
test8 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test7 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test6 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test5 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test4 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test3 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test2 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test1 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test8 | DROP SCHEMA foobar CASCADE; | DROP SCHEMA foobar CASCADE;
test7 | DROP SCHEMA foobar CASCADE; | DROP SCHEMA foobar CASCADE;
set_name | ddl_sql_raw | ddl_sql_sent
----------+---------------------------+---------------------------
test8 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test7 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test6 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test5 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test4 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test3 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test2 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test1 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test8 | DROP SEQUENCE foobar.foo; | DROP SEQUENCE foobar.foo;
test7 | DROP SEQUENCE foobar.foo; | DROP SEQUENCE foobar.foo;
(10 rows)

SELECT set_name, ddl_sql_raw, command_tag, reason FROM pgl_ddl_deploy.unhandled ORDER BY id DESC LIMIT 10;
Expand Down Expand Up @@ -60,14 +60,14 @@ WARNING: Unhandled deployment logged in pgl_ddl_deploy.unhandled
WARNING: Unhandled deployment logged in pgl_ddl_deploy.unhandled
COMMIT
SELECT set_name, ddl_sql_raw, ddl_sql_sent FROM pgl_ddl_deploy.events ORDER BY id DESC LIMIT 10;
set_name | ddl_sql_raw | ddl_sql_sent
----------+-------------------------------------------------------------+------------------------------------------------
test7 | BEGIN; CREATE TABLE foobar.foo(id int primary key); COMMIT; | CREATE TABLE foobar.foo(id int primary key);
test5 | BEGIN; CREATE TABLE foobar.foo(id int primary key); COMMIT; | CREATE TABLE foobar.foo(id int primary key);
test3 | BEGIN; CREATE TABLE foobar.foo(id int primary key); COMMIT; | CREATE TABLE foobar.foo(id int primary key);
test1 | BEGIN; CREATE TABLE foobar.foo(id int primary key); COMMIT; | CREATE TABLE foobar.foo(id int primary key);
test3 | BEGIN; CREATE TABLE foo(id int primary key); COMMIT; | CREATE TABLE foo(id int primary key);
test1 | BEGIN; CREATE TABLE foo(id int primary key); COMMIT; | CREATE TABLE foo(id int primary key);
set_name | ddl_sql_raw | ddl_sql_sent
----------+-------------------------------------------------------------+-----------------------------------------------
test7 | BEGIN; CREATE TABLE foobar.foo(id int primary key); COMMIT; | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test5 | BEGIN; CREATE TABLE foobar.foo(id int primary key); COMMIT; | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test3 | BEGIN; CREATE TABLE foobar.foo(id int primary key); COMMIT; | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test1 | BEGIN; CREATE TABLE foobar.foo(id int primary key); COMMIT; | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test3 | BEGIN; CREATE TABLE foo(id int primary key); COMMIT; | CREATE TABLE foo (id int PRIMARY KEY);
test1 | BEGIN; CREATE TABLE foo(id int primary key); COMMIT; | CREATE TABLE foo (id int PRIMARY KEY);
test8 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test7 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
test6 | CREATE SCHEMA foobar; | CREATE SCHEMA foobar;
Expand Down Expand Up @@ -106,14 +106,14 @@ WARNING: Unhandled deployment logged in pgl_ddl_deploy.unhandled
WARNING: Unhandled deployment logged in pgl_ddl_deploy.unhandled
DROP TABLE
SELECT set_name, ddl_sql_raw, ddl_sql_sent FROM pgl_ddl_deploy.events ORDER BY id DESC LIMIT 10;
set_name | ddl_sql_raw | ddl_sql_sent
----------+-----------------------------------------------------------------------------+-----------------------------------------------------------------------------
test7 | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE; | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE;
test5 | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE; | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE;
test3 | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE; | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE;
test1 | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE; | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE;
test3 | CREATE TABLE foo(id int primary key); DROP TABLE foo CASCADE; | CREATE TABLE foo(id int primary key); DROP TABLE foo CASCADE;
test1 | CREATE TABLE foo(id int primary key); DROP TABLE foo CASCADE; | CREATE TABLE foo(id int primary key); DROP TABLE foo CASCADE;
set_name | ddl_sql_raw | ddl_sql_sent
----------+-----------------------------------------------------------------------------+------------------------------------------------------------------------------
test7 | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE; | CREATE TABLE foobar.foo (id int PRIMARY KEY); DROP TABLE foobar.foo CASCADE;
test5 | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE; | CREATE TABLE foobar.foo (id int PRIMARY KEY); DROP TABLE foobar.foo CASCADE;
test3 | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE; | CREATE TABLE foobar.foo (id int PRIMARY KEY); DROP TABLE foobar.foo CASCADE;
test1 | CREATE TABLE foobar.foo(id int primary key); DROP TABLE foobar.foo CASCADE; | CREATE TABLE foobar.foo (id int PRIMARY KEY); DROP TABLE foobar.foo CASCADE;
test3 | CREATE TABLE foo(id int primary key); DROP TABLE foo CASCADE; | CREATE TABLE foo (id int PRIMARY KEY); DROP TABLE foo CASCADE;
test1 | CREATE TABLE foo(id int primary key); DROP TABLE foo CASCADE; | CREATE TABLE foo (id int PRIMARY KEY); DROP TABLE foo CASCADE;
test8 | DROP TABLE foobar.foo CASCADE; | DROP TABLE foobar.foo CASCADE;
test7 | DROP TABLE foobar.foo CASCADE; | DROP TABLE foobar.foo CASCADE;
test6 | DROP TABLE foobar.foo CASCADE; | DROP TABLE foobar.foo CASCADE;
Expand Down Expand Up @@ -147,18 +147,18 @@ WARNING: Unhandled deployment logged in pgl_ddl_deploy.unhandled
WARNING: Unhandled deployment logged in pgl_ddl_deploy.unhandled
DROP TABLE
SELECT set_name, ddl_sql_raw, ddl_sql_sent FROM pgl_ddl_deploy.events ORDER BY id DESC LIMIT 10;
set_name | ddl_sql_raw | ddl_sql_sent
----------+----------------------------------------------+----------------------------------------------
set_name | ddl_sql_raw | ddl_sql_sent
----------+----------------------------------------------+-----------------------------------------------
test4 | DROP TABLE foo, foobar.foo CASCADE; | DROP TABLE foo, foobar.foo CASCADE;
test3 | DROP TABLE foo, foobar.foo CASCADE; | DROP TABLE foo, foobar.foo CASCADE;
test2 | DROP TABLE foo, foobar.foo CASCADE; | DROP TABLE foo, foobar.foo CASCADE;
test1 | DROP TABLE foo, foobar.foo CASCADE; | DROP TABLE foo, foobar.foo CASCADE;
test8 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo(id int primary key);
test7 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo(id int primary key);
test6 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo(id int primary key);
test5 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo(id int primary key);
test4 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo(id int primary key);
test3 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo(id int primary key);
test8 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test7 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test6 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test5 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test4 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo (id int PRIMARY KEY);
test3 | CREATE TABLE foobar.foo(id int primary key); | CREATE TABLE foobar.foo (id int PRIMARY KEY);
(10 rows)

SELECT set_name, ddl_sql_raw, command_tag, reason FROM pgl_ddl_deploy.unhandled ORDER BY id DESC LIMIT 10;
Expand Down
Loading