summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2018-08-30 15:18:35 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2018-08-31 17:07:43 +0200
commit796d54df115a0e5485a7df0835088a51dd0f9e77 (patch)
tree5769259f7df0b2ba6519f93de58c19598b7b84ea
parent42f09adab68f80fb99d6da0413cd4983ec13f5ab (diff)
downloadmariadb-git-796d54df115a0e5485a7df0835088a51dd0f9e77.tar.gz
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.
-rw-r--r--mysql-test/r/join.result6
-rw-r--r--mysql-test/r/sp.result17
-rw-r--r--mysql-test/t/join.test3
-rw-r--r--mysql-test/t/sp.test21
-rw-r--r--sql/sql_base.cc14
-rw-r--r--sql/table.h10
6 files changed, 67 insertions, 4 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..272aa11977d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -7764,10 +7764,22 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
result= FALSE;
-err:
if (arena)
thd->restore_active_arena(arena, &backup);
DBUG_RETURN(result);
+
+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(TRUE);
}
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);