diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-05-30 17:03:26 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-05-30 17:03:26 +0400 |
commit | cd1d161c261dcb6f9158bf0a537cb9deee051010 (patch) | |
tree | bb4afa8e4b8f143c8aa11ec325eabf91e041ccc7 | |
parent | f98bb23168ee9bc0da8aa7111f35cf2539986387 (diff) | |
download | mariadb-git-cd1d161c261dcb6f9158bf0a537cb9deee051010.tar.gz |
MDEV-19637 Crash on an SP variable assignment to a wrong subselect
-rw-r--r-- | mysql-test/main/sp.result | 15 | ||||
-rw-r--r-- | mysql-test/main/sp.test | 23 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/sp.result | 16 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/sp.test | 25 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 18 |
5 files changed, 96 insertions, 1 deletions
diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 3129a2e165c..5908ee24ad4 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -8792,3 +8792,18 @@ drop procedure p4; drop table t1; set @@sql_mode=@save_sql_mode; # End of 10.3 tests +# +# Start of 10.4 tests +# +# +# MDEV-19637 Crash on an SP variable assignment to a wrong subselect +# +BEGIN NOT ATOMIC +DECLARE a INT; +SET a=(SELECT 1 FROM DUAL UNION SELECT HIGH_PRIORITY 2 FROM DUAL); +END; +$$ +ERROR 42000: Incorrect usage/placement of 'HIGH_PRIORITY' +# +# End of 10.4 tests +# diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index 7f841ccd0b4..920b09077d3 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -10323,3 +10323,26 @@ drop table t1; set @@sql_mode=@save_sql_mode; --echo # End of 10.3 tests + + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-19637 Crash on an SP variable assignment to a wrong subselect +--echo # + +DELIMITER $$; +--error ER_CANT_USE_OPTION_HERE +BEGIN NOT ATOMIC + DECLARE a INT; + SET a=(SELECT 1 FROM DUAL UNION SELECT HIGH_PRIORITY 2 FROM DUAL); +END; +$$ +DELIMITER ;$$ + + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result index 6db999b238f..1d088a98ab7 100644 --- a/mysql-test/suite/compat/oracle/r/sp.result +++ b/mysql-test/suite/compat/oracle/r/sp.result @@ -2552,3 +2552,19 @@ idx idx 1 DROP PROCEDURE p1; +# +# Start of 10.4 tests +# +# +# MDEV-19637 Crash on an SP variable assignment to a wrong subselect +# +DECLARE +a INT; +BEGIN +SET a=(SELECT 1 FROM DUAL UNION SELECT HIGH_PRIORITY 2 FROM DUAL); +END; +$$ +ERROR 42000: Incorrect usage/placement of 'HIGH_PRIORITY' +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test index 96b4cd59fbd..4d046533457 100644 --- a/mysql-test/suite/compat/oracle/t/sp.test +++ b/mysql-test/suite/compat/oracle/t/sp.test @@ -2387,3 +2387,28 @@ $$ DELIMITER ;$$ CALL p1(); DROP PROCEDURE p1; + + +--echo # +--echo # Start of 10.4 tests +--echo # + + +--echo # +--echo # MDEV-19637 Crash on an SP variable assignment to a wrong subselect +--echo # + +DELIMITER $$; +--error ER_CANT_USE_OPTION_HERE +DECLARE + a INT; +BEGIN + SET a=(SELECT 1 FROM DUAL UNION SELECT HIGH_PRIORITY 2 FROM DUAL); +END; +$$ +DELIMITER ;$$ + + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6547bee15ac..3b6e83dd7cc 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -575,8 +575,24 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead) return true; } lex->pop_select(); - if (Lex->check_main_unit_semantics()) + if (lex->check_main_unit_semantics()) + { + /* + "lex" can be referrenced by: + - sp_instr_set SET a= expr; + - sp_instr_set_row_field SET r.a= expr; + - sp_instr_stmt (just generated above) SET @a= expr; + In this case, "lex" is fully owned by sp_instr_xxx and it will + be deleted by the destructor ~sp_instr_xxx(). + So we should remove "lex" from the stack sp_head::m_lex, + to avoid double free. + Note, in case "lex" is not owned by any sp_instr_xxx, + it's also safe to remove it from the stack right now. + So we can remove it unconditionally, without testing lex->sp_lex_in_use. + */ + lex->sphead->restore_lex(thd); return true; + } enum_var_type inner_option_type= lex->option_type; if (lex->sphead->restore_lex(thd)) return true; |