From 96b3872bc5b8a80d17809ed691f04108f0358160 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 5 Mar 2018 17:43:30 +0100 Subject: MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM LAST_INSERT_ID () There is not current SELECT during assigning SP parameters, do not use it if current_select is empty. --- mysql-test/r/query_cache.result | 19 +++++++++++++++++++ mysql-test/r/sp.result | 8 ++++++++ mysql-test/t/query_cache.test | 15 +++++++++++++++ mysql-test/t/sp.test | 10 ++++++++++ sql/sql_lex.h | 29 ++++++++++++++++------------- 5 files changed, 68 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index eb9b1d16011..ee734845a9e 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -2168,6 +2168,25 @@ show status like "Qcache_hits"; Variable_name Value Qcache_hits 1 drop table t1; +# +# MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM +# LAST_INSERT_ID () +# (part 2, part 1 is in sp.test) +# +create table t1 (a int); +insert into t1 values (1); +CREATE FUNCTION foo (i INT UNSIGNED ) RETURNS int deterministic RETURN 1; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +SELECT foo( LAST_INSERT_ID() ) from t1; +foo( LAST_INSERT_ID() ) +1 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +DROP FUNCTION foo; +drop table t1; restore defaults SET GLOBAL query_cache_type= default; SET GLOBAL query_cache_size= default; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index d99780ad2ee..274727d58c4 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -8335,3 +8335,11 @@ ERROR 42S22: Unknown column 'name2' in 'field list' drop procedure p1; drop procedure p2; drop procedure p3; +# +# MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM +# LAST_INSERT_ID () +# (part 1, part 2 is in query_cache.test) +# +CREATE PROCEDURE foo ( IN i INT UNSIGNED ) BEGIN END; +CALL foo( LAST_INSERT_ID() ); +DROP PROCEDURE foo; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index c354032bc36..1b1e24bc6f4 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -1767,6 +1767,21 @@ show status like "Qcache_inserts"; show status like "Qcache_hits"; drop table t1; +--echo # +--echo # MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM +--echo # LAST_INSERT_ID () +--echo # (part 2, part 1 is in sp.test) +--echo # + +create table t1 (a int); +insert into t1 values (1); +CREATE FUNCTION foo (i INT UNSIGNED ) RETURNS int deterministic RETURN 1; +show status like "Qcache_queries_in_cache"; +SELECT foo( LAST_INSERT_ID() ) from t1; +show status like "Qcache_queries_in_cache"; +DROP FUNCTION foo; +drop table t1; + --echo restore defaults SET GLOBAL query_cache_type= default; SET GLOBAL query_cache_size= default; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 68a0c060906..529ebd4736a 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -9840,3 +9840,13 @@ call p3(); drop procedure p1; drop procedure p2; drop procedure p3; + +--echo # +--echo # MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM +--echo # LAST_INSERT_ID () +--echo # (part 1, part 2 is in query_cache.test) +--echo # + +CREATE PROCEDURE foo ( IN i INT UNSIGNED ) BEGIN END; +CALL foo( LAST_INSERT_ID() ); +DROP PROCEDURE foo; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 88462477de9..6d281930d1f 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2902,21 +2902,24 @@ public: { safe_to_cache_query= 0; - /* - There are no sense to mark select_lex and union fields of LEX, - but we should merk all subselects as uncacheable from current till - most upper - */ - SELECT_LEX *sl; - SELECT_LEX_UNIT *un; - for (sl= current_select, un= sl->master_unit(); - un != &unit; - sl= sl->outer_select(), un= sl->master_unit()) + if (current_select) // initialisation SP variables has no SELECT { - sl->uncacheable|= cause; - un->uncacheable|= cause; + /* + There are no sense to mark select_lex and union fields of LEX, + but we should merk all subselects as uncacheable from current till + most upper + */ + SELECT_LEX *sl; + SELECT_LEX_UNIT *un; + for (sl= current_select, un= sl->master_unit(); + un != &unit; + sl= sl->outer_select(), un= sl->master_unit()) + { + sl->uncacheable|= cause; + un->uncacheable|= cause; + } + select_lex.uncacheable|= cause; } - select_lex.uncacheable|= cause; } void set_trg_event_type_for_tables(); -- cgit v1.2.1