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.
--Bug#52157 various crashes and assertions with multi-table update, stored function
--Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb
--Bug#57703 create view cause Assertion failed: 0, file .\item_subselect.cc, line 846
--Bug#57352 valgrind warnings when creating view
--Recently discovered problem when a nested materialized derived table is used
before being populated and it leads to incorrect result
We have several modes when we should disable subquery evaluation.
The reasons for disabling are different. It could be
uselessness of the evaluation as in case of 'CREATE VIEW'
or 'PREPARE stmt', or we should disable subquery evaluation
if tables are not locked yet as it happens in bug#54475, or
too early evaluation of subqueries can lead to wrong result
as it happened in Bug#19077.
Main problem is that if subquery items are treated as const
they are evaluated in ::fix_fields(), ::fix_length_and_dec()
of the parental items as a lot of these methods have
Item::val_...() calls inside.
We have to make subqueries non-const to prevent unnecessary
subquery evaluation. At the moment we have different methods
for this. Here is a list of these modes:
1. PREPARE stmt;
We use UNCACHEABLE_PREPARE flag.
It is set during parsing in sql_parse.cc, mysql_new_select() for
each SELECT_LEX object and cleared at the end of PREPARE in
sql_prepare.cc, init_stmt_after_parse(). If this flag is set
subquery becomes non-const and evaluation does not happen.
2. CREATE|ALTER VIEW, SHOW CREATE VIEW, I_S tables which
process FRM files
We use LEX::view_prepare_mode field. We set it before
view preparation and check this flag in
::fix_fields(), ::fix_length_and_dec().
Some bugs are fixed using this approach,
some are not(Bug#57352, Bug#57703). The problem here is
that we have a lot of ::fix_fields(), ::fix_length_and_dec()
where we use Item::val_...() calls for const items.
3. Derived tables with subquery = wrong result(Bug19077)
The reason of this bug is too early subquery evaluation.
It was fixed by adding Item::with_subselect field
The check of this field in appropriate places prevents
const item evaluation if the item have subquery.
The fix for Bug19077 fixes only the problem with
convert_constant_item() function and does not cover
other places(::fix_fields(), ::fix_length_and_dec() again)
where subqueries could be evaluated.
Example:
CREATE TABLE t1 (i INT, j BIGINT);
INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
SELECT * FROM (SELECT MIN(i) FROM t1
WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3;
DROP TABLE t1;
4. Derived tables with subquery where subquery
is evaluated before table locking(Bug#54475, Bug#52157)
Suggested solution is following:
-Introduce new field LEX::context_analysis_only with the following
possible flags:
#define CONTEXT_ANALYSIS_ONLY_PREPARE 1
#define CONTEXT_ANALYSIS_ONLY_VIEW 2
#define CONTEXT_ANALYSIS_ONLY_DERIVED 4
-Set/clean these flags when we perform
context analysis operation
-Item_subselect::const_item() returns
result depending on LEX::context_analysis_only.
If context_analysis_only is set then we return
FALSE that means that subquery is non-const.
As all subquery types are wrapped by Item_subselect
it allow as to make subquery non-const when
it's necessary.
------------------------------------------------------------
revno: 2572.2.1
revision-id: sp1r-davi@mysql.com/endora.local-20080227225948-16317
parent: sp1r-anozdrin/alik@quad.-20080226165712-10409
committer: davi@mysql.com/endora.local
timestamp: Wed 2008-02-27 19:59:48 -0300
message:
Bug#27525 table not found when using multi-table-deletes with aliases over several databas
Bug#30234 Unexpected behavior using DELETE with AS and USING
The multi-delete statement has a documented limitation that
cross-database multiple-table deletes using aliases are not
supported because it fails to find the tables by alias if it
belongs to a different database. The problem is that when
building the list of tables to delete from, if a database
name is not specified (maybe an alias) it defaults to the
name of the current selected database, making impossible to
to properly resolve tables by alias later. Another problem
is a inconsistency of the multiple table delete syntax that
permits ambiguities in a delete statement (aliases that refer
to multiple different tables or vice-versa).
The first step for a solution and proper implementation of
the cross-databse multiple table delete is to get rid of any
ambiguities in a multiple table statement. Currently, the parser
is accepting multiple table delete statements that have no obvious
meaning, such as:
DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
DELETE a1 AS a1 FROM db1.t1 AS a1, db2.t2 AS a1;
The solution is to resolve the left part of a delete statement
using the right part, if the a table on right has an alias,
it must be referenced in the left using the given alias. Also,
each table on the left side must match unambiguously only one
table in the right side.
mutually-nested subqueries
Queries of the form
SELECT * FROM (SELECT 1) AS t1,
(SELECT 2) AS t2,...
(SELECT 32) AS t32
caused the "Too high level of nesting for select" error
as if the query has a form
SELECT * FROM (SELECT 1 FROM (SELECT 2 FROM (SELECT 3 FROM...
The table_factor parser rule has been modified to adjust
the LEX::nest_level variable value after every derived table.
No warning was generated when a TIMESTAMP with a non-zero time part
was converted to a DATE value. This caused index lookup to assume
that this is a valid conversion and was returning rows that match
a comparison between a TIMESTAMP value and a DATE keypart.
Fixed by generating a warning on such a truncation.
- added join cache indication in EXPLAIN (Extra column).
- prefer filesort over full scan over
index for ORDER BY (because it's faster).
- when switching from REF to RANGE because
RANGE uses longer key turn off sort on
the head table only as the resulting
RANGE access is a candidate for join cache
and we don't want to disable it by sorting
on the first table only.
- Use mysql_system_tables.sql to create MySQL system tables in
all places where we create them(mysql_install_db, mysql-test-run-pl
and mysql_fix_privilege_tables.sql)
"real" table fails in JOINs".
This is a regression caused by the fix for Bug 18444.
This fix removed the assignment of empty_c_string to table->db performed
in add_table_to_list, as neither me nor anyone else knew what it was
there for. Now we know it and it's covered with tests: the only case
when a table database name can be empty is when the table is a derived
table. The fix puts the assignment back but makes it a bit more explicit.
Additionally, finally drop sp.result.orig which was checked in by mistake.
"Process NATURAL and USING joins according to SQL:2003".
* Some of the main problems fixed by the patch:
- in "select *" queries the * expanded correctly according to
ANSI for arbitrary natural/using joins
- natural/using joins are correctly transformed into JOIN ... ON
for any number/nesting of the joins.
- column references are correctly resolved against natural joins
of any nesting and combined with arbitrary other joins.
* This patch also contains a fix for name resolution of items
inside the ON condition of JOIN ... ON - in this case items must
be resolved only against the JOIN operands. To support such
'local' name resolution, the patch introduces a stack of
name resolution contexts used at parse time.
NOTICE:
- This patch is not complete in the sense that
- there are 2 test cases that still do not pass -
one in join.test, one in select.test. Both are marked
with a comment "TODO: WL#2486".
- it does not include a new test specific for the task
Column names weren't checked for uniqueness for subqueries.
Code for names uniqueness checking used for view creation moved into
separate function named check_duplicate_names(). It's called on
preparation of subqueries to check uniqueness of names. If duplicate names
are found then error is raised.
If cost(full_scan_on_shortest_covering_index) < cost(best_range_scan) < cost(full_table_scan)
use full_scan_on_shortest_covering_index
(before this fix best_range_scan was used)
Fixed output from mysqlbinlog when using --skip-comments
Fixed warnings from valgrind
Fixed ref_length when used with HEAP tables
More efficent need_conversion()
Fixed error handling in UPDATE with not updateable tables
Fixed bug in null handling in CAST to signed/unsigned
New multi-key-cache handling. This was needed becasue the old one didn't work reliable with MERGE tables.
ALTER TABLE table_name ... CHARACTER SET ... now changes all char/varchar/text columns to the given character set
(One must use ALTER TABLE ... DEFAULT CHARACTER SET ... to change the default character set)
Fixed that have_compress is detected properly (fixes problems with func_compress.test on platforms without zlib)
New syntax for CACHE INDEX ('keys' is optional if no index name is given and one mentions the key cache name only ones)
Removed compiler warnings
Added mysql_set_server_option() to allow clients like PHP to easaily set/reset the multi-statement flag.
- correct table name shown in EXPLAIN Iindex reference)
- pointer on freed memmory (reallocation of table name in reusing table entry) can't be used in EXPLAIN
(BUG#1584)