The function SELECT_LEX::update_used_tables first must clean up
all bitmaps to be recalculated for all tables that require it
and only after this walk through on conditions attached to the
tables to update these bitmaps.
This bug happened for the queries over multi-table mergeable views
because the bitmap TABLE::read_set of the underlying tables were not
updated after the views had been merged into the query.
Now this bitmaps are updated properly.
Also the bitmap TABLE::merge_keys now is updated in prevention of
future bugs.
This bug happened because the maps of covering keys for mergeable derived
tables/views was not recalculated after the derived tables/vies had been
merged into the main query.
Cleanup: Changed procedure type from a int/char to an enum for easier to manage and debug code.
mysql-test/r/trigger.result:
Test that mysql.proc is not used as part of creating or using a trigger.
mysql-test/t/trigger.test:
Test that mysql.proc is not used as part of creating or using a trigger.
sql/sp.cc:
The main bug fix is to not look up triggers in mysql.proc; This is done by ignoreing type == TYPE_ENUM_TRIGGER in sp_add_used_routine()
Cleanup: Changed procedure type from a int/char to an enum.
sql/sp.h:
Cleanup: Changed procedure type from a int/char to an enum.
sql/sp_head.h:
Cleanup: Changed procedure type from a int/char to an enum.
sql/sql_db.cc:
Fix include order
sql/sql_lex.cc:
Fix include order
sql/sql_parse.cc:
Cleanup: Changed procedure type from a int/char to an enum.
sql/sql_show.cc:
Fix include order
sql/sql_view.cc:
Fix include order
- The problem was that Item_direct_view_ref and its embedded Item_field were getting incorrect
value of item->used_tables() after fix_fields() in the second and subsequent EXECUTE.
- Made relevant fixes in Item_field::fix_fields() and find_field_in_tables(), so that the
Item_field gets the correct attributes.
When merging a view / derived table the function SELECT_LEX::merge_subquery
incorrectly updated the list SELECT_LEX::leaf_tables. Erroneously it
appended the leaf_tables list of the merged object L and then removed the
reference to the merged object T from the SELECT_LEX::leaf_tables list.
A correct implementation should insert the list L into the
SELECT_LEX::leaf_tables list in place of the element of the list that
refers to T.
The bug could lead to wrong results or even crashes for queries with
nested outer joins over views / derived tables.
The problem was that optimizer removes some outer references (it they are
constant for example) and the list of outer items built during prepare phase is
not actual during execution phase when we need it as the cache parameters.
First solution was use pointer on pointer on outer reference Item and
initialize temporary table on demand. This solved most problem except case
when optimiser also reduce Item which contains outer references ('OR' in
this bug test suite).
The solution is to build the list of outer reference items on execution
phase (after optimization) on demand (just before temporary table creation)
by walking Item tree and finding outer references among Item_ident
(Item_field/Item_ref) and Item_sum items.
Removed depends_on list (because it is not neede any mnore for the cache, in the place where it was used it replaced with upper_refs).
Added processor (collect_outer_ref_processor) and get_cache_parameters() methods to collect outer references (or other expression parameters in future).
mysql-test/r/subselect_cache.result:
A new test added.
mysql-test/r/subselect_scache.result:
Changes in creating the cache and its paremeters order or adding arguments of aggregate function (which is a parameter also, but this has no influence on the result).
mysql-test/t/subselect_cache.test:
Added a new test.
sql/item.cc:
depends_on removed.
Added processor (collect_outer_ref_processor) and get_cache_parameters() methods to collect outer references.
Item_cache_wrapper collect parameters befor initialization of its cache.
sql/item.h:
depends_on removed.
Added processor (collect_outer_ref_processor) and get_cache_parameters() methods to collect outer references.
sql/item_cmpfunc.cc:
depends_on removed.
Added processor (collect_outer_ref_processor) to collect outer references.
sql/item_cmpfunc.h:
Added processor (collect_outer_ref_processor) to collect outer references.
sql/item_subselect.cc:
depends_on removed.
Added processor get_cache_parameters() method to collect outer references.
sql/item_subselect.h:
depends_on removed.
Added processor get_cache_parameters() method to collect outer references.
sql/item_sum.cc:
Added processor (collect_outer_ref_processor) method to collect outer references.
sql/item_sum.h:
Added processor (collect_outer_ref_processor) and get_cache_parameters() methods to collect outer references.
sql/opt_range.cc:
depends_on removed.
sql/sql_base.cc:
depends_on removed.
sql/sql_class.h:
New iterator added.
sql/sql_expression_cache.cc:
Build of list of items resolved in outer query done just before creating expression cache on the first execution of the subquery which removes influence of optimizer removing items (all optimization already done).
sql/sql_expression_cache.h:
Build of list of items resolved in outer query done just before creating expression cache on the first execution of the subquery which removes influence of optimizer removing items (all optimization already done).
sql/sql_lex.cc:
depends_on removed.
sql/sql_lex.h:
depends_on removed.
sql/sql_list.h:
Added add_unique method to add only unique elements to the list.
sql/sql_select.cc:
Support of new Item list added.
sql/sql_select.h:
Support of new Item list added.
Also:
1. simplified the code of the function mysql_derived_merge_for_insert.
2. moved merge of views/dt for multi-update/delete to the prepare stage.
3. the list of the references to the candidates for semi-join now is
allocated in the statement memory.
The attribute not_null_tables could be calculated incorrectly in the
function SELECT_LEX::update_used_tables for queries over views
with row items in the WHERE clause. It happened because no
implementation of the virtual callback function eval_not_null_tables
was provided for the class Item_row.
Also slightly optimized the code calculating the value of the maybe_null
flag for tables in the function SELECT_LEX::update_used_tables.
The bitmap of used tables must be evaluated for the select list of every
materialized derived table / view and saved in a dedicated field.
This is also applied to materialized subqueries.
Missing initialization of the bitmap not_null_tables_cache to 0
in the function Item_func::eval_not_null_tables caused this bug.
This function is called indirectly from the function
SELECT_LEX::update_used_tables after merging mergeable views and
derived tables into the main query. The leaf tables of resulting
query may change their bitmap numbers after this merge. That's why
the not_null_tables_cache bitmaps must be updated. Due to the bug
mentioned above the result of the re-evaluation of the
not_null_tables_cache turned out to be incorrect in some cases.
This could trigger an invalid conversion of outer joins into
inner joins leading to invalid query result sets.
Also removed an implicit conversion from int to bool in the function
SELECT_LEX::update_used_tables.
The value of THD::used tables should be re-evaluated after merges
of views and derived tables into the main query.
Now it's done in the function SELECT_LEX::update_used_tables.
The re-evaluation of the 'used_table' bitmaps for the items
in HAVING, GROUP BY and ORDER BY clauses has been added as well.
The offending query returns a wrong result set because the optimizer
erroneously eliminated the where condition evaluated it to TRUE.
The cause of this wrong transformation was that the flag maybe_null
for an inner table of the outer join was not set to TRUE after the
table had replaced the wrapping view.
Now the function SELECT_LEX::update_used_tables resets the value
of the maybe_null flag for each leaf table of the query after all
merges of views have been done.
- JOIN::prepare would have set JOIN::table_count to incorrect value (bad merge of MWL 106)
- optimize_keyuse() would use table-bit as table number
(the change in optimize_keyuse is also the reason for query plan changes. Not
expected to have much effect because only handles cases of no index statistics)
- st_select_lex::register_dependency_item() ignored the fact that some of the
selects on the dependency paths could have been merged to their parents (because they
were mergeable VIEWs)
- Undo the incorrect fix in Item_subselect::recalc_used_tables(): do not call
fix_after_pullout() for Item_subselect::Ref_to_outside members.
Changed the code that processing of multi-updates and multi-deletes
with multitable views at the prepare stage.
A proper solution would be: never to perform any transformations of views
before and at the prepare stage. Yet it would require re-engineering
of the code that checks privileges and updatability of views.
Ultimately this re-engineering has to be done to provide a clean solution
for INSERT/UPDATE/DELETE statements that use views.
Fixed a valgrind problem in the function TABLE::use_index.
Uncommented the failing test cases.
Commented out the failing test case from parts.partition_repair_myisam.test.
The test case has to be changed to bear the same semantics as before mwl106.
mysql-test/r/subselect4.result:
Moved test case for LP BUG#718593 into the correct test file subselect_mat_cost_bugs.test.
mysql-test/t/subselect4.test:
Moved test case for LP BUG#718593 into the correct test file subselect_mat_cost_bugs.test.
One was due the fact that the field SELECT_LEX::insert_tables was not
initialized while the second was due to missing initialization of
JOIN_TAB::preread_init_done in subselect_hash_sj_engine::make_unique_engine.
Removed an invalid assert.
client/mysqltest.cc:
Column names.
mysql-test/r/grant_cache_no_prot.result:
fix of text.
mysql-test/r/grant_cache_ps_prot.result:
Fix of test.
mysql-test/r/query_cache.result:
Switching on and off query cache.
mysql-test/t/query_cache.test:
Switching on and off query cache.
mysys/charset.c:
Fix of parser.
sql/handler.cc:
thd added to parameters.
sql/log_event.cc:
thd added to parameters.
sql/log_event_old.cc:
thd added to parameters.
sql/mysql_priv.h:
Fixed functions definitions.
sql/mysqld.cc:
Comments stripping.
sql/set_var.cc:
Switching on and off query cache.
sql/set_var.h:
Switching on and off query cache.
sql/share/errmsg.txt:
New errors.
sql/sql_cache.cc:
Switching query cache on and off, removing comments.
sql/sql_cache.h:
thd added to parameters.
sql/sql_class.h:
Comments stripping.
sql/sql_db.cc:
thd added to parameters.
sql/sql_lex.cc:
lex fixed.
sql/sql_parse.cc:
thd added to parameters.
When a view is merged into a select all the depended_from fields
pointing to the select of the view should have been corrected to
point to the select where the view is used. It was not done yet.
This could lead to wrong results returned by queries such as
one from the test case for bug 33389.
Correction of outer references required walking through all items
of the proccesed qurery. To avoid this the following solution was
implemented.
Each select now contains a pointer to the select it is merged into
(if there is any). Such pointers allow to get the corrected value
of depended_from on the fly. The function Item_ident::get_depended_from
was introduced for this purpose.
Resolved all conflicts, bad merges and fixed a few minor bugs in the code.
Commented out the queries from multi_update, view, subselect_sj, func_str,
derived_view, view_grant that failed either with crashes in ps-protocol or
with wrong results.
The failures are clear indications of some bugs in the code and these bugs
are to be fixed.
Analysis:
The method st_select_lex::optimize_unflattened_subqueries()
incorrectly propagated to each subquery the complete
select_options flag set for the whole query. Among other
flags in select_options, this propagated incorrectly the
STRAIGHT_JOIN flag from the upper query to the subquery.
Solution:
During EXPLAIN set only the SELECT_DESCRIBE bit in the
select_options of the subquery.
mysql-test/r/explain.result:
fixed results (new item)
mysql-test/r/subselect.result:
fixed results (new item)
mysql-test/r/subselect_no_mat.result:
fixed results (new item)
mysql-test/r/subselect_no_opts.result:
fixed results (new item)
mysql-test/r/subselect_no_semijoin.result:
Fixed results (new item)
mysql-test/suite/pbxt/r/subselect.result:
Fixed results (new item)
mysql-test/t/explain.test:
Fixed results (correct behaviour)
sql/item_cmpfunc.cc:
Pass through for max/min
sql/item_subselect.cc:
moving max/min
sql/item_subselect.h:
moving max/min
sql/mysql_priv.h:
new uncacheble flags added
sql/opt_subselect.cc:
maxmin moved.
sql/opt_subselect.h:
New function for maxmin.
sql/sql_class.h:
debug code
sql/sql_lex.cc:
Fixed flags.
Limit setting fixed.
sql/sql_lex.h:
2 new flags.
sql/sql_select.cc:
Prepare divided on 2 function to be able recollect some info after transformation.
sql/sql_select.h:
Prepare divided on 2 functions.
- Auto-merge with 5.3 main.
- Changed the test for LP BUG#719198 so that
an two more queries were added, and removed a
query that produces a wrong result due to an
unrelated problem. The wrong result is submitted
as a separate bug.
Fixed memory leak from HEAP tables that was not deleted properly
BUILD/compile-alpha-ccc:
Use g++ instead of gcc for linking
BUILD/compile-alpha-debug:
Use g++ instead of gcc for linking
BUILD/compile-pentium-pgcc:
Use g++ instead of gcc for linking
BUILD/compile-solaris-sparc:
Use g++ instead of gcc for linking
BUILD/compile-solaris-sparc-debug:
Use g++ instead of gcc for linking
BUILD/compile-solaris-sparc-purify:
Use g++ instead of gcc for linking
sql/item.cc:
Safety fixes for expr_cache
Call Item_result:field::cleanup() in Item_cache_wrapper::cleanup()
More DBUG_PRINT
sql/sql_base.cc:
Simple optimization for setup_wild
More DBUG_PRINT
sql/sql_expression_cache.cc:
Added header
Removed not needed initialization
sql/sql_lex.cc:
More DBUG_PRINT
sql/sql_select.cc:
More DBUG_PRINT
Fixed memory leak from HEAP tables that was not deleted properly
storage/heap/hp_create.c:
More DBUG_PRINT
- Fixed some issues with partitions and connection_string, which also fixed lp:716890 "Pre- and post-recovery crash in Aria"
- Fixed wrong assert in Aria
Now need to merge with latest xtradb before pushing
sql/ha_partition.cc:
Ensure that m_ordered_rec_buffer is not freed before close.
sql/mysqld.cc:
Changed to use opt_stack_trace instead of opt_pstack.
Removed references to pstack
sql/partition_element.h:
Ensure that connect_string is initialized
storage/maria/ma_key_recover.c:
Fixed wrong assert
Fixed a memory leak found by valgrind. The memory leak was
a result of JOINs corresponding to subselects in a global
ORDER BY of a UNION not being cleaned up because the
fake_select of the UNION didn't point down to the subquery
select.
--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.
mysql-test/r/derived.result:
test case
mysql-test/r/multi_update.result:
test case
mysql-test/r/view.result:
test case
mysql-test/suite/innodb/r/innodb_multi_update.result:
test case
mysql-test/suite/innodb/t/innodb_multi_update.test:
test case
mysql-test/suite/innodb_plugin/r/innodb_multi_update.result:
test case
mysql-test/suite/innodb_plugin/t/innodb_multi_update.test:
test case
mysql-test/t/derived.test:
test case
mysql-test/t/multi_update.test:
test case
mysql-test/t/view.test:
test case
sql/item.cc:
--removed unnecessary code
sql/item_cmpfunc.cc:
--removed unnecessary checks
--THD::is_context_analysis_only() is replaced with LEX::is_ps_or_view_context_analysis()
sql/item_func.cc:
--refactored context analysis checks
sql/item_row.cc:
--removed unnecessary checks
sql/item_subselect.cc:
--removed unnecessary code
--added DBUG_ASSERT into Item_subselect::exec()
which asserts that subquery execution can not happen
if LEX::context_analysis_only is set, i.e. at context
analysis stage.
--Item_subselect::const_item()
Return FALSE if LEX::context_analysis_only is set.
It prevents subquery evaluation in ::fix_fields &
::fix_length_and_dec at context analysis stage.
sql/item_subselect.h:
--removed unnecessary code
sql/mysql_priv.h:
--Added new set of flags.
sql/sql_class.h:
--removed unnecessary code
sql/sql_derived.cc:
--added LEX::context_analysis_only analysis intialization/cleanup
sql/sql_lex.cc:
--init LEX::context_analysis_only field
sql/sql_lex.h:
--New LEX::context_analysis_only field
sql/sql_parse.cc:
--removed unnecessary code
sql/sql_prepare.cc:
--removed unnecessary code
--added LEX::context_analysis_only analysis intialization/cleanup
sql/sql_select.cc:
--refactored context analysis checks
sql/sql_show.cc:
--added LEX::context_analysis_only analysis intialization/cleanup
sql/sql_view.cc:
--added LEX::context_analysis_only analysis intialization/cleanup
- Fixed problem with oqgraph and 'make dist'
Note that after this merge we have a problem show in join_outer where we examine too many rows in one specific case (related to BUG#57024).
This will be fixed when mwl#128 is merged into 5.3.