Before this fix, the ha_read_last_count status variable was defined and
updated internally, for never exposed as a system variable.
This fix exposes the system variable as "Handler_read_last",
for completness of the Handler_read_* system variables interface.
Adjusted tests results accordingly.
file .\dtoa.c
The assertion failure was correct because the 'width' argument
of my_gcvt() has the signed integer type, whereas the unsigned
value UINT_MAX32 was being passed by the caller
(Field_double::val_str()) leading to a negative width in
my_gcvt().
The following chain of problems was found by further analysis:
1. The display width for a floating point number is calculated
in Field_double::val_str() as either field_length or the
maximum possible length of string representation of a floating
point number, whichever is greater. Since in the bug's test
case field_length is UINT_MAX32, we get the same value as the
display width. This does not make any sense because for numeric
values field_length only matters for ZEROFILL columns,
otherwise it does not make sense to allocate that much memory
just to print a number. Field_float::val_str() has a similar
problem.
2. Even if the above wasn't the case, we would still get a
crash on a slightly different test case when trying to allocate
UINT_MAX32 bytes with String::alloc() because the latter does
not handle such large input values correctly due to alignment
overflows.
3. Even when String::alloc() is fixed to return an error when
an alignment overflow occurs, there is still a problem because
almost no callers check its return value, and
Field_double::val_str() is not an exception (same for
Field_float::val_str()).
4. Even if all of the above wasn't the case, creating a
Field_double object with UINT_MAX32 as its field_length does
not make much sense either, since the .frm code limits it to
MAX_FIELD_CHARLENGTH (255) bytes. Such a beast can only be
created by create_tmp_field_from_item() from an Item with
REAL_RESULT as its result_type() and UINT_MAX32 as its
max_length.
5. For the bug's test case, the above condition (REAL_RESULT
Item with max_length = UINT_MAX32) was a result of
Item_func_if::fix_length_and_dec() "shortcutting" aggregation
of argument types when one of the arguments was a constant
NULL. In this case, the attributes of the aggregated type were
simply copied from the other, non-NULL argument, but max_length
was still calculated as per the general, non-shortcut case, by
choosing the greatest of argument's max_length, which is
obviously not correct.
The patch addresses all of the above problems, even though
fixing the assertion failure for the particular test case would
require only a subset of the above problems to be solved.
with two connections doing LOCK TABLE+INSERT DELAYED".
Disabled --ps-protocol for this part of the test as INSERT
DELAYED simply doesn't work with it under LOCK TABLES.
Queries involving predicates of the form "const NOT BETWEEN
not_indexed_column AND indexed_column" could return wrong data
due to incorrect handling by the range optimizer.
For "c NOT BETWEEN f1 AND f2" predicates, get_mm_tree()
produces a disjunction of the SEL_ARG trees for "f1 > c" and
"f2 < c". If one of the trees is empty (i.e. one of the
arguments is not sargable) the resulting tree should be empty
as well, since the whole expression in this case is not
sargable.
The above logic is implemented in get_mm_tree() as follows. The
initial state of the resulting tree is NULL (aka empty). We
then iterate through arguments and compute the corresponding
SEL_ARG tree (either "f1 > c" or "f2 < c"). If the resulting
tree is NULL, it is simply replaced by the generated
tree. Otherwise it is replaced by a disjunction of itself and
the generated tree. The obvious flaw in this implementation is
that if the first argument is not sargable and thus produces a
NULL tree, the resulting tree will simply be replaced by the
tree for the second argument. As a result, "c NOT BETWEEN f1
AND f2" will end up as just "f2 < c".
Fixed by adding a check so that when the first argument
produces an empty tree for the NOT BETWEEN case, the loop is
aborted with an empty tree as a result. The whole idea of using
a loop for 2 arguments does not make much sense, but it was
probably used to avoid code duplication for several BETWEEN
variants.
within query
The server could crash after materializing a derived table
which requires a temporary table for grouping.
When destroying the temporary table used to execute a query for
a derived table, JOIN::destroy() did not clean up Item_fields
pointing to fields in the temporary table. This led to
dereferencing a dangling pointer when printing out the items
tree later in the outer SELECT.
The solution is an addendum to the patch for bug37362: in
addition to cleaning up items in tmp_all_fields3, do the same
for items in tmp_all_fields1, since now we have an example
where this is necessary.
The Item_cache_datetime::val_str function wasn't taking into account that time
could be negative. This led to failed assertion.
Now Item_cache_datetime::val_str correctly converts negative time values
from integer to string representation.
The problem was that deadlocks involving INSERT DELAYED were not detected.
The reason for this is that two threads are involved in INSERT DELAYED:
the connection thread and the handler thread. The connection thread would
wait while the handler thread acquired locks and opened the table.
In essence, this adds an edge to the wait-for-graph between the
connection thread and the handler thread that the deadlock detector is
unaware of. Therefore many deadlocks involving INSERT DELAYED were not
detected.
This patch fixes the problem by having the connection thread acquire the
metadata lock the table before starting the handler thread. This allows the
deadlock detector to detect any possible deadlocks resulting from trying to
acquire a metadata lock the table. If a metadata lock is successfully acquired,
the handler thread is started and given a copy of the ticket representing the
metadata lock. When the handler thread then tries to lock and open the table,
it will find that it already has the metadata lock and therefore not acquire
any new metadata locks.
Test cases added to delayed.test.
The ALTER PARTITION and SELECT seemed to be deadlocked
when having innodb_thread_concurrency = 1.
Problem was that there was unreleased latches
in the ALTER PARTITION thread which was needed
by the SELECT thread to be able to continue.
Solution was to release the latches by commit
before requesting upgrade to exclusive MDL lock.
Updated according to reviewers comments (3).
files for cmake had some minor bugs causing this.
per-file comments:
mysql-test/CMakeLists.txt
Bug#54129 Missing the execute bit for scripts
use same permissions as in the source folder
mysql-test/t/disabled.def
Bug#54129 Missing the execute bit for scripts
mysqlhotcopy tests enabled
scripts/CMakeLists.txt
Bug#54129 Missing the execute bit for scripts
chmod +x for the script files
Problems:
- dot character was always printed as decimal point
instead of localized decimal point for short
numbers without thousands
- Item_func_format::val_str always returned values in ASCII
format,
regargless of @@character_set_connection, which in case of utf32
led to crash in debug build, or to incorrect values in release build.
Fix:
- Adding a piece of code to replace dot character to
localized decimal point in short numbers.
- Changing parent class for Item_func_format to
Item_str_ascii_func, because its val_str() implementation is heavily ASCII oriented.
on CREATE TABLE .. SELECT I_S.PART
This assert was triggered if an InnoDB table was created using
CREATE TABLE ... AS SELECT where the query used an I_S table, and
a view existed in the database. It would also be triggered for
any statement changing an InnoDB table (e.g. INSERT, UPDATE, DELETE)
which had a subquery referencing an I_S table.
The assert was triggered if open_normal_and_derived_tables() failed
and a statement transaction had been started. This will usually not
happen as tables are opened before a statement transaction is started.
However, e.g. CREATE TABLE ... AS SELECT starts a transaction in order
to insert tuples into the new table. And if the subquery references
an I_S table, all current tables and views can be opened in order to
fill the I_S table on the fly. If a view is discovered, open will fail
as it is instructed to open tables only (OPEN_TABLE_ONLY). This would
cause the assert to be triggered.
The assert was added in the patch for Bug#52044 and was therefore
not in any released versions of the server.
This patch fixes the problem by adjusting the assert to take into
consideration the possibility of tables being opened as part of
an I_S query. This is similar to what is already done for
close_tables_for_reopen().
Test case added to information_schema_inno.test.
Problem: a few functions did not calculate their max_length correctly.
This is an after-fix for WL#2649 Number-to-string conversions".
Fix: changing the buggy functions to calculate max_length
using fix_char_length() introduced in WL#2649,
instead of setting max_length directly
mysql-test/include/ctype_numconv.inc
Adding new tests
mysql-test/r/ctype_binary.result
Adding new tests
mysql-test/r/ctype_cp1251.result
Adding new tests
mysql-test/r/ctype_latin1.result
Adding new tests
mysql-test/r/ctype_ucs.result
Adding new tests
mysql-test/r/ctype_utf8.result
Adding new tests
mysql-test/t/ctype_utf8.test
Including ctype_numconv
sql/item.h
- Introducing new method fix_char_length_ulonglong(),
for the cases when length is potentially greater
than UINT_MAX32. This method removes a few
instances of duplicate code, e.g. in item_strfunc.cc.
- Setting collation in Item_copy properly. This change
fixes wrong metadata on client side in some cases, when
"binary" instead of the real character set was reported.
sql/item_cmpfunc.cc
- Using fix_char_length() and max_char_length() methods,
instead of direct access to max_length, to calculate
item length properly.
- Moving count_only_length() in COALESCE after
agg_arg_charsets_for_string_result(). The old
order was incorrect and led to wrong length
calucation in case of multi-byte character sets.
sql/item_func.cc
Fixing that count_only_length() didn't work
properly for multi-byte character sets.
Using fix_char_length() and max_char_length()
instead of direct access to max_length.
sql/item_strfunc.cc
- Using fix_char_length(), fix_char_length_ulonglong(),
max_char_length() instead of direct access to max_length.
- Removing wierd condition: "if (collation.collation->mbmaxlen > 0)",
which is never FALSE.
#ifdef THREAD removed from mysql.cc.
No reason was found for this limitation to persist.
per-file comments:
client/mysql.cc
Bug#54466 client 5.5 built from source lacks "pager" support
now we have USE_POPEN always if not __WIN__
mysql-test/r/mysql.result
Bug#54466 client 5.5 built from source lacks "pager" support
result updated.
mysql-test/t/mysql.test
Bug#54466 client 5.5 built from source lacks "pager" support
test case added.
Problem: Item_func_hex::val_str() returned data in ASCII format,
which did not match collation.collation pointing to my_charset_utf32_general_ci.
Fix: changing parent class of Item_func_hex to Item_str_ascii_func,
as val_str() implementation is heavily ASCII-oriented.
mysql-test/r/ctype_utf32.result
mysql-test/t/ctype_utf32.test
Adding test case
sql/item_strfunc.cc
sql/item_strfunc.h
- Changing parent class to Item_str_ascii_func
- Clean-up in Item_func_hex::fix_length_and_dec()
Using fix_char_length() instead of setting max_length directly.
'CREATE TABLE IF NOT EXISTS ... SELECT' behaviour
BUG#47132, BUG#47442, BUG49494, BUG#23992 and BUG#48814 will disappear
automatically after the this patch.
BUG#55617 is fixed by this patch too.
This is the 5.5 part.
It implements:
- 'CREATE TABLE IF NOT EXISTS ... SELECT' statement will not insert
anything and binlog anything if the table already exists.
It only generate a warning that table already exists.
- A couple of test cases for the behavior changing.
Followup to vasil.dimov@oracle.com-20100817063430-inglmzgdtj95t29d
which didn't fully fix the test because the order of the returned
rows was different in embedded and non-embedded version. So the only
way to fix this is to add an ORDER BY clause.
locks on the table
Fixing the partitioning specifics after TRUNCATE TABLE in
bug-42643 was fixed.
Reorganize of code to decrease the size of the giant switch
in mysql_execute_command, and to prepare for future parser
reengineering. Moved code into Sql_statement objects.
Updated patch according to davi's review comments.
variable assignments
The assert() that is firing is checking if expressions that can't be
null return a NULL when evaluated.
MAKEDATE() function can return NULL if the second argument is
less then or equal to 0. Thus its nullability depends not only on
the nullability of its arguments but also on their values.
Fixed by (overoptimistically) setting MAKEDATE() to be nullable
despite the nullability of its arguments.
Test added.
Had to update one test result to reflect the metadata change.
An user assignment variable expression that's
evaluated in a logical expression context
(Item::val_bool()) can be pre-calculated in a
temporary table for GROUP BY.
However when the expression value is used after the
temp table creation it was re-evaluated instead of
being read from the temp table due to a missing
val_bool_result() method.
Fixed by implementing the method.