Bug #116266 | Binlog record error when delimiter is set to other symbols | ||
---|---|---|---|
Submitted: | 29 Sep 2024 14:14 | Modified: | 10 Oct 2024 11:21 |
Reporter: | xilin Chen | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S2 (Serious) |
Version: | 8.0.39 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[29 Sep 2024 14:14]
xilin Chen
[30 Sep 2024 15:01]
MySQL Verification Team
Hello xilin Chen, Thank you for the report and test case. Verified as described. regards, Umesh
[10 Oct 2024 11:21]
xilin Chen
The reason is that the SQL length is truncated according to the semicolon. In fact, the semicolon here is not a separator. The corresponding code is as follows 8.0.39 sql/sql_parse.cc:5267 void dispatch_sql_command(THD *thd, Parser_state *parser_state) { ... if (!err) { err = parse_sql(thd, parser_state, nullptr); if (!err) err = invoke_post_parse_rewrite_plugins(thd, false); found_semicolon = parser_state->m_lip.found_semicolon; qlen = found_semicolon ? (found_semicolon - thd->query().str) : thd->query().length; /* We set thd->query_length correctly to not log several queries, when we execute only first. We set it to not see the ';' otherwise it would get into binlog and Query_log_event::print() would give ';;' output. */ if (!thd->is_error() && found_semicolon && (ulong)(qlen)) { thd->set_query(thd->query().str, qlen - 1); } }
[14 Oct 2024 3:46]
huahua xu
Hi all: This issue has persisted since the earlier versions of MySQL. I suggest that the special comment with ';' should be considered as a syntax error, when expanding the content as real sql statement. diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 9a5b5c9..e613cf0 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1963,6 +1963,8 @@ static int lex_one_token(Lexer_yystype *yylval, THD *thd) { lip->yySkip(); return (SET_VAR); case MY_LEX_SEMICOLON: // optional line terminator + /* The special comments with ';' are a syntax error */ + if (lip->in_comment == DISCARD_COMMENT) return (ABORT_SYM); state = MY_LEX_CHAR; // Return ';' break; case MY_LEX_EOL: