st_select_lex::handle_derived() and mysql_handle_list_of_derived() had
exactly the same implementations.
- Adding a new method LEX::handle_list_of_derived() instead
- Removing public function mysql_handle_list_of_derived()
- Reusing LEX::handle_list_of_derived() in st_select_lex::handle_derived()
The bug happened when the specification of a recursive CTE had
no recursive references at the top level of the specification.
In this case the regular processing of derived table references
of the select containing a non-recursive reference to this
recursive CTE misses handling the specification unit.
At the preparation stage any non-recursive reference to a
recursive CTE must be handled after the preparation of the
specification unit for this CTE. So we have to force this
preparation when regular handling of derived tables does not
do it.
Call mysql_derived_reinit() if we are reusing view.
This is needed as during a previous error condition the view may not have been reset
sql/sql_derived.cc:
More DBUG_PRINT
Always reset merged_for_insert (no reason to not do that)
sql/sql_derived.h:
Added prototype
sql/sql_insert.cc:
More DBUG_PRINT
Added DBUG_ASSERT
sql/sql_view.cc:
Call mysql_derived_reinit() if we are reusing view.
This is needed as during a previous error condition the view may not have been reset
sql/table.cc:
More DBUG_PRINT
sql/sql_insert.cc:
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
******
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
sql/sql_table.cc:
small cleanup
******
small cleanup
temptable views
The TABLE::key_read field indicates if the optimizer has found that row
retrieval only should access the index tree. The triggered assert
inside close_thread_table() checks that this field has been reset when
the table is about to be closed.
During normal execution, these fields are reset right before tables are
closed at the end of mysql_execute_command(). But in the case of errors,
tables are closed earlier. The patch for Bug#52044 refactored the open
tables code so that close_thread_tables() is called immediately if
opening of tables fails. At this point in the execution, it could
happend that all TABLE::key_read fields had not been properly reset,
therefore triggering the assert.
The problematic statement in this case was EXPLAIN where the query
accessed two derived tables and where the first derived table was
processed successfully while the second derived table was not.
Since it was an EXPLAIN, TABLE::key_read fields were not reset after
successful derived table processing since the state needs to be
accessible afterwards. When processing of the second derived table
failed, it's corresponding SELECT_LEX_UNIT was cleaned, which caused
it's TABLE::key_read fields to be reset. Since processing failed,
the error path of open_and_lock_tables() was entered and
close_thread_tables() was called. The assert was then triggered due
to the TABLE::key_read fields set during processing of the first
derived table.
This patch fixes the problem by adding a new derived table processor,
mysql_derived_cleanup() that is called after mysql_derived_filling().
It causes cleanup of all SELECT_LEX_UNITs to be called, resetting
all relevant TABLE::key_read fields.
Test case added to derived.test.
This patch:
- Moves all definitions from the mysql_priv.h file into
header files for the component where the variable is
defined
- Creates header files if the component lacks one
- Eliminates all include directives from mysql_priv.h
- Eliminates all circular include cycles
- Rename time.cc to sql_time.cc
- Rename mysql_priv.h to sql_priv.h