Don't let network errors from mysql_close() leak into THD.
* remove incorrect upstream fix
** table->in_use can be NULL, must use ha_thd()
** clear_error() may remove earlier errors, don't use it
* fix the bug properly in federated and federatedx
fix innodb auto-increment handling
three bugs:
1. innobase_next_autoinc treated the case of current<offset incorrectly
2. ha_innobase::get_auto_increment didn't recalculate current when increment changed
3. ha_innobase::get_auto_increment didn't pass offset down to innobase_next_autoinc
Analysis: There were two problems. (1) if partition table was
created using lower_case_tables = 1 on windows we did find the
correct table but we did not set share->ib_table correctly.
(2) we did open table on dictionary but did not increase
mysql_open_tables.
Fix: In xtradb allow access to tables with incorrect
lower case names (warning is printed to error log). If
table is opened increase mysql_open_tables count to avoid
crash on flush tables.
Item_func_coalesce::fix_length_and_dec() calls
Item_func::count_string_result_length()) which called agg_arg_charsets()
with wrong flags, so the collation derivation of the COALESCE result was
not properly set to DERIVATION_COERCIBLE. It erroneously stayed
DERIVATION_NUMERIC. So GREATEST() misinterpreted the argument as
a number rather that a string and did not calculate its own length properly.
mysqldump --routine fails to dump databases containing backslash ("\")
character. This happened because escaped database name was being used as an
identifier while changing current database. Such identifers are not supposed
to be escaped, they must be properly quoted instead.
Analysis: debug only assertion I_S function (IS is XtraDB feature) is calling
buf_block_get_frame on any page it reads, which debug-asserts that the page is
buffer-fixed, which is not the case in I_S query.
Fixed by holding the buffer page mutex while the fields are read directly.
Problem:
========
1) Drop table queries are re-generated by server
before writing the events(queries) into binlog
for various reasons. If table name/db name contains
a non regular characters (like latin characters),
the generated query is wrong. Hence it breaks the
replication.
2) In the edge case, when table name/db name contains
64 characters, server is throwing an assert
assert(M_TBLLEN < 128)
3) In the edge case, when db name contains 64 latin
characters, binlog content is interpreted badly
which is leading replication failure.
Analysis & Fix :
================
1) Parser reads the table name from the query and converts
it to standard charset(utf8) and stores it in table_name variable.
When drop table query is regenerated with the same table_name
variable, it should be converted back to the original charset
from standard charset(utf8).
2) Latin character takes two bytes for each character. Limit
of the identifier is 64. SYSTEM_CHARSET_MBMAXLEN is set to '3'.
So there is a possiblity that tablename/dbname contains 3 * 64.
Hence assert is changed to
(M_TBLLEN <= NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN)
3) db_len in the binlog event header is taking 1 byte.
db_len is ranged from 0 to 192 bytes (3 * 64).
While reading the db_len from the event, server
is casting to uint instead of uchar which is leading
to bad db_len. This problem is fixed by changing the
cast type to uchar.
Problem:
At the end of first execution select_lex->prep_where is pointing to
a runtime created object (temporary table field). As a result
server exits trying to access a invalid pointer during second
execution.
Analysis:
While optimizing the join conditions for the query, after the
permanent transformation, optimizer makes a copy of the new
where conditions in select_lex->prep_where. "prep_where" is what
is used as the "where condition" for the query at the start of execution.
W.r.t the query in question, "where" condition is actually pointing
to a field in the temporary table. As a result, for the second
execution the pointer is no more valid resulting in server exit.
Fix:
At the end of the first execution, select_lex->where will have the
original item of the where condition.
Make prep_where the new place where the original item of select->where
has to be rolled back.
Fixed in 5.7 with the wl#7082 - Move permanent transformations from
JOIN::optimize to JOIN::prepare
Patch for 5.5 includes the following backports from 5.6:
Bugfix for Bug12603141 - This makes the first execute statement in the testcase
pass in 5.5
However it was noted later in in Bug16163596 that the above bugfix needed to
be modified. Although Bug16163596 is reproducible only with changes done for
Bug12582849, we have decided include the fix.
Considering that Bug12582849 is related to Bug12603141, the fix is
also included here. However this results in Bug16317817, Bug16317685,
Bug16739050. So fix for the above three bugs is also part of this patch.
Problem & Analysis: If DML invokes a trigger or a
stored function that inserts into an AUTO_INCREMENT column,
that DML has to be marked as 'unsafe' statement. If the
tables are locked in the transaction prior to DML statement
(using LOCK TABLES), then the same statement is not marked as
'unsafe' statement. The logic of checking whether unsafeness
is protected with if (!thd->locked_tables_mode). Hence if
we lock the tables prior to DML statement, it is *not* entering
into this if condition. Hence the statement is not marked
as unsafe statement.
Fix: Irrespective of locked_tables_mode value, the unsafeness
check should be done. Now with this patch, the code is moved
out to 'decide_logging_format()' function where all these checks
are happening and also with out 'if(!thd->locked_tables_mode)'.
Along with the specified test case in the bug scenario
(BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS), we also identified that
other cases BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST,
BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT, BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS
are also protected with thd->locked_tables_mode which is not right. All
of those checks also moved to 'decide_logging_format()' function.
make it possible to change feedback plugin wait intervals
* only in debug builds
* and force the feedback report to be ignored
update the test to use this feature
FAILURE WITH VALGRIND FOR RELEASE BUILD
Issue:
------
Initialization of variable with UNINIT_VAR is flagged by
valgrind 3.11.
SOLUTION:
---------
Initialize the variable to 0.
This is a backport of Bug# 14580121.
HA_MYISAMMRG.CC:631
Analysis
========
Any attempt to open a temporary MyISAM merge table consisting
of a view in its list of tables (not the last table in the list)
under LOCK TABLES causes the server to exit.
Current implementation doesn't perform sanity checks during
merge table creation. This allows merge table to be created
with incompatible tables (table with non-myisam engine),
views or even with table doesn't exist in the system.
During view open, check to verify whether requested view
is part of a merge table is missing under LOCK TABLES path
in open_table(). This leads to opening of underlying table
with parent_l having NULL value. Later when attaching child
tables to parent, this hits an ASSERT as all child tables
should have parent_l pointing to merge parent. If the operation
does not happen under LOCK TABLES mode, open_table() checks
for view's parent_l and returns error.
Fix:
======
Check added before opening view Under LOCK TABLES in open_table()
to verify whether it is part of merge table. Error is returned
if the view is part of a merge table.
DOING BAD DDL IN PREPARED STATEMENT
Analysis
========
A repeat execution of the prepared statement 'ALTER TABLE v1
CHECK PARTITION' where v1 is a view leads to server exit.
ALTER TABLE ... CHECK PARTITION is not applicable for views
and check for the same check is missing. This leads to
further execution and creation of derived table for the view
(Allocated under temp_table mem_root). Any reference to open
view or related pointers from second execution leads to
server exit as the same was freed at previous execution closure.
Fix:
======
Added check for view in mysql_admin_table() on PARTITION
operation. This will prevent mysql_admin_table() from
going ahead and creating temp table and related issues.
Changed message on admin table view operation error to
be more appropriate.
MDEV-8938 Server Crash on Update with joins
Make unique table check after setup_fields of update because unique table can materialize table and we do not need field resolving after materialization.
Issue:
-----
When a varchar column is used to fill the record in an
internal temporary table, the length of the string stored
in the column is not taken into account. Instead the
default length of packed data is used to copy with memmove.
This will cause valgrind issues since some bytes are
uninitialized.
SOLUTION:
---------
The solution is to take into account the length of the
string stored in the column while filling the record.
This fix is a backport of BUG#13389854.
Issue
-----
This problem occurs when varchar columns are used in a
internal temporary table. The type of the field is set
incorrectly to the generic FIELD_NORMAL type. This in turn
results in an inaccurate calculation of the record length.
Valgrind issues will occur since initialization has not
happend for some bytes.
Fix
----
While creating the temporary table, the type of the field
needs to be to set FIELD_VARCHAR. This will allow myisam
to calculate the record length accurately.
This fix is a backport of BUG#13350136.
2ND EXECUTION OF PS
Description:
------------
When MySQL calls 'EXECUTE stmt' firstly to deal with ORDER BY clause which is
similar with 'ORDER BY 1,(t2a.f2+1)' in find_order_in_list(), it believes the
first expression is a position, the function replaces the pointer of the first
expression with Item_field object associated with a temporary table field,
then releases it after the end of the execution, that behavior destroys the
pointer of first expression.
After that, when MySQL calls 'EXECUTE stmt' once more, the first expression
points to an invalid pointer, so it crashed.
Fix:
----
If an item of ORDER clause is a location, reset 'args' with a original value.
===========
When doing an upgrade, you execute mysql_upgrade. If
mysql_upgrade fails to connect or it connects with a user
without the proper privileges, it will return the error:
FATAL ERROR: Upgrade failed
which is not very informative.
ANALYSIS
========
In main() and check_version_match(), the condition for
errors are clubbed together and throw the same error msg.
The functions need to be splitted up and the corresponding
error msgs have to be displayed.
FIX
===
Splitted the functions and added the specific error msg.
Issue: main.events_1 will fail after 10-10-2015 due
to hardcoded dates specified with events.
Fix: Replace harcoded dates with current dates and offset.
Issue:
======
While re-preparing the statement in
Prepared_statement::swap_prepared_statement for swapping
the database of PS we only swapped the db string but not
its length. This resulted in mismatch between the actual
string and its length. In one particular case where db
of PS was dropped, we have db as null pointer and length
as non-zero. strdup which used above values resulted in
invalid memory access.
Solution:
=========
In Prepared_statement::swap_prepared_statement also swap
db_length along with db variable. Also, remove
DBUG_ASSERT(db_length == copy->db_length) as this have
no meaning if they are 2 different entities.