With MDEV-19384 fixed FTWRL releases HANDLER locks early, which allows
concurrent threads to go. Test case may get stuck on FTWRL waiting for
LOCK TABLES.
So to push index condition for each join tab we have calculate the index condition that can be pushed and then
remove this index condition from the original condition. This is done through the function make_cond_remainder.
The problem is the function make_cond_remainder does not remove index condition when there is an OR operator.
Fixed this by making the function make_cond_remainder to keep in mind of the OR operator.
Also updated results for multiple test files which were incorrectly updated by the commit e0c1b3f242
code which was supposed to remove the condition present in the index
condition was not getting executed when the condition had OR operator, with AND the pushed
index condition was getting removed from where.
This problem affects all versions starting from 5.5 but this is a performance improvement, so fixing it in 10.4
For a table column `a`, the above expressions logically
equate to false in all cases.
With this patch the optimizer knows about this and queries
like:
SELECT * FROM t1 WHERE a!=a
no longer need to evaluate a!=a for every row.
The same applies if the expression was `a<a`, or `a>a`
An `EXPLAIN SELECT COOUNT(*) FROM t1 WHERE a<a` will show:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Similarly `NOT (a!=a)` is always true.
EXPLAIN SELECT COUNT(*) FROM t1 WHERE not (a!=a);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
With MAX_INDEXIES=64(default), key_map=Bitmap<64> is just a wrapper around
ulonglong and thus "trivial" (can be bzero-ed, or memcpy-ed, and stays
valid still)
With MAX_INDEXES=128, key_map = Bitmap<128> is not a "trivial" type
anymore. The implementation uses MY_BITMAP, and MY_BITMAP contains pointers
which make Bitmap invalid, when it is memcpy-ed/bzero-ed.
The problem in 10.4 is that there are many new key_map members, inside TABLE
or KEY, and those are often memcopied and bzeroed
The fix makes Bitmap "trivial", by inlining most of MY_BITMAP functionality.
pointers/heap allocations are not used anymore.
Parenthesis around table names and derived tables should be allowed
in FROM clauses and some other context as it was in earlier versions.
Returned test queries that used such parenthesis in 10.3 to their
original form. Adjusted test results accordingly.
The deadlock happened between FTWRL under open HANDLER, LOCK TABLE and
DROP DATABASE
Fixed by reverting the previous fix for handler open in
lock_global_read_lock()
Fixed the original (wrong) test case in flush_read_lock.test to be
repeatable.
- Updated results
- Run mysqlcheck without --user-stat-tables=PREFERABLY to keep results
consistent
- Don't allow one to run analyze table under FTWRL as analyze table
nowadays has to update status tables.
This patch corrects the patch for MDEV-19324. The latter did not
work properly in the cases when the transformation
(SELECT ... ORDER BY ...) LIMIT ... =>
SELECT ... ORDER BY ... LIMIT ...
was applied to the operands of a set operation.
If a derived table has SELECT DISTINCT, provide index statistics for it so that the join optimizer in the
upper select knows that ref access to the table will produce one row.
If a select query was of the form (SELECT ... ORDER BY ...) LIMIT ...
then in most cases it returned incorrect result. It happened because
SELECT ... ORDER BY ... was wrapped into a select with materialized
derived table:
SELECT ... ORDER BY ... =>
SELECT * FROM (SELECT ... ORDER BY ...) dt.
Yet for any materialized derived table ORDER BY without LIMIT is ignored.
This patch resolves the problem by the conversion
(SELECT ... ORDER BY ...) LIMIT ... =>
SELECT ... ORDER BY ... LIMIT ...
at the parser stage.
Similarly
((SELECT ... UNION ...) ORDER BY ...) LIMIT ...
is converted to
(SELECT ... UNION ...) ORDER BY ... LIMIT ...
This conversion optimizes execution of the query because the result of
(SELECT ... UNION ...) ORDER BY ... is not materialized into a temporary
table anymore.
Adding new virtual methods in Field:
- make_empty_rec_store_default_value()
- make_empty_rec_reset()
This simplifies the logic for every Field type,
and makes the code more friendly to pluggable data types.
The bug appears because not all conditions are found to be knowingly
true or false in WHERE after HAVING pushdown optimization.
Impossible WHERE can be found much earlier compared with how it is done now.
To fix it and_new_conditions_to_optimized_cond() is changed.
A sequence of <digits>e<mbhead><mbtail>, e.g.:
SELECT 123eXYzzz FROM t1;
was not scanned correctly (where XY is a multi-byte character).
The multi-byte head byte X was appended to 123e separately from
the multi-byte tail byte Y, so a pointer to "Yzzz" was passed
into scan_ident_start(), which failed on a bad multi-byte sequence.
After this change, scan_ident_start() gets a pointer to "XYzzz",
so it correctly sees the whole multi-byte character.
`sel->quick' failure in JOIN::make_range_rowid_filters upon query
with rowid_filter=ON
Index ranges can be defined using conditions with inexpensive subqueries.
Such a subquery is evaluated when some representation of a possible range
sequence is built. After the evaluation the JOIN structure of the subsquery is distroyed.
Any attempt to build the above representation may fail because the
function that checks whether a subquery is inexpensive in some cases uses
the join structure of the subquery.
When a range rowid filter is built by a range sequence constructed out of
a range condition that uses an inexpensive subquery the representation of
the the sequence is built twice. Building the second representation fails
due to the described problem with the execution of Item_subselect::is_expensive().
The function was corrected to return the result of the last its invocation
if the Item_subselect object has been already evaluated.
This also fixes:
MDEV-17299 Assertion `maybe_null' failed in make_sortkey
Note, during merge of the 10.1 version of MDEV-17299,
please use the 10.3 version of the code (i.e. null merge the 10.1 version).
When pushing a condition from HAVING into WHERE the function
st_select_lex::pushdown_from_having_into_where() transforms column
references in the pushed condition then performs cleanup of
items of the condition and finally calls fix_fields() for the condition
items. The cleanup is performed by a call of the method walk() with
cleanup_processor as the first parameter. Unfortunately this sequence
of calls does not work if the condition contains cached items, because
fix_fields() cannot go through Item_cache items and this leaves
underlying items unfixed.
The solution of this problem used in this patch is just does not allow
to process Item_cache objects when performing cleanup of the pushed
condition. In order to let the traversal procedure walk() not to process
Item_cache objects the third parameter of the used call of walk()
is set to a fictitious pointer (void *) 1. And Item_cache::walk() is
changed to prevent any action when it gets such value as the third
parameter.
Currently usage of range rowid filters can be combined only with
ref access and single index range access. So if the optimizer has
chosen some other quick select method to access a joined table
then no range rowid filter can be used for this table.
If SUBS_IN_TO_EXISTS strategy has been chosen for a subquery then
additional conditions are injected into WHERE/ON/HAVING of this subquery
and it may happen that test_quick_select() invoked from
JOIN::make_range_rowid_filters() discovers impossible range. This
must be checked.
Temporary table is defined with the view field in HAVING.
Item_direct_view_ref for this field is dropped and that causes error.
To fix it Item_direct_view_ref::remove_item_direct_ref() is added.
The bug occurs because of the wrong pushdown of constant function
defined with subquery from HAVING into WHERE. Subqueries can't be
pushed into WHERE.
To fix it with_subquery() call is added to check if the function contains
subquery.
A syntax error was reported for any INSERT statement with explicit
partition selection it if i used a column list.
Fixed by saving the parsing place before parsing the clause for explicit
partition selection and restoring it when the clause has been parsed.
This bug is caused by pushdown from HAVING into WHERE.
It appears because condition that is pushed wasn't fixed.
It is also discovered that condition pushdown from HAVING into
WHERE is done wrong. There is no need to build clones for some
conditions that can be pushed. They can be simply moved from HAVING
into WHERE without cloning.
build_pushable_cond_for_having_pushdown(),
remove_pushed_top_conjuncts_for_having() methods are changed.
It is found that there is no transformation made for fields of
pushed condition.
field_transformer_for_having_pushdown transformer is added.
New tests are added. Some comments are changed.
This check was introduced in 602a222 and then became redundant in ad1553e,
where we attempt to open a table even for non-copy algorithms.
Added missing test case from 602a222.
Part of MDEV-17805 - Remove InnoDB cache for temporary tables.
CREATE TEMPORARY TABLE locks SE plugin 6 times. 5 of these locks are
released by the end of the statement. And only 1 acquired by
init_from_binary_frm_image() / plugin_lock() remains.
The lock removed in this patch was clearly redundant.
Part of MDEV-17805 - Remove InnoDB cache for temporary tables.