v11-0001-refactoring-ReadOneStatement.no-cfbot

application/octet-stream

Filename: v11-0001-refactoring-ReadOneStatement.no-cfbot
Type: application/octet-stream
Part: 0
Message: Re: Non-text mode for pg_dumpall
From 11c1f38413415f582c0596ff745e4cbfb1848126 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Sun, 26 Jan 2025 22:36:28 +0800
Subject: [PATCH v11 1/1] refactoring ReadOneStatement escape single quote and
 double quote for ReadOneStatement.

the following are some tests to prove it accurate.

create role y;
comment on role y is $$;"'$$;
create role "'";
create role "'';";
create role "';;;';";
create role z;
comment on role z is $$"";';$$;

create role ";
';
;
";
create role ";";
comment on role ";" is $$;"';',",' $$;
comment on role ";" is $$;"';',",'

$$;

create role "

";
comment on role z is $$;"';',",'';;'"";$$;
---
 src/bin/pg_dump/pg_restore.c | 49 ++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index 79f61395ae..65029ecb76 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -764,6 +764,10 @@ static int
 ReadOneStatement(StringInfo inBuf, FILE *pfile)
 {
 	int			c; /* character read from getc() */
+	int			m;
+
+	StringInfoData	q;
+	initStringInfo(&q);
 
 	resetStringInfo(inBuf);
 
@@ -772,16 +776,44 @@ ReadOneStatement(StringInfo inBuf, FILE *pfile)
 	 */
 	while ((c = fgetc(pfile)) != EOF)
 	{
-		appendStringInfoChar(inBuf, (char) c);
+		if (c != '\'' && c != '"' && c != '\n' && c != ';')
+		{
+			appendStringInfoChar(inBuf, (char) c);
+			while ((c = fgetc(pfile)) != EOF)
+			{
+				if (c != '\'' && c != '"' && c != ';' && c != '\n')
+					appendStringInfoChar(inBuf, (char) c);
+				else
+					break;
+			}
+		}
+
+		if (c == '\'' || c == '"')
+		{
+			appendStringInfoChar(&q, (char) c);
+			m = c;
+
+			while ((c = fgetc(pfile)) != EOF)
+			{
+				appendStringInfoChar(&q, (char) c);
+
+				if( c == m)
+				{
+					appendStringInfoString(inBuf, q.data);
+					resetStringInfo(&q);
+					break;
+				}
+			}
+		}
+
+		if (c == ';')
+		{
+			appendStringInfoChar(inBuf, (char) c);
+			break;
+		}
 
 		if (c == '\n')
-		{
-			if(inBuf->len > 1 &&
-					inBuf->data[inBuf->len - 2] == ';')
-				break;
-			else
-				continue;
-		}
+			appendStringInfoChar(inBuf, (char) c);
 	}
 
 	/* No input before EOF signal means time to quit. */
@@ -1113,6 +1145,7 @@ execute_global_sql_commands(PGconn *conn, const char *dumpdirpath, const char *o
 	/* Process file till EOF and execute sql statements */
 	while (ReadOneStatement(&sqlstatement, pfile) != EOF)
 	{
+		pg_log_info("executing %s", sqlstatement.data);
 		result = PQexec(conn, sqlstatement.data);
 
 		switch (PQresultStatus(result))
-- 
2.34.1