Fix psql's COPY support to deal with \r\n line endings.

Andrew Dunstan, some further hacking by Tom Lane.
This commit is contained in:
Tom Lane 2004-08-13 22:59:29 +00:00
parent 2193121fa9
commit b681bf9323

View File

@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2003, PostgreSQL Global Development Group * Copyright (c) 2000-2003, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.51 2004/08/13 14:47:23 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.52 2004/08/13 22:59:29 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "copy.h" #include "copy.h"
@ -663,6 +663,7 @@ handleCopyIn(PGconn *conn, FILE *copystream)
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;
@ -695,30 +696,49 @@ handleCopyIn(PGconn *conn, FILE *copystream)
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;
@ -726,7 +746,6 @@ handleCopyIn(PGconn *conn, FILE *copystream)
firstload = false; firstload = false;
} }
} }
PQputline(conn, "\n");
linecount++; linecount++;
} }
ret = !PQendcopy(conn); ret = !PQendcopy(conn);