diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml
index e2e99092428..d60d4ffbfcc 100644
--- a/doc/src/sgml/ref/postgres-ref.sgml
+++ b/doc/src/sgml/ref/postgres-ref.sgml
@@ -529,7 +529,9 @@ PostgreSQL documentation
- The following options only apply to the single-user mode.
+ The following options only apply to the single-user mode
+ (see ).
@@ -558,7 +560,7 @@ PostgreSQL documentation
- Echo all commands.
+ Echo all commands to standard output before executing them.
@@ -567,7 +569,8 @@ PostgreSQL documentation
- Disables use of newline as a statement delimiter.
+ Use semicolon followed by two newlines, rather than just newline,
+ as the command entry terminator.
@@ -760,8 +763,8 @@ PostgreSQL documentation
-
- Usage
+
+ Single-User Mode
To start a single-user mode server, use a command like
@@ -778,30 +781,40 @@ PostgreSQL documentation
entry terminator; there is no intelligence about semicolons,
as there is in psql>. To continue a command
across multiple lines, you must type backslash just before each
- newline except the last one.
+ newline except the last one. The backslash and adjacent newline are
+ both dropped from the input command. Note that this will happen even
+ when within a string literal or comment.
- But if you use the
+
+
+ In either input mode, if you type a semicolon that is not just before or
+ part of a command entry terminator, it is considered a command separator.
+ When you do type a command entry terminator, the multiple statements
+ you've entered will be executed as a single transaction.
To quit the session, type EOF
(Control>D>>, usually).
- If you've
- used
-j>, two consecutive EOF>s are needed to exit.
+ If you've entered any text since the last command entry terminator,
+ then EOF will be taken as a command entry terminator,
+ and another EOF> will be needed to exit.
Note that the single-user mode server does not provide sophisticated
line-editing features (no command history, for example).
- Single-User mode also does not do any background processing, like
- automatic checkpoints.
-
+ Single-user mode also does not do any background processing, such as
+ automatic checkpoints or replication.
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index 6e1b241956a..22398598734 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -5,6 +5,14 @@
* Copyright (c) 2003-2015, PostgreSQL Global Development Group
*
* src/backend/catalog/information_schema.sql
+ *
+ * Note: this file is read in single-user -j mode, which means that the
+ * command terminator is semicolon-newline-newline; whenever the backend
+ * sees that, it stops and executes what it's got. If you write a lot of
+ * statements without empty lines between, they'll all get quoted to you
+ * in any error message about one of them, so don't do that. Also, you
+ * cannot write a semicolon immediately followed by an empty line in a
+ * string literal (including a function body!) or a multiline comment.
*/
/*
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index ccc030fd7fb..536c805598b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -4,6 +4,14 @@
* Copyright (c) 1996-2015, PostgreSQL Global Development Group
*
* src/backend/catalog/system_views.sql
+ *
+ * Note: this file is read in single-user -j mode, which means that the
+ * command terminator is semicolon-newline-newline; whenever the backend
+ * sees that, it stops and executes what it's got. If you write a lot of
+ * statements without empty lines between, they'll all get quoted to you
+ * in any error message about one of them, so don't do that. Also, you
+ * cannot write a semicolon immediately followed by an empty line in a
+ * string literal (including a function body!) or a multiline comment.
*/
CREATE VIEW pg_roles AS
diff --git a/src/backend/snowball/snowball.sql.in b/src/backend/snowball/snowball.sql.in
index 2f68393ab5b..68363f11a51 100644
--- a/src/backend/snowball/snowball.sql.in
+++ b/src/backend/snowball/snowball.sql.in
@@ -1,6 +1,22 @@
--- src/backend/snowball/snowball.sql.in$
+/*
+ * text search configuration for _LANGNAME_ language
+ *
+ * Copyright (c) 2007-2015, PostgreSQL Global Development Group
+ *
+ * src/backend/snowball/snowball.sql.in
+ *
+ * _LANGNAME_ and certain other macros are replaced for each language;
+ * see the Makefile for details.
+ *
+ * Note: this file is read in single-user -j mode, which means that the
+ * command terminator is semicolon-newline-newline; whenever the backend
+ * sees that, it stops and executes what it's got. If you write a lot of
+ * statements without empty lines between, they'll all get quoted to you
+ * in any error message about one of them, so don't do that. Also, you
+ * cannot write a semicolon immediately followed by an empty line in a
+ * string literal (including a function body!) or a multiline comment.
+ */
--- text search configuration for _LANGNAME_ language
CREATE TEXT SEARCH DICTIONARY _DICTNAME_
(TEMPLATE = snowball, Language = _LANGNAME_ _STOPWORDS_);
diff --git a/src/backend/snowball/snowball_func.sql.in b/src/backend/snowball/snowball_func.sql.in
index e7d45109b4e..debb0e00e4e 100644
--- a/src/backend/snowball/snowball_func.sql.in
+++ b/src/backend/snowball/snowball_func.sql.in
@@ -1,4 +1,21 @@
--- src/backend/snowball/snowball_func.sql.in$
+/*
+ * Create underlying C functions for Snowball stemmers
+ *
+ * Copyright (c) 2007-2015, PostgreSQL Global Development Group
+ *
+ * src/backend/snowball/snowball_func.sql.in
+ *
+ * This file is combined with multiple instances of snowball.sql.in to
+ * build snowball_create.sql, which is executed during initdb.
+ *
+ * Note: this file is read in single-user -j mode, which means that the
+ * command terminator is semicolon-newline-newline; whenever the backend
+ * sees that, it stops and executes what it's got. If you write a lot of
+ * statements without empty lines between, they'll all get quoted to you
+ * in any error message about one of them, so don't do that. Also, you
+ * cannot write a semicolon immediately followed by an empty line in a
+ * string literal (including a function body!) or a multiline comment.
+ */
SET search_path = pg_catalog;
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 1dc2eb0fcca..4ae25487ef4 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -157,18 +157,8 @@ static CachedPlanSource *unnamed_stmt_psrc = NULL;
/* assorted command-line switches */
static const char *userDoption = NULL; /* -D switch */
-
static bool EchoQuery = false; /* -E switch */
-
-/*
- * people who want to use EOF should #define DONTUSENEWLINE in
- * tcop/tcopdebug.h
- */
-#ifndef TCOP_DONTUSENEWLINE
-static int UseNewLine = 1; /* Use newlines query delimiters (the default) */
-#else
-static int UseNewLine = 0; /* Use EOF as query delimiters */
-#endif /* TCOP_DONTUSENEWLINE */
+static bool UseSemiNewlineNewline = false; /* -j switch */
/* whether or not, and why, we were canceled by conflict with recovery */
static bool RecoveryConflictPending = false;
@@ -219,8 +209,6 @@ static int
InteractiveBackend(StringInfo inBuf)
{
int c; /* character read from getc() */
- bool end = false; /* end-of-input flag */
- bool backslashSeen = false; /* have we seen a \ ? */
/*
* display a prompt and obtain input from the user
@@ -230,55 +218,56 @@ InteractiveBackend(StringInfo inBuf)
resetStringInfo(inBuf);
- if (UseNewLine)
+ /*
+ * Read characters until EOF or the appropriate delimiter is seen.
+ */
+ while ((c = interactive_getc()) != EOF)
{
- /*
- * if we are using \n as a delimiter, then read characters until the
- * \n.
- */
- while ((c = interactive_getc()) != EOF)
+ if (c == '\n')
{
- if (c == '\n')
+ if (UseSemiNewlineNewline)
{
- if (backslashSeen)
+ /*
+ * In -j mode, semicolon followed by two newlines ends the
+ * command; otherwise treat newline as regular character.
+ */
+ if (inBuf->len > 1 &&
+ inBuf->data[inBuf->len - 1] == '\n' &&
+ inBuf->data[inBuf->len - 2] == ';')
+ {
+ /* might as well drop the second newline */
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * In plain mode, newline ends the command unless preceded by
+ * backslash.
+ */
+ if (inBuf->len > 0 &&
+ inBuf->data[inBuf->len - 1] == '\\')
{
/* discard backslash from inBuf */
inBuf->data[--inBuf->len] = '\0';
- backslashSeen = false;
+ /* discard newline too */
continue;
}
else
{
- /* keep the newline character */
+ /* keep the newline character, but end the command */
appendStringInfoChar(inBuf, '\n');
break;
}
}
- else if (c == '\\')
- backslashSeen = true;
- else
- backslashSeen = false;
-
- appendStringInfoChar(inBuf, (char) c);
}
- if (c == EOF)
- end = true;
- }
- else
- {
- /*
- * otherwise read characters until EOF.
- */
- while ((c = interactive_getc()) != EOF)
- appendStringInfoChar(inBuf, (char) c);
-
- /* No input before EOF signal means time to quit. */
- if (inBuf->len == 0)
- end = true;
+ /* Not newline, or newline treated as regular character */
+ appendStringInfoChar(inBuf, (char) c);
}
- if (end)
+ /* No input before EOF signal means time to quit. */
+ if (c == EOF && inBuf->len == 0)
return EOF;
/*
@@ -3391,7 +3380,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
case 'j':
if (secure)
- UseNewLine = 0;
+ UseSemiNewlineNewline = true;
break;
case 'k':
@@ -3901,7 +3890,7 @@ PostgresMain(int argc, char *argv[],
if (pq_is_reading_msg())
ereport(FATAL,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
- errmsg("terminating connection because protocol synchronization was lost")));
+ errmsg("terminating connection because protocol synchronization was lost")));
/* Now we can allow interrupts again */
RESUME_INTERRUPTS();
diff --git a/src/include/tcop/tcopdebug.h b/src/include/tcop/tcopdebug.h
deleted file mode 100644
index d7145ceed49..00000000000
--- a/src/include/tcop/tcopdebug.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * tcopdebug.h
- * #defines governing debugging behaviour in the traffic cop
- *
- *
- * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * src/include/tcop/tcopdebug.h
- *
- *-------------------------------------------------------------------------
- */
-#ifndef TCOPDEBUG_H
-#define TCOPDEBUG_H
-
-/* ----------------------------------------------------------------
- * debugging defines.
- *
- * If you want certain debugging behaviour, then #define
- * the variable to 1, else #undef it. -cim 10/26/89
- * ----------------------------------------------------------------
- */
-
-/* ----------------
- * TCOP_SHOWSTATS controls whether or not buffer and
- * access method statistics are shown for each query. -cim 2/9/89
- * ----------------
- */
-#undef TCOP_SHOWSTATS
-
-/* ----------------
- * TCOP_DONTUSENEWLINE controls the default setting of
- * the UseNewLine variable in postgres.c
- * ----------------
- */
-#undef TCOP_DONTUSENEWLINE
-
-/* ----------------------------------------------------------------
- * #defines controlled by above definitions
- * ----------------------------------------------------------------
- */
-
-#endif /* TCOPDEBUG_H */