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
This commit is contained in:
Bruce Momjian 1999-12-10 03:59:30 +00:00
parent 97dec77fab
commit 77a4729936
7 changed files with 63 additions and 40 deletions

View File

@ -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

View File

@ -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)
{ {
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)
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)
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)
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)

View File

@ -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

View File

@ -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)
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)
{ {
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)
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)
/* 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)
/* 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)
/* 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)
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)
} /* 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)
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)
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;

View File

@ -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,
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++)
{ {

View File

@ -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%# "

View File

@ -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)
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)
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)
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';
} }