Commit f1de4f95 authored by Tom Lane's avatar Tom Lane

Additional long-query fixes from Mike Ansley and yours truly.

psql.c seems clean of query length restrictions now.
parent d2f7d1f3
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.188 1999/07/20 17:20:43 momjian Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.189 1999/09/06 23:30:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "postgres.h" #include "postgres.h"
#include "libpq-fe.h" #include "libpq-fe.h"
#include "pqexpbuffer.h"
#include "pqsignal.h" #include "pqsignal.h"
#include "stringutils.h" #include "stringutils.h"
#include "psqlHelp.h" #include "psqlHelp.h"
...@@ -108,7 +109,7 @@ static char *has_client_encoding = 0; ...@@ -108,7 +109,7 @@ static char *has_client_encoding = 0;
/* Backslash command handling: /* Backslash command handling:
* 0 - send currently constructed query to backend (i.e. we got a \g) * 0 - send currently constructed query to backend (i.e. we got a \g)
* 1 - skip processing of this line, continue building up query * 1 - skip processing of this line, continue building up query
* 2 - terminate processing of this query entirely * 2 - terminate processing (i.e. we got a \q)
* 3 - new query supplied by edit * 3 - new query supplied by edit
*/ */
#define CMD_UNKNOWN -1 #define CMD_UNKNOWN -1
...@@ -117,8 +118,6 @@ static char *has_client_encoding = 0; ...@@ -117,8 +118,6 @@ static char *has_client_encoding = 0;
#define CMD_TERMINATE 2 #define CMD_TERMINATE 2
#define CMD_NEWEDIT 3 #define CMD_NEWEDIT 3
#define MAX_QUERY_BUFFER MAX_QUERY_SIZE
#define COPYBUFSIZ 8192 #define COPYBUFSIZ 8192
#define DEFAULT_FIELD_SEP "|" #define DEFAULT_FIELD_SEP "|"
...@@ -188,8 +187,9 @@ static char *gets_fromFile(char *prompt, FILE *source); ...@@ -188,8 +187,9 @@ static char *gets_fromFile(char *prompt, FILE *source);
static int listAllDbs(PsqlSettings *pset); static int listAllDbs(PsqlSettings *pset);
static bool SendQuery(PsqlSettings *pset, const char *query, static bool SendQuery(PsqlSettings *pset, const char *query,
FILE *copy_in_stream, FILE *copy_out_stream); FILE *copy_in_stream, FILE *copy_out_stream);
static int HandleSlashCmds(PsqlSettings *pset, char *line, char *query); static int HandleSlashCmds(PsqlSettings *pset, char *line,
static int MainLoop(PsqlSettings *pset, char *query, FILE *source); PQExpBuffer query_buf);
static int MainLoop(PsqlSettings *pset, FILE *source);
static FILE *setFout(PsqlSettings *pset, char *fname); static FILE *setFout(PsqlSettings *pset, char *fname);
static char *selectVersion(PsqlSettings *pset); static char *selectVersion(PsqlSettings *pset);
...@@ -1100,11 +1100,18 @@ objectDescription(PsqlSettings *pset, char *object) ...@@ -1100,11 +1100,18 @@ objectDescription(PsqlSettings *pset, char *object)
return 0; return 0;
} }
/*
* Basic routines to read a line of input
*
* All three routines will return a malloc'd string of indefinite size.
*/
typedef char *(*READ_ROUTINE) (char *prompt, FILE *source); typedef char *(*READ_ROUTINE) (char *prompt, FILE *source);
/* /*
* gets_noreadline prompt source gets a line of input without calling * gets_noreadline
* readline, the source is ignored * gets a line of interactive input (without using readline)
*
* the source is ignored
*/ */
static char * static char *
gets_noreadline(char *prompt, FILE *source) gets_noreadline(char *prompt, FILE *source)
...@@ -1115,8 +1122,10 @@ gets_noreadline(char *prompt, FILE *source) ...@@ -1115,8 +1122,10 @@ gets_noreadline(char *prompt, FILE *source)
} }
/* /*
* gets_readline prompt source the routine to get input from GNU readline(), * gets_readline
* the source is ignored the prompt argument is used as the prompting string * gets a line of interactive input using readline library
*
* the source is ignored
*/ */
static char * static char *
gets_readline(char *prompt, FILE *source) gets_readline(char *prompt, FILE *source)
...@@ -1126,10 +1135,7 @@ gets_readline(char *prompt, FILE *source) ...@@ -1126,10 +1135,7 @@ gets_readline(char *prompt, FILE *source)
#ifdef USE_READLINE #ifdef USE_READLINE
s = readline(prompt); s = readline(prompt);
#else #else
char buf[500]; s = gets_noreadline(prompt, source);
printf("%s", prompt);
s = fgets(buf, 500, stdin);
#endif #endif
fputc('\r', stdout); fputc('\r', stdout);
fflush(stdout); fflush(stdout);
...@@ -1137,32 +1143,32 @@ gets_readline(char *prompt, FILE *source) ...@@ -1137,32 +1143,32 @@ gets_readline(char *prompt, FILE *source)
} }
/* /*
* gets_fromFile prompt source * gets_fromFile
* gets a line of noninteractive input from a file
* *
* the routine to read from a file, the prompt argument is ignored the source * the prompt is ignored
* argument is a FILE *
*/ */
static char * static char *
gets_fromFile(char *prompt, FILE *source) gets_fromFile(char *prompt, FILE *source)
{ {
char *line; PQExpBufferData buffer;
char line[COPYBUFSIZ];
line = malloc(MAX_QUERY_BUFFER); initPQExpBuffer(&buffer);
/* read up to MAX_QUERY_BUFFER characters */ while (fgets(line, COPYBUFSIZ, source) != NULL)
if (fgets(line, MAX_QUERY_BUFFER, source) == NULL)
{ {
free(line); appendPQExpBufferStr(&buffer, line);
return NULL; if (buffer.data[buffer.len-1] == '\n')
return buffer.data;
} }
line[MAX_QUERY_BUFFER - 1] = '\0'; /* this is unnecessary, I think */ if (buffer.len > 0)
if (strlen(line) == MAX_QUERY_BUFFER - 1) return buffer.data; /* EOF after reading some bufferload(s) */
{
fprintf(stderr, "line read exceeds maximum length. Truncating at %d\n", /* EOF, so return null */
MAX_QUERY_BUFFER - 1); termPQExpBuffer(&buffer);
} return NULL;
return line;
} }
/* /*
...@@ -1630,15 +1636,15 @@ do_connect(const char *new_dbname, ...@@ -1630,15 +1636,15 @@ do_connect(const char *new_dbname,
static void static void
do_edit(const char *filename_arg, char *query, int *status_p) do_edit(const char *filename_arg, PQExpBuffer query_buf, int *status_p)
{ {
int fd; int fd;
char tmp[64]; char fnametmp[64];
char *fname; char *fname;
int cc; int cc;
const int ql = strlen(query); int ql = query_buf->len;
bool error; bool error;
char line[COPYBUFSIZ+1];
if (filename_arg) if (filename_arg)
{ {
...@@ -1648,37 +1654,38 @@ do_edit(const char *filename_arg, char *query, int *status_p) ...@@ -1648,37 +1654,38 @@ do_edit(const char *filename_arg, char *query, int *status_p)
else else
{ {
#ifndef WIN32 #ifndef WIN32
sprintf(tmp, "/tmp/psql.%ld.%ld", (long) geteuid(), (long) getpid()); sprintf(fnametmp, "/tmp/psql.%ld.%ld",
(long) geteuid(), (long) getpid());
#else #else
GetTempFileName(".", "psql", 0, tmp); GetTempFileName(".", "psql", 0, fnametmp);
#endif #endif
fname = tmp; fname = fnametmp;
unlink(tmp); unlink(fname);
if (ql > 0) if ((fd = open(fname, O_EXCL | O_CREAT | O_WRONLY, 0600)) < 0)
{
if ((fd = open(tmp, O_EXCL | O_CREAT | O_WRONLY, 0600)) == -1)
{ {
perror(tmp); perror(fname);
error = true; error = true;
} }
else else
{ {
if (query[ql - 1] != '\n') if (ql == 0 || query_buf->data[ql - 1] != '\n')
strcat(query, "\n"); {
if (write(fd, query, ql) != ql) appendPQExpBufferChar(query_buf, '\n');
ql++;
}
if (write(fd, query_buf->data, ql) != ql)
{ {
perror(tmp); perror(fname);
close(fd); close(fd);
unlink(tmp); unlink(fname);
error = true; error = true;
} }
else else
error = false; {
close(fd); close(fd);
error = false;
} }
} }
else
error = false;
} }
if (error) if (error)
...@@ -1686,38 +1693,30 @@ do_edit(const char *filename_arg, char *query, int *status_p) ...@@ -1686,38 +1693,30 @@ do_edit(const char *filename_arg, char *query, int *status_p)
else else
{ {
editFile(fname); editFile(fname);
if ((fd = open(fname, O_RDONLY, 0)) == -1) if ((fd = open(fname, O_RDONLY, 0)) < 0)
{ {
perror(fname); perror(fname);
if (!filename_arg)
unlink(fname);
*status_p = CMD_SKIP_LINE; *status_p = CMD_SKIP_LINE;
} }
else else
{ {
if ((cc = read(fd, query, MAX_QUERY_BUFFER)) == -1) resetPQExpBuffer(query_buf);
while ((cc = (int) read(fd, line, COPYBUFSIZ)) > 0)
{ {
perror(fname); line[cc] = '\0';
close(fd); appendPQExpBufferStr(query_buf, line);
if (!filename_arg)
unlink(fname);
*status_p = CMD_SKIP_LINE;
} }
else
{
query[cc] = '\0';
close(fd); close(fd);
if (!filename_arg) rightTrim(query_buf->data);
unlink(fname); query_buf->len = strlen(query_buf->data);
rightTrim(query);
*status_p = CMD_NEWEDIT; *status_p = CMD_NEWEDIT;
} }
} if (!filename_arg)
unlink(fname);
} }
} }
static void static void
do_help(PsqlSettings *pset, const char *topic) do_help(PsqlSettings *pset, const char *topic)
{ {
...@@ -1832,48 +1831,49 @@ do_shell(const char *command) ...@@ -1832,48 +1831,49 @@ do_shell(const char *command)
/* /*----------
* HandleSlashCmds: * HandleSlashCmds:
* *
* Handles all the different commands that start with \ * Handles all the different commands that start with \
* db_ptr is a pointer to the TgDb* structure line is the current input *
* line prompt_ptr is a pointer to the prompt string, a pointer is used * 'line' is the current input line (ie, the backslash command)
* because the prompt can be used with a connection to a new database. * 'query_buf' contains the query-so-far, which may be modified by
* Returns a status: * execution of the backslash command (for example, \r clears it)
*
* query_buf can be NULL if there is no query-so-far.
*
* Returns a status code:
* 0 - send currently constructed query to backend (i.e. we got a \g) * 0 - send currently constructed query to backend (i.e. we got a \g)
* 1 - skip processing of this line, continue building up query * 1 - skip processing of this line, continue building up query
* 2 - terminate processing of this query entirely * 2 - terminate processing (i.e. we got a \q)
* 3 - new query supplied by edit * 3 - new query supplied by edit
*----------
*/ */
static int static int
HandleSlashCmds(PsqlSettings *pset, HandleSlashCmds(PsqlSettings *pset,
char *line, char *line,
char *query) PQExpBuffer query_buf)
{ {
int status = CMD_SKIP_LINE; int status = CMD_SKIP_LINE;
char *optarg;
bool success; bool success;
char *cmd;
/*
* String: value of the slash command, less the slash and with escape
* sequences decoded.
*/
char *optarg;
/* /*
* Pointer inside the <cmd> string to the argument of the slash * Pointer inside the <cmd> string to the argument of the slash
* command, assuming it is a one-character slash command. If it's not * command, assuming it is a one-character slash command. If it's not
* a one-character command, this is meaningless. * a one-character command, this is meaningless.
*/ */
char *optarg2; char *optarg2;
/* /*
* Pointer inside the <cmd> string to the argument of the slash * Pointer inside the <cmd> string to the argument of the slash
* command assuming it's not a one-character command. If it's a * command assuming it's not a one-character command. If it's a
* one-character command, this is meaningless. * one-character command, this is meaningless.
*/ */
char *cmd;
/*
* String: value of the slash command, less the slash and with escape
* sequences decoded.
*/
int blank_loc; int blank_loc;
/* Offset within <cmd> of first blank */ /* Offset within <cmd> of first blank */
cmd = malloc(strlen(line)); /* unescaping better not make string grow. */ cmd = malloc(strlen(line)); /* unescaping better not make string grow. */
...@@ -2202,10 +2202,9 @@ HandleSlashCmds(PsqlSettings *pset, ...@@ -2202,10 +2202,9 @@ HandleSlashCmds(PsqlSettings *pset,
break; break;
case 'e': /* edit */ case 'e': /* edit */
{ if (query_buf)
do_edit(optarg, query, &status); do_edit(optarg, query_buf, &status);
break; break;
}
case 'E': case 'E':
{ {
...@@ -2249,7 +2248,7 @@ HandleSlashCmds(PsqlSettings *pset, ...@@ -2249,7 +2248,7 @@ HandleSlashCmds(PsqlSettings *pset,
fclose(fd); fclose(fd);
break; break;
} }
MainLoop(pset, query, fd); MainLoop(pset, fd);
fclose(fd); fclose(fd);
break; break;
} }
...@@ -2316,7 +2315,7 @@ HandleSlashCmds(PsqlSettings *pset, ...@@ -2316,7 +2315,7 @@ HandleSlashCmds(PsqlSettings *pset,
fprintf(stderr, "file named %s could not be opened\n", optarg); fprintf(stderr, "file named %s could not be opened\n", optarg);
break; break;
} }
MainLoop(pset, query, fd); MainLoop(pset, fd);
fclose(fd); fclose(fd);
break; break;
} }
...@@ -2356,9 +2355,9 @@ HandleSlashCmds(PsqlSettings *pset, ...@@ -2356,9 +2355,9 @@ HandleSlashCmds(PsqlSettings *pset,
break; break;
case 'p': case 'p':
if (query) if (query_buf && query_buf->len > 0)
{ {
fputs(query, stdout); fputs(query_buf->data, stdout);
fputc('\n', stdout); fputc('\n', stdout);
} }
break; break;
...@@ -2368,9 +2367,12 @@ HandleSlashCmds(PsqlSettings *pset, ...@@ -2368,9 +2367,12 @@ HandleSlashCmds(PsqlSettings *pset,
break; break;
case 'r': /* reset(clear) the buffer */ case 'r': /* reset(clear) the buffer */
query[0] = '\0'; if (query_buf)
{
resetPQExpBuffer(query_buf);
if (!pset->quiet) if (!pset->quiet)
printf("buffer reset(cleared)\n"); printf("buffer reset(cleared)\n");
}
break; break;
case 's': /* \s is save history to a file */ case 's': /* \s is save history to a file */
...@@ -2416,8 +2418,9 @@ HandleSlashCmds(PsqlSettings *pset, ...@@ -2416,8 +2418,9 @@ HandleSlashCmds(PsqlSettings *pset,
fprintf(stderr, "file named %s could not be opened\n", optarg); fprintf(stderr, "file named %s could not be opened\n", optarg);
break; break;
} }
fputs(query, fd); if (query_buf)
fputs("\n", fd); fputs(query_buf->data, fd);
fputc('\n', fd);
fclose(fd); fclose(fd);
break; break;
} }
...@@ -2453,9 +2456,10 @@ HandleSlashCmds(PsqlSettings *pset, ...@@ -2453,9 +2456,10 @@ HandleSlashCmds(PsqlSettings *pset,
*/ */
static int static int
MainLoop(PsqlSettings *pset, char *query, FILE *source) MainLoop(PsqlSettings *pset, FILE *source)
{ {
char *line; /* line of input */ PQExpBuffer query_buf; /* buffer for query being accumulated */
char *line; /* current line of input */
char *xcomment; /* start of extended comment */ char *xcomment; /* start of extended comment */
int len; /* length of the line */ int len; /* length of the line */
int successResult = 1; int successResult = 1;
...@@ -2491,9 +2495,6 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2491,9 +2495,6 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
cur_cmd_source = source; cur_cmd_source = source;
cur_cmd_interactive = ((source == stdin) && !pset->notty); cur_cmd_interactive = ((source == stdin) && !pset->notty);
if ((query = malloc(MAX_QUERY_BUFFER)) == NULL)
perror("Memory Allocation Failed");
if (cur_cmd_interactive) if (cur_cmd_interactive)
{ {
if (pset->prompt) if (pset->prompt)
...@@ -2516,7 +2517,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2516,7 +2517,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
else else
GetNextLine = gets_fromFile; GetNextLine = gets_fromFile;
query[0] = '\0'; query_buf = createPQExpBuffer();
xcomment = NULL; xcomment = NULL;
in_quote = false; in_quote = false;
paren_level = 0; paren_level = 0;
...@@ -2525,24 +2526,25 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2525,24 +2526,25 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
/* main loop to get queries and execute them */ /* main loop to get queries and execute them */
while (!eof) while (!eof)
{ {
if (slashCmdStatus == CMD_NEWEDIT)
{
/* /*
* just returned from editing the line? then just copy to the * just returned from editing the line? then just copy to the
* input buffer * input buffer
*/ */
if (slashCmdStatus == CMD_NEWEDIT) line = strdup(query_buf->data);
{ resetPQExpBuffer(query_buf);
/* reset parsing state since we are rescanning whole query */
xcomment = NULL;
in_quote = false;
paren_level = 0; paren_level = 0;
line = strdup(query);
query[0] = '\0';
/*
* otherwise, get another line and set interactive prompt if
* necessary
*/
} }
else else
{ {
/*
* otherwise, set interactive prompt if necessary
* and get another line
*/
if (cur_cmd_interactive && !pset->quiet) if (cur_cmd_interactive && !pset->quiet)
{ {
if (in_quote && in_quote == PROMPT_SINGLEQUOTE) if (in_quote && in_quote == PROMPT_SINGLEQUOTE)
...@@ -2551,7 +2553,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2551,7 +2553,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
pset->prompt[strlen(pset->prompt) - 3] = PROMPT_DOUBLEQUOTE; pset->prompt[strlen(pset->prompt) - 3] = PROMPT_DOUBLEQUOTE;
else if (xcomment != NULL) else if (xcomment != NULL)
pset->prompt[strlen(pset->prompt) - 3] = PROMPT_COMMENT; pset->prompt[strlen(pset->prompt) - 3] = PROMPT_COMMENT;
else if (query[0] != '\0' && !querySent) else if (query_buf->len > 0 && !querySent)
pset->prompt[strlen(pset->prompt) - 3] = PROMPT_CONTINUE; pset->prompt[strlen(pset->prompt) - 3] = PROMPT_CONTINUE;
else else
pset->prompt[strlen(pset->prompt) - 3] = PROMPT_READY; pset->prompt[strlen(pset->prompt) - 3] = PROMPT_READY;
...@@ -2564,8 +2566,9 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2564,8 +2566,9 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
} }
/* /*
* query - pointer to current command query_start - placeholder * query_buf holds query already accumulated. line is the malloc'd
* for next command * new line of input (note it must be freed before looping around!)
* query_start is the next command start location within the line.
*/ */
if (line == NULL || (!cur_cmd_interactive && *line == '\0')) if (line == NULL || (!cur_cmd_interactive && *line == '\0'))
{ /* No more input. Time to quit, or \i { /* No more input. Time to quit, or \i
...@@ -2580,11 +2583,10 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2580,11 +2583,10 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
if (xcomment == NULL) if (xcomment == NULL)
{ {
query_start = line; query_start = line;
/* otherwise, continue the extended comment... */
} }
else else
{ {
/* otherwise, continue the extended comment... */
query_start = line; query_start = line;
xcomment = line; xcomment = line;
} }
...@@ -2617,6 +2619,8 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2617,6 +2619,8 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
int i; int i;
/* /*
* Parse line, looking for command separators.
*
* The current character is at line[i], the prior character at * The current character is at line[i], the prior character at
* line[i - prevlen], the next character at line[i + thislen]. * line[i - prevlen], the next character at line[i + thislen].
*/ */
...@@ -2636,29 +2640,28 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2636,29 +2640,28 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
{ {
if (line[i] == '\\' && !in_quote) if (line[i] == '\\' && !in_quote)
{ {
/* backslash command. Copy whatever is before \ to
* query_buf.
*/
char hold_char = line[i]; char hold_char = line[i];
line[i] = '\0'; line[i] = '\0';
if (query_start[0] != '\0') if (query_start[0] != '\0')
{ {
if (query[0] != '\0') if (query_buf->len > 0)
{ appendPQExpBufferChar(query_buf, '\n');
strcat(query, "\n"); appendPQExpBufferStr(query_buf, query_start);
strcat(query, query_start);
}
else
strcpy(query, query_start);
} }
line[i] = hold_char; line[i] = hold_char;
query_start = line + i; query_start = line + i;
break; /* handle command */ break; /* go handle backslash command */
} }
if (querySent && if (querySent &&
isascii((unsigned char) (line[i])) && isascii((unsigned char) (line[i])) &&
!isspace(line[i])) !isspace(line[i]))
{ {
query[0] = '\0'; resetPQExpBuffer(query_buf);
querySent = false; querySent = false;
} }
...@@ -2705,18 +2708,13 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2705,18 +2708,13 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
char hold_char = line[i + thislen]; char hold_char = line[i + thislen];
line[i + thislen] = '\0'; line[i + thislen] = '\0';
if ((query_start[0] != '\0') && if (query_start[0] != '\0')
(strlen(query) + strlen(query_start) <= MAX_QUERY_BUFFER))
{
if (query[0] != '\0')
{ {
strcat(query, "\n"); if (query_buf->len > 0)
strcat(query, query_start); appendPQExpBufferChar(query_buf, '\n');
} appendPQExpBufferStr(query_buf, query_start);
else
strcpy(query, query_start);
} }
success = SendQuery(pset, query, NULL, NULL); success = SendQuery(pset, query_buf->data, NULL, NULL);
successResult &= success; successResult &= success;
line[i + thislen] = hold_char; line[i + thislen] = hold_char;
query_start = line + i + thislen; query_start = line + i + thislen;
...@@ -2745,7 +2743,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2745,7 +2743,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
if (!in_quote && query_start[0] == '\\') if (!in_quote && query_start[0] == '\\')
{ {
/* handle \p\g and other backslash combinations */ /* loop to handle \p\g and other backslash combinations */
while (query_start[0] != '\0') while (query_start[0] != '\0')
{ {
char hold_char; char hold_char;
...@@ -2766,11 +2764,11 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2766,11 +2764,11 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
slashCmdStatus = HandleSlashCmds(pset, slashCmdStatus = HandleSlashCmds(pset,
query_start, query_start,
query); query_buf);
if (slashCmdStatus == CMD_SKIP_LINE && !hold_char) if (slashCmdStatus == CMD_SKIP_LINE && !hold_char)
{ {
if (query[0] == '\0') if (query_buf->len == 0)
paren_level = 0; paren_level = 0;
break; break;
} }
...@@ -2782,29 +2780,17 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2782,29 +2780,17 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
query_start[0] = hold_char; query_start[0] = hold_char;
} }
free(line); free(line);
/* They did \q, leave the loop */
if (slashCmdStatus == CMD_TERMINATE) if (slashCmdStatus == CMD_TERMINATE)
break; break; /* They did \q, leave the loop */
}
else if (strlen(query) + strlen(query_start) > MAX_QUERY_BUFFER)
{
fprintf(stderr, "query buffer max length of %d exceeded\n",
MAX_QUERY_BUFFER);
fprintf(stderr, "query line ignored\n");
free(line);
} }
else else
{ {
if (query_start[0] != '\0') if (query_start[0] != '\0')
{ {
querySent = false; querySent = false;
if (query[0] != '\0') if (query_buf->len > 0)
{ appendPQExpBufferChar(query_buf, '\n');
strcat(query, "\n"); appendPQExpBufferStr(query_buf, query_start);
strcat(query, query_start);
}
else
strcpy(query, query_start);
} }
free(line); free(line);
} }
...@@ -2812,7 +2798,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2812,7 +2798,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
/* had a backslash-g? force the query to be sent */ /* had a backslash-g? force the query to be sent */
if (slashCmdStatus == CMD_SEND) if (slashCmdStatus == CMD_SEND)
{ {
success = SendQuery(pset, query, NULL, NULL); success = SendQuery(pset, query_buf->data, NULL, NULL);
successResult &= success; successResult &= success;
xcomment = NULL; xcomment = NULL;
in_quote = false; in_quote = false;
...@@ -2821,8 +2807,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) ...@@ -2821,8 +2807,7 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source)
} }
} /* while */ } /* while */
if (query) destroyPQExpBuffer(query_buf);
free(query);
cur_cmd_source = prev_cmd_source; cur_cmd_source = prev_cmd_source;
cur_cmd_interactive = prev_cmd_interactive; cur_cmd_interactive = prev_cmd_interactive;
...@@ -3025,7 +3010,7 @@ main(int argc, char **argv) ...@@ -3025,7 +3010,7 @@ main(int argc, char **argv)
* 20.06.97 ACRM See if we've got a /etc/psqlrc or .psqlrc file * 20.06.97 ACRM See if we've got a /etc/psqlrc or .psqlrc file
*/ */
if (!access("/etc/psqlrc", R_OK)) if (!access("/etc/psqlrc", R_OK))
HandleSlashCmds(&settings, "\\i /etc/psqlrc", ""); HandleSlashCmds(&settings, "\\i /etc/psqlrc", NULL);
if ((home = getenv("HOME")) != NULL) if ((home = getenv("HOME")) != NULL)
{ {
char *psqlrc = NULL, char *psqlrc = NULL,
...@@ -3039,7 +3024,7 @@ main(int argc, char **argv) ...@@ -3039,7 +3024,7 @@ main(int argc, char **argv)
if ((line = (char *) malloc(strlen(psqlrc) + 5)) != NULL) if ((line = (char *) malloc(strlen(psqlrc) + 5)) != NULL)
{ {
sprintf(line, "\\i %s", psqlrc); sprintf(line, "\\i %s", psqlrc);
HandleSlashCmds(&settings, line, ""); HandleSlashCmds(&settings, line, NULL);
free(line); free(line);
} }
} }
...@@ -3067,7 +3052,7 @@ main(int argc, char **argv) ...@@ -3067,7 +3052,7 @@ main(int argc, char **argv)
line = malloc(strlen(qfilename) + 5); line = malloc(strlen(qfilename) + 5);
sprintf(line, "\\i %s", qfilename); sprintf(line, "\\i %s", qfilename);
} }
HandleSlashCmds(&settings, line, ""); HandleSlashCmds(&settings, line, NULL);
free(line); free(line);
} }
else else
...@@ -3075,7 +3060,7 @@ main(int argc, char **argv) ...@@ -3075,7 +3060,7 @@ main(int argc, char **argv)
if (singleQuery) if (singleQuery)
successResult = SendQuery(&settings, singleQuery, NULL, NULL); successResult = SendQuery(&settings, singleQuery, NULL, NULL);
else else
successResult = MainLoop(&settings, NULL, stdin); successResult = MainLoop(&settings, stdin);
} }
PQfinish(settings.db); PQfinish(settings.db);
...@@ -3086,8 +3071,6 @@ main(int argc, char **argv) ...@@ -3086,8 +3071,6 @@ main(int argc, char **argv)
return !successResult; return !successResult;
} }
#define COPYBUFSIZ 8192
static bool static bool
handleCopyOut(PGconn *conn, FILE *copystream) handleCopyOut(PGconn *conn, FILE *copystream)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment