From 70066eb1a1adb4d1ac608c1127bbb3139fa09942 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 17 Jan 2008 21:21:50 +0000
Subject: [PATCH] Insert into getCopyDataMessage() the same logic that already
 existed in the main code path for enlarging libpq's input buffer in one swoop
 when needing to read a long data message.  Without this, the code will double
 the buffer size, read more data, notice it still hasn't got the whole
 message, and repeat till it finally has a large enough buffer.  Which wastes
 a lot of data-moving effort and also memory (since malloc probably can't do
 anything very useful with the freed-up smaller buffers).  Not sure why this
 wasn't there already; certainly the COPY data path is a place where we're
 quite likely to see long data messages.  I'm not backpatching though, since
 this is just a marginal performance issue rather than a real bug.

---
 src/interfaces/libpq/fe-protocol3.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index c40868805f3..89c0d5018f0 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.33 2008/01/15 22:18:20 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.34 2008/01/17 21:21:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1305,7 +1305,24 @@ getCopyDataMessage(PGconn *conn)
 		}
 		avail = conn->inEnd - conn->inCursor;
 		if (avail < msgLength - 4)
+		{
+			/*
+			 * Before returning, enlarge the input buffer if needed to hold
+			 * the whole message.  See notes in parseInput.
+			 */
+			if (pqCheckInBufferSpace(conn->inCursor + msgLength - 4, conn))
+			{
+				/*
+				 * XXX add some better recovery code... plan is to skip over
+				 * the message using its length, then report an error. For the
+				 * moment, just treat this like loss of sync (which indeed it
+				 * might be!)
+				 */
+				handleSyncLoss(conn, id, msgLength);
+				return -2;
+			}
 			return 0;
+		}
 
 		/*
 		 * If it's a legitimate async message type, process it.  (NOTIFY
-- 
GitLab