summaryrefslogtreecommitdiff
path: root/src/bin/psql/copy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/psql/copy.c')
-rw-r--r--src/bin/psql/copy.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c
index 961ae326949..e020e4d665d 100644
--- a/src/bin/psql/copy.c
+++ b/src/bin/psql/copy.c
@@ -620,20 +620,29 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
/* current line is done? */
if (buf[buflen - 1] == '\n')
{
- /* check for EOF marker, but not on a partial line */
- if (at_line_begin)
+ /*
+ * When at the beginning of the line and the data is
+ * inlined, check for EOF marker. If the marker is found,
+ * we must stop at this point. If not, the \. line can be
+ * sent to the server, and we let it decide whether it's
+ * an EOF or not depending on the format: in TEXT mode, \.
+ * will be interpreted as an EOF, in CSV, it will not.
+ */
+ if (at_line_begin && copystream == pset.cur_cmd_source)
{
- /*
- * This code erroneously assumes '\.' on a line alone
- * inside a quoted CSV string terminates the \copy.
- * https://www.postgresql.org/message-id/E1TdNVQ-0001ju-GO@wrigleys.postgresql.org
- *
- * https://www.postgresql.org/message-id/bfcd57e4-8f23-4c3e-a5db-2571d09208e2@beta.fastmail.com
- */
if ((linelen == 3 && memcmp(fgresult, "\\.\n", 3) == 0) ||
(linelen == 4 && memcmp(fgresult, "\\.\r\n", 4) == 0))
{
copydone = true;
+
+ /*
+ * Remove the EOF marker from the data sent. In
+ * CSV mode, the EOF marker must be removed,
+ * otherwise it would be interpreted by the server
+ * as valid data.
+ */
+ *fgresult = '\0';
+ buflen -= linelen;
}
}