提交 e25e6a6d 编写于 作者: T Tom Lane

Commit the bulk of Mike Ansley's long-query changes in the

backend.  Still much left to do.
上级 ab5cafa5
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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) ...@@ -526,38 +526,32 @@ pq_getbytes(char *s, size_t len)
/* -------------------------------- /* --------------------------------
* pq_getstring - get a null terminated string from connection * 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, * NOTE: this routine does not do any MULTIBYTE conversion,
* even though it is presumably useful only for text, because * even though it is presumably useful only for text, because
* no code in this module should depend on MULTIBYTE mode. * no code in this module should depend on MULTIBYTE mode.
* See pq_getstr in pqformat.c for that. * 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 * returns 0 if OK, EOF if trouble
* -------------------------------- * --------------------------------
*/ */
int int
pq_getstring(char *s, size_t len) pq_getstring(StringInfo s)
{ {
int c; int c;
/* /* Reset string to empty */
* Keep on reading until we get the terminating '\0', discarding any s->len = 0;
* bytes we don't have room for. s->data[0] = '\0';
*/
/* Read until we get the terminating '\0' */
while ((c = pq_getbyte()) != EOF && c != '\0') while ((c = pq_getbyte()) != EOF && c != '\0')
{ {
if (len > 1) appendStringInfoChar(s, c);
{
*s++ = c;
len--;
}
} }
*s = '\0';
if (c == EOF) if (c == EOF)
return EOF; return EOF;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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) ...@@ -290,37 +290,30 @@ pq_getint(int *result, int b)
/* -------------------------------- /* --------------------------------
* pq_getstr - get a null terminated string from connection * pq_getstr - get a null terminated string from connection
* *
* FIXME: we ought to use an expansible StringInfo buffer, * The return value is placed in an expansible StringInfo.
* rather than dropping data if the message is too long. * Note that space allocation comes from the current memory context!
* *
* returns 0 if OK, EOF if trouble * returns 0 if OK, EOF if trouble
* -------------------------------- * --------------------------------
*/ */
int int
pq_getstr(char *s, int maxlen) pq_getstr(StringInfo s)
{ {
int c; int c;
#ifdef MULTIBYTE #ifdef MULTIBYTE
char *p; char *p;
#endif #endif
c = pq_getstring(s, maxlen); c = pq_getstring(s);
#ifdef MULTIBYTE #ifdef MULTIBYTE
p = (char *) pg_client_to_server((unsigned char *) s, strlen(s)); p = (char *) pg_client_to_server((unsigned char *) s->data, s->len);
if (p != s) /* actual conversion has been done? */ if (p != s->data) /* actual conversion has been done? */
{ {
int newlen = strlen(p); /* reset s to empty, and append the new string p */
s->len = 0;
if (newlen < maxlen) s->data[0] = '\0';
strcpy(s, p); appendBinaryStringInfo(s, p, strlen(p));
else
{
strncpy(s, p, maxlen);
s[maxlen - 1] = '\0';
}
} }
#endif #endif
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -158,9 +158,9 @@ int _exec_repeat_ = 1; ...@@ -158,9 +158,9 @@ int _exec_repeat_ = 1;
* decls for routines only used in this file * decls for routines only used in this file
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
static int InteractiveBackend(char *inBuf); static int InteractiveBackend(StringInfo inBuf);
static int SocketBackend(char *inBuf); static int SocketBackend(StringInfo inBuf);
static int ReadCommand(char *inBuf); static int ReadCommand(StringInfo inBuf);
static void pg_exec_query(char *query_string); static void pg_exec_query(char *query_string);
...@@ -178,9 +178,8 @@ static void pg_exec_query(char *query_string); ...@@ -178,9 +178,8 @@ static void pg_exec_query(char *query_string);
*/ */
static int static int
InteractiveBackend(char *inBuf) InteractiveBackend(StringInfo inBuf)
{ {
char *stuff = inBuf; /* current place in input buffer */
int c; /* character read from getc() */ int c; /* character read from getc() */
bool end = false; /* end-of-input flag */ bool end = false; /* end-of-input flag */
bool backslashSeen = false; /* have we seen a \ ? */ bool backslashSeen = false; /* have we seen a \ ? */
...@@ -192,6 +191,10 @@ InteractiveBackend(char *inBuf) ...@@ -192,6 +191,10 @@ InteractiveBackend(char *inBuf)
printf("backend> "); printf("backend> ");
fflush(stdout); fflush(stdout);
/* Reset inBuf to empty */
inBuf->len = 0;
inBuf->data[0] = '\0';
for (;;) for (;;)
{ {
if (UseNewLine) if (UseNewLine)
...@@ -207,14 +210,15 @@ InteractiveBackend(char *inBuf) ...@@ -207,14 +210,15 @@ InteractiveBackend(char *inBuf)
{ {
if (backslashSeen) if (backslashSeen)
{ {
stuff--; /* discard backslash from inBuf */
inBuf->data[--inBuf->len] = '\0';
backslashSeen = false;
continue; continue;
} }
else else
{ {
/* keep the newline character */ /* keep the newline character */
*stuff++ = '\n'; appendStringInfoChar(inBuf, '\n');
*stuff++ = '\0';
break; break;
} }
} }
...@@ -223,7 +227,7 @@ InteractiveBackend(char *inBuf) ...@@ -223,7 +227,7 @@ InteractiveBackend(char *inBuf)
else else
backslashSeen = false; backslashSeen = false;
*stuff++ = (char) c; appendStringInfoChar(inBuf, (char) c);
} }
if (c == EOF) if (c == EOF)
...@@ -236,9 +240,9 @@ InteractiveBackend(char *inBuf) ...@@ -236,9 +240,9 @@ InteractiveBackend(char *inBuf)
* ---------------- * ----------------
*/ */
while ((c = getc(stdin)) != EOF) while ((c = getc(stdin)) != EOF)
*stuff++ = (char) c; appendStringInfoChar(inBuf, (char) c);
if (stuff == inBuf) if (inBuf->len == 0)
end = true; end = true;
} }
...@@ -261,7 +265,7 @@ InteractiveBackend(char *inBuf) ...@@ -261,7 +265,7 @@ InteractiveBackend(char *inBuf)
* ---------------- * ----------------
*/ */
if (EchoQuery) if (EchoQuery)
printf("query: %s\n", inBuf); printf("query: %s\n", inBuf->data);
fflush(stdout); fflush(stdout);
return 'Q'; return 'Q';
...@@ -274,7 +278,7 @@ InteractiveBackend(char *inBuf) ...@@ -274,7 +278,7 @@ InteractiveBackend(char *inBuf)
* the user is placed in its parameter inBuf. * the user is placed in its parameter inBuf.
* *
* If the input is a fastpath function call (case 'F') then * 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()). * (now called from PostgresMain()).
* *
* EOF is returned if the connection is lost. * EOF is returned if the connection is lost.
...@@ -282,7 +286,7 @@ InteractiveBackend(char *inBuf) ...@@ -282,7 +286,7 @@ InteractiveBackend(char *inBuf)
*/ */
static int static int
SocketBackend(char *inBuf) SocketBackend(StringInfo inBuf)
{ {
char qtype; char qtype;
char result = '\0'; char result = '\0';
...@@ -302,7 +306,7 @@ SocketBackend(char *inBuf) ...@@ -302,7 +306,7 @@ SocketBackend(char *inBuf)
* ---------------- * ----------------
*/ */
case 'Q': case 'Q':
if (pq_getstr(inBuf, MAX_PARSE_BUFFER)) if (pq_getstr(inBuf))
return EOF; return EOF;
result = 'Q'; result = 'Q';
break; break;
...@@ -312,7 +316,7 @@ SocketBackend(char *inBuf) ...@@ -312,7 +316,7 @@ SocketBackend(char *inBuf)
* ---------------- * ----------------
*/ */
case 'F': case 'F':
if (pq_getstr(inBuf, MAX_PARSE_BUFFER)) if (pq_getstr(inBuf))
return EOF; /* ignore "string" at start of F message */ return EOF; /* ignore "string" at start of F message */
result = 'F'; result = 'F';
break; break;
...@@ -347,12 +351,21 @@ SocketBackend(char *inBuf) ...@@ -347,12 +351,21 @@ SocketBackend(char *inBuf)
* ---------------- * ----------------
*/ */
static int 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) if (IsUnderPostmaster)
return SocketBackend(inBuf); result = SocketBackend(inBuf);
else else
return InteractiveBackend(inBuf); result = InteractiveBackend(inBuf);
MemoryContextSwitchTo(oldcontext);
return result;
} }
List * List *
...@@ -374,45 +387,7 @@ pg_parse_and_plan(char *query_string, /* string to execute */ ...@@ -374,45 +387,7 @@ pg_parse_and_plan(char *query_string, /* string to execute */
if (DebugPrintQuery) if (DebugPrintQuery)
{ {
if (DebugPrintQuery > 3) TPRINTF(TRACE_QUERY, "query: %s", query_string);
{
/* 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);
}
} }
/* ---------------- /* ----------------
...@@ -889,7 +864,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) ...@@ -889,7 +864,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
int errs = 0; int errs = 0;
int firstchar; int firstchar;
char parser_input[MAX_PARSE_BUFFER]; StringInfo parser_input;
char *userName; char *userName;
/* Used if verbose is set, must be initialized */ /* Used if verbose is set, must be initialized */
...@@ -1452,6 +1427,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) ...@@ -1452,6 +1427,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
on_shmem_exit(remove_all_temp_relations, NULL); on_shmem_exit(remove_all_temp_relations, NULL);
parser_input = makeStringInfo(); /* initialize input buffer */
/* ---------------- /* ----------------
* Set up handler for cancel-request signal, and * Set up handler for cancel-request signal, and
* send this backend's cancellation info to the frontend. * send this backend's cancellation info to the frontend.
...@@ -1492,7 +1469,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) ...@@ -1492,7 +1469,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); 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[]) ...@@ -1548,8 +1525,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
* (3) read a command. * (3) read a command.
* ---------------- * ----------------
*/ */
MemSet(parser_input, 0, MAX_PARSE_BUFFER);
firstchar = ReadCommand(parser_input); firstchar = ReadCommand(parser_input);
QueryCancel = false; /* forget any earlier CANCEL signal */ QueryCancel = false; /* forget any earlier CANCEL signal */
...@@ -1592,7 +1567,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) ...@@ -1592,7 +1567,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
* ---------------- * ----------------
*/ */
case 'Q': 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 * 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[]) ...@@ -1616,7 +1591,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
TPRINTF(TRACE_VERBOSE, "StartTransactionCommand"); TPRINTF(TRACE_VERBOSE, "StartTransactionCommand");
StartTransactionCommand(); StartTransactionCommand();
pg_exec_query(parser_input); pg_exec_query(parser_input->data);
if (ShowStats) if (ShowStats)
ShowUsage(); ShowUsage();
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -17,6 +17,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include "lib/stringinfo.h"
#include "libpq/libpq-be.h" #include "libpq/libpq-be.h"
#include "tcop/dest.h" #include "tcop/dest.h"
#include "utils/exc.h" #include "utils/exc.h"
...@@ -241,7 +242,7 @@ extern void pq_init(void); ...@@ -241,7 +242,7 @@ extern void pq_init(void);
extern int pq_getport(void); extern int pq_getport(void);
extern void pq_close(void); extern void pq_close(void);
extern int pq_getbytes(char *s, size_t len); 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_peekbyte(void);
extern int pq_putbytes(const char *s, size_t len); extern int pq_putbytes(const char *s, size_t len);
extern int pq_flush(void); extern int pq_flush(void);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -26,11 +26,6 @@ ...@@ -26,11 +26,6 @@
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
/*
* Internal send/receive buffers in libpq.
*/
#define PQ_BUFFER_SIZE 8192
/* Define a generic socket address type. */ /* Define a generic socket address type. */
typedef union SockAddr typedef union SockAddr
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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); ...@@ -26,6 +26,6 @@ extern void pq_endmessage(StringInfo buf);
extern int pq_puttextmessage(char msgtype, const char *str); extern int pq_puttextmessage(char msgtype, const char *str);
extern int pq_getint(int *result, int b); 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 */ #endif /* PQFORMAT_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册