From b0e3f484f76bfcd26f8da919d621f56972d21aa7 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 22 Oct 2015 16:08:45 +0200 Subject: [PATCH] MDEV-8756 MariaDB 10.0.21 crashes during PREPARE Non-select-like queries has no correct JOIN structure connected to top-most SELECT_LEX (and should not). --- mysql-test/r/ps.result | 21 +++++++++++++++++++++ mysql-test/t/ps.test | 22 ++++++++++++++++++++++ sql/item.cc | 20 ++++++++++++++++++-- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 31fcea528aa..8d073f8da1e 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -4052,3 +4052,24 @@ SELECT 1 FROM t1 GROUP BY 0 OR 18446744073709551615+1; ERROR 22003: BIGINT UNSIGNED value is out of range in '(18446744073709551615 + 1)' drop table t1; # End of 5.3 tests +# +# MDEV-8756: MariaDB 10.0.21 crashes during PREPARE +# +CREATE TABLE t1 ( id INT(10), value INT(10) ); +CREATE TABLE t2 ( id INT(10) ); +SET @save_sql_mode= @@sql_mode; +SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY'; +PREPARE stmt FROM 'UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id)'; +execute stmt; +insert into t1 values (1,10),(2,10),(3,10); +insert into t2 values (1),(2); +execute stmt; +select * from t1; +id value +1 1 +2 1 +3 NULL +deallocate prepare stmt; +SET SESSION sql_mode = @save_sql_mode; +DROP TABLE t1,t2; +# End of 10.0 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 0233b2e428b..c45b27281a7 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3633,3 +3633,25 @@ SELECT 1 FROM t1 GROUP BY 0 OR 18446744073709551615+1; drop table t1; --echo # End of 5.3 tests + +--echo # +--echo # MDEV-8756: MariaDB 10.0.21 crashes during PREPARE +--echo # + +CREATE TABLE t1 ( id INT(10), value INT(10) ); +CREATE TABLE t2 ( id INT(10) ); +SET @save_sql_mode= @@sql_mode; +SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY'; + +PREPARE stmt FROM 'UPDATE t1 t1 SET value = (SELECT 1 FROM t2 WHERE id = t1.id)'; +execute stmt; +insert into t1 values (1,10),(2,10),(3,10); +insert into t2 values (1),(2); +execute stmt; +select * from t1; +deallocate prepare stmt; +SET SESSION sql_mode = @save_sql_mode; +DROP TABLE t1,t2; + + +--echo # End of 10.0 tests diff --git a/sql/item.cc b/sql/item.cc index 90a8777d8f7..543ea4f0ffb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4834,8 +4834,24 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) As this is an outer field it should be added to the list of non aggregated fields of the outer select. */ - marker= select->cur_pos_in_select_list; - select->join->non_agg_fields.push_back(this); + if (select->join) + { + marker= select->cur_pos_in_select_list; + select->join->non_agg_fields.push_back(this); + } + else + { + /* + join is absent if it is upper SELECT_LEX of non-select + command + */ + DBUG_ASSERT(select->master_unit()->outer_select() == NULL && + (thd->lex->sql_command != SQLCOM_SELECT && + thd->lex->sql_command != SQLCOM_UPDATE_MULTI && + thd->lex->sql_command != SQLCOM_DELETE_MULTI && + thd->lex->sql_command != SQLCOM_INSERT_SELECT && + thd->lex->sql_command != SQLCOM_REPLACE_SELECT)); + } } if (*from_field != view_ref_found) {