Commit 77a47299 authored by Bruce Momjian's avatar Bruce Momjian

This should fix the \e (\p, \g, ...) behaviour on an empty query buffer.

Also, minor tweakage of tab completion, and I hope the output is flushed
on time now.

--
Peter Eisentraut                  Sernanders väg 10:115
parent 97dec77f
...@@ -624,7 +624,7 @@ exec_command(const char *cmd, ...@@ -624,7 +624,7 @@ exec_command(const char *cmd,
if (!options[0]) if (!options[0])
{ {
fprintf(stderr, "Usage \\%s <filename>\n", cmd); fprintf(stderr, "Usage: \\%s <filename>\n", cmd);
success = false; success = false;
} }
else else
......
...@@ -433,7 +433,6 @@ SendQuery(PsqlSettings *pset, const char *query) ...@@ -433,7 +433,6 @@ SendQuery(PsqlSettings *pset, const char *query)
fgets(buf, 3, stdin); fgets(buf, 3, stdin);
if (buf[0] == 'x') if (buf[0] == 'x')
return false; return false;
fflush(stdin);
} }
cancelConn = pset->db; cancelConn = pset->db;
...@@ -479,7 +478,6 @@ SendQuery(PsqlSettings *pset, const char *query) ...@@ -479,7 +478,6 @@ SendQuery(PsqlSettings *pset, const char *query)
{ {
success = true; success = true;
printQuery(results, &pset->popt, pset->queryFout); printQuery(results, &pset->popt, pset->queryFout);
fflush(pset->queryFout);
} }
break; break;
case PGRES_EMPTY_QUERY: case PGRES_EMPTY_QUERY:
...@@ -488,10 +486,8 @@ SendQuery(PsqlSettings *pset, const char *query) ...@@ -488,10 +486,8 @@ SendQuery(PsqlSettings *pset, const char *query)
case PGRES_COMMAND_OK: case PGRES_COMMAND_OK:
success = true; success = true;
pset->lastOid = PQoidValue(results); pset->lastOid = PQoidValue(results);
if (!GetVariableBool(pset->vars, "quiet")) { if (!GetVariableBool(pset->vars, "quiet"))
fprintf(pset->queryFout, "%s\n", PQcmdStatus(results)); fprintf(pset->queryFout, "%s\n", PQcmdStatus(results));
fflush(pset->queryFout);
}
break; break;
case PGRES_COPY_OUT: case PGRES_COPY_OUT:
...@@ -515,10 +511,11 @@ SendQuery(PsqlSettings *pset, const char *query) ...@@ -515,10 +511,11 @@ SendQuery(PsqlSettings *pset, const char *query)
case PGRES_BAD_RESPONSE: case PGRES_BAD_RESPONSE:
success = false; success = false;
fputs(PQerrorMessage(pset->db), pset->queryFout); fputs(PQerrorMessage(pset->db), pset->queryFout);
fflush(pset->queryFout);
break; break;
} }
fflush(pset->queryFout);
if (PQstatus(pset->db) == CONNECTION_BAD) if (PQstatus(pset->db) == CONNECTION_BAD)
{ {
fputs("The connection to the server was lost. Attempting reset: ", stderr); fputs("The connection to the server was lost. Attempting reset: ", stderr);
...@@ -541,6 +538,7 @@ SendQuery(PsqlSettings *pset, const char *query) ...@@ -541,6 +538,7 @@ SendQuery(PsqlSettings *pset, const char *query)
fprintf(pset->queryFout, "Asynchronous NOTIFY '%s' from backend with pid '%d' received.\n", fprintf(pset->queryFout, "Asynchronous NOTIFY '%s' from backend with pid '%d' received.\n",
notify->relname, notify->be_pid); notify->relname, notify->be_pid);
free(notify); free(notify);
fflush(pset->queryFout);
} }
if (results) if (results)
......
...@@ -32,11 +32,7 @@ gets_interactive(const char *prompt) ...@@ -32,11 +32,7 @@ gets_interactive(const char *prompt)
#ifdef USE_READLINE #ifdef USE_READLINE
if (useReadline) if (useReadline)
{
s = readline(prompt); s = readline(prompt);
fputc('\r', stdout);
fflush(stdout);
}
else else
{ {
#endif #endif
......
...@@ -29,6 +29,8 @@ int ...@@ -29,6 +29,8 @@ int
MainLoop(PsqlSettings *pset, FILE *source) MainLoop(PsqlSettings *pset, FILE *source)
{ {
PQExpBuffer query_buf; /* buffer for query being accumulated */ PQExpBuffer query_buf; /* buffer for query being accumulated */
PQExpBuffer previous_buf; /* if there isn't anything in the new buffer
yet, use this one for \e, etc. */
char *line; /* current line of input */ char *line; /* current line of input */
int len; /* length of the line */ int len; /* length of the line */
int successResult = EXIT_SUCCESS; int successResult = EXIT_SUCCESS;
...@@ -63,7 +65,8 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -63,7 +65,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
query_buf = createPQExpBuffer(); query_buf = createPQExpBuffer();
if (!query_buf) previous_buf = createPQExpBuffer();
if (!query_buf || !previous_buf)
{ {
perror("createPQExpBuffer"); perror("createPQExpBuffer");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
...@@ -80,21 +83,21 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -80,21 +83,21 @@ MainLoop(PsqlSettings *pset, FILE *source)
{ {
if (slashCmdStatus == CMD_NEWEDIT) 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
*/ */
line = strdup(query_buf->data); line = xstrdup(query_buf->data);
resetPQExpBuffer(query_buf); resetPQExpBuffer(query_buf);
/* reset parsing state since we are rescanning whole query */ /* reset parsing state since we are rescanning whole line */
xcomment = false; xcomment = false;
in_quote = 0; in_quote = 0;
paren_level = 0; paren_level = 0;
slashCmdStatus = CMD_UNKNOWN;
} }
else else
{ {
fflush(stdout);
/* /*
* otherwise, set interactive prompt if necessary and get * otherwise, set interactive prompt if necessary and get
* another line * another line
...@@ -170,8 +173,6 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -170,8 +173,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
puts(line); puts(line);
slashCmdStatus = CMD_UNKNOWN;
len = strlen(line); len = strlen(line);
query_start = 0; query_start = 0;
...@@ -275,11 +276,13 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -275,11 +276,13 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* semicolon? then send query */ /* semicolon? then send query */
else if (line[i] == ';' && !was_bslash) else if (line[i] == ';' && !was_bslash)
{ {
/* delete the old query buffer from last time around */
if (slashCmdStatus == CMD_SEND)
line[i] = '\0'; line[i] = '\0';
/* is there anything else on the line? */ /* is there anything else on the line? */
if (line[query_start + strspn(line + query_start, " \t")] != '\0') if (line[query_start + strspn(line + query_start, " \t")] != '\0')
{ {
/* /*
* insert a cosmetic newline, if this is not the first * insert a cosmetic newline, if this is not the first
* line in the buffer * line in the buffer
...@@ -292,8 +295,11 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -292,8 +295,11 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* execute query */ /* execute query */
success = SendQuery(pset, query_buf->data); success = SendQuery(pset, query_buf->data);
slashCmdStatus = success ? CMD_SEND : CMD_ERROR;
resetPQExpBuffer(query_buf); resetPQExpBuffer(previous_buf);
appendPQExpBufferStr(previous_buf, query_buf->data);
resetPQExpBuffer(query_buf);
query_start = i + thislen; query_start = i + thislen;
} }
...@@ -316,7 +322,6 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -316,7 +322,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* is there anything else on the line? */ /* is there anything else on the line? */
if (line[query_start + strspn(line + query_start, " \t")] != '\0') if (line[query_start + strspn(line + query_start, " \t")] != '\0')
{ {
/* /*
* insert a cosmetic newline, if this is not the first * insert a cosmetic newline, if this is not the first
* line in the buffer * line in the buffer
...@@ -327,17 +332,27 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -327,17 +332,27 @@ MainLoop(PsqlSettings *pset, FILE *source)
appendPQExpBufferStr(query_buf, line + query_start); appendPQExpBufferStr(query_buf, line + query_start);
} }
/* handle backslash command */ /* handle backslash command */
slashCmdStatus = HandleSlashCmds(pset, &line[i],
slashCmdStatus = HandleSlashCmds(pset, &line[i], query_buf, &end_of_cmd); query_buf->len>0 ? query_buf : previous_buf,
&end_of_cmd);
success = slashCmdStatus != CMD_ERROR; success = slashCmdStatus != CMD_ERROR;
if ((slashCmdStatus == CMD_SEND || slashCmdStatus == CMD_NEWEDIT) &&
query_buf->len == 0) {
/* copy previous buffer to current for for handling */
appendPQExpBufferStr(query_buf, previous_buf->data);
}
if (slashCmdStatus == CMD_SEND) if (slashCmdStatus == CMD_SEND)
{ {
success = SendQuery(pset, query_buf->data); success = SendQuery(pset, query_buf->data);
resetPQExpBuffer(query_buf);
query_start = i + thislen; query_start = i + thislen;
resetPQExpBuffer(previous_buf);
appendPQExpBufferStr(previous_buf, query_buf->data);
resetPQExpBuffer(query_buf);
} }
/* is there anything left after the backslash command? */ /* is there anything left after the backslash command? */
...@@ -358,13 +373,6 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -358,13 +373,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
} /* for (line) */ } /* for (line) */
if (!success && die_on_error && !pset->cur_cmd_interactive)
{
successResult = EXIT_USER;
break;
}
if (slashCmdStatus == CMD_TERMINATE) if (slashCmdStatus == CMD_TERMINATE)
{ {
successResult = EXIT_SUCCESS; successResult = EXIT_SUCCESS;
...@@ -387,7 +395,17 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -387,7 +395,17 @@ MainLoop(PsqlSettings *pset, FILE *source)
if (query_buf->data[0] != '\0' && GetVariableBool(pset->vars, "singleline")) if (query_buf->data[0] != '\0' && GetVariableBool(pset->vars, "singleline"))
{ {
success = SendQuery(pset, query_buf->data); success = SendQuery(pset, query_buf->data);
resetPQExpBuffer(query_buf); slashCmdStatus = success ? CMD_SEND : CMD_ERROR;
resetPQExpBuffer(previous_buf);
appendPQExpBufferStr(previous_buf, query_buf->data);
resetPQExpBuffer(query_buf);
}
if (!success && die_on_error && !pset->cur_cmd_interactive)
{
successResult = EXIT_USER;
break;
} }
...@@ -397,9 +415,10 @@ MainLoop(PsqlSettings *pset, FILE *source) ...@@ -397,9 +415,10 @@ MainLoop(PsqlSettings *pset, FILE *source)
successResult = EXIT_BADCONN; successResult = EXIT_BADCONN;
break; break;
} }
} /* while */ } /* while !EOF */
destroyPQExpBuffer(query_buf); destroyPQExpBuffer(query_buf);
destroyPQExpBuffer(previous_buf);
pset->cur_cmd_source = prev_cmd_source; pset->cur_cmd_source = prev_cmd_source;
pset->cur_cmd_interactive = prev_cmd_interactive; pset->cur_cmd_interactive = prev_cmd_interactive;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <libpq-fe.h> #include <libpq-fe.h>
#include <postgres_ext.h> /* for Oid type */ #include <postgres_ext.h> /* for Oid type */
#define DEFAULT_PAGER "/bin/more" #define DEFAULT_PAGER "more"
...@@ -325,6 +325,11 @@ print_aligned_vertical(const char *title, const char * const * headers, ...@@ -325,6 +325,11 @@ print_aligned_vertical(const char *title, const char * const * headers,
dwidth = 0; dwidth = 0;
char *divider; char *divider;
if (cells[0] == NULL) {
puts("(No rows)\n");
return;
}
/* count columns and find longest header */ /* count columns and find longest header */
for (ptr = headers; *ptr; ptr++) for (ptr = headers; *ptr; ptr++)
{ {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "print.h" #include "print.h"
#define DEFAULT_FIELD_SEP "|" #define DEFAULT_FIELD_SEP "|"
#define DEFAULT_EDITOR "/bin/vi" #define DEFAULT_EDITOR "vi"
#define DEFAULT_PROMPT1 "%/%R%# " #define DEFAULT_PROMPT1 "%/%R%# "
#define DEFAULT_PROMPT2 "%/%R%# " #define DEFAULT_PROMPT2 "%/%R%# "
......
...@@ -203,7 +203,7 @@ char ** psql_completion(char *text, int start, int end) ...@@ -203,7 +203,7 @@ char ** psql_completion(char *text, int start, int end)
(void)end; /* not used */ (void)end; /* not used */
rl_filename_quoting_desired = 1; rl_completion_append_character = ' ';
/* Clear a few things. */ /* Clear a few things. */
completion_charp = NULL; completion_charp = NULL;
...@@ -501,6 +501,11 @@ char ** psql_completion(char *text, int start, int end) ...@@ -501,6 +501,11 @@ char ** psql_completion(char *text, int start, int end)
COMPLETE_WITH_QUERY(Query_for_list_of_tables); COMPLETE_WITH_QUERY(Query_for_list_of_tables);
/* ... FROM ... */
else if (strcasecmp(prev_wd, "FROM") == 0 )
COMPLETE_WITH_QUERY(Query_for_list_of_tables);
/* Backslash commands */ /* Backslash commands */
else if (strcmp(prev_wd, "\\connect")==0 || strcmp(prev_wd, "\\c")==0) else if (strcmp(prev_wd, "\\connect")==0 || strcmp(prev_wd, "\\c")==0)
COMPLETE_WITH_QUERY(Query_for_list_of_databases); COMPLETE_WITH_QUERY(Query_for_list_of_databases);
...@@ -510,7 +515,7 @@ char ** psql_completion(char *text, int start, int end) ...@@ -510,7 +515,7 @@ char ** psql_completion(char *text, int start, int end)
COMPLETE_WITH_LIST(sql_commands); COMPLETE_WITH_LIST(sql_commands);
else if (strcmp(prev_wd, "\\pset")==0) { else if (strcmp(prev_wd, "\\pset")==0) {
char * my_list[] = { "format", "border", "expanded", "null", "fieldsep", char * my_list[] = { "format", "border", "expanded", "null", "fieldsep",
"tuples_only", "title", "tableattr", "pager" }; "tuples_only", "title", "tableattr", "pager", NULL };
COMPLETE_WITH_LIST(my_list); COMPLETE_WITH_LIST(my_list);
} }
else if( strcmp(prev_wd, "\\e")==0 || strcmp(prev_wd, "\\edit")==0 || else if( strcmp(prev_wd, "\\e")==0 || strcmp(prev_wd, "\\edit")==0 ||
...@@ -541,8 +546,8 @@ char ** psql_completion(char *text, int start, int end) ...@@ -541,8 +546,8 @@ char ** psql_completion(char *text, int start, int end)
of default list. If we were to just return NULL, readline automatically of default list. If we were to just return NULL, readline automatically
attempts filename completion, and that's usually no good. */ attempts filename completion, and that's usually no good. */
if (matches == NULL) { if (matches == NULL) {
char * my_list[] = { "", "", NULL }; COMPLETE_WITH_CONST("");
COMPLETE_WITH_LIST(my_list); rl_completion_append_character = '\0';
} }
......
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