diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml index e2e9909242..d60d4ffbfc 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 (ControlD, usually). - If you've - used 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 6e1b241956..2239859873 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 ccc030fd7f..536c805598 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 2f68393ab5..68363f11a5 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 e7d45109b4..debb0e00e4 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 1dc2eb0fcc..4ae25487ef 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 d7145ceed4..0000000000 --- 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 */