From 456431823892fe98df3fcfa30d8b8c08006d88e6 Mon Sep 17 00:00:00 2001 From: Srinath Reddy Sadipiralla Date: Wed, 3 Jun 2026 10:29:30 +0530 Subject: [PATCH] Reject the "pgrepack" output plugin outside REPACK (CONCURRENTLY) The "pgrepack" output plugin is an internal component of REPACK (CONCURRENTLY) and is not meant to be driven through the generic logical decoding interface. --- contrib/test_decoding/expected/repack.out | 5 +++++ contrib/test_decoding/sql/repack.sql | 4 ++++ src/backend/replication/slotfuncs.c | 14 ++++++++++++++ src/backend/replication/walsender.c | 10 ++++++++++ 4 files changed, 33 insertions(+) diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out index 6204e620b43..2732561281b 100644 --- a/contrib/test_decoding/expected/repack.out +++ b/contrib/test_decoding/expected/repack.out @@ -99,5 +99,10 @@ REPACK (CONCURRENTLY) repack_conc_replident; ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident" DETAIL: REPACK (CONCURRENTLY) does not support deferrable primary keys. HINT: Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity. +-- The "pgrepack" output plugin is internal to REPACK (CONCURRENTLY); it cannot +-- be selected through the generic logical decoding interface (bug #19500). +SELECT pg_create_logical_replication_slot('repack_misuse_slot', 'pgrepack'); +ERROR: output plugin "pgrepack" cannot be used through the logical decoding interface +DETAIL: This output plugin is reserved for internal use by REPACK (CONCURRENTLY). -- clean up DROP TABLE repack_conc_replident, clstrpart; diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql index cea3bd33689..a7cb615e55d 100644 --- a/contrib/test_decoding/sql/repack.sql +++ b/contrib/test_decoding/sql/repack.sql @@ -73,5 +73,9 @@ REPACK (CONCURRENTLY) repack_conc_replident; ALTER TABLE repack_conc_replident ADD PRIMARY KEY (i) DEFERRABLE; REPACK (CONCURRENTLY) repack_conc_replident; +-- The "pgrepack" output plugin is internal to REPACK (CONCURRENTLY); it cannot +-- be selected through the generic logical decoding interface (bug #19500). +SELECT pg_create_logical_replication_slot('repack_misuse_slot', 'pgrepack'); + -- clean up DROP TABLE repack_conc_replident, clstrpart; diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 16fbd383735..17548abf601 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -136,6 +136,20 @@ create_logical_replication_slot(char *name, char *plugin, Assert(!MyReplicationSlot); + /* + * The "pgrepack" output plugin is for internal use by REPACK + * (CONCURRENTLY) only. Reject it here so that misuse through the SQL + * interface fails immediately with a clear message, instead of being + * caught later (and only after some decoding work) by the plugin's own + * magic-number check in its begin callback. REPACK creates its slot + * directly via ReplicationSlotCreate(), so it is unaffected. + */ + if (strcmp(plugin, "pgrepack") == 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("output plugin \"pgrepack\" cannot be used through the logical decoding interface"), + errdetail("This output plugin is reserved for internal use by REPACK (CONCURRENTLY).")); + /* * Acquire a logical decoding slot, this will check for conflicting names. * Initially create persistent slot as ephemeral - that allows us to diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 04aa770d981..b9e52a20173 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -1270,6 +1270,16 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) CheckLogicalDecodingRequirements(false); + /* + * The "pgrepack" output plugin is reserved for REPACK (CONCURRENTLY); + * reject it here too (see create_logical_replication_slot()). + */ + if (strcmp(cmd->plugin, "pgrepack") == 0) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("output plugin \"pgrepack\" cannot be used through the logical decoding interface"), + errdetail("This output plugin is reserved for internal use by REPACK (CONCURRENTLY).")); + /* * Initially create persistent slot as ephemeral - that allows us to * nicely handle errors during initialization because it'll get -- 2.43.0