> On 26 May 2017 at 23:05, Peter Eisentraut < peter.eisentr...@2ndquadrant.com> wrote: > > > On 5/25/17 19:16, Petr Jelinek wrote: > >> The reported error is just one of many errors that can happen when DROP > >> SUBSCRIPTION tries to drop the slot (doens't exist, still active, no > >> permission, etc.). We don't want to give the hint that is effectively > >> "just forget about the slot then" for all of them. So we would need > >> some way to distinguish "you can't do this right now" from "this would > >> never work" (400 vs 500 errors). > >> > > This specific error returns ERRCODE_UNDEFINED_OBJECT error code so we > > could check for it and offer hint only for this case. > > We would have to extend the walreceiver interface a little to pass that > through, but it seems doable.
Just to make it clear for me. If I understand correctly, it should be more or less easy to extend it in that way, something like in the attached patch. Or am I missing something?
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 86eb31d..9f7d73c 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -941,10 +941,20 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) res = walrcv_exec(wrconn, cmd.data, 0, NULL); if (res->status != WALRCV_OK_COMMAND) - ereport(ERROR, - (errmsg("could not drop the replication slot \"%s\" on publisher", - slotname), - errdetail("The error was: %s", res->err))); + { + if (res->errcode == ERRCODE_UNDEFINED_OBJECT) + ereport(ERROR, + (errmsg("could not drop the replication slot \"%s\" on publisher", + slotname), + errdetail("The error was: %s", res->err), + errhint("Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) " + "to disassociate the subscription from the slot."))); + else + ereport(ERROR, + (errmsg("could not drop the replication slot \"%s\" on publisher", + slotname), + errdetail("The error was: %s", res->err))); + } else ereport(NOTICE, (errmsg("dropped replication slot \"%s\" on publisher", diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index ebe9c91..1caa051 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -873,6 +873,7 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query, { PGresult *pgres = NULL; WalRcvExecResult *walres = palloc0(sizeof(WalRcvExecResult)); + const char *errorcode = NULL; if (MyDatabaseId == InvalidOid) ereport(ERROR, @@ -915,6 +916,9 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query, case PGRES_FATAL_ERROR: case PGRES_BAD_RESPONSE: walres->status = WALRCV_ERROR; + errorcode = PQresultErrorField(pgres, PG_DIAG_SQLSTATE); + walres->errcode = MAKE_SQLSTATE(errorcode[0], errorcode[1], errorcode[2], + errorcode[3], errorcode[4]); walres->err = pchomp(PQerrorMessage(conn->streamConn)); break; } diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index 31d090c..b0582af 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -186,6 +186,7 @@ typedef struct WalRcvExecResult { WalRcvExecStatus status; char *err; + int errcode; Tuplestorestate *tuplestore; TupleDesc tupledesc; } WalRcvExecResult;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers