Changeset: e61ac4dd3f9b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e61ac4dd3f9b
Modified Files:
        clients/ChangeLog.Jan2022
        clients/mapiclient/mclient.c
Branch: Jan2022
Log Message:

Fixed problem in SQL/client interaction in COPY INTO FROM STDIN.
The problem is, at the end of a query, SQL reads any remaining white
space (including newlines).  If the COPY INTO buffer ends right after
the semicolon, the following newline is not read here, but instead
during CSV file processing, which then barfs.  Our solution is to not
send a semicolon at the end of a buffer but instead postpone it until
the next chunk.


diffs (81 lines):

diff --git a/clients/ChangeLog.Jan2022 b/clients/ChangeLog.Jan2022
--- a/clients/ChangeLog.Jan2022
+++ b/clients/ChangeLog.Jan2022
@@ -1,3 +1,9 @@
 # ChangeLog file for clients
 # This file is updated with Maddlog
 
+* Tue May 31 2022 Sjoerd Mullender <[email protected]>
+- Fixed a bug where when the semicolon at the end of a COPY INTO query
+  that reads from STDIN is at exactly a 10240 byte boundary in a file,
+  the data isn't read as input for the COPY INTO but instead as a new
+  SQL query.
+
diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c
--- a/clients/mapiclient/mclient.c
+++ b/clients/mapiclient/mclient.c
@@ -2042,6 +2042,7 @@ static bool
 doFileBulk(Mapi mid, stream *fp)
 {
        char *buf = NULL;
+       size_t semicolon1 = 0, semicolon2 = 0;
        ssize_t length;
        MapiHdl hdl = mapi_get_active(mid);
        MapiMsg rc = MOK;
@@ -2064,18 +2065,28 @@ doFileBulk(Mapi mid, stream *fp)
                                break;
                        length = 0;
                        buf[0] = 0;
-               } else if ((length = mnstr_read(fp, buf, 1, bufsize)) <= 0) {
-                       /* end of file or error */
-                       if (hdl == NULL)
+               } else {
+                       if ((length = mnstr_read(fp, buf, 1, bufsize)) < 0) {
+                               /* error */
+                               errseen = true;
                                break;  /* nothing more to do */
-                       buf[0] = 0;
-                       length = 0; /* handle error like EOF */
-               } else {
-                       buf[length] = 0;
-                       if (strlen(buf) < (size_t) length) {
-                               mnstr_printf(stderr_stream, "NULL byte in 
input\n");
-                               errseen = true;
-                               break;
+                       } else {
+                               buf[length] = 0;
+                               if (length == 0) {
+                                       /* end of file */
+                                       if (semicolon2 == 0 && hdl == NULL)
+                                               break;  /* nothing more to do */
+                               } else {
+                                       if (strlen(buf) < (size_t) length) {
+                                               mnstr_printf(stderr_stream, 
"NULL byte in input\n");
+                                               errseen = true;
+                                               break;
+                                       }
+                                       while (length > 1 && buf[length - 1] == 
';') {
+                                               semicolon1++;
+                                               buf[--length] = 0;
+                                       }
+                               }
                        }
                }
                timerResume();
@@ -2085,7 +2096,15 @@ doFileBulk(Mapi mid, stream *fp)
                }
 
                assert(hdl != NULL);
-               mapi_query_part(hdl, buf, (size_t) length);
+               while (semicolon2 > 0) {
+                       mapi_query_part(hdl, ";", 1);
+                       CHECK_RESULT(mid, hdl, buf, fp);
+                       semicolon2--;
+               }
+               semicolon2 = semicolon1;
+               semicolon1 = 0;
+               if (length > 0)
+                       mapi_query_part(hdl, buf, (size_t) length);
                CHECK_RESULT(mid, hdl, buf, fp);
 
                /* if not at EOF, make sure there is a newline in the
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to