mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Commit the bulk of Mike Ansley's long-query changes in the
backend. Still much left to do.
This commit is contained in:
@ -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,37 +526,31 @@ 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 @@
|
|||||||
*
|
*
|
||||||
* 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)
|
|||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
* 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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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;
|
|||||||
* 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);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
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)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
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)
|
|||||||
* 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)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
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)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
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)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
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,46 +387,8 @@ pg_parse_and_plan(char *query_string, /* string to execute */
|
|||||||
|
|
||||||
if (DebugPrintQuery)
|
if (DebugPrintQuery)
|
||||||
{
|
{
|
||||||
if (DebugPrintQuery > 3)
|
|
||||||
{
|
|
||||||
/* Print the query string as is if query debug level > 3 */
|
|
||||||
TPRINTF(TRACE_QUERY, "query: %s", query_string);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* (1) parse the request string into a list of parse trees
|
* (1) parse the request string into a list of parse trees
|
||||||
@ -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[])
|
|||||||
|
|
||||||
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[])
|
|||||||
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[])
|
|||||||
* (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[])
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
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[])
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
|
|
||||||
#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);
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
#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 @@
|
|||||||
*
|
*
|
||||||
* 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);
|
|||||||
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 */
|
||||||
|
Reference in New Issue
Block a user