summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/derived.result53
-rw-r--r--mysql-test/t/derived.test51
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/table.cc24
4 files changed, 127 insertions, 3 deletions
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index 2106ba504a9..5085feaaedc 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -1204,5 +1204,58 @@ REPLACE INTO v2 ( SELECT * FROM v4 ) UNION ( SELECT f FROM v2 );
drop view v1,v2,v3,v4;
drop table t1,t2,t3;
#
+# MDEV-20325: Assertion `outer_context || !*from_field || *from_field == not_found_field' failed in Item_field::fix_outer_field | `!derived->is_excluded()' failed in TABLE_LIST::set_check_materialized | SIGEGV in st_select_lex::mark_as_dependent (optimized builds)
+#
+CREATE TABLE t1 (a INT);
+# Check that re-execution of a stored routine containing
+# a query with subquery in the FROM clause doesn't result in
+# assert failure in case the 'derived_merge' optimizer option
+# has been turned on/off
+CREATE PROCEDURE sp() SELECT * FROM (SELECT a FROM t1) tb;
+CALL sp();
+a
+SET optimizer_switch='derived_merge=off';
+# Without the patch the following statement would result in assert
+# failure
+CALL sp();
+a
+# Check the same test case for Prepared Statement
+SET optimizer_switch='derived_merge=on';
+PREPARE stmt FROM "SELECT * FROM (SELECT a FROM t1) tb";
+EXECUTE stmt;
+a
+SET optimizer_switch='derived_merge=off';
+# Without the patch the following statement would result in assert
+# failure
+EXECUTE stmt;
+a
+DEALLOCATE PREPARE stmt;
+# Here check the reverse test case - first turn off the 'derived_merge'
+# optimizer option, run the stored routine containing a query with
+# subquery in the FROM clause, then turn on the 'derived_merge'
+# optimizer option and re-execute the same stored routine to check that
+# the routine is finished successfully.
+CREATE PROCEDURE sp1() SELECT * FROM (SELECT a FROM t1) tb;
+SET optimizer_switch='derived_merge=off';
+CALL sp1();
+a
+SET optimizer_switch='derived_merge=on';
+CALL sp1();
+a
+# Check the same test case for Prepared Statement
+SET optimizer_switch='derived_merge=off';
+PREPARE stmt FROM "SELECT * FROM (SELECT a FROM t1) tb";
+EXECUTE stmt;
+a
+SET optimizer_switch='derived_merge=on';
+# Without the patch the following statement would result in assert
+# failure
+EXECUTE stmt;
+a
+DEALLOCATE PREPARE stmt;
+DROP PROCEDURE sp;
+DROP PROCEDURE sp1;
+DROP TABLE t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index 6d9d5e23cf9..c8e6681e80b 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -1037,5 +1037,56 @@ drop view v1,v2,v3,v4;
drop table t1,t2,t3;
--echo #
+--echo # MDEV-20325: Assertion `outer_context || !*from_field || *from_field == not_found_field' failed in Item_field::fix_outer_field | `!derived->is_excluded()' failed in TABLE_LIST::set_check_materialized | SIGEGV in st_select_lex::mark_as_dependent (optimized builds)
+--echo #
+CREATE TABLE t1 (a INT);
+
+--echo # Check that re-execution of a stored routine containing
+--echo # a query with subquery in the FROM clause doesn't result in
+--echo # assert failure in case the 'derived_merge' optimizer option
+--echo # has been turned on/off
+CREATE PROCEDURE sp() SELECT * FROM (SELECT a FROM t1) tb;
+CALL sp();
+SET optimizer_switch='derived_merge=off';
+--echo # Without the patch the following statement would result in assert
+--echo # failure
+CALL sp();
+
+--echo # Check the same test case for Prepared Statement
+SET optimizer_switch='derived_merge=on';
+PREPARE stmt FROM "SELECT * FROM (SELECT a FROM t1) tb";
+EXECUTE stmt;
+SET optimizer_switch='derived_merge=off';
+--echo # Without the patch the following statement would result in assert
+--echo # failure
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+--echo # Here check the reverse test case - first turn off the 'derived_merge'
+--echo # optimizer option, run the stored routine containing a query with
+--echo # subquery in the FROM clause, then turn on the 'derived_merge'
+--echo # optimizer option and re-execute the same stored routine to check that
+--echo # the routine is finished successfully.
+CREATE PROCEDURE sp1() SELECT * FROM (SELECT a FROM t1) tb;
+SET optimizer_switch='derived_merge=off';
+CALL sp1();
+SET optimizer_switch='derived_merge=on';
+CALL sp1();
+
+--echo # Check the same test case for Prepared Statement
+SET optimizer_switch='derived_merge=off';
+PREPARE stmt FROM "SELECT * FROM (SELECT a FROM t1) tb";
+EXECUTE stmt;
+SET optimizer_switch='derived_merge=on';
+--echo # Without the patch the following statement would result in assert
+--echo # failure
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+DROP PROCEDURE sp;
+DROP PROCEDURE sp1;
+DROP TABLE t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 9a66b27a454..5345fdbecd0 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -5980,7 +5980,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
TRUE, &(item->cached_field_index));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Check if there are sufficient access rights to the found field. */
- if (found && check_privileges &&
+ if (found && check_privileges && !is_temporary_table(table_ref) &&
check_column_grant_in_table_ref(thd, table_ref, name, length))
found= WRONG_GRANT;
#endif
diff --git a/sql/table.cc b/sql/table.cc
index d4f8170e0af..ca6ce02e4f2 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8232,6 +8232,24 @@ void TABLE_LIST::wrap_into_nested_join(List<TABLE_LIST> &join_list)
/**
+ Check whether optimization has been performed and a derived table either
+ been merged to upper select level or materialized.
+
+ @param table a TABLE_LIST object containing a derived table
+
+ @return true in case the derived table has been merged to surrounding select,
+ false otherwise
+*/
+
+static inline bool derived_table_optimization_done(TABLE_LIST *table)
+{
+ return table->derived &&
+ (table->derived->is_excluded() ||
+ table->is_materialized_derived());
+}
+
+
+/**
@brief
Initialize this derived table/view
@@ -8267,13 +8285,15 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view)
set_multitable();
unit->derived= this;
- if (init_view && !view)
+ if (init_view && !view &&
+ !derived_table_optimization_done(this))
{
/* This is all what we can do for a derived table for now. */
set_derived();
}
- if (!is_view())
+ if (!is_view() &&
+ !derived_table_optimization_done(this))
{
/* A subquery might be forced to be materialized due to a side-effect. */
if (!is_materialized_derived() && first_select->is_mergeable() &&