From 4fa3b2c59959c1a3a8d878dd62dda7683db7a08e Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Tue, 9 Feb 2021 10:27:14 +1100 Subject: [PATCH v1] ReplicationSlotDropAtPubNode detect slot does not exist. A new sqlstate member was to WalRcvExecResult. This allows walrcv_exec calling code to know detail of the cause of any error. Specifically, here it means the ReplicationSlotDropAtPubNode function can now identify the "slot does not exist error", and so can handle "missing_ok" more correctly. --- src/backend/commands/subscriptioncmds.c | 3 ++- src/backend/replication/libpqwalreceiver/libpqwalreceiver.c | 8 ++++++++ src/include/replication/walreceiver.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 1d3ca43..eee7512 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -1296,7 +1296,8 @@ ReplicationSlotDropAtPubNode(WalReceiverConn *wrconn, char *slotname, bool missi (errmsg("dropped replication slot \"%s\" on publisher", slotname))); } - else if (res->status == WALRCV_ERROR && missing_ok) + else if (res->status == WALRCV_ERROR && + missing_ok && res->sqlstate == ERRCODE_UNDEFINED_OBJECT) { /* WARNING. Error, but missing_ok = true. */ ereport(WARNING, diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index e958274..7714696 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -982,6 +982,7 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query, { PGresult *pgres = NULL; WalRcvExecResult *walres = palloc0(sizeof(WalRcvExecResult)); + char *diag_sqlstate; if (MyDatabaseId == InvalidOid) ereport(ERROR, @@ -1025,6 +1026,13 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query, case PGRES_BAD_RESPONSE: walres->status = WALRCV_ERROR; walres->err = pchomp(PQerrorMessage(conn->streamConn)); + diag_sqlstate = PQresultErrorField(pgres, PG_DIAG_SQLSTATE); + if (diag_sqlstate) + walres->sqlstate = MAKE_SQLSTATE(diag_sqlstate[0], + diag_sqlstate[1], + diag_sqlstate[2], + diag_sqlstate[3], + diag_sqlstate[4]); break; } diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index 4313f51..a97a59a 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -210,6 +210,7 @@ typedef enum typedef struct WalRcvExecResult { WalRcvExecStatus status; + int sqlstate; char *err; Tuplestorestate *tuplestore; TupleDesc tupledesc; -- 1.8.3.1