aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/psql/command.c2
-rw-r--r--src/bin/psql/common.c10
-rw-r--r--src/bin/psql/input.c4
-rw-r--r--src/bin/psql/mainloop.c65
-rw-r--r--src/bin/psql/print.c7
-rw-r--r--src/bin/psql/settings.h2
-rw-r--r--src/bin/psql/tab-complete.c13
7 files changed, 63 insertions, 40 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 59b596d6f22..9489a8e2af6 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -624,7 +624,7 @@ exec_command(const char *cmd,
if (!options[0])
{
- fprintf(stderr, "Usage \\%s <filename>\n", cmd);
+ fprintf(stderr, "Usage: \\%s <filename>\n", cmd);
success = false;
}
else
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index 30167847a0f..6bbf663733c 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -433,7 +433,6 @@ SendQuery(PsqlSettings *pset, const char *query)
fgets(buf, 3, stdin);
if (buf[0] == 'x')
return false;
- fflush(stdin);
}
cancelConn = pset->db;
@@ -479,7 +478,6 @@ SendQuery(PsqlSettings *pset, const char *query)
{
success = true;
printQuery(results, &pset->popt, pset->queryFout);
- fflush(pset->queryFout);
}
break;
case PGRES_EMPTY_QUERY:
@@ -488,10 +486,8 @@ SendQuery(PsqlSettings *pset, const char *query)
case PGRES_COMMAND_OK:
success = true;
pset->lastOid = PQoidValue(results);
- if (!GetVariableBool(pset->vars, "quiet")) {
+ if (!GetVariableBool(pset->vars, "quiet"))
fprintf(pset->queryFout, "%s\n", PQcmdStatus(results));
- fflush(pset->queryFout);
- }
break;
case PGRES_COPY_OUT:
@@ -515,10 +511,11 @@ SendQuery(PsqlSettings *pset, const char *query)
case PGRES_BAD_RESPONSE:
success = false;
fputs(PQerrorMessage(pset->db), pset->queryFout);
- fflush(pset->queryFout);
break;
}
+ fflush(pset->queryFout);
+
if (PQstatus(pset->db) == CONNECTION_BAD)
{
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",
notify->relname, notify->be_pid);
free(notify);
+ fflush(pset->queryFout);
}
if (results)
diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c
index 31fe4ce7737..250f1233ea6 100644
--- a/src/bin/psql/input.c
+++ b/src/bin/psql/input.c
@@ -32,11 +32,7 @@ gets_interactive(const char *prompt)
#ifdef USE_READLINE
if (useReadline)
- {
s = readline(prompt);
- fputc('\r', stdout);
- fflush(stdout);
- }
else
{
#endif
diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c
index 067be54e2cc..f85247689b9 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -29,6 +29,8 @@ int
MainLoop(PsqlSettings *pset, FILE *source)
{
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 */
int len; /* length of the line */
int successResult = EXIT_SUCCESS;
@@ -63,7 +65,8 @@ MainLoop(PsqlSettings *pset, FILE *source)
query_buf = createPQExpBuffer();
- if (!query_buf)
+ previous_buf = createPQExpBuffer();
+ if (!query_buf || !previous_buf)
{
perror("createPQExpBuffer");
exit(EXIT_FAILURE);
@@ -80,21 +83,21 @@ MainLoop(PsqlSettings *pset, FILE *source)
{
if (slashCmdStatus == CMD_NEWEDIT)
{
-
/*
* just returned from editing the line? then just copy to the
* input buffer
*/
- line = strdup(query_buf->data);
+ line = xstrdup(query_buf->data);
resetPQExpBuffer(query_buf);
- /* reset parsing state since we are rescanning whole query */
+ /* reset parsing state since we are rescanning whole line */
xcomment = false;
in_quote = 0;
paren_level = 0;
+ slashCmdStatus = CMD_UNKNOWN;
}
else
{
-
+ fflush(stdout);
/*
* otherwise, set interactive prompt if necessary and get
* another line
@@ -170,8 +173,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
puts(line);
- slashCmdStatus = CMD_UNKNOWN;
-
len = strlen(line);
query_start = 0;
@@ -275,11 +276,13 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* semicolon? then send query */
else if (line[i] == ';' && !was_bslash)
{
+ /* delete the old query buffer from last time around */
+ if (slashCmdStatus == CMD_SEND)
+
line[i] = '\0';
/* is there anything else on the line? */
if (line[query_start + strspn(line + query_start, " \t")] != '\0')
{
-
/*
* insert a cosmetic newline, if this is not the first
* line in the buffer
@@ -292,8 +295,11 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* execute query */
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;
}
@@ -316,7 +322,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
/* is there anything else on the line? */
if (line[query_start + strspn(line + query_start, " \t")] != '\0')
{
-
/*
* insert a cosmetic newline, if this is not the first
* line in the buffer
@@ -327,17 +332,27 @@ MainLoop(PsqlSettings *pset, FILE *source)
appendPQExpBufferStr(query_buf, line + query_start);
}
- /* handle backslash command */
-
- slashCmdStatus = HandleSlashCmds(pset, &line[i], query_buf, &end_of_cmd);
+ /* handle backslash command */
+ slashCmdStatus = HandleSlashCmds(pset, &line[i],
+ query_buf->len>0 ? query_buf : previous_buf,
+ &end_of_cmd);
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)
{
success = SendQuery(pset, query_buf->data);
- resetPQExpBuffer(query_buf);
query_start = i + thislen;
+
+ resetPQExpBuffer(previous_buf);
+ appendPQExpBufferStr(previous_buf, query_buf->data);
+ resetPQExpBuffer(query_buf);
}
/* is there anything left after the backslash command? */
@@ -358,13 +373,6 @@ MainLoop(PsqlSettings *pset, FILE *source)
} /* for (line) */
- if (!success && die_on_error && !pset->cur_cmd_interactive)
- {
- successResult = EXIT_USER;
- break;
- }
-
-
if (slashCmdStatus == CMD_TERMINATE)
{
successResult = EXIT_SUCCESS;
@@ -387,7 +395,17 @@ MainLoop(PsqlSettings *pset, FILE *source)
if (query_buf->data[0] != '\0' && GetVariableBool(pset->vars, "singleline"))
{
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;
break;
}
- } /* while */
+ } /* while !EOF */
destroyPQExpBuffer(query_buf);
+ destroyPQExpBuffer(previous_buf);
pset->cur_cmd_source = prev_cmd_source;
pset->cur_cmd_interactive = prev_cmd_interactive;
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 481f76f343e..15d40a806a9 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -18,7 +18,7 @@
#include <libpq-fe.h>
#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;
char *divider;
+ if (cells[0] == NULL) {
+ puts("(No rows)\n");
+ return;
+ }
+
/* count columns and find longest header */
for (ptr = headers; *ptr; ptr++)
{
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index 828dbd40d0f..85cf9dcb7f3 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -13,7 +13,7 @@
#include "print.h"
#define DEFAULT_FIELD_SEP "|"
-#define DEFAULT_EDITOR "/bin/vi"
+#define DEFAULT_EDITOR "vi"
#define DEFAULT_PROMPT1 "%/%R%# "
#define DEFAULT_PROMPT2 "%/%R%# "
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index f2025b0d26a..2b08ff3f861 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -203,7 +203,7 @@ char ** psql_completion(char *text, int start, int end)
(void)end; /* not used */
- rl_filename_quoting_desired = 1;
+ rl_completion_append_character = ' ';
/* Clear a few things. */
completion_charp = NULL;
@@ -501,6 +501,11 @@ char ** psql_completion(char *text, int start, int end)
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 */
else if (strcmp(prev_wd, "\\connect")==0 || strcmp(prev_wd, "\\c")==0)
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);
else if (strcmp(prev_wd, "\\pset")==0) {
char * my_list[] = { "format", "border", "expanded", "null", "fieldsep",
- "tuples_only", "title", "tableattr", "pager" };
+ "tuples_only", "title", "tableattr", "pager", NULL };
COMPLETE_WITH_LIST(my_list);
}
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
attempts filename completion, and that's usually no good. */
if (matches == NULL) {
- char * my_list[] = { "", "", NULL };
- COMPLETE_WITH_LIST(my_list);
+ COMPLETE_WITH_CONST("");
+ rl_completion_append_character = '\0';
}