v1-0002-Remove-server-side-support-for-standard_conformin.patch
text/x-diff
Filename: v1-0002-Remove-server-side-support-for-standard_conformin.patch
Type: text/x-diff
Part: 1
From 562f29aedb0207420a8e3aeb807a9a1b18095fda Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 30 Dec 2025 15:42:22 -0500
Subject: [PATCH v1 2/4] Remove server-side support for
!standard_conforming_strings.
Mostly this consists of dropping scan.l's support for
escape_string_warning, which is no longer reachable.
(To see that, note that the warning subroutines are
only called within the <xe> exclusive state, and after
the change in the {xqstart} rule, <xe> state cannot be
reached with yyextra->warn_on_first_escape true.
So the subroutines can never warn.)
This leaves the escape_string_warning GUC nonfunctional,
but cleaning up that situation will come later.
Also adjust assorted comments to reflect the fact that
standard_conforming_strings = false is no longer possible
locally, but we still have to allow for the possibility
that a remote server might have it.
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/3279216.1767072538@sss.pgh.pa.us
---
.../pg_stat_statements/pg_stat_statements.c | 3 -
contrib/test_decoding/test_decoding.c | 4 +-
src/backend/parser/scan.l | 76 ++-----------------
src/backend/utils/adt/quote.c | 8 +-
src/backend/utils/adt/ruleutils.c | 6 +-
src/backend/utils/misc/guc_tables.c | 5 +-
src/include/parser/parser.h | 4 +-
src/include/parser/scanner.h | 5 +-
8 files changed, 17 insertions(+), 94 deletions(-)
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 39208f80b5b..58892d12246 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/test_decoding/test_decoding.c b/contrib/test_decoding/test_decoding.c
index 47094f86f5f..4c92f0eeffa 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/src/backend/parser/scan.l b/src/backend/parser/scan.l
index a67815339b7..cc88eea3708 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 .
<xe>{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);
}
<xe>{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 .
<xe>{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 551de59a07f..e62bf04a9f9 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 9f85eb86da1..61028db020f 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_tables.c b/src/backend/utils/misc/guc_tables.c
index 04ab0a26608..beea9b00657 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -529,10 +529,11 @@ 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;
+static bool escape_string_warning = true;
bool current_role_is_superuser;
diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h
index 350196cd641..cbf9a704dfb 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 8d202d5b284..f5806feb91d 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;
--
2.43.7