revision-id: 1e40186998b1c609059f8840f05af031f68b6647 (mariadb-5.5.61-10-g1e40186998b) parent(s): e560f2f342aeb2d72937e9c6f5a4fcbfecc1c35e author: Oleksandr Byelkin committer: Oleksandr Byelkin timestamp: 2018-08-30 15:18:35 +0200 message: MDEV-16957: Server crashes in Field_iterator_natural_join::next upon 2nd execution of SP The problem was that join_columns creation was not finished due to error of notfound column in USING, but next execution tried to use join_columns lists. Solution is cleanup the lists on error. It can eat memory in statement MEM_ROOT but it is an error and error will be fixed or statement/procedure removed/altered. --- mysql-test/r/join.result | 6 ++++-- mysql-test/r/sp.result | 17 +++++++++++++++++ mysql-test/t/join.test | 3 ++- mysql-test/t/sp.test | 21 +++++++++++++++++++++ sql/sql_base.cc | 8 ++++++++ sql/table.h | 10 ++++++++++ 6 files changed, 62 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 7b0e7807e39..2e5ee30b54e 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -1514,11 +1514,13 @@ ERROR 42S22: Unknown column 'f' in 'from clause' DROP TABLE t; CREATE TABLE t (f INT); CALL p; -ERROR 42S22: Unknown column 'f' in 'from clause' +f DROP TABLE t; CREATE TABLE t (i INT); CALL p; -ERROR 42S22: Unknown column 'f' in 'from clause' +ERROR 42S22: Unknown column 't1.f' in 'field list' +CALL p; +ERROR 42S22: Unknown column 't1.f' in 'field list' DROP PROCEDURE p; DROP TABLE t; CREATE TABLE t1 (a INT, b INT); diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 823c6f78cee..4535056242a 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -8055,4 +8055,21 @@ SET S.CLOSE_YN = '' where 1=1; drop function if exists f1; drop table t1,t2; +# +# MDEV-16957: Server crashes in Field_iterator_natural_join::next +# upon 2nd execution of SP +# +CREATE TABLE t1 (a INT, b VARCHAR(32)); +CREATE PROCEDURE sp() SELECT * FROM t1 AS t1x JOIN t1 AS t1y USING (c); +CALL sp; +ERROR 42S22: Unknown column 'c' in 'from clause' +CALL sp; +ERROR 42S22: Unknown column 'c' in 'from clause' +CALL sp; +ERROR 42S22: Unknown column 'c' in 'from clause' +alter table t1 add column c int; +CALL sp; +c a b a b +DROP PROCEDURE sp; +DROP TABLE t1; # End of 5.5 test diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index feafac57a7e..5a29fe72049 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -1185,12 +1185,13 @@ CREATE TABLE t (f INT); # # The following shouldn't fail as the table is now matching the using # ---error ER_BAD_FIELD_ERROR CALL p; DROP TABLE t; CREATE TABLE t (i INT); --error ER_BAD_FIELD_ERROR CALL p; +--error ER_BAD_FIELD_ERROR +CALL p; DROP PROCEDURE p; DROP TABLE t; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 0e42bf3c831..cb93cd31442 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -9353,4 +9353,25 @@ where 1=1; drop function if exists f1; drop table t1,t2; +--echo # +--echo # MDEV-16957: Server crashes in Field_iterator_natural_join::next +--echo # upon 2nd execution of SP +--echo # + +CREATE TABLE t1 (a INT, b VARCHAR(32)); +CREATE PROCEDURE sp() SELECT * FROM t1 AS t1x JOIN t1 AS t1y USING (c); +--error ER_BAD_FIELD_ERROR +CALL sp; +--error ER_BAD_FIELD_ERROR +CALL sp; +--error ER_BAD_FIELD_ERROR +CALL sp; +alter table t1 add column c int; +CALL sp; + +# Cleanup +DROP PROCEDURE sp; +DROP TABLE t1; + + --echo # End of 5.5 test diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8ffb7bc118b..b0f6c191334 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7765,6 +7765,14 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join, result= FALSE; err: + /* + Actually we failed to build join columns list, so we have to + clear it to avoid problems with half-build join on next run. + The list was created in mark_common_columns(). + */ + table_ref_1->remove_join_columns(); + table_ref_2->remove_join_columns(); + if (arena) thd->restore_active_arena(arena, &backup); DBUG_RETURN(result); diff --git a/sql/table.h b/sql/table.h index 1d4a1d9a2d2..4725eb96432 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2184,6 +2184,16 @@ struct TABLE_LIST } void set_lock_type(THD* thd, enum thr_lock_type lock); + void remove_join_columns() + { + if (join_columns) + { + join_columns->empty(); + join_columns= NULL; + is_join_columns_complete= FALSE; + } + } + private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause);