static bool RecoveryConflictPending = false;
static ProcSignalReason RecoveryConflictReason;
+/*
+ * Are we disallowed from sending a "ready for query" message right
+ * now because it would confuse the frontend?
+ */
+bool silent_error_while_idle = false;
+
/* ----------------------------------------------------------------
* decls for routines only used in this file
* ----------------------------------------------------------------
RecoveryConflictPending = false;
DisableNotifyInterrupt();
DisableCatchupInterrupt();
- if (DoingCommandRead)
- ereport(FATAL,
- (errcode(ERRCODE_ADMIN_SHUTDOWN),
- errmsg("terminating connection due to conflict with recovery"),
- errdetail_recovery_conflict(),
- errhint("In a moment you should be able to reconnect to the"
- " database and repeat your command.")));
- else
+ if (DoingCommandRead){
+ /*
+ * We cant issue a normal ERROR here because the
+ * client doesnt expect the server to send an error at
+ * that point.
+ * We also may not send a "ready for query"/Z message
+ * because that would be unexpected as well.
+ */
+ silent_error_while_idle = true;
+ ereport(ERROR | LOG_NO_CLIENT,
+ (errcode(ERRCODE_QUERY_CANCELED),
+ errmsg("canceling statement due to conflict with recovery"),
+ errdetail_recovery_conflict()));
+ }
+ else{
ereport(ERROR,
(errcode(ERRCODE_QUERY_CANCELED),
errmsg("canceling statement due to conflict with recovery"),
errdetail_recovery_conflict()));
+ }
}
/*
* processing of batched messages, and because we don't want to report
* uncommitted updates (that confuses autovacuum).
*/
- if (send_ready_for_query)
+ if (send_ready_for_query && !silent_error_while_idle)
{
if (IsAbortedTransactionBlockState())
{
send_ready_for_query = false;
}
+ /*
+ * After ReadCommand continued we are sure that the frontend
+ * sent a message and can handle a 'Z' message. We cant set
+ * that after ReadCommand because that will error out when in
+ * an aborted transaction - which we are when
+ * silent_error_while_idle was set.
+ */
+ silent_error_while_idle = false;
+
/*
* (2) Allow asynchronous signals to be executed immediately if they
* come in while we are waiting for client input. (This must be