Remove pgbench's hardwired limit on line length in custom script files.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 16 Nov 2013 00:41:09 +0000 (19:41 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 16 Nov 2013 00:41:09 +0000 (19:41 -0500)
pgbench formerly failed on lines longer than BUFSIZ, unexpectedly
splitting them into multiple commands.  Allow it to work with any
length of input line.

Sawada Masahiko

contrib/pgbench/pgbench.c

index fff71e526f359b542746dd0a08c1ba81e62d6e6c..2c96fae78245ca127d87b0df0f2f56c5904a2e92 100644 (file)
@@ -2016,6 +2016,49 @@ process_commands(char *buf)
    return my_commands;
 }
 
+/*
+ * Read a line from fd, and return it in a malloc'd buffer.
+ * Return NULL at EOF.
+ *
+ * The buffer will typically be larger than necessary, but we don't care
+ * in this program, because we'll free it as soon as we've parsed the line.
+ */
+static char *
+read_line_from_file(FILE *fd)
+{
+   char        tmpbuf[BUFSIZ];
+   char       *buf;
+   size_t      buflen = BUFSIZ;
+   size_t      used = 0;
+
+   buf = (char *) palloc(buflen);
+   buf[0] = '\0';
+
+   while (fgets(tmpbuf, BUFSIZ, fd) != NULL)
+   {
+       size_t      thislen = strlen(tmpbuf);
+
+       /* Append tmpbuf to whatever we had already */
+       memcpy(buf + used, tmpbuf, thislen + 1);
+       used += thislen;
+
+       /* Done if we collected a newline */
+       if (thislen > 0 && tmpbuf[thislen - 1] == '\n')
+           break;
+
+       /* Else, enlarge buf to ensure we can append next bufferload */
+       buflen += BUFSIZ;
+       buf = (char *) pg_realloc(buf, buflen);
+   }
+
+   if (used > 0)
+       return buf;
+
+   /* Reached EOF */
+   free(buf);
+   return NULL;
+}
+
 static int
 process_file(char *filename)
 {
@@ -2024,7 +2067,7 @@ process_file(char *filename)
    Command   **my_commands;
    FILE       *fd;
    int         lineno;
-   char        buf[BUFSIZ];
+   char       *buf;
    int         alloc_num;
 
    if (num_files >= MAX_FILES)
@@ -2046,11 +2089,14 @@ process_file(char *filename)
 
    lineno = 0;
 
-   while (fgets(buf, sizeof(buf), fd) != NULL)
+   while ((buf = read_line_from_file(fd)) != NULL)
    {
        Command    *command;
 
        command = process_commands(buf);
+
+       free(buf);
+
        if (command == NULL)
            continue;