From 22ac1594ef6eefcc5f7f07447e49ea3ef6f99b12 Mon Sep 17 00:00:00 2001
From: Jacob Champion <jacob.champion@enterprisedb.com>
Date: Wed, 18 Feb 2026 12:11:49 -0800
Subject: [PATCH v8 2/2] squash! libpq: Grease the protocol by default

Also attempt to notify the user when the server closes the connection
suspiciously.
---
 src/interfaces/libpq/fe-connect.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 418c71a9aa8..b42a0cb4c78 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -91,8 +91,9 @@ static int	ldapServiceLookup(const char *purl, PQconninfoOption *options,
 
 /* This is part of the protocol so just define it */
 #define ERRCODE_INVALID_PASSWORD "28P01"
-/* This too */
+/* These too */
 #define ERRCODE_CANNOT_CONNECT_NOW "57P03"
+#define ERRCODE_PROTOCOL_VIOLATION "08P01"
 
 /*
  * Cope with the various platform-specific ways to spell TCP keepalive socket
@@ -4154,6 +4155,32 @@ keep_going:						/* We will come back to here until there is
 					/* Check to see if we should mention pgpassfile */
 					pgpassfileWarning(conn);
 
+					/*
+					 * ...and whether we should mention grease. If the error
+					 * message contains the PG_PROTOCOL_GREASE number (in
+					 * major.minor, decimal, or hex format) or a complaint
+					 * about a protocol violation before we've even started an
+					 * authentication exchange, it's probably caused by a
+					 * grease interaction.
+					 */
+					if (conn->max_pversion == PG_PROTOCOL_GREASE &&
+						!conn->auth_req_received)
+					{
+						const char *sqlstate = PQresultErrorField(conn->result,
+																  PG_DIAG_SQLSTATE);
+
+						if ((sqlstate &&
+							 strcmp(sqlstate, ERRCODE_PROTOCOL_VIOLATION) == 0) ||
+							(conn->errorMessage.len > 0 &&
+							 (strstr(conn->errorMessage.data, "3.9999") ||
+							  strstr(conn->errorMessage.data, "206607") ||
+							  strstr(conn->errorMessage.data, "3270F") ||
+							  strstr(conn->errorMessage.data, "3270f"))))
+						{
+							libpq_append_grease_info(conn);
+						}
+					}
+
 					CONNECTION_FAILED();
 				}
 				/* Handle NegotiateProtocolVersion */
-- 
2.34.1

