]> granicus.if.org Git - postgresql/commitdiff
Back-patch fix for \r\n line endings in psql's COPY support.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 14 Aug 2004 22:24:49 +0000 (22:24 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 14 Aug 2004 22:24:49 +0000 (22:24 +0000)
Andrew Dunstan.

src/bin/psql/copy.c

index b3c07ffab53494f7c421fc45083951d4e74772bb..aed8b3196aed74ef4a7c0ae403982159dff49e59 100644 (file)
@@ -3,7 +3,7 @@
  *
  * 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 "copy.h"
@@ -496,6 +496,7 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt)
        bool            copydone = false;
        bool            firstload;
        bool            linedone;
+       bool            saw_cr = false;
        char            copybuf[COPYBUFSIZ];
        char       *s;
        int                     bufleft;
@@ -521,30 +522,49 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt)
 
                while (!linedone)
                {                                               /* for each bufferload in line ... */
+                       /* Fetch string until \n, EOF, or buffer full */
                        s = copybuf;
                        for (bufleft = COPYBUFSIZ - 1; bufleft > 0; bufleft--)
                        {
                                c = getc(copystream);
-                               if (c == '\n' || c == EOF)
+                               if (c == EOF)
                                {
                                        linedone = true;
                                        break;
                                }
                                *s++ = c;
+                               if (c == '\n')
+                               {
+                                       linedone = true;
+                                       break;
+                               }
+                               if (c == '\r')
+                                       saw_cr = true;
                        }
                        *s = '\0';
+                       /* EOF with empty line-so-far? */
                        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;
                                if (pset.cur_cmd_interactive)
                                        puts("\\.");
                                break;
                        }
+                       /* No, so pass the data to the backend */
                        PQputline(conn, copybuf);
+                       /* Check for line consisting only of \. */
                        if (firstload)
                        {
-                               if (!strcmp(copybuf, "\\."))
+                               if (strcmp(copybuf, "\\.\n") == 0 ||
+                                       strcmp(copybuf, "\\.\r\n") == 0)
                                {
                                        copydone = true;
                                        break;
@@ -552,7 +572,6 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt)
                                firstload = false;
                        }
                }
-               PQputline(conn, "\n");
                linecount++;
        }
        ret = !PQendcopy(conn);