From 27d3b98cdf869b413efaadbc8dc3946f7d530bf8 Mon Sep 17 00:00:00 2001 From: Matej Klonfar Date: Tue, 14 Oct 2025 12:47:36 +0200 Subject: [PATCH] Allowing comments in replication statements --- src/backend/replication/repl_scanner.l | 71 +++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index b6930e28659..035a82c2e4e 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -45,6 +45,9 @@ struct replication_yy_extra_type /* Work area for collecting literals */ StringInfoData litbuf; + + /* Depth of nesting in slash-star comments */ + int xcdepth; }; static void startlit(yyscan_t yyscanner); @@ -75,15 +78,44 @@ static void addlitchar(unsigned char ychar, yyscan_t yyscanner); * Exclusive states: * delimited identifiers (double-quoted identifiers) * standard single-quoted strings + * extended C-style comments */ %x xd %x xq +%x xc space [ \t\n\r\f\v] +op_chars [\~\!\@\#\^\&\|\`\?\+\-\*\/\%\<\>\=] +non_newline [^\n\r] +comment ("--"{non_newline}*) +whitespace ({space}+|{comment}) quote ' quotestop {quote} +/* C-style comments + * + * The "extended comment" syntax closely resembles allowable operator syntax. + * The tricky part here is to get lex to recognize a string starting with + * slash-star as a comment, when interpreting it as an operator would produce + * a longer match --- remember lex will prefer a longer match! Also, if we + * have something like plus-slash-star, lex will think this is a 3-character + * operator whereas we want to see it as a + operator and a comment start. + * The solution is two-fold: + * 1. append {op_chars}* to xcstart so that it matches as much text as + * {operator} would. Then the tie-breaker (first matching rule of same + * length) ensures xcstart wins. We put back the extra stuff with yyless() + * in case it contains a star-slash that should terminate the comment. + * 2. In the operator rule, check for slash-star within the operator, and + * if found throw it back with yyless(). This handles the plus-slash-star + * problem. + * Dash-dash comments have similar interactions with the operator rule. + */ +xcstart \/\*{op_chars}* +xcstop \*+\/ +xcinside [^*/]+ + + /* Extended quote * xqdouble implements embedded quote, '''' */ @@ -145,7 +177,44 @@ USE_SNAPSHOT { return K_USE_SNAPSHOT; } WAIT { return K_WAIT; } UPLOAD_MANIFEST { return K_UPLOAD_MANIFEST; } -{space}+ { /* do nothing */ } +{whitespace} { /* do nothing */ } +{xcstart} { + yyextra->xcdepth = 0; + BEGIN(xc); + /* Put back any characters past slash-star; see above */ + yyless(2); + } + +{ +{xcstart} { + (yyextra->xcdepth)++; + /* Put back any characters past slash-star; see above */ + yyless(2); + } + +{xcstop} { + if (yyextra->xcdepth <= 0) + BEGIN(INITIAL); + else + (yyextra->xcdepth)--; + } + +{xcinside} { + /* ignore */ + } +{op_chars} { + /* ignore */ + } + +\*+ { + /* ignore */ + } + +<> { + replication_yyerror(NULL, yyscanner, "unterminated /* comment"); + } +} /* */ + {digit}+ { yylval->uintval = strtoul(yytext, NULL, 10); -- 2.51.0