Back-patch fix for \r\n line endings in psql's COPY support.

Andrew Dunstan.
This commit is contained in:
Tom Lane 2004-08-14 22:24:49 +00:00
parent b2280a5de9
commit d9dda2d737

View File

@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * Copyright (c) 2000-2003, PostgreSQL Global Development Group
* *
* $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.33 2003/08/04 23:59:39 tgl Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.33.4.1 2004/08/14 22:24:49 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "copy.h" #include "copy.h"
@ -496,6 +496,7 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt)
bool copydone = false; bool copydone = false;
bool firstload; bool firstload;
bool linedone; bool linedone;
bool saw_cr = false;
char copybuf[COPYBUFSIZ]; char copybuf[COPYBUFSIZ];
char *s; char *s;
int bufleft; int bufleft;
@ -521,30 +522,49 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt)
while (!linedone) while (!linedone)
{ /* for each bufferload in line ... */ { /* for each bufferload in line ... */
/* Fetch string until \n, EOF, or buffer full */
s = copybuf; s = copybuf;
for (bufleft = COPYBUFSIZ - 1; bufleft > 0; bufleft--) for (bufleft = COPYBUFSIZ - 1; bufleft > 0; bufleft--)
{ {
c = getc(copystream); c = getc(copystream);
if (c == '\n' || c == EOF) if (c == EOF)
{ {
linedone = true; linedone = true;
break; break;
} }
*s++ = c; *s++ = c;
if (c == '\n')
{
linedone = true;
break;
}
if (c == '\r')
saw_cr = true;
} }
*s = '\0'; *s = '\0';
/* EOF with empty line-so-far? */
if (c == EOF && s == copybuf && firstload) if (c == EOF && s == copybuf && firstload)
{ {
PQputline(conn, "\\."); /*
* We are guessing a little bit as to the right line-ending
* here...
*/
if (saw_cr)
PQputline(conn, "\\.\r\n");
else
PQputline(conn, "\\.\n");
copydone = true; copydone = true;
if (pset.cur_cmd_interactive) if (pset.cur_cmd_interactive)
puts("\\."); puts("\\.");
break; break;
} }
/* No, so pass the data to the backend */
PQputline(conn, copybuf); PQputline(conn, copybuf);
/* Check for line consisting only of \. */
if (firstload) if (firstload)
{ {
if (!strcmp(copybuf, "\\.")) if (strcmp(copybuf, "\\.\n") == 0 ||
strcmp(copybuf, "\\.\r\n") == 0)
{ {
copydone = true; copydone = true;
break; break;
@ -552,7 +572,6 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt)
firstload = false; firstload = false;
} }
} }
PQputline(conn, "\n");
linecount++; linecount++;
} }
ret = !PQendcopy(conn); ret = !PQendcopy(conn);