diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out index 1836c9acf39..acea8806ba4 100644 --- a/contrib/hstore/expected/hstore.out +++ b/contrib/hstore/expected/hstore.out @@ -7,7 +7,6 @@ WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid); --------+--------- (0 rows) -set escape_string_warning=off; --hstore; select ''::hstore; hstore diff --git a/contrib/hstore/sql/hstore.sql b/contrib/hstore/sql/hstore.sql index efef91292a3..8ae95e8a510 100644 --- a/contrib/hstore/sql/hstore.sql +++ b/contrib/hstore/sql/hstore.sql @@ -5,8 +5,6 @@ SELECT amname, opcname FROM pg_opclass opc LEFT JOIN pg_am am ON am.oid = opcmethod WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid); -set escape_string_warning=off; - --hstore; select ''::hstore; diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index adc493e9850..4a427533bd8 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -2991,9 +2991,6 @@ fill_in_constant_lengths(JumbleState *jstate, const char *query, &ScanKeywords, ScanKeywordTokens); - /* we don't want to re-emit any escape string warnings */ - yyextra.escape_string_warning = false; - /* Search for each constant, in sequence */ for (int i = 0; i < jstate->clocations_count; i++) { diff --git a/contrib/pg_trgm/expected/pg_trgm.out b/contrib/pg_trgm/expected/pg_trgm.out index 04da98170ab..612625f1fda 100644 --- a/contrib/pg_trgm/expected/pg_trgm.out +++ b/contrib/pg_trgm/expected/pg_trgm.out @@ -7,9 +7,6 @@ WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid); --------+--------- (0 rows) ---backslash is used in tests below, installcheck will fail if ---standard_conforming_string is off -set standard_conforming_strings=on; -- reduce noise set extra_float_digits = 0; select show_trgm(''); diff --git a/contrib/pg_trgm/sql/pg_trgm.sql b/contrib/pg_trgm/sql/pg_trgm.sql index 44debced6d5..49db86caf7d 100644 --- a/contrib/pg_trgm/sql/pg_trgm.sql +++ b/contrib/pg_trgm/sql/pg_trgm.sql @@ -5,10 +5,6 @@ SELECT amname, opcname FROM pg_opclass opc LEFT JOIN pg_am am ON am.oid = opcmethod WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid); ---backslash is used in tests below, installcheck will fail if ---standard_conforming_string is off -set standard_conforming_strings=on; - -- reduce noise set extra_float_digits = 0; diff --git a/contrib/test_decoding/test_decoding.c b/contrib/test_decoding/test_decoding.c index e104aa5aa6e..809382880a2 100644 --- a/contrib/test_decoding/test_decoding.c +++ b/contrib/test_decoding/test_decoding.c @@ -474,8 +474,8 @@ pg_decode_filter(LogicalDecodingContext *ctx, * Print literal `outputstr' already represented as string of type `typid' * into stringbuf `s'. * - * Some builtin types aren't quoted, the rest is quoted. Escaping is done as - * if standard_conforming_strings were enabled. + * Some builtin types aren't quoted, the rest is quoted. Escaping is done + * per standard SQL rules. */ static void print_literal(StringInfo s, Oid typid, char *outputstr) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 0fad34da6eb..5560b95ee60 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -11390,8 +11390,9 @@ dynamic_library_path = '/usr/local/lib/postgresql:$libdir' - This controls whether a quote mark can be represented by - \' in a string literal. The preferred, SQL-standard way + This parameter controls whether a quote mark can be represented by + \' in the escape string syntax + (E'...'). The preferred, SQL-standard way to represent a quote mark is by doubling it ('') but PostgreSQL has historically also accepted \'. However, use of \' creates security risks @@ -11410,34 +11411,9 @@ dynamic_library_path = '/usr/local/lib/postgresql:$libdir' - Note that in a standard-conforming string literal, \ just - means \ anyway. This parameter only affects the handling of - non-standard-conforming literals, including - escape string syntax (E'...'). - - - - - - escape_string_warning (boolean) - stringsescape warning - - escape_string_warning configuration parameter - - - - - When on, a warning is issued if a backslash (\) - appears in an ordinary string literal ('...' - syntax) and standard_conforming_strings is off. - The default is on. - - - Applications that wish to use backslash as escape should be - modified to use escape string syntax (E'...'), - because the default behavior of ordinary strings is now to treat - backslash as an ordinary character, per SQL standard. This variable - can be enabled to help locate code that needs to be changed. + Note that in an ordinary string literal, \ just + means \ anyway. This parameter only affects + the handling of escape string syntax. @@ -11493,15 +11469,12 @@ dynamic_library_path = '/usr/local/lib/postgresql:$libdir' - This controls whether ordinary string literals - ('...') treat backslashes literally, as specified in - the SQL standard. - Beginning in PostgreSQL 9.1, the default is - on (prior releases defaulted to off). - Applications can check this - parameter to determine how string literals will be processed. - The presence of this parameter can also be taken as an indication - that the escape string syntax (E'...') is supported. + Beginning in PostgreSQL 19, this + parameter is always on. String literals are + always parsed as specified in the SQL standard (that is, + backslashes are ordinary characters within a string literal). + This parameter continues to exist because applications may consult + it; but it cannot be set to off. Escape string syntax () should be used if an application desires backslashes to be treated as escape characters. diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index e6e3a82905c..6203b2518cf 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -75,9 +75,7 @@ EXEC SQL ...; Embedded SQL statements likewise use SQL rules, not C rules, for parsing quoted strings and identifiers. (See and - respectively. Note that - ECPG assumes that standard_conforming_strings - is on.) + respectively.) Of course, the C part of the program follows C quoting rules. diff --git a/doc/src/sgml/func/func-matching.sgml b/doc/src/sgml/func/func-matching.sgml index f466860ddb0..b159137f93a 100644 --- a/doc/src/sgml/func/func-matching.sgml +++ b/doc/src/sgml/func/func-matching.sgml @@ -152,14 +152,6 @@ character itself, write two escape characters. - - - If you have turned off, - any backslashes you write in literal string constants will need to be - doubled. See for more information. - - - It's also possible to select no escape character by writing ESCAPE ''. This effectively disables the @@ -1156,14 +1148,6 @@ regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2) An RE cannot end with a backslash (\). - - - If you have turned off, - any backslashes you write in literal string constants will need to be - doubled. See for more information. - - - Regular Expression Quantifiers diff --git a/doc/src/sgml/hstore.sgml b/doc/src/sgml/hstore.sgml index 5f8d1d1ff43..780ee224dce 100644 --- a/doc/src/sgml/hstore.sgml +++ b/doc/src/sgml/hstore.sgml @@ -73,9 +73,7 @@ key => NULL applies before any required quoting or escaping. If you are passing an hstore literal via a parameter, then no additional processing is needed. But if you're passing it as a quoted literal - constant, then any single-quote characters and (depending on the setting of - the standard_conforming_strings configuration parameter) - backslash characters need to be escaped correctly. See + constant, then any single-quote characters need to be escaped correctly. See for more on the handling of string constants. diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index c2cc1326081..21e1ba34a4e 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -2889,18 +2889,13 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); before 16; search_path was not reported by releases before 18.) Note that - server_version, - server_encoding and - integer_datetimes + server_version and + server_encoding cannot change after startup. - - - - If no value for standard_conforming_strings is reported, - applications can assume it is off, that is, backslashes - are treated as escapes in string literals. Also, the presence of - this parameter can be taken as an indication that the escape string - syntax (E'...') is accepted. + Also, integer_datetimes is + always on in releases 9.5 and later, + and standard_conforming_strings is + always on in releases 19 and later. @@ -11108,7 +11103,6 @@ main(int argc, char **argv) * * CREATE SCHEMA testlibpq3; * SET search_path = testlibpq3; - * SET standard_conforming_strings = ON; * CREATE TABLE test1 (i int4, t text, b bytea); * INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004'); * INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000'); diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index 41c5954a424..a2b528c481e 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -3040,8 +3040,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" Sets the label of the backup. If none is specified, a backup label of base backup will be used. The quoting rules - for the label are the same as a standard SQL string with - turned on. + for the label are the same as for a standard SQL string. diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml index 34c83880a66..67482996861 100644 --- a/doc/src/sgml/syntax.sgml +++ b/doc/src/sgml/syntax.sgml @@ -438,30 +438,6 @@ SELECT 'foo' 'bar'; will check that the character conversion is possible. - - - If the configuration parameter - is off, - then PostgreSQL recognizes backslash escapes - in both regular and escape string constants. However, as of - PostgreSQL 9.1, the default is on, meaning - that backslash escapes are recognized only in escape string constants. - This behavior is more standards-compliant, but might break applications - which rely on the historical behavior, where backslash escapes - were always recognized. As a workaround, you can set this parameter - to off, but it is better to migrate away from using backslash - escapes. If you need to use a backslash escape to represent a special - character, write the string constant with an E. - - - - In addition to standard_conforming_strings, the configuration - parameters and - govern treatment of backslashes - in string constants. - - - The character with the code zero cannot be in a string constant. @@ -532,17 +508,6 @@ U&'d!0061t!+000061' UESCAPE '!' by one of these escape sequences is converted to the actual server encoding; an error is reported if that's not possible. - - - Also, the Unicode escape syntax for string constants only works - when the configuration - parameter is - turned on. This is because otherwise this syntax could confuse - clients that parse the SQL statements to the point that it could - lead to SQL injections and similar security issues. If the - parameter is set to off, this syntax will be rejected with an - error message. - diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index bda932d4992..4440aff4925 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -1257,3 +1257,18 @@ check_ssl(bool *newval, void **extra, GucSource source) #endif return true; } + +bool +check_standard_conforming_strings(bool *newval, void **extra, GucSource source) +{ + if (!*newval) + { + /* check the GUC's definition for an explanation */ + GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED); + GUC_check_errmsg("non-standard string literals are not supported"); + + return false; + } + + return true; +} diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 731d584106d..6c162f48342 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -60,14 +60,13 @@ fprintf_to_ereport(const char *fmt, const char *msg) } /* - * GUC variables. This is a DIRECT violation of the warning given at the + * GUC variable. This is a DIRECT violation of the warning given at the * head of gram.y, ie flex/bison code must not depend on any GUC variables; - * as such, changing their values can induce very unintuitive behavior. - * But we shall have to live with it until we can remove these variables. + * as such, changing its value can induce very unintuitive behavior. + * In practice, backslash_quote is not too awful since it only controls + * whether to throw an error: it cannot change non-error results. */ int backslash_quote = BACKSLASH_QUOTE_SAFE_ENCODING; -bool escape_string_warning = true; -bool standard_conforming_strings = true; /* * Constant data exported from this file. This array maps from the @@ -127,9 +126,6 @@ static void addunicode(char32_t c, yyscan_t yyscanner); #define lexer_errposition() scanner_errposition(*(yylloc), yyscanner) -static void check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner); -static void check_escape_warning(core_yyscan_t yyscanner); - %} %option reentrant @@ -543,17 +539,12 @@ other . } {xqstart} { - yyextra->warn_on_first_escape = true; yyextra->saw_non_ascii = false; SET_YYLLOC(); - if (yyextra->standard_conforming_strings) - BEGIN(xq); - else - BEGIN(xe); + BEGIN(xq); startlit(); } {xestart} { - yyextra->warn_on_first_escape = false; yyextra->saw_non_ascii = false; SET_YYLLOC(); BEGIN(xe); @@ -561,12 +552,6 @@ other . } {xusstart} { SET_YYLLOC(); - if (!yyextra->standard_conforming_strings) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("unsafe use of string constant with Unicode escapes"), - errdetail("String constants with Unicode escapes cannot be used when \"standard_conforming_strings\" is off."), - lexer_errposition())); BEGIN(xus); startlit(); } @@ -642,13 +627,6 @@ other . {xeunicode} { char32_t c = strtoul(yytext + 2, NULL, 16); - /* - * For consistency with other productions, issue any - * escape warning with cursor pointing to start of string. - * We might want to change that, someday. - */ - check_escape_warning(yyscanner); - /* Remember start of overall string token ... */ PUSH_YYLLOC(); /* ... and set the error cursor to point at this esc seq */ @@ -715,14 +693,12 @@ other . errhint("Use '' to write quotes in strings. \\' is insecure in client-only encodings."), lexer_errposition())); } - check_string_escape_warning(yytext[1], yyscanner); addlitchar(unescape_single_char(yytext[1], yyscanner), yyscanner); } {xeoctesc} { unsigned char c = strtoul(yytext + 1, NULL, 8); - check_escape_warning(yyscanner); addlitchar(c, yyscanner); if (c == '\0' || IS_HIGHBIT_SET(c)) yyextra->saw_non_ascii = true; @@ -730,7 +706,6 @@ other . {xehexesc} { unsigned char c = strtoul(yytext + 2, NULL, 16); - check_escape_warning(yyscanner); addlitchar(c, yyscanner); if (c == '\0' || IS_HIGHBIT_SET(c)) yyextra->saw_non_ascii = true; @@ -1263,8 +1238,6 @@ scanner_init(const char *str, yyext->keyword_tokens = keyword_tokens; yyext->backslash_quote = backslash_quote; - yyext->escape_string_warning = escape_string_warning; - yyext->standard_conforming_strings = standard_conforming_strings; /* * Make a scan buffer with special termination needed by flex. @@ -1420,45 +1393,6 @@ unescape_single_char(unsigned char c, core_yyscan_t yyscanner) } } -static void -check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner) -{ - if (ychar == '\'') - { - if (yyextra->warn_on_first_escape && yyextra->escape_string_warning) - ereport(WARNING, - (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER), - errmsg("nonstandard use of \\' in a string literal"), - errhint("Use '' to write quotes in strings, or use the escape string syntax (E'...')."), - lexer_errposition())); - yyextra->warn_on_first_escape = false; /* warn only once per string */ - } - else if (ychar == '\\') - { - if (yyextra->warn_on_first_escape && yyextra->escape_string_warning) - ereport(WARNING, - (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER), - errmsg("nonstandard use of \\\\ in a string literal"), - errhint("Use the escape string syntax for backslashes, e.g., E'\\\\'."), - lexer_errposition())); - yyextra->warn_on_first_escape = false; /* warn only once per string */ - } - else - check_escape_warning(yyscanner); -} - -static void -check_escape_warning(core_yyscan_t yyscanner) -{ - if (yyextra->warn_on_first_escape && yyextra->escape_string_warning) - ereport(WARNING, - (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER), - errmsg("nonstandard use of escape in a string literal"), - errhint("Use the escape string syntax for escapes, e.g., E'\\r\\n'."), - lexer_errposition())); - yyextra->warn_on_first_escape = false; /* warn only once per string */ -} - /* * Interface functions to make flex use palloc() instead of malloc(). * It'd be better to make these static, but flex insists otherwise. diff --git a/src/backend/utils/adt/quote.c b/src/backend/utils/adt/quote.c index 0aebcc43e5b..d2ef6a9dc0f 100644 --- a/src/backend/utils/adt/quote.c +++ b/src/backend/utils/adt/quote.c @@ -37,11 +37,9 @@ quote_ident(PG_FUNCTION_ARGS) * quote_literal_internal - * helper function for quote_literal and quote_literal_cstr * - * NOTE: think not to make this function's behavior change with - * standard_conforming_strings. We don't know where the result - * literal will be used, and so we must generate a result that - * will work with either setting. Take a look at what dblink - * uses this for before thinking you know better. + * NOTE: This must produce output that will work in old servers with + * standard_conforming_strings = off. It's used for example by + * dblink, which may send the result to another server. */ static size_t quote_literal_internal(char *dst, const char *src, size_t len) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 033b625f3fc..b5a7ad9066e 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -11828,16 +11828,14 @@ simple_quote_literal(StringInfo buf, const char *val) const char *valptr; /* - * We form the string literal according to the prevailing setting of - * standard_conforming_strings; we never use E''. User is responsible for - * making sure result is used correctly. + * We always form the string literal according to standard SQL rules. */ appendStringInfoChar(buf, '\''); for (valptr = val; *valptr; valptr++) { char ch = *valptr; - if (SQL_STR_DOUBLE(ch, !standard_conforming_strings)) + if (SQL_STR_DOUBLE(ch, false)) appendStringInfoChar(buf, ch); appendStringInfoChar(buf, ch); } diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat index 7c60b125564..f0260e6e412 100644 --- a/src/backend/utils/misc/guc_parameters.dat +++ b/src/backend/utils/misc/guc_parameters.dat @@ -991,12 +991,6 @@ boot_val => 'true', }, -{ name => 'escape_string_warning', type => 'bool', context => 'PGC_USERSET', group => 'COMPAT_OPTIONS_PREVIOUS', - short_desc => 'Warn about backslash escapes in ordinary string literals.', - variable => 'escape_string_warning', - boot_val => 'true', -}, - { name => 'event_source', type => 'string', context => 'PGC_POSTMASTER', group => 'LOGGING_WHERE', short_desc => 'Sets the application name used to identify PostgreSQL messages in the event log.', variable => 'event_source', @@ -2759,11 +2753,15 @@ boot_val => '""', }, +# We removed support for non-conforming string literals in PostgreSQL 19, +# but this parameter must be kept indefinitely, since client code might +# consult it or attempt to set it. We allow it to be explicitly set to true. { name => 'standard_conforming_strings', type => 'bool', context => 'PGC_USERSET', group => 'COMPAT_OPTIONS_PREVIOUS', - short_desc => 'Causes \'...\' strings to treat backslashes literally.', - flags => 'GUC_REPORT', + short_desc => 'Nonstandard strings are no longer supported; this can only be true.', + flags => 'GUC_REPORT | GUC_NOT_IN_SAMPLE', variable => 'standard_conforming_strings', boot_val => 'true', + check_hook => 'check_standard_conforming_strings', }, { name => 'statement_timeout', type => 'int', context => 'PGC_USERSET', group => 'CLIENT_CONN_STATEMENT', diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 73ff6ad0a32..13c569d8790 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -529,10 +529,10 @@ bool row_security; bool check_function_bodies = true; /* - * This GUC exists solely for backward compatibility, check its definition for - * details. + * These GUCs exist solely for backward compatibility. */ static bool default_with_oids = false; +static bool standard_conforming_strings = true; bool current_role_is_superuser; diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index dc9e2255f8a..c4f92fcdac8 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -847,10 +847,8 @@ #array_nulls = on #backslash_quote = safe_encoding # on, off, or safe_encoding -#escape_string_warning = on #lo_compat_privileges = off #quote_all_identifiers = off -#standard_conforming_strings = on #synchronize_seqscans = on # - Other Platforms and Clients - diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 4a63f7392ae..18d3822fd82 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -3426,8 +3426,6 @@ _doSetFixedOutputState(ArchiveHandle *AH) /* Avoid annoying notices etc */ ahprintf(AH, "SET client_min_messages = warning;\n"); - if (!AH->public.std_strings) - ahprintf(AH, "SET escape_string_warning = off;\n"); /* Adjust row-security state */ if (ropt && ropt->enable_row_security) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 687dc98e46d..fff929b26df 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -1429,7 +1429,6 @@ setup_connection(Archive *AH, const char *dumpencoding, { DumpOptions *dopt = AH->dopt; PGconn *conn = GetConnection(AH); - const char *std_strings; PQclear(ExecuteSqlQueryForSingleRow(AH, ALWAYS_SECURE_SEARCH_PATH_SQL)); @@ -1444,15 +1443,27 @@ setup_connection(Archive *AH, const char *dumpencoding, } /* - * Get the active encoding and the standard_conforming_strings setting, so - * we know how to escape strings. + * Force standard_conforming_strings on, just in case we are dumping from + * an old server that has it disabled. Without this, literals in views, + * expressions, etc, would be incorrect for modern servers. + */ + ExecuteSqlStatement(AH, "SET standard_conforming_strings = on"); + + /* + * And reflect that to AH->std_strings. You might think that we should + * just delete that variable and the code that checks it, but that would + * be problematic for pg_restore, which at least for now should still cope + * with archives containing the other setting (cf. processStdStringsEntry + * in pg_backup_archiver.c). + */ + AH->std_strings = true; + + /* + * Get the active encoding, so we know how to escape strings. */ AH->encoding = PQclientEncoding(conn); setFmtEncoding(AH->encoding); - std_strings = PQparameterStatus(conn, "standard_conforming_strings"); - AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0); - /* * Set the role if requested. In a parallel dump worker, we'll be passed * use_role == NULL, but AH->use_role is already set (if user specified it diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index e85f227d182..30fecd0c252 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -204,7 +204,6 @@ main(int argc, char *argv[]) bool tablespaces_only = false; PGconn *conn; int encoding; - const char *std_strings; int c, ret; int optindex; @@ -568,14 +567,17 @@ main(int argc, char *argv[]) } /* - * Get the active encoding and the standard_conforming_strings setting, so - * we know how to escape strings. + * Force standard_conforming_strings on, just in case we are dumping from + * an old server that has it disabled. Without this, literals in views, + * expressions, etc, would be incorrect for modern servers. + */ + executeCommand(conn, "SET standard_conforming_strings = on"); + + /* + * Get the active encoding, so we know how to escape strings. */ encoding = PQclientEncoding(conn); setFmtEncoding(encoding); - std_strings = PQparameterStatus(conn, "standard_conforming_strings"); - if (!std_strings) - std_strings = "off"; /* Set the role if requested */ if (use_role) @@ -615,12 +617,10 @@ main(int argc, char *argv[]) /* Restore will need to write to the target cluster */ fprintf(OPF, "SET default_transaction_read_only = off;\n\n"); - /* Replicate encoding and std_strings in output */ + /* Replicate encoding and standard_conforming_strings in output */ fprintf(OPF, "SET client_encoding = '%s';\n", pg_encoding_to_char(encoding)); - fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings); - if (strcmp(std_strings, "off") == 0) - fprintf(OPF, "SET escape_string_warning = off;\n"); + fprintf(OPF, "SET standard_conforming_strings = on;\n"); fprintf(OPF, "\n"); if (!data_only && !statistics_only && !no_schema) diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c index d87f1d476f3..89ce396ed4f 100644 --- a/src/fe_utils/string_utils.c +++ b/src/fe_utils/string_utils.c @@ -449,9 +449,9 @@ appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn) /* * XXX This is a kluge to silence escape_string_warning in our utility - * programs. It should go away someday. + * programs. It can go away once pre-v19 servers are out of support. */ - if (strchr(str, '\\') != NULL && PQserverVersion(conn) >= 80100) + if (strchr(str, '\\') != NULL && PQserverVersion(conn) < 190000) { /* ensure we are not adjacent to an identifier */ if (buf->len > 0 && buf->data[buf->len - 1] != ' ') diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h index 70af67086c3..93bd7c439f8 100644 --- a/src/include/parser/parser.h +++ b/src/include/parser/parser.h @@ -52,10 +52,8 @@ typedef enum BACKSLASH_QUOTE_SAFE_ENCODING, } BackslashQuoteType; -/* GUC variables in scan.l (every one of these is a bad idea :-() */ +/* GUC variable in scan.l */ extern PGDLLIMPORT int backslash_quote; -extern PGDLLIMPORT bool escape_string_warning; -extern PGDLLIMPORT bool standard_conforming_strings; /* Primary entry point for the raw parsing functions */ diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h index 2d5904a6214..8c2de655688 100644 --- a/src/include/parser/scanner.h +++ b/src/include/parser/scanner.h @@ -85,8 +85,6 @@ typedef struct core_yy_extra_type * prevailing GUC settings. */ int backslash_quote; - bool escape_string_warning; - bool standard_conforming_strings; /* * literalbuf is used to accumulate literal values when multiple rules are @@ -110,8 +108,7 @@ typedef struct core_yy_extra_type /* first part of UTF16 surrogate pair for Unicode escapes */ int32 utf16_first_part; - /* state variables for literal-lexing warnings */ - bool warn_on_first_escape; + /* true if we need to verify valid encoding of current literal string */ bool saw_non_ascii; } core_yy_extra_type; diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h index f723668da9e..b6ecb0e769f 100644 --- a/src/include/utils/guc_hooks.h +++ b/src/include/utils/guc_hooks.h @@ -134,6 +134,8 @@ extern void assign_session_replication_role(int newval, void *extra); extern void assign_stats_fetch_consistency(int newval, void *extra); extern bool check_ssl(bool *newval, void **extra, GucSource source); extern bool check_stage_log_stats(bool *newval, void **extra, GucSource source); +extern bool check_standard_conforming_strings(bool *newval, void **extra, + GucSource source); extern bool check_subtrans_buffers(int *newval, void **extra, GucSource source); extern bool check_synchronous_standby_names(char **newval, void **extra, diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c index 05841bd6999..ddc1e90b1c3 100644 --- a/src/interfaces/ecpg/test/expected/sql-quote.c +++ b/src/interfaces/ecpg/test/expected/sql-quote.c @@ -61,119 +61,75 @@ if (sqlca.sqlcode < 0) exit (1);} #line 20 "quote.pgc" - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set standard_conforming_strings to off", ECPGt_EOIT, ECPGt_EORT); -#line 22 "quote.pgc" - -if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 22 "quote.pgc" - -if (sqlca.sqlcode < 0) exit (1);} -#line 22 "quote.pgc" - - - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "show standard_conforming_strings", ECPGt_EOIT, - ECPGt_char,(var),(long)25,(long)1,(25)*sizeof(char), - ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); -#line 24 "quote.pgc" - -if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 24 "quote.pgc" - -if (sqlca.sqlcode < 0) exit (1);} -#line 24 "quote.pgc" - - printf("Standard conforming strings: %s\n", var); - - /* this is a\\b actually */ - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into \"My_Table\" values ( 1 , 'a\\\\\\\\b' )", ECPGt_EOIT, ECPGt_EORT); -#line 28 "quote.pgc" - -if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 28 "quote.pgc" - -if (sqlca.sqlcode < 0) exit (1);} -#line 28 "quote.pgc" - - /* this is a\\b */ - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into \"My_Table\" values ( 1 , E'a\\\\\\\\b' )", ECPGt_EOIT, ECPGt_EORT); -#line 30 "quote.pgc" - -if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 30 "quote.pgc" - -if (sqlca.sqlcode < 0) exit (1);} -#line 30 "quote.pgc" - - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set standard_conforming_strings to on", ECPGt_EOIT, ECPGt_EORT); -#line 32 "quote.pgc" +#line 22 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 32 "quote.pgc" +#line 22 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 32 "quote.pgc" +#line 22 "quote.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "show standard_conforming_strings", ECPGt_EOIT, ECPGt_char,(var),(long)25,(long)1,(25)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); -#line 34 "quote.pgc" +#line 24 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 34 "quote.pgc" +#line 24 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 34 "quote.pgc" +#line 24 "quote.pgc" printf("Standard conforming strings: %s\n", var); /* this is a\\\\b actually */ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into \"My_Table\" values ( 2 , 'a\\\\\\\\b' )", ECPGt_EOIT, ECPGt_EORT); -#line 38 "quote.pgc" +#line 28 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 38 "quote.pgc" +#line 28 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 38 "quote.pgc" +#line 28 "quote.pgc" /* this is a\\b */ { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into \"My_Table\" values ( 2 , E'a\\\\\\\\b' )", ECPGt_EOIT, ECPGt_EORT); -#line 40 "quote.pgc" +#line 30 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 40 "quote.pgc" +#line 30 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 40 "quote.pgc" +#line 30 "quote.pgc" { ECPGtrans(__LINE__, NULL, "begin"); -#line 42 "quote.pgc" +#line 32 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 42 "quote.pgc" +#line 32 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 42 "quote.pgc" +#line 32 "quote.pgc" /* declare C cursor for select * from \"My_Table\" */ -#line 43 "quote.pgc" +#line 33 "quote.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select * from \"My_Table\"", ECPGt_EOIT, ECPGt_EORT); -#line 45 "quote.pgc" +#line 35 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 45 "quote.pgc" +#line 35 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 45 "quote.pgc" +#line 35 "quote.pgc" /* exec sql whenever not found break ; */ -#line 47 "quote.pgc" +#line 37 "quote.pgc" for (loopcount = 0; loopcount < 100; loopcount++) @@ -183,47 +139,47 @@ if (sqlca.sqlcode < 0) exit (1);} ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,(var),(long)25,(long)1,(25)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); -#line 51 "quote.pgc" +#line 41 "quote.pgc" if (sqlca.sqlcode == ECPG_NOT_FOUND) break; -#line 51 "quote.pgc" +#line 41 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 51 "quote.pgc" +#line 41 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 51 "quote.pgc" +#line 41 "quote.pgc" printf("value: %d %s\n", i, var); } { ECPGtrans(__LINE__, NULL, "rollback"); -#line 55 "quote.pgc" +#line 45 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 55 "quote.pgc" +#line 45 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 55 "quote.pgc" +#line 45 "quote.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table \"My_Table\"", ECPGt_EOIT, ECPGt_EORT); -#line 56 "quote.pgc" +#line 46 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 56 "quote.pgc" +#line 46 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 56 "quote.pgc" +#line 46 "quote.pgc" { ECPGdisconnect(__LINE__, "ALL"); -#line 58 "quote.pgc" +#line 48 "quote.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 58 "quote.pgc" +#line 48 "quote.pgc" if (sqlca.sqlcode < 0) exit (1);} -#line 58 "quote.pgc" +#line 48 "quote.pgc" return 0; diff --git a/src/interfaces/ecpg/test/expected/sql-quote.stderr b/src/interfaces/ecpg/test/expected/sql-quote.stderr index 3df8702a8a6..5f5bfb8133a 100644 --- a/src/interfaces/ecpg/test/expected/sql-quote.stderr +++ b/src/interfaces/ecpg/test/expected/sql-quote.stderr @@ -10,7 +10,7 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_process_output on line 20: OK: CREATE TABLE [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 22: query: set standard_conforming_strings to off; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ecpg_execute on line 22: query: set standard_conforming_strings to on; with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_execute on line 22: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 @@ -22,114 +22,63 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_process_output on line 24: correctly got 1 tuples with 1 fields [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 24: RESULT: off offset: -1; array: no +[NO_PID]: ecpg_get_data on line 24: RESULT: on offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 28: query: insert into "My_Table" values ( 1 , 'a\\\\b' ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ecpg_execute on line 28: query: insert into "My_Table" values ( 2 , 'a\\\\b' ); with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ECPGnoticeReceiver: nonstandard use of \\ in a string literal -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: raising sqlcode 0 -[NO_PID]: sqlca: code: 0, state: 22P06 [NO_PID]: ecpg_execute on line 28: using PQexec -[NO_PID]: sqlca: code: 0, state: 22P06 +[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_process_output on line 28: OK: INSERT 0 1 -[NO_PID]: sqlca: code: 0, state: 22P06 -SQL error: nonstandard use of \\ in a string literal -[NO_PID]: ecpg_execute on line 30: query: insert into "My_Table" values ( 1 , E'a\\\\b' ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 30: query: insert into "My_Table" values ( 2 , E'a\\\\b' ); with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_execute on line 30: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_process_output on line 30: OK: INSERT 0 1 [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 32: query: set standard_conforming_strings to on; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ECPGtrans on line 32: action "begin"; connection "ecpg1_regression" [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 32: using PQexec +[NO_PID]: ecpg_execute on line 35: query: declare C cursor for select * from "My_Table"; with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 32: OK: SET +[NO_PID]: ecpg_execute on line 35: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 34: query: show standard_conforming_strings; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ecpg_process_output on line 35: OK: DECLARE CURSOR [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 34: using PQexec +[NO_PID]: ecpg_execute on line 41: query: fetch C; with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 34: correctly got 1 tuples with 1 fields +[NO_PID]: ecpg_execute on line 41: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 34: RESULT: on offset: -1; array: no +[NO_PID]: ecpg_process_output on line 41: correctly got 1 tuples with 2 fields [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 38: query: insert into "My_Table" values ( 2 , 'a\\\\b' ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ecpg_get_data on line 41: RESULT: 2 offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 38: using PQexec +[NO_PID]: ecpg_get_data on line 41: RESULT: a\\\\b offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 38: OK: INSERT 0 1 +[NO_PID]: ecpg_execute on line 41: query: fetch C; with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 40: query: insert into "My_Table" values ( 2 , E'a\\\\b' ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ecpg_execute on line 41: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 40: using PQexec +[NO_PID]: ecpg_process_output on line 41: correctly got 1 tuples with 2 fields [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 40: OK: INSERT 0 1 +[NO_PID]: ecpg_get_data on line 41: RESULT: 2 offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ECPGtrans on line 42: action "begin"; connection "ecpg1_regression" +[NO_PID]: ecpg_get_data on line 41: RESULT: a\\b offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 45: query: declare C cursor for select * from "My_Table"; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ecpg_execute on line 41: query: fetch C; with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 45: using PQexec +[NO_PID]: ecpg_execute on line 41: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 45: OK: DECLARE CURSOR +[NO_PID]: ecpg_process_output on line 41: correctly got 0 tuples with 2 fields [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: query: fetch C; with 0 parameter(s) on connection ecpg1_regression -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: using PQexec -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 51: correctly got 1 tuples with 2 fields -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 51: RESULT: 1 offset: -1; array: no -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 51: RESULT: a\\b offset: -1; array: no -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: query: fetch C; with 0 parameter(s) on connection ecpg1_regression -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: using PQexec -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 51: correctly got 1 tuples with 2 fields -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 51: RESULT: 1 offset: -1; array: no -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 51: RESULT: a\\b offset: -1; array: no -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: query: fetch C; with 0 parameter(s) on connection ecpg1_regression -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: using PQexec -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 51: correctly got 1 tuples with 2 fields -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 51: RESULT: 2 offset: -1; array: no -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 51: RESULT: a\\\\b offset: -1; array: no -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: query: fetch C; with 0 parameter(s) on connection ecpg1_regression -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: using PQexec -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 51: correctly got 1 tuples with 2 fields -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 51: RESULT: 2 offset: -1; array: no -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 51: RESULT: a\\b offset: -1; array: no -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: query: fetch C; with 0 parameter(s) on connection ecpg1_regression -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 51: using PQexec -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 51: correctly got 0 tuples with 2 fields -[NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: raising sqlcode 100 on line 51: no data found on line 51 +[NO_PID]: raising sqlcode 100 on line 41: no data found on line 41 [NO_PID]: sqlca: code: 100, state: 02000 -[NO_PID]: ECPGtrans on line 55: action "rollback"; connection "ecpg1_regression" +[NO_PID]: ECPGtrans on line 45: action "rollback"; connection "ecpg1_regression" [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 56: query: drop table "My_Table"; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ecpg_execute on line 46: query: drop table "My_Table"; with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 56: using PQexec +[NO_PID]: ecpg_execute on line 46: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_process_output on line 56: OK: DROP TABLE +[NO_PID]: ecpg_process_output on line 46: OK: DROP TABLE [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_finish: connection ecpg1_regression closed [NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/expected/sql-quote.stdout b/src/interfaces/ecpg/test/expected/sql-quote.stdout index 2f92f994831..31892d5261e 100644 --- a/src/interfaces/ecpg/test/expected/sql-quote.stdout +++ b/src/interfaces/ecpg/test/expected/sql-quote.stdout @@ -1,6 +1,3 @@ -Standard conforming strings: off Standard conforming strings: on -value: 1 a\\b -value: 1 a\\b value: 2 a\\\\b value: 2 a\\b diff --git a/src/interfaces/ecpg/test/expected/sql-show.c b/src/interfaces/ecpg/test/expected/sql-show.c index 1b52d5eaf4e..f934dc99feb 100644 --- a/src/interfaces/ecpg/test/expected/sql-show.c +++ b/src/interfaces/ecpg/test/expected/sql-show.c @@ -90,7 +90,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("Var: Search path: %s\n", var); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set standard_conforming_strings to off", ECPGt_EOIT, ECPGt_EORT); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set standard_conforming_strings to on", ECPGt_EOIT, ECPGt_EORT); #line 26 "show.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); diff --git a/src/interfaces/ecpg/test/expected/sql-show.stderr b/src/interfaces/ecpg/test/expected/sql-show.stderr index c303a845b25..e906abad91e 100644 --- a/src/interfaces/ecpg/test/expected/sql-show.stderr +++ b/src/interfaces/ecpg/test/expected/sql-show.stderr @@ -30,7 +30,7 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_get_data on line 23: RESULT: public offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 26: query: set standard_conforming_strings to off; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: ecpg_execute on line 26: query: set standard_conforming_strings to on; with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_execute on line 26: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 @@ -42,7 +42,7 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_process_output on line 27: correctly got 1 tuples with 1 fields [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_get_data on line 27: RESULT: off offset: -1; array: no +[NO_PID]: ecpg_get_data on line 27: RESULT: on offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_execute on line 30: query: set time zone PST8PDT; with 0 parameter(s) on connection ecpg1_regression [NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/expected/sql-show.stdout b/src/interfaces/ecpg/test/expected/sql-show.stdout index 9319c5d1135..d5628025a0e 100644 --- a/src/interfaces/ecpg/test/expected/sql-show.stdout +++ b/src/interfaces/ecpg/test/expected/sql-show.stdout @@ -1,5 +1,5 @@ Var: Search path: public Var: Search path: public -Var: Standard conforming strings: off +Var: Standard conforming strings: on Time Zone: PST8PDT Transaction isolation level: read committed diff --git a/src/interfaces/ecpg/test/sql/quote.pgc b/src/interfaces/ecpg/test/sql/quote.pgc index 9b62b7da90d..5cf4833d053 100644 --- a/src/interfaces/ecpg/test/sql/quote.pgc +++ b/src/interfaces/ecpg/test/sql/quote.pgc @@ -19,16 +19,6 @@ int main() { EXEC SQL CREATE TABLE "My_Table" ( Item1 int, Item2 text ); - EXEC SQL SET standard_conforming_strings TO off; - - EXEC SQL SHOW standard_conforming_strings INTO :var; - printf("Standard conforming strings: %s\n", var); - - /* this is a\\b actually */ - EXEC SQL INSERT INTO "My_Table" VALUES ( 1, 'a\\\\b' ); - /* this is a\\b */ - EXEC SQL INSERT INTO "My_Table" VALUES ( 1, E'a\\\\b' ); - EXEC SQL SET standard_conforming_strings TO on; EXEC SQL SHOW standard_conforming_strings INTO :var; diff --git a/src/interfaces/ecpg/test/sql/show.pgc b/src/interfaces/ecpg/test/sql/show.pgc index 339678ae994..232b3e77348 100644 --- a/src/interfaces/ecpg/test/sql/show.pgc +++ b/src/interfaces/ecpg/test/sql/show.pgc @@ -23,7 +23,7 @@ int main() { EXEC SQL SHOW search_path INTO :var; printf("Var: Search path: %s\n", var); - EXEC SQL SET standard_conforming_strings TO off; + EXEC SQL SET standard_conforming_strings TO on; EXEC SQL SHOW standard_conforming_strings INTO :var; printf("Var: Standard conforming strings: %s\n", var); diff --git a/src/test/examples/testlibpq3.c b/src/test/examples/testlibpq3.c index 4f7b7913889..cf74865ccb9 100644 --- a/src/test/examples/testlibpq3.c +++ b/src/test/examples/testlibpq3.c @@ -10,7 +10,6 @@ * * CREATE SCHEMA testlibpq3; * SET search_path = testlibpq3; - * SET standard_conforming_strings = ON; * CREATE TABLE test1 (i int4, t text, b bytea); * INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004'); * INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000'); diff --git a/src/test/examples/testlibpq3.sql b/src/test/examples/testlibpq3.sql index 35a95ca347b..a113849b14b 100644 --- a/src/test/examples/testlibpq3.sql +++ b/src/test/examples/testlibpq3.sql @@ -1,6 +1,5 @@ CREATE SCHEMA testlibpq3; SET search_path = testlibpq3; -SET standard_conforming_strings = ON; CREATE TABLE test1 (i int4, t text, b bytea); INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004'); INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000'); diff --git a/src/test/modules/test_regex/expected/test_regex.out b/src/test/modules/test_regex/expected/test_regex.out index c44c717edf4..a3d35fc142c 100644 --- a/src/test/modules/test_regex/expected/test_regex.out +++ b/src/test/modules/test_regex/expected/test_regex.out @@ -5,7 +5,6 @@ -- Most commented lines below are copied from reg.test. Each -- test case is followed by an equivalent test using test_regex(). create extension test_regex; -set standard_conforming_strings = on; -- # support functions and preliminary misc. -- # This is sensitive to changes in message wording, but we really have to -- # test the code->message expansion at least once. diff --git a/src/test/modules/test_regex/expected/test_regex_utf8.out b/src/test/modules/test_regex/expected/test_regex_utf8.out index befd75e96f3..329780ef400 100644 --- a/src/test/modules/test_regex/expected/test_regex_utf8.out +++ b/src/test/modules/test_regex/expected/test_regex_utf8.out @@ -8,7 +8,6 @@ SELECT getdatabaseencoding() <> 'UTF8' \quit \endif set client_encoding = utf8; -set standard_conforming_strings = on; -- Run the Tcl test cases that require Unicode -- expectMatch 9.44 EMP* {a[\u00fe-\u0507][\u00ff-\u0300]b} \ -- "a\u0102\u02ffb" "a\u0102\u02ffb" diff --git a/src/test/modules/test_regex/sql/test_regex.sql b/src/test/modules/test_regex/sql/test_regex.sql index b2a847577e8..8f80ce0fe1d 100644 --- a/src/test/modules/test_regex/sql/test_regex.sql +++ b/src/test/modules/test_regex/sql/test_regex.sql @@ -7,8 +7,6 @@ create extension test_regex; -set standard_conforming_strings = on; - -- # support functions and preliminary misc. -- # This is sensitive to changes in message wording, but we really have to -- # test the code->message expansion at least once. diff --git a/src/test/modules/test_regex/sql/test_regex_utf8.sql b/src/test/modules/test_regex/sql/test_regex_utf8.sql index 2aa3e0f1022..1f69f105fd7 100644 --- a/src/test/modules/test_regex/sql/test_regex_utf8.sql +++ b/src/test/modules/test_regex/sql/test_regex_utf8.sql @@ -11,8 +11,6 @@ SELECT getdatabaseencoding() <> 'UTF8' set client_encoding = utf8; -set standard_conforming_strings = on; - -- Run the Tcl test cases that require Unicode diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 474be478ce8..b37b2abaf80 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -4576,51 +4576,6 @@ CONTEXT: PL/pgSQL expression "1/0" PL/pgSQL function fail() line 3 at RETURN drop function fail(); -- Test handling of string literals. -set standard_conforming_strings = off; -create or replace function strtest() returns text as $$ -begin - raise notice 'foo\\bar\041baz'; - return 'foo\\bar\041baz'; -end -$$ language plpgsql; -WARNING: nonstandard use of \\ in a string literal -LINE 3: raise notice 'foo\\bar\041baz'; - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -WARNING: nonstandard use of \\ in a string literal -LINE 4: return 'foo\\bar\041baz'; - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -WARNING: nonstandard use of \\ in a string literal -LINE 4: return 'foo\\bar\041baz'; - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -select strtest(); -NOTICE: foo\bar!baz -WARNING: nonstandard use of \\ in a string literal -LINE 1: 'foo\\bar\041baz' - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -QUERY: 'foo\\bar\041baz' - strtest -------------- - foo\bar!baz -(1 row) - -create or replace function strtest() returns text as $$ -begin - raise notice E'foo\\bar\041baz'; - return E'foo\\bar\041baz'; -end -$$ language plpgsql; -select strtest(); -NOTICE: foo\bar!baz - strtest -------------- - foo\bar!baz -(1 row) - -set standard_conforming_strings = on; create or replace function strtest() returns text as $$ begin raise notice 'foo\\bar\041baz\'; diff --git a/src/test/regress/expected/regex.out b/src/test/regress/expected/regex.out index ae0de7307db..9fd503ffe78 100644 --- a/src/test/regress/expected/regex.out +++ b/src/test/regress/expected/regex.out @@ -1,8 +1,6 @@ -- -- Regular expression tests -- --- Don't want to have to double backslashes in regexes -set standard_conforming_strings = on; -- Test simple quantified backrefs select 'bbbbb' ~ '^([bc])\1*$' as t; t diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out index 727304f60e7..5f2b5c39173 100644 --- a/src/test/regress/expected/strings.out +++ b/src/test/regress/expected/strings.out @@ -22,7 +22,6 @@ ERROR: syntax error at or near "' - third line'" LINE 3: ' - third line' ^ -- Unicode escapes -SET standard_conforming_strings TO on; SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; data ------ @@ -142,43 +141,12 @@ SELECT E'wrong: \U002FFFFF'; ERROR: invalid Unicode escape value at or near "\U002FFFFF" LINE 1: SELECT E'wrong: \U002FFFFF'; ^ +-- this is no longer allowed: SET standard_conforming_strings TO off; -SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; -ERROR: unsafe use of string constant with Unicode escapes -LINE 1: SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; - ^ -DETAIL: String constants with Unicode escapes cannot be used when "standard_conforming_strings" is off. -SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; -ERROR: unsafe use of string constant with Unicode escapes -LINE 1: SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061... - ^ -DETAIL: String constants with Unicode escapes cannot be used when "standard_conforming_strings" is off. -SELECT U&' \' UESCAPE '!' AS "tricky"; -ERROR: unsafe use of string constant with Unicode escapes -LINE 1: SELECT U&' \' UESCAPE '!' AS "tricky"; - ^ -DETAIL: String constants with Unicode escapes cannot be used when "standard_conforming_strings" is off. -SELECT 'tricky' AS U&"\" UESCAPE '!'; - \ --------- - tricky -(1 row) - -SELECT U&'wrong: \061'; -ERROR: unsafe use of string constant with Unicode escapes -LINE 1: SELECT U&'wrong: \061'; - ^ -DETAIL: String constants with Unicode escapes cannot be used when "standard_conforming_strings" is off. -SELECT U&'wrong: \+0061'; -ERROR: unsafe use of string constant with Unicode escapes -LINE 1: SELECT U&'wrong: \+0061'; - ^ -DETAIL: String constants with Unicode escapes cannot be used when "standard_conforming_strings" is off. -SELECT U&'wrong: +0061' UESCAPE '+'; -ERROR: unsafe use of string constant with Unicode escapes -LINE 1: SELECT U&'wrong: +0061' UESCAPE '+'; - ^ -DETAIL: String constants with Unicode escapes cannot be used when "standard_conforming_strings" is off. +ERROR: non-standard string literals are not supported +-- but this should be acceptable: +SET standard_conforming_strings TO on; +-- or this: RESET standard_conforming_strings; -- bytea SET bytea_output TO hex; @@ -2869,90 +2837,6 @@ SELECT '\x8000000000000000'::bytea::int8 AS "-9223372036854775808", -9223372036854775808 | 9223372036854775807 (1 row) --- --- test behavior of escape_string_warning and standard_conforming_strings options --- -set escape_string_warning = off; -set standard_conforming_strings = off; -show escape_string_warning; - escape_string_warning ------------------------ - off -(1 row) - -show standard_conforming_strings; - standard_conforming_strings ------------------------------ - off -(1 row) - -set escape_string_warning = on; -set standard_conforming_strings = on; -show escape_string_warning; - escape_string_warning ------------------------ - on -(1 row) - -show standard_conforming_strings; - standard_conforming_strings ------------------------------ - on -(1 row) - -select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; - f1 | f2 | f3 | f4 | f5 | f6 --------+--------+---------+-------+--------+---- - a\bcd | a\b'cd | a\b''cd | abcd\ | ab\'cd | \\ -(1 row) - -set standard_conforming_strings = off; -select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6; -WARNING: nonstandard use of \\ in a string literal -LINE 1: select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3,... - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -WARNING: nonstandard use of \\ in a string literal -LINE 1: select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3,... - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -WARNING: nonstandard use of \\ in a string literal -LINE 1: select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3,... - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -WARNING: nonstandard use of \\ in a string literal -LINE 1: ...bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' ... - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -WARNING: nonstandard use of \\ in a string literal -LINE 1: ...'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd'... - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. -WARNING: nonstandard use of \\ in a string literal -LINE 1: ...'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as ... - ^ -HINT: Use the escape string syntax for backslashes, e.g., E'\\'. - f1 | f2 | f3 | f4 | f5 | f6 --------+--------+---------+-------+--------+---- - a\bcd | a\b'cd | a\b''cd | abcd\ | ab\'cd | \\ -(1 row) - -set escape_string_warning = off; -set standard_conforming_strings = on; -select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; - f1 | f2 | f3 | f4 | f5 | f6 --------+--------+---------+-------+--------+---- - a\bcd | a\b'cd | a\b''cd | abcd\ | ab\'cd | \\ -(1 row) - -set standard_conforming_strings = off; -select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6; - f1 | f2 | f3 | f4 | f5 | f6 --------+--------+---------+-------+--------+---- - a\bcd | a\b'cd | a\b''cd | abcd\ | ab\'cd | \\ -(1 row) - -reset standard_conforming_strings; -- -- Additional string functions -- diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index d413d995d17..ae6b67e3e22 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -3773,28 +3773,6 @@ drop function fail(); -- Test handling of string literals. -set standard_conforming_strings = off; - -create or replace function strtest() returns text as $$ -begin - raise notice 'foo\\bar\041baz'; - return 'foo\\bar\041baz'; -end -$$ language plpgsql; - -select strtest(); - -create or replace function strtest() returns text as $$ -begin - raise notice E'foo\\bar\041baz'; - return E'foo\\bar\041baz'; -end -$$ language plpgsql; - -select strtest(); - -set standard_conforming_strings = on; - create or replace function strtest() returns text as $$ begin raise notice 'foo\\bar\041baz\'; diff --git a/src/test/regress/sql/regex.sql b/src/test/regress/sql/regex.sql index 56217104ce6..a4f99c1f25f 100644 --- a/src/test/regress/sql/regex.sql +++ b/src/test/regress/sql/regex.sql @@ -2,9 +2,6 @@ -- Regular expression tests -- --- Don't want to have to double backslashes in regexes -set standard_conforming_strings = on; - -- Test simple quantified backrefs select 'bbbbb' ~ '^([bc])\1*$' as t; select 'ccc' ~ '^([bc])\1*$' as t; diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql index 88aa4c2983b..37c0893ae83 100644 --- a/src/test/regress/sql/strings.sql +++ b/src/test/regress/sql/strings.sql @@ -17,8 +17,6 @@ SELECT 'first line' AS "Illegal comment within continuation"; -- Unicode escapes -SET standard_conforming_strings TO on; - SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; SELECT U&'a\\b' AS "a\b"; @@ -50,18 +48,11 @@ SELECT E'wrong: \udb99\u0061'; SELECT E'wrong: \U0000db99\U00000061'; SELECT E'wrong: \U002FFFFF'; +-- this is no longer allowed: SET standard_conforming_strings TO off; - -SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; -SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; - -SELECT U&' \' UESCAPE '!' AS "tricky"; -SELECT 'tricky' AS U&"\" UESCAPE '!'; - -SELECT U&'wrong: \061'; -SELECT U&'wrong: \+0061'; -SELECT U&'wrong: +0061' UESCAPE '+'; - +-- but this should be acceptable: +SET standard_conforming_strings TO on; +-- or this: RESET standard_conforming_strings; -- bytea @@ -914,39 +905,6 @@ SELECT '\x80000000'::bytea::int4 AS "-2147483648", '\x7FFFFFFF'::bytea::int4 AS SELECT '\x8000000000000000'::bytea::int8 AS "-9223372036854775808", '\x7FFFFFFFFFFFFFFF'::bytea::int8 AS "9223372036854775807"; --- --- test behavior of escape_string_warning and standard_conforming_strings options --- -set escape_string_warning = off; -set standard_conforming_strings = off; - -show escape_string_warning; -show standard_conforming_strings; - -set escape_string_warning = on; -set standard_conforming_strings = on; - -show escape_string_warning; -show standard_conforming_strings; - -select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; - -set standard_conforming_strings = off; - -select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6; - -set escape_string_warning = off; -set standard_conforming_strings = on; - -select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; - -set standard_conforming_strings = off; - -select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6; - -reset standard_conforming_strings; - - -- -- Additional string functions -- diff --git a/src/tutorial/syscat.source b/src/tutorial/syscat.source index eb765c47364..e410228e117 100644 --- a/src/tutorial/syscat.source +++ b/src/tutorial/syscat.source @@ -17,10 +17,6 @@ -- SET search_path TO pg_catalog; --- The LIKE pattern language requires underscores to be escaped, so make --- sure the backslashes are not misinterpreted. -SET standard_conforming_strings TO on; - -- -- lists the names of all database owners and the name of their database(s) -- @@ -169,7 +165,6 @@ SELECT am.amname, n.nspname, opf.opfname, opr.oprname ORDER BY nspname, amname, opfname, oprname; -- --- Reset the search path and standard_conforming_strings to their defaults +-- Reset the search path to default -- RESET search_path; -RESET standard_conforming_strings;