Re: The number of character limitation of custom script on pgbench - Mailing list pgsql-hackers

From Tom Lane
Subject Re: The number of character limitation of custom script on pgbench
Date
Msg-id 32435.1384562886@sss.pgh.pa.us
Whole thread Raw
In response to Re: The number of character limitation of custom script on pgbench  (Sawada Masahiko <sawada.mshk@gmail.com>)
List pgsql-hackers
Sawada Masahiko <sawada.mshk@gmail.com> writes:
> I attached the patch which solves this problem, and have submitted to CF3.
> I changed how to get the SQL from custom script file.

This needed a bit of work:

- Use of strncat didn't seem particularly safe, or efficient.  I changed
it to explicitly account for space consumption in the result buffer.
- It leaked the buffer space used.  While this likely doesn't matter for
foreseeable usage, it seemed worth fixing.
- Didn't do the right thing for a file not ending with a newline.
- Didn't follow project code layout standards.

I've committed the attached revised version.

            regards, tom lane

diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
index fff71e5..2c96fae 100644
*** a/contrib/pgbench/pgbench.c
--- b/contrib/pgbench/pgbench.c
*************** process_commands(char *buf)
*** 2016,2021 ****
--- 2016,2064 ----
      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)
  {
*************** process_file(char *filename)
*** 2024,2030 ****
      Command   **my_commands;
      FILE       *fd;
      int            lineno;
!     char        buf[BUFSIZ];
      int            alloc_num;

      if (num_files >= MAX_FILES)
--- 2067,2073 ----
      Command   **my_commands;
      FILE       *fd;
      int            lineno;
!     char       *buf;
      int            alloc_num;

      if (num_files >= MAX_FILES)
*************** process_file(char *filename)
*** 2046,2056 ****

      lineno = 0;

!     while (fgets(buf, sizeof(buf), fd) != NULL)
      {
          Command    *command;

          command = process_commands(buf);
          if (command == NULL)
              continue;

--- 2089,2102 ----

      lineno = 0;

!     while ((buf = read_line_from_file(fd)) != NULL)
      {
          Command    *command;

          command = process_commands(buf);
+
+         free(buf);
+
          if (command == NULL)
              continue;


pgsql-hackers by date:

Previous
From: Andrew Dunstan
Date:
Subject: Re: additional json functionality
Next
From: Nigel Heron
Date:
Subject: Re: review: autovacuum_work_mem