From 0266e98c6b865246c3031bbf55cb15f330134e30 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Tue, 5 Oct 2021 12:52:49 -0400 Subject: Flexible options for CREATE_REPLICATION_SLOT. Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a hard-coded syntax. To improve future extensibility, adopt a flexible options syntax here, too. In the new syntax, instead of three mutually exclusive options EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'. This commit does not remove support for the old syntax. It just adds the new one as an additional option, makes pg_receivewal, pg_recvlogical, and walreceiver processes use it. Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and Fujii Masao. Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com --- src/backend/replication/walsender.c | 40 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'src/backend/replication/walsender.c') diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 3ca2a11389d..b811a5c0ef2 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -872,26 +872,30 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd, { DefElem *defel = (DefElem *) lfirst(lc); - if (strcmp(defel->defname, "export_snapshot") == 0) + if (strcmp(defel->defname, "snapshot") == 0) { + char *action; + if (snapshot_action_given || cmd->kind != REPLICATION_KIND_LOGICAL) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); + action = defGetString(defel); snapshot_action_given = true; - *snapshot_action = defGetBoolean(defel) ? CRS_EXPORT_SNAPSHOT : - CRS_NOEXPORT_SNAPSHOT; - } - else if (strcmp(defel->defname, "use_snapshot") == 0) - { - if (snapshot_action_given || cmd->kind != REPLICATION_KIND_LOGICAL) + + if (strcmp(action, "export") == 0) + *snapshot_action = CRS_EXPORT_SNAPSHOT; + else if (strcmp(action, "nothing") == 0) + *snapshot_action = CRS_NOEXPORT_SNAPSHOT; + else if (strcmp(action, "use") == 0) + *snapshot_action = CRS_USE_SNAPSHOT; + else ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("unrecognized value for CREATE_REPLICATION_SLOT option \"%s\": \"%s\"", + defel->defname, action))); - snapshot_action_given = true; - *snapshot_action = CRS_USE_SNAPSHOT; } else if (strcmp(defel->defname, "reserve_wal") == 0) { @@ -901,7 +905,7 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd, errmsg("conflicting or redundant options"))); reserve_wal_given = true; - *reserve_wal = true; + *reserve_wal = defGetBoolean(defel); } else if (strcmp(defel->defname, "two_phase") == 0) { @@ -910,7 +914,7 @@ parseCreateReplSlotOptions(CreateReplicationSlotCmd *cmd, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); two_phase_given = true; - *two_phase = true; + *two_phase = defGetBoolean(defel); } else elog(ERROR, "unrecognized option: %s", defel->defname); @@ -980,7 +984,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) ereport(ERROR, /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ (errmsg("%s must not be called inside a transaction", - "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT"))); + "CREATE_REPLICATION_SLOT ... (SNAPSHOT 'export')"))); need_full_snapshot = true; } @@ -990,25 +994,25 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) ereport(ERROR, /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ (errmsg("%s must be called inside a transaction", - "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT"))); + "CREATE_REPLICATION_SLOT ... (SNAPSHOT 'use')"))); if (XactIsoLevel != XACT_REPEATABLE_READ) ereport(ERROR, /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ (errmsg("%s must be called in REPEATABLE READ isolation mode transaction", - "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT"))); + "CREATE_REPLICATION_SLOT ... (SNAPSHOT 'use')"))); if (FirstSnapshotSet) ereport(ERROR, /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ (errmsg("%s must be called before any query", - "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT"))); + "CREATE_REPLICATION_SLOT ... (SNAPSHOT 'use')"))); if (IsSubTransaction()) ereport(ERROR, /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ (errmsg("%s must not be called in a subtransaction", - "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT"))); + "CREATE_REPLICATION_SLOT ... (SNAPSHOT 'use')"))); need_full_snapshot = true; } -- cgit v1.2.3