Commit the bulk of Mike Ansley's long-query changes in the
authorTom Lane
Tue, 31 Aug 1999 04:26:40 +0000 (04:26 +0000)
committerTom Lane
Tue, 31 Aug 1999 04:26:40 +0000 (04:26 +0000)
backend.  Still much left to do.

src/backend/libpq/pqcomm.c
src/backend/libpq/pqformat.c
src/backend/tcop/postgres.c
src/include/libpq/libpq.h
src/include/libpq/pqcomm.h
src/include/libpq/pqformat.h

index 5e129bc56ff13d5a0ba1790ca7e2d3639974cfa2..1d57415860407867373669a424d4ed36f80963d2 100644 (file)
@@ -28,7 +28,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pqcomm.c,v 1.81 1999/07/23 03:00:10 tgl Exp $
+ * $Id: pqcomm.c,v 1.82 1999/08/31 04:26:37 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -526,38 +526,32 @@ pq_getbytes(char *s, size_t len)
 /* --------------------------------
  *     pq_getstring    - get a null terminated string from connection
  *
+ *     The return value is placed in an expansible StringInfo.
+ *     Note that space allocation comes from the current memory context!
+ *
  *     NOTE: this routine does not do any MULTIBYTE conversion,
  *     even though it is presumably useful only for text, because
  *     no code in this module should depend on MULTIBYTE mode.
  *     See pq_getstr in pqformat.c for that.
  *
- *     FIXME: we ought to use an expansible StringInfo buffer,
- *     rather than dropping data if the message is too long.
- *
  *     returns 0 if OK, EOF if trouble
  * --------------------------------
  */
 int
-pq_getstring(char *s, size_t len)
+pq_getstring(StringInfo s)
 {
    int         c;
 
-   /*
-    * Keep on reading until we get the terminating '\0', discarding any
-    * bytes we don't have room for.
-    */
+   /* Reset string to empty */
+   s->len = 0;
+   s->data[0] = '\0';
 
+   /* Read until we get the terminating '\0' */
    while ((c = pq_getbyte()) != EOF && c != '\0')
    {
-       if (len > 1)
-       {
-           *s++ = c;
-           len--;
-       }
+       appendStringInfoChar(s, c);
    }
 
-   *s = '\0';
-
    if (c == EOF)
        return EOF;
 
index e5da571886dc4bb33e9c10b102f2a39c862d857c..1cc715b92a352c5dbf9f79eca23aef79bdf6c015 100644 (file)
@@ -15,7 +15,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pqformat.c,v 1.7 1999/07/17 20:17:03 momjian Exp $
+ * $Id: pqformat.c,v 1.8 1999/08/31 04:26:37 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -290,37 +290,30 @@ pq_getint(int *result, int b)
 /* --------------------------------
  *     pq_getstr - get a null terminated string from connection
  *
- *     FIXME: we ought to use an expansible StringInfo buffer,
- *     rather than dropping data if the message is too long.
+ *     The return value is placed in an expansible StringInfo.
+ *     Note that space allocation comes from the current memory context!
  *
  *     returns 0 if OK, EOF if trouble
  * --------------------------------
  */
 int
-pq_getstr(char *s, int maxlen)
+pq_getstr(StringInfo s)
 {
    int         c;
-
 #ifdef MULTIBYTE
    char       *p;
-
 #endif
 
-   c = pq_getstring(s, maxlen);
+   c = pq_getstring(s);
 
 #ifdef MULTIBYTE
-   p = (char *) pg_client_to_server((unsigned char *) s, strlen(s));
-   if (p != s)                 /* actual conversion has been done? */
+   p = (char *) pg_client_to_server((unsigned char *) s->data, s->len);
+   if (p != s->data)           /* actual conversion has been done? */
    {
-       int         newlen = strlen(p);
-
-       if (newlen < maxlen)
-           strcpy(s, p);
-       else
-       {
-           strncpy(s, p, maxlen);
-           s[maxlen - 1] = '\0';
-       }
+       /* reset s to empty, and append the new string p */
+       s->len = 0;
+       s->data[0] = '\0';
+       appendBinaryStringInfo(s, p, strlen(p));
    }
 #endif
 
index a667fa70c40f82893ba4957e7e8b2b992017c3fa..3986bee47bed7caecca17de16dac16c52e487514 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.127 1999/07/22 02:40:07 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.128 1999/08/31 04:26:40 tgl Exp $
  *
  * NOTES
  *   this is the "main" module of the postgres backend and
@@ -158,9 +158,9 @@ int         _exec_repeat_ = 1;
  *     decls for routines only used in this file
  * ----------------------------------------------------------------
  */
-static int InteractiveBackend(char *inBuf);
-static int SocketBackend(char *inBuf);
-static int ReadCommand(char *inBuf);
+static int InteractiveBackend(StringInfo inBuf);
+static int SocketBackend(StringInfo inBuf);
+static int ReadCommand(StringInfo inBuf);
 static void pg_exec_query(char *query_string);
 
 
@@ -178,9 +178,8 @@ static void pg_exec_query(char *query_string);
  */
 
 static int
-InteractiveBackend(char *inBuf)
+InteractiveBackend(StringInfo inBuf)
 {
-   char       *stuff = inBuf;  /* current place in input buffer */
    int         c;              /* character read from getc() */
    bool        end = false;    /* end-of-input flag */
    bool        backslashSeen = false;  /* have we seen a \ ? */
@@ -192,6 +191,10 @@ InteractiveBackend(char *inBuf)
    printf("backend> ");
    fflush(stdout);
 
+   /* Reset inBuf to empty */
+   inBuf->len = 0;
+   inBuf->data[0] = '\0';
+
    for (;;)
    {
        if (UseNewLine)
@@ -207,14 +210,15 @@ InteractiveBackend(char *inBuf)
                {
                    if (backslashSeen)
                    {
-                       stuff--;
+                       /* discard backslash from inBuf */
+                       inBuf->data[--inBuf->len] = '\0';
+                       backslashSeen = false;
                        continue;
                    }
                    else
                    {
                        /* keep the newline character */
-                       *stuff++ = '\n';
-                       *stuff++ = '\0';
+                       appendStringInfoChar(inBuf, '\n');
                        break;
                    }
                }
@@ -223,7 +227,7 @@ InteractiveBackend(char *inBuf)
                else
                    backslashSeen = false;
 
-               *stuff++ = (char) c;
+               appendStringInfoChar(inBuf, (char) c);
            }
 
            if (c == EOF)
@@ -236,9 +240,9 @@ InteractiveBackend(char *inBuf)
             * ----------------
             */
            while ((c = getc(stdin)) != EOF)
-               *stuff++ = (char) c;
+               appendStringInfoChar(inBuf, (char) c);
 
-           if (stuff == inBuf)
+           if (inBuf->len == 0)
                end = true;
        }
 
@@ -261,7 +265,7 @@ InteractiveBackend(char *inBuf)
     * ----------------
     */
    if (EchoQuery)
-       printf("query: %s\n", inBuf);
+       printf("query: %s\n", inBuf->data);
    fflush(stdout);
 
    return 'Q';
@@ -274,7 +278,7 @@ InteractiveBackend(char *inBuf)
  * the user is placed in its parameter inBuf.
  *
  * If the input is a fastpath function call (case 'F') then
- * the function call is processed in HandleFunctionRequest().
+ * the function call is processed in HandleFunctionRequest()
  * (now called from PostgresMain()).
  *
  *  EOF is returned if the connection is lost.
@@ -282,7 +286,7 @@ InteractiveBackend(char *inBuf)
  */
 
 static int
-SocketBackend(char *inBuf)
+SocketBackend(StringInfo inBuf)
 {
    char        qtype;
    char        result = '\0';
@@ -302,7 +306,7 @@ SocketBackend(char *inBuf)
             * ----------------
             */
        case 'Q':
-           if (pq_getstr(inBuf, MAX_PARSE_BUFFER))
+           if (pq_getstr(inBuf))
                return EOF;
            result = 'Q';
            break;
@@ -312,7 +316,7 @@ SocketBackend(char *inBuf)
             * ----------------
             */
        case 'F':
-           if (pq_getstr(inBuf, MAX_PARSE_BUFFER))
+           if (pq_getstr(inBuf))
                return EOF;     /* ignore "string" at start of F message */
            result = 'F';
            break;
@@ -347,12 +351,21 @@ SocketBackend(char *inBuf)
  * ----------------
  */
 static int
-ReadCommand(char *inBuf)
+ReadCommand(StringInfo inBuf)
 {
+   MemoryContext   oldcontext;
+   int             result;
+
+   /* Make sure any expansion of inBuf happens in permanent memory context,
+    * so that we can keep using it for future command cycles.
+    */
+   oldcontext = MemoryContextSwitchTo(TopMemoryContext);
    if (IsUnderPostmaster)
-       return SocketBackend(inBuf);
+       result = SocketBackend(inBuf);
    else
-       return InteractiveBackend(inBuf);
+       result = InteractiveBackend(inBuf);
+   MemoryContextSwitchTo(oldcontext);
+   return result;
 }
 
 List *
@@ -374,45 +387,7 @@ pg_parse_and_plan(char *query_string,  /* string to execute */
 
    if (DebugPrintQuery)
    {
-       if (DebugPrintQuery > 3)
-       {
-           /* Print the query string as is if query debug level > 3 */
-           TPRINTF(TRACE_QUERY, "query: %s", query_string);
-       }
-       else
-       {
-           /* Print condensed query string to fit in one log line */
-           char        buff[MAX_QUERY_SIZE + 1];
-           char        c,
-                      *s,
-                      *d;
-           int         n,
-                       is_space = 1;
-
-           for (s = query_string, d = buff, n = 0; (c = *s) && (n < MAX_QUERY_SIZE); s++)
-           {
-               switch (c)
-               {
-                   case '\r':
-                   case '\n':
-                   case '\t':
-                       c = ' ';
-                       /* fall through */
-                   case ' ':
-                       if (is_space)
-                           continue;
-                       is_space = 1;
-                       break;
-                   default:
-                       is_space = 0;
-                       break;
-               }
-               *d++ = c;
-               n++;
-           }
-           *d = '\0';
-           TPRINTF(TRACE_QUERY, "query: %s", buff);
-       }
+       TPRINTF(TRACE_QUERY, "query: %s", query_string);
    }
 
    /* ----------------
@@ -889,7 +864,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
    int         errs = 0;
 
    int         firstchar;
-   char        parser_input[MAX_PARSE_BUFFER];
+   StringInfo  parser_input;
    char       *userName;
 
    /* Used if verbose is set, must be initialized */
@@ -1452,6 +1427,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
 
    on_shmem_exit(remove_all_temp_relations, NULL);
 
+   parser_input = makeStringInfo(); /* initialize input buffer */
+
    /* ----------------
     *  Set up handler for cancel-request signal, and
     *  send this backend's cancellation info to the frontend.
@@ -1492,7 +1469,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
    if (!IsUnderPostmaster)
    {
        puts("\nPOSTGRES backend interactive interface ");
-       puts("$Revision: 1.127 $ $Date: 1999/07/22 02:40:07 $\n");
+       puts("$Revision: 1.128 $ $Date: 1999/08/31 04:26:40 $\n");
    }
 
    /* ----------------
@@ -1548,8 +1525,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
         *   (3) read a command.
         * ----------------
         */
-       MemSet(parser_input, 0, MAX_PARSE_BUFFER);
-
        firstchar = ReadCommand(parser_input);
 
        QueryCancel = false;    /* forget any earlier CANCEL signal */
@@ -1592,7 +1567,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
                 * ----------------
                 */
            case 'Q':
-               if (strspn(parser_input, " \t\n") == strlen(parser_input))
+               if (strspn(parser_input->data, " \t\n") == parser_input->len)
                {
                    /* ----------------
                     *  if there is nothing in the input buffer, don't bother
@@ -1616,7 +1591,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
                        TPRINTF(TRACE_VERBOSE, "StartTransactionCommand");
                    StartTransactionCommand();
 
-                   pg_exec_query(parser_input);
+                   pg_exec_query(parser_input->data);
 
                    if (ShowStats)
                        ShowUsage();
index f4086c1137e52c969ee1c35e5101ec482dec6b23..463c5564b413a36c3275768ff47a2d9e6f7c0845 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: libpq.h,v 1.32 1999/07/15 15:21:15 momjian Exp $
+ * $Id: libpq.h,v 1.33 1999/08/31 04:26:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,6 +17,7 @@
 
 #include 
 
+#include "lib/stringinfo.h"
 #include "libpq/libpq-be.h"
 #include "tcop/dest.h"
 #include "utils/exc.h"
@@ -241,7 +242,7 @@ extern void pq_init(void);
 extern int pq_getport(void);
 extern void pq_close(void);
 extern int pq_getbytes(char *s, size_t len);
-extern int pq_getstring(char *s, size_t len);
+extern int pq_getstring(StringInfo s);
 extern int pq_peekbyte(void);
 extern int pq_putbytes(const char *s, size_t len);
 extern int pq_flush(void);
index d9481970372a9b53485310093d75d2ef3a7c3ca7..181428265ac8f6613ba42abeccb8383042178811 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pqcomm.h,v 1.38 1999/07/17 20:18:29 momjian Exp $
+ * $Id: pqcomm.h,v 1.39 1999/08/31 04:26:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include 
 #endif
 
-/*
- * Internal send/receive buffers in libpq.
- */
-#define PQ_BUFFER_SIZE 8192
-
 /* Define a generic socket address type. */
 
 typedef union SockAddr
index c7289e239036a7874a6ebbd809080466683fe56c..0871ee9673ea279aa95531b248bc5f9a6dbb8656 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pqformat.h,v 1.5 1999/07/15 15:21:16 momjian Exp $
+ * $Id: pqformat.h,v 1.6 1999/08/31 04:26:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,6 +26,6 @@ extern void pq_endmessage(StringInfo buf);
 extern int pq_puttextmessage(char msgtype, const char *str);
 
 extern int pq_getint(int *result, int b);
-extern int pq_getstr(char *s, int maxlen);
+extern int pq_getstr(StringInfo s);
 
 #endif  /* PQFORMAT_H */