Skip to content

Commit d151643

Browse files
committed
MDEV-36675 Optimizer hints parser catches irrelevant thd->is_error() set by multi-RENAME TABLE
Optimizer hints parser analyzes `thd->is_error()` flag to detect a fatal error occured during hints processing. However, this criteria is not reliable and considered a bad practice. This commit replaces the criteria with the parser's own `is_fatal_error()` flag which is related strictly to hints parsing and not something else
1 parent 127f28a commit d151643

File tree

5 files changed

+51
-15
lines changed

5 files changed

+51
-15
lines changed

mysql-test/main/opt_hints.result

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1985,5 +1985,21 @@ DROP TABLE t1;
19851985
set optimizer_switch = DEFAULT;
19861986
set join_cache_level = DEFAULT;
19871987
#
1988-
# End of 11.7 tests
1988+
# MDEV-36675 Optimizer hints parser catches irrelevant `thd->is_error()`
1989+
# set by multi-RENAME TABLE
1990+
#
1991+
CREATE TABLE t1 (a INT);
1992+
CREATE TRIGGER t1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (0);
1993+
RENAME TABLE t1 TO t2, t3 TO t4;
1994+
ERROR 42S02: Table 'test.t3' doesn't exist
1995+
SHOW CREATE TRIGGER t1;
1996+
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
1997+
t1 CREATE DEFINER=`root`@`localhost` TRIGGER t1 AFTER INSERT ON `t1` FOR EACH ROW INSERT INTO t1 VALUES (0) utf8mb3 utf8mb3_uca1400_ai_ci utf8mb4_uca1400_ai_ci #
1998+
RENAME TABLE t1 TO t2;
1999+
SHOW CREATE TRIGGER t1;
2000+
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created
2001+
t1 CREATE DEFINER=`root`@`localhost` TRIGGER t1 AFTER INSERT ON `t2` FOR EACH ROW INSERT INTO t1 VALUES (0) utf8mb3 utf8mb3_uca1400_ai_ci utf8mb4_uca1400_ai_ci #
2002+
DROP TABLE t2;
2003+
#
2004+
# End of 12.0 tests
19892005
#

mysql-test/main/opt_hints.test

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,24 @@ SELECT
10211021
DROP TABLE t1;
10221022
set optimizer_switch = DEFAULT;
10231023
set join_cache_level = DEFAULT;
1024+
1025+
--echo #
1026+
--echo # MDEV-36675 Optimizer hints parser catches irrelevant `thd->is_error()`
1027+
--echo # set by multi-RENAME TABLE
1028+
--echo #
1029+
CREATE TABLE t1 (a INT);
1030+
CREATE TRIGGER t1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (0);
1031+
--error ER_NO_SUCH_TABLE
1032+
RENAME TABLE t1 TO t2, t3 TO t4;
1033+
1034+
--replace_column 7 #
1035+
SHOW CREATE TRIGGER t1;
1036+
RENAME TABLE t1 TO t2;
1037+
1038+
--replace_column 7 #
1039+
SHOW CREATE TRIGGER t1;
1040+
DROP TABLE t2;
1041+
10241042
--echo #
1025-
--echo # End of 11.7 tests
1043+
--echo # End of 12.0 tests
10261044
--echo #

sql/sql_lex.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12702,22 +12702,22 @@ bool SELECT_LEX_UNIT::is_derived_eliminated() const
1270212702
/*
1270312703
Parse optimizer hints and return as Hint_list allocated on thd->mem_root.
1270412704
12705-
The caller should check both return value and thd->is_error()
12705+
The caller should check both parts of the return value
1270612706
to know what happened, as follows:
1270712707
12708-
Return value thd->is_error() Meaning
12708+
Retval.first Retval.second Meaning
1270912709
------------ --------------- -------
12710-
rc != nullptr false the hints were parsed without errors
12711-
rc != nullptr true not possible
12712-
rc == nullptr false no hints, empty hints, hint parse error
12713-
rc == nullptr true fatal error, such as EOM
12710+
false != nullptr the hints were parsed without errors
12711+
true != nullptr impossible combination
12712+
false == nullptr no hints, empty hints, hint parse error
12713+
true == nullptr fatal error, such as EOM
1271412714
*/
12715-
Optimizer_hint_parser_output *
12715+
std::pair<bool, Optimizer_hint_parser_output *>
1271612716
LEX::parse_optimizer_hints(const Lex_comment_st &hints_str)
1271712717
{
1271812718
DBUG_ASSERT(!hints_str.str || hints_str.length >= 5);
1271912719
if (!hints_str.str)
12720-
return nullptr; // There were no a hint comment
12720+
return {false, nullptr}; // There were no a hint comment
1272112721

1272212722
// Instantiate the query hint parser.
1272312723
// Remove the leading '/*+' and trailing '*/'
@@ -12735,17 +12735,17 @@ LEX::parse_optimizer_hints(const Lex_comment_st &hints_str)
1273512735
The SQL error should be in DA already.
1273612736
*/
1273712737
DBUG_ASSERT(thd->is_error());
12738-
return nullptr; // Continue, the caller will test thd->is_error()
12738+
return {true, nullptr}; // Set the flag of fatal error
1273912739
}
1274012740

1274112741
if (!hints) // Hint parsing failed with a syntax error
1274212742
{
1274312743
p.push_warning_syntax_error(thd, hints_str.lineno);
12744-
return nullptr; // Continue and ignore hints.
12744+
return {false, nullptr}; // Continue and ignore hints.
1274512745
}
1274612746

1274712747
// Hints were not empty and were parsed without errors
12748-
return new (thd->mem_root) Optimizer_hint_parser_output(std::move(hints));
12748+
return {false, new (thd->mem_root) Optimizer_hint_parser_output(std::move(hints))};
1274912749
}
1275012750

1275112751

sql/sql_lex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4948,7 +4948,7 @@ struct LEX: public Query_tables_list
49484948
return nullptr;
49494949
}
49504950

4951-
Optimizer_hint_parser_output *
4951+
std::pair<bool, Optimizer_hint_parser_output *>
49524952
parse_optimizer_hints(const Lex_comment_st &hint);
49534953
};
49544954

sql/sql_yacc.yy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8984,7 +8984,9 @@ opt_optimizer_hint:
89848984
opt_hint_comment
89858985
{
89868986
YYLIP->hint_comment= false;
8987-
if (!($$= Lex->parse_optimizer_hints($2)) && thd->is_error())
8987+
std::pair<bool, Optimizer_hint_parser_output *> parse_res=
8988+
Lex->parse_optimizer_hints($2);
8989+
if (!($$= parse_res.second) && parse_res.first)
89888990
MYSQL_YYABORT;
89898991
}
89908992
;

0 commit comments

Comments
 (0)