From d6ee351bbb66b023e8c477b039aa469b053f84ad Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 5 Jan 2022 20:23:52 -0800 Subject: Revert "MDEV-24454 Crash at change_item_tree" This patch reverts the fixes of the bugs MDEV-24454 and MDEV-25631 from the commit 3690c549c6e72646ba74f6b4c83813ee4ac3aea4. It leaves the changes in plugin/feedback/feedback.cc and corresponding test files introduced in this commit intact. Proper fixes for the bug MDEV-24454 and MDEV-25631 will follow immediately. --- sql/sql_base.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql/sql_base.cc') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5173df260d5..9a66b27a454 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6440,7 +6440,6 @@ set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref) if (!(context= new (thd->mem_root) Name_resolution_context)) return TRUE; context->init(); - context->select_lex= table_ref->select_lex; context->first_name_resolution_table= context->last_name_resolution_table= table_ref; item->context= context; -- cgit v1.2.1 From 89c870b2b4b0003c592887253d165b10569749a3 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Tue, 11 Jan 2022 11:50:29 +0700 Subject: 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) Re-execution of a query containing subquery in the FROM clause results in assert failure in case the query is run as part of a stored routine or as a prepared statement AND derived table merge optimization is off. As an example, the following test case CREATE TABLE t1 (a INT) ; CREATE PROCEDURE sp() SELECT * FROM (SELECT a FROM t1) tb; CALL sp(); SET optimizer_switch='derived_merge=off'; CALL sp(); results in assert failure on the second invocation of the 'sp' stored routine. The reason for assertion failure is that the expression derived->is_excluded() returns the value true where the value false expected. The method is_excluded() returns the value true for a derived table that has been merged to a parent select. Such transformation happens as part of Derived Table Merge Optimization that is performed on first invocation of a stored routine or a prepared statement containing a query with subquery in the FROM clause of the main SELECT. When the same routine or prepared statement is run the second time and Derived Table Merge Optimization is OFF the MariaDB server tries to materialize a derived table specified by the subquery that fails since this subquery has already been merged to the top-most SELECT. This transformation is permanent and can't be reverted. That is the reason why the assert DBUG_ASSERT(!derived->is_excluded()); fails inside the function TABLE_LIST::set_check_materialized(). Similar behaviour can be observed in case a stored routine or prepared statement containing a SELECT statement with subquery in the FROM clause, first is run with the optimizer_switch option set to derived_merge=off and re-run after this option has been switched to derived_merge=on. In this case a derived table for subquery is materialized on the first execution and marked as merged derived table on the second execution that results in error with misleading error message: MariaDB [test]> CALL sp1(); ERROR 1030 (HY000): Got error 1 "Operation not permitted" from storage engine MEMORY To fix the issue, a derived table that has been already optimized shouldn't be re-marked for one more round of optimization. One significant consequence following from suggested change is that the data member TABLE_LIST::derived_type is not updated once the table optimization has been done. This fact should be taken into account when Prepared Statement being handled since once a table listed in a query has been optimized on execution of the statement PREPARE FROM it won't be touched anymore on handling the statement EXECUTE. One side effect caused by this change could be observed for the following test case: CREATE TABLE t1 (s1 INT); CREATE VIEW v1 AS SELECT s1,s2 FROM (SELECT s1 as s2 FROM t1 WHERE s1 <100) x, t1 WHERE t1.s1=x.s2; INSERT INTO v1 (s1) VALUES (-300); PREPARE stmt FROM "INSERT INTO v1 (s1) VALUES (-300)"; EXECUTE stmt; Execution of the above EXECUTE statement results in issuing the error ER_COLUMNACCESS_DENIED_ERROR since table_ref->is_merged_derived() is false and check_column_grant_in_table_ref() called for a temporary table that shouldn't be. To fix this issue the function find_field_in_tables has been modified in such a way that the function check_column_grant_in_table_ref() is not called for a temporary table. --- sql/sql_base.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_base.cc') 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 -- cgit v1.2.1 From a38b937bf12ab7e39eeda6e6d4da1b426302dc70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Sun, 9 Jan 2022 09:37:44 +0200 Subject: MDEV-25201 : Assertion `thd->wsrep_trx_meta.gtid.seqno == (-1)' failed in int wsrep_to_isolation_begin(THD*, const char*, const char*, const TABLE_LIST*, Alter_info*) Test case does not assert anymore but works incorrectly. We should not replicate PREPARE using TOI. --- sql/sql_base.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql/sql_base.cc') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5345fdbecd0..248dedf36e4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4227,6 +4227,7 @@ restart: wsrep_thd_exec_mode(thd) == LOCAL_STATE && !is_stat_table((*start)->db, (*start)->alias) && thd->get_command() != COM_STMT_PREPARE && + !thd->stmt_arena->is_stmt_prepare() && ((thd->lex->sql_command == SQLCOM_INSERT || thd->lex->sql_command == SQLCOM_INSERT_SELECT || thd->lex->sql_command == SQLCOM_REPLACE || -- cgit v1.2.1