> On 26 May 2017 at 23:05, Peter Eisentraut <
[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers