From f9a8e3a0445ee99f5807de0598fafc674ddf2b8a Mon Sep 17 00:00:00 2001 From: hcduan Date: Mon, 27 Dec 2021 17:33:09 +0800 Subject: [PATCH] [bugfix] parse_ending_of_sp_error The parser in multi_statements mode keeps terminating semi-colon for a statement. When it is a DDL creating a stored program, the semi-colon becomes part of the definition. Tools like mysqldump wrap the definition within a version comment which does not support any semi-colon-terminated complete statement, as a result, the output could not be imported. When defining a SP (e.g., TRIGGER, PROCEDURE, and FUNCTION), we often set new separators to distinguish the default line separator (semicolon ';') and whole SP terminators. Normally, the newly defined delimiter is directly used as the ending character of the SP. Eg., DELIMITER // CREATE TRIGGER `TG` BEFORE UPDATE ON `t1` FOR EACH ROW LABELTRI: BEGIN SET new.NAME = '1'; END// Even if the last line incorrectly writes one more semicolon, the extra semicolon will be deleted when storing the SP. Eg., DELIMITER // ... ... END; // The problem is that when the user or other DBA auxiliary tools not only write one more semicolon, but also add additional characters before the newly defined end separator, the SP will incorrectly stored one more semicolon. Eg., DELIMITER // ... ... END; *// The SP is stored as: DELIMITER // ... ... END; At this time, when mysqldump is used, the last line will generated "end;". Which causes errors when importing the SP. Fix: When setting the SP terminator (sp_head.cc:set_body_end), we verify that the above error and remove the extra semicolon to correct the end pointer. --- sql/sp_head.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 6771fb9c1..90b022c60 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1777,6 +1777,11 @@ void sp_head::set_body_start(THD *thd, const char *begin_ptr) { void sp_head::set_body_end(THD *thd) { Lex_input_stream *lip = &thd->m_parser_state->m_lip; /* shortcut */ const char *end_ptr = lip->get_cpp_ptr(); /* shortcut */ + /* Remove the extra semicolon to prevent mysqldump export errors */ + if (end_ptr - m_parser_data.get_body_start_ptr() > 0 && + (end_ptr[-1] == ';')) { + end_ptr--; + } /* Make the string of parameters. */ -- 2.32.0