- In eliminate_item_equal(), we could end up in a situation where:
= The multiple equality has a constant C1 (and so it is the "head item")
= The join order was such that we've generated "sj_inner_table1=C1" equality,
and now are looking to generate "sj_inner_table2_=..." equality.
When looking for what should be the other member of equality, we run
Item *head_item= current_sjm? current_sjm_head: head;
which sees current_sjm!=NULL, and takes current_sjm_head (which is NULL because
the constant C1 is the head for all cases).
- Fixed in a trivial way: take current_sjm_head if we don't have constant.
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.
The third parameter in the call of make_cond_for_table() that
built the pushed condition containing only outer references
was incorrect. This condition appeared for the first time in
the patch fixing bug 729039.
mysql-test/r/alter_table_online.result:
Test new feature
mysql-test/t/alter_table_online.test:
Test new feature
sql/handler.cc:
Added comment
sql/lex.h:
Added ONLINE keyword
sql/mysql_priv.h:
Added option to alter table to require online operation
sql/share/errmsg.txt:
Added error message if ONLINE can't be done
sql/sql_lex.h:
Added online option
sql/sql_parse.cc:
Added online option to mysql_alter_table()
sql/sql_table.cc:
Added test that gives error if table can't be done instantly when requsted to be online.
Fixed wrong test if table includes a VARCHAR
Fixed wrong (but unlikely) handling of error conditions in ALTER table
sql/sql_yacc.yy:
Added ALTER ONLINE TABLE syntax
storage/maria/ha_maria.cc:
Fixed bug where 'start_bulk_insert' used too small buffer if used with unknown number of rows
This makes it possible to do safe multi volume snapshots as long as one snapshots the volume with the transaction logs last.
include/mysql_com.h:
Added REFRESH_CHECKPOINT
mysql-test/r/flush.result:
Added test of new FLUSH TABLES syntax + calls to checkpoint_status handler calls
mysql-test/t/flush.test:
Added test of new FLUSH TABLES syntax + calls to checkpoint_status handler calls
sql/handler.cc:
Added code to call checkpoint_state for all handlertons that supports it
sql/handler.h:
Added new checkpoint_state() handlerton call to temporarly disable checkpoints.
sql/lex.h:
Added CHECKPOINT keyword
sql/sql_yacc.yy:
Added support for FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT
storage/maria/ha_maria.cc:
Added handlerton call to disable checkpoints.
storage/maria/ma_checkpoint.c:
Don't do checkpoint if checkpoints are disabled.
storage/maria/ma_static.c:
Added maria_checkpoint_disabled
storage/maria/maria_def.h:
Added maria_checkpoint_disabled
storage/xtradb/handler/ha_innodb.cc:
Added handlerton call to disable checkpoints.
storage/xtradb/include/log0log.h:
Added option to log_checkpoint() to allow one to ignore not critical checkpoints during the time checkpoints are disabled.
storage/xtradb/log/log0log.c:
Added code to allow one to disable checkpoints during a FLUSH TABLES ... DISABLE CHECKPOINT
This was done by adding a new argument to log_checkpoint() which tells us when the checkpoint is called by srv_master_thread (which are safe to ignore)
storage/xtradb/srv/srv0srv.c:
Tell log_checkpoint() that checkpoints from srv_master_thread() are safe to ignore (will just delay recovery time a bit).
Analysis:
Build_equal_items_for_cond() rewrites the WHERE clause in such a way,
that it may merge the list join->cond_equal->current_level with the
list of child Items in an AND condition of the WHERE clause.
The place where this is done is:
static COND *build_equal_items_for_cond(THD *thd, COND *cond,
COND_EQUAL *inherited)
{
...
if (and_level)
{
args->concat(&eq_list);
args->concat((List<Item> *)&cond_equal.current_level);
}
...
}
As a result, later transformations on the WHERE clause may change the
structure of the list join->cond_equal->current_level without knowing this.
Specifically in this bug, Item_in_subselect::inject_in_to_exists_cond
creates a new AND of the old WHERE clause and the IN->EXISTS conditions.
It then calls fix_fields() for the new AND. Among other things, fix_fields
flattens all nested ANDs into one by merging the AND argument lists.
When there is a cond_equal for the JOIN, its list of Item_equal objects
is attached to the end of the original AND. When a lower-level AND is
merged into the top-level one, the argument list of the lower-level AND
is concatenated to the list of multiple equalities in the upper-level AND.
As a result, when substitute_for_best_equal_field processes the
multiple equalities, it turns out that the multiple equality list contains
the Items from the lower-level AND which were concatenated to the end of
the join->cond_equal->current_level list. This results in a crash because
this list must not contain any other Items except for the previously found
Item_equal ones.
Solution:
When performing IN->EXIST predicate injection, and the where clause is an
AND, detach the list of Item_equal objects before calling fix_fields on
the injected where clause.
After fix_fields is done, reattach back the multiple equalities list to
the end of the argument list of the new AND.
The function test_quick_select by mistake did not update the value
of table->quick_condition_rows for index intersection scans though
the specification explicitly required to do so from any table access
plan once the plan provided a better upper bound for the number of
rows selected from the table. It resulted in a bogus, usually very
big number saved as the cost of the table access. This, in its turn,
in many cases forced the optimizer to make a bad choice of the
execution plan for join queries.
Both these two bugs happened due to the following problem.
When a view column is referenced in the query an Item_direct_view_ref
object is created that is refers to the Item_field for the column.
All references to the same view column refer to the same Item_field.
Different references can belong to different AND/OR levels and,
as a result, can be included in different Item_equal object.
These Item_equal objects may include different constant objects.
If these constant objects are substituted for the Item_field created
for a view column we have a conflict situation when the second
substitution annuls the first substitution. This leads to
wrong result sets returned by the query. Bug #724942 demonstrates
such an erroneous behaviour.
Test case of the bug #717577 produces wrong result sets because best
equal fields of the multiple equalities built for different OR levels
of the WHERE condition differs. The subsitution for the best equal field
in the second OR branch overwrites the the substitution made for the
first branch.
To avoid such conflicts we have to substitute for the references
to the view columns rather than for the underlying field items.
To make such substitutions possible we have to include into
multiple equalities references to view columns rather than
field items created for such columns.
This patch modifies the Item_equal class to include references
to view columns into multiple equality objects. It also performs
a clean up of the class methods and adds more comments. The methods
of the Item_direct_view_ref class that assist substitutions for
references to view columns has been also added by this patch.
Analysis:
The wrong result is a consquence of sorting the subquery
result and then selecting only the first row due to the
artificial LIMIT 1 introduced by the fix_fields phase.
Normally, if there is an ORDER BY in a subquery, the ORDER
is removed (Item_in_subselect::select_in_like_transformer),
however if a GROUP BY is transformed into ORDER, this happens
later, after the removal of the ORDER clause of subqueries, so
we end up with a subquery with an ORDER clause, and an artificially
added LIMIT 1.
The reason why the same works in the main 5.3 without MWL#89, is
that the 5.3 performs all subquery transformations, including
IN->EXISTS before JOIN::optimize(). The beginning of JOIN::optimize
does:
if (having || (select_options & OPTION_FOUND_ROWS))
select_limit= HA_POS_ERROR;
which sets the limit back to infinity, thus 5.3 sorts the whole
subquery result, and IN performs the lookup into all subquery result
rows.
Solution:
Sorting of subqueries without LIMIT is meaningless. Since LIMIT in
subqueries is not supported, the patch removes sorting by setting
join->skip_sort_order= true
for each subquery JOIN object. This improves a number of execution
plans to not perform unnecessary sorting at all.
- Let advance_sj_state() save the value of JOIN::cur_dups_producing_tables
in POSITION::prefix_dups_producing_tables, and restore_sj_state() restore
it.
- "Using MRR" is no longer shown with range access.
- Instead, both range and BKA accesses will show one of the following:
= "Rowid-ordered scan"
= "Key-ordered scan"
= "Key-ordered Rowid-ordered scan"
depending on whether DS-MRR implementation will do scan keys in order, rowids in order,
or both.
- The patch also introduces a way for other storage engines/MRR implementations to
pass information to EXPLAIN output about the properties of employed MRR scans.
- 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.
sql/item.cc:
If a item_ref is referenced by name, we have to reset it's ref in item_ref::cleanup() as the reference may be to a memory that is freed.
This happens at least when you have 'HAVING MAX()' in a sub query and you execute 'cond_having->print()' which tries to access items before fix fields.
sql/item.h:
Added 'reference_trough_name' as a marker for Item_ref that needs to have ref reset during cleanup
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
sql/sql_base.cc:
Don't allocate memory in fill_record().
Fix was to remove the list of tables. This was not necessary as this call is only used with one table.
mysql-test/mysql-test-run.pl:
Set port-open-timeout to 10 to retry binds
sql/mysqld.cc:
Write error number for bind failure. (perror can't do that on windows as errno dosn't contain error code)