Re: [Fwd: Re: [pgsql-hackers-win32] Import from Linux to Windows] - Mailing list pgsql-hackers

From Tom Lane
Subject Re: [Fwd: Re: [pgsql-hackers-win32] Import from Linux to Windows]
Date
Msg-id 28833.1092438153@sss.pgh.pa.us
Whole thread Raw
In response to Re: [Fwd: Re: [pgsql-hackers-win32] Import from Linux to Windows]  (Andrew Dunstan <andrew@dunslane.net>)
Responses Re: [Fwd: Re: [pgsql-hackers-win32] Import from Linux to
List pgsql-hackers
Andrew Dunstan <andrew@dunslane.net> writes:
>> The attached patch appears to solve the problem. However, while it
>> makes us conform to the first sentence below from the docs, it doesn't
>> comply with the second. Not sure what to do about that. Maybe there's
>> a better solution?

> Attached patch seems much better, I think.

I think it is still not quite there.  Since as you noted the backend
will complain if line endings don't match, if we hit EOF then we have
to cons up a \. line with the correct ending.  (BTW, this is not
actually necessary when talking 3.0 protocol, but it is when talking
to an older server.)

I modified the patch a little more and applied the attached.  It seems
to work for me but could use more testing.

            regards, tom lane

*** src/bin/psql/copy.c.orig    Fri Aug 13 10:47:23 2004
--- src/bin/psql/copy.c    Fri Aug 13 18:51:25 2004
***************
*** 663,668 ****
--- 663,669 ----
      bool        copydone = false;
      bool        firstload;
      bool        linedone;
+     bool        saw_cr = false;
      char        copybuf[COPYBUFSIZ];
      char       *s;
      int            bufleft;
***************
*** 695,724 ****

          while (!linedone)
          {                        /* for each bufferload in line ... */
              s = copybuf;
              for (bufleft = COPYBUFSIZ - 1; bufleft > 0; bufleft--)
              {
                  c = getc(copystream);
!                 if (c == '\n' || c == EOF)
                  {
                      linedone = true;
                      break;
                  }
                  *s++ = c;
              }
              *s = '\0';
              if (c == EOF && s == copybuf && firstload)
              {
!                 PQputline(conn, "\\.");
                  copydone = true;
                  if (pset.cur_cmd_interactive)
                      puts("\\.");
                  break;
              }
              PQputline(conn, copybuf);
              if (firstload)
              {
!                 if (!strcmp(copybuf, "\\."))
                  {
                      copydone = true;
                      break;
--- 696,744 ----

          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 == 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)
              {
!                 /*
!                  * 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, "\\.\n") == 0 ||
!                     strcmp(copybuf, "\\.\r\n") == 0)
                  {
                      copydone = true;
                      break;
***************
*** 726,732 ****
                  firstload = false;
              }
          }
-         PQputline(conn, "\n");
          linecount++;
      }
      ret = !PQendcopy(conn);
--- 746,751 ----

pgsql-hackers by date:

Previous
From: "Simon@2ndquadrant.com"
Date:
Subject: Re: Re: We have got a serious problem with pg_clog/WAL synchronization
Next
From: "Simon@2ndquadrant.com"
Date:
Subject: Development Schedule Page