The patch caused some test failures when merged to 5.5 because,
unlike 5.1, it utilizes Item_cache_row to actually cache row
values. The problem was that Item_cache_row::bring_value()
essentially did nothing. In particular, it did not update its
null_value, so all Item_cache_row objects were always having
their null_values set to TRUE. This went unnoticed previously,
but now when Arg_comparator::compare_row() actually depends on
the row's null_value to evaluate the comparison, the problem
has surfaced.
Fixed by calling the underlying item's bring_value() and
updating null_value in Item_cache_row::bring_value().
Since the problem also exists in 5.1 code (albeit hidden, since
the relevant code is not used anywhere), the addendum patch is
against 5.1.
table causes assert failure".
Attempting to use FLUSH TABLE table_list WITH READ LOCK
statement for a MERGE table led to an assertion failure if
one of its children was not present in the list of tables
to be flushed. The problem was not visible in non-debug builds.
The assertion failure was caused by the fact that in such
situations FLUSH TABLES table_list WITH READ LOCK implementation
tried to use (e.g. lock) such child tables without acquiring
metadata lock on them. This happened because when opening tables
we assumed metadata locks on all tables were already acquired
earlier during statement execution and a such assumption was
false for MERGE children.
This patch fixes the problem by ensuring at open_tables() time
that we try to acquire metadata locks on all tables to be opened.
For normal tables such requests are satisfied instantly since
locks are already acquired for them. For MERGE children metadata
locks are acquired in normal fashion.
Note that FLUSH TABLES merge_table WITH READ LOCK will lock for
read both the MERGE table and its children but will flush only
the MERGE table. To flush children one has to mention them in table
list explicitly. This is expected behavior and it is consistent with
usage patterns for this statement (e.g. in mysqlhotcopy script).
mysql-test/r/flush.result:
Added test case for bug #55273 "FLUSH TABLE tm WITH READ LOCK
for Merge table causes assert failure".
mysql-test/t/flush.test:
Added test case for bug #55273 "FLUSH TABLE tm WITH READ LOCK
for Merge table causes assert failure".
sql/sql_base.cc:
Changed lock_table_names() to support newly introduced
MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK flag.
sql/sql_base.h:
Introduced MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK flag for
open_tables() and lock_table_names() which allows to skip
acquiring of global and schema-scope locks when SNW, SNRW or
X metadata locks are acquired.
sql/sql_reload.cc:
Changed "FLUSH TABLES table_list WITH READ LOCK" code not to
cause assert about missing metadata locks when MERGE table is
flushed without one of its underlying tables.
To achieve this we no longer call open_and_lock_tables() with
MYSQL_OPEN_HAS_MDL_LOCK flag so this function automatically
acquires metadata locks on MERGE children if such lock has
not been already acquired at earlier stage. Instead we call
this function with MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK flag to
suppress acquiring of global IX lock in order to keep FLUSH
TABLES table_list WITH READ LOCK compatible with FLUSH TABLE
WITH READ LOCK.
Also changed implementation to use lock_table_names() function
for pre-acquiring of metadata locks instead of custom code.
To implement this change moved setting of open_type member for
table list elements to parser.
sql/sql_yacc.yy:
Now we set acceptable type of table for FLUSH TABLES table_list
WITH READ LOCK at parsing time instead of execution time.
result
Row subqueries producing no rows were not handled as UNKNOWN
values in row comparison expressions.
That was a result of the following two problems:
1. Item_singlerow_subselect did not mark the resulting row
value as NULL/UNKNOWN when no rows were produced.
2. Arg_comparator::compare_row() did not take into account that
a whole argument may be NULL rather than just individual scalar
values.
Before bug#34384 was fixed, the above problems were hidden
because an uninitialized (i.e. without any stored value) cached
object would appear as NULL for scalar values in a row subquery
returning an empty result. After the fix
Arg_comparator::compare_row() would try to evaluate
uninitialized cached objects.
Fixed by removing the aforementioned problems.
mysql-test/r/row.result:
Added a test case for bug #54190.
mysql-test/r/subselect.result:
Updated the result for a test relying on wrong behavior.
mysql-test/t/row.test:
Added a test case for bug #54190.
sql/item_cmpfunc.cc:
If either of the argument rows is NULL, return NULL as the
result of comparison.
sql/item_subselect.cc:
Adjust null_value for Item_singlerow_subselect depending on
whether a row has been produced by the row subquery.
The problem was that mysql_stmt_next_result() (new to 5.5)
was not properly updated.
libmysql/libmysql.c:
mysql_stmt_next_result() modified: set mysql->status= MYSQL_STATUS_STATEMENT_GET_RESULT before return
if there is a result set.
Item_func_spatial_collection::fix_length_and_dec()
changed to use argument's print() method to print
the ER_ILLEGAL_VALUE_FOR_TYPE error.
mysql-test/r/gis.result:
Fix for bug#56679: gis.test: valgrind error
- test result adjusted.
sql/item_geofunc.h:
Fix for bug#56679: gis.test: valgrind error
- use argument's print() method instead of improper val_str()
call in the Item_func_spatial_collection::fix_length_and_dec(), as
it's applicable only for constant items.
With recent changes in the performance schema default sizing parameters,
the memory used by a mysqld binary increased accordingly.
This negatively affects the MTR test suite,
because running several tests in parallel now consumes more ressources.
The fix is to leave the default production values unchanged,
and to configure the MTR environment to limit memory
used when running tests in the test suite, which is ok
because only a few objects are typically used within a test script.
This fix:
- changed the default configuration in MTR to use less memory
- adjusted the performance schema tests accordingly
Note that 1,000 mutex instances was too short and caused test failures
in the past in team trees, so the default used is now 10,000 in MTR.
The amount of memory used by the performance schema itself
can be observed with the statement SHOW ENGINE PERFORMANCE_SCHEMA STATUS
ALTER TABLE on a MERGE table could cause a deadlock with two
other connections if we reached a situation where:
1) A connection doing ALTER TABLE can't upgrade to MDL_EXCLUSIVE on the
parent table, but holds TL_READ_NO_INSERT on the child tables.
2) A connection doing DELETE on a child table can't get TL_WRITE on it
since ALTER TABLE holds TL_READ_NO_INSERT.
3) A connection doing SELECT on the parent table can't get TL_READ on
the child tables since TL_WRITE is ahead in the lock queue, but holds
MDL_SHARED_READ on the parent table preventing ALTER TABLE from upgrading.
For regular tables, this deadlock is avoided by having ALTER TABLE
take a MDL_SHARED_NO_WRITE metadata lock on the table. This prevents
DELETE from acquiring MDL_SHARED_WRITE on the table before ALTER TABLE
tries to upgrade to MDL_EXCLUSIVE. In the example above, SELECT would
therefore not be blocked by the pending DELETE as DELETE would not be
able to enter TL_WRITE in the table lock queue.
This patch fixes the problem for merge tables by using the same metadata
lock type for child tables as for the parent table. The child tables will
in this case therefore be locked with MDL_SHARED_NO_WRITE, preventing
DELETE from acquiring a metadata lock and enter into the table lock queue.
Change in behavior: By taking the same metadata lock for child tables
as for the parent table, LOCK TABLE on the parent table will now also
implicitly lock the child tables. Since LOCK TABLE on the parent table
now takes more than one metadata lock, it is possible for LOCK TABLE
... WRITE on the parent table or child tables to give ER_LOCK_DEADLOCK
error.
Test case added to mdl_sync.test.
Merge.test/.result has been updated to reflect the change to LOCK TABLE.
After installation from RPM, server is run under root, not mysql user
The problem was that in the cmake way of building
the variable "MYSQLD_USER" was not set and propagated.
In the script "mysqld_safe" its value is used as the
name of the user who should run the server process.
The fix is to explicitly set this variable to "mysql"
and propagate it in the build process.
It was analyzed and proposed by Jonathan Perkin.
Convertion from a floating point number to a string caused a
crash.
During rare circumstances a String object could crash when
it was requested to allocate new memory.
A crash could occcur in Field_double::val_str() because of
a pointer referencing memory inside a String object which was
of unknown size.
And finally, the geometric collection should not accept
arguments which are non geometric.
mysql-test/r/gis.result:
* Test cases change because we intercept the error behind the
previous crashes much earlier.
sql/field.cc:
* It makes no sense to impose a lower limit on the length
and not setting a upper limit will cause crashes later.
sql/item_geofunc.h:
* Disallow for binding with field- and item types which
differ from MYSQL_TYPE_GEOMETRY types.
The EXISTS transformation has additional switches to catch the known corner
cases that appear when transforming an IN predicate into EXISTS. Guarded
conditions are used which are deactivated when a NULL value is seen in the
outer expression's row. When the inner query block supplies NULL values,
however, they are filtered out because no distinction is made between the
guarded conditions; guarded NOT x IS NULL conditions in the HAVING clause that
filter out NULL values cannot be de-activated in isolation from those that
match values or from the outer expression or NULL's.
The above problem is handled by making the guarded conditions remember whether
they have rejected a NULL value or not, and index access methods are taking
this into account as well.
The bug consisted of
1) Not resetting the property for every nested loop iteration on the inner
query's result.
2) Not propagating the NULL result properly from inner query to IN optimizer.
3) A hack that may or may not have been needed at some point. According to a
comment it was aimed to fix#2 by returning NULL when FALSE was actually
the result. This caused failures when #2 was properly fixed. The hack is
now removed.
The fix resolves all three points.
multi-table UPDATE IGNORE.
The problem was that if there was an active SELECT statement
during trigger execution, an error risen during the execution
may cause a crash. The fix is to temporary reset LEX::current_select
before trigger execution and restore it afterwards. This way
errors risen during the trigger execution are processed as
if there was no active SELECT.
mysql-test/r/trigger_notembedded.result:
added test case result for bug #55421.
mysql-test/t/trigger_notembedded.test:
added test case for bug #55421.
sql/sql_trigger.cc:
Reset thd->lex->current_select before start trigger execution
and restore its original value after execution is finished.
This is neccessery in order to set error status in
diagnostic_area in case of trigger execution failure.
inited==INDEX
When an error occurs while sending the data in a temporary table there was no
cleanup performed. This caused a failed assertion in the case when different
access methods were used for populating the table vs. retrieving the data from
the table if IGNORE was specified and sql_safe_updates = 0. In this case
execution continues, but the handler expects to continue with the access
method used for row retrieval.
Fixed by doing the cleanup even if errors occur.
for a prepared statement.
include/mysql.h:
enumerator MYSQL_STATUS_STATEMENT_GET_RESULT was added
into mysql_status enum.
include/mysql.h.pp:
enumerator MYSQL_STATUS_STATEMENT_GET_RESULT was added
into mysql_status enum.
libmysql/libmysql.c:
Introduce a separate mysql state to distinguish the situation
when we have a binary result set pending on the server from the
situation when the result set is in text protocol.
execute() modified: if mysql->status == MYSQL_STATUS_GET_RESULT
before return then set it to value MYSQL_STATUS_STATEMENT_GET_RESULT.
stmt_read_row_unbuffered() and mysql_stmt_store_result()
were modified: added checking for mysql->status against
MYSQL_STATUS_STATEMENT_GET_RESULT value instead of MYSQL_STATUS_GET_RESULT.
tests/mysql_client_test.c:
added test_bug47485()
The Item_func_str_to_date class wasn't providing correct integer DATETIME
representation as expected. This led to wrong comparison result and didn't
allowed the STR_TO_DATE function to be used with indexes.
Also, STR_TO_DATE function was inconsisted on throwing warnings/errors.
Fixed now.
val_int and result_as_longlong methods were added to the Item_func_str_to_date
class.
mysql-test/r/func_time.result:
Test case result adjusted after fixing bug#56271.
mysql-test/r/parser.result:
Test case result adjusted after fixing bug#56271.
mysql-test/r/select.result:
A test case result adjusted after fixing bug#56271.
mysql-test/r/strict.result:
Test case result adjusted after fixing bug#56271.
mysql-test/r/type_datetime.result:
Added a test case for the bug#56271.
mysql-test/t/strict.test:
Test case adjusted after fixing bug#56271.
mysql-test/t/type_datetime.test:
Added a test case for the bug#56271.
sql/item_timefunc.cc:
Bug#56271: Wrong comparison result with STR_TO_DATE function
val_int and result_as_longlong methods were added to the Item_func_str_to_date
class.
Item_func_str_to_date::get_date now throws the ER_WRONG_VALUE_FOR_TYPE warning
on incorrect value.
sql/item_timefunc.h:
Bug#56271: Wrong comparison result with STR_TO_DATE function
val_int and result_as_longlong methods were added to the Item_func_str_to_date
class.
MDL deadlock detector".
Deadlock could have occurred when workload containing mix
of DML, DDL and FLUSH TABLES statements affecting same
set of tables was executed in heavily concurrent environment.
This deadlock occurred when several connections tried to
perform deadlock detection in metadata locking subsystem.
The first connection started traversing wait-for graph,
encountered sub-graph representing wait for flush, acquired
LOCK_open and dived into sub-graph inspection. When it has
encounterd sub-graph corresponding to wait for metadata lock
and blocked while trying to acquire rd-lock on
MDL_lock::m_rwlock (*) protecting this subgraph, since some
other thread had wr-lock on it. When this wr-lock was released
it could have happened (if there was other pending wr-lock
against this rwlock) that rd-lock from the first connection
was left unsatisfied but at the same time new rd-lock request
from the second connection sneaked in and was satisfied (for
this to be possible second rd- request should come exactly
after wr-lock is released but before pending wr-lock manages
to grab rwlock, which is possible both on Linux and in our
own rwlock implementation). If this second connection
continued traversing wait-for graph and encountered sub-graph
representing wait for flush it tried to acquire LOCK_open
and thus deadlock was created.
This patch tries to workaround this problem but not allowing
deadlock detector to lock LOCK_open mutex if some other thread
doing deadlock detection already owns it and current search
depth is greater than 0. Instead deadlock is reported.
Other possible solutions are either known to have negative
effects on performance or require much more time for proper
implementation and testing.
No test case is provided as this bug is very hard to repeat
in MTR environment but is repeatable with the help of RQG
tests.
sql/mdl.cc:
Moved Deadlock_detection_visitor::m_current_search_depth to
parent class to make it available in
TABLE_SHARE::visit_subgraph().
Added MDL_wait_for_graph_visitor::abort_traversal() method
which allows to abort traversal of a wait-for graph and
report a deadlock.
sql/mdl.h:
Moved Deadlock_detection_visitor::m_current_search_depth to
parent class to make it available in
TABLE_SHARE::visit_subgraph().
Added MDL_wait_for_graph_visitor::abort_traversal() method
which allows to abort traversal of a wait-for graph and
report a deadlock.
sql/sql_base.cc:
Added dd_owns_lock_open counter and mutex protecting it to
track number of connections which do deadlock detection and
own or try to acquire LOCK_open.
sql/sql_base.h:
Added dd_owns_lock_open counter and mutex protecting it to
track number of connections which do deadlock detection and
own or try to acquire LOCK_open.
sql/table.cc:
Workaround bug #56405 but not allowing MDL deadlock detector
to lock LOCK_open mutex if some other thread doing deadlock
detection already owns it and current search depth is greater
than 0. Instead report deadlock.
In sql/log.c, member function wait_for_update_bin_log, a condition is entered with
THD::enter_cond but is not exited. This might leave dangling references to the
mutex/condition in the per-thread information area.
To fix the problem, we call exit_cond to properly remove references to the mutex,
LOCK_log.
On Solaris with version 3.4.6, the ha_example.so shared library is built
with DTrace and the server is built without DTrace support. This occurs
because dtrace.cmake disables DTrace support for 3.4.6, but still set
HAVE_DTRACE, which causes probes_mysql.h to include probes_mysql_dtrace.h
instead of probes_mysql_nodtrace.h.
This patch fixes this by not setting HAVE_DTRACE on Solaris for GCC 3.4.6.
The problem was not caused by a change in the client,
rather by the tests using the Windows built-in "echo"
and not the one built by MySQL.
This again happened because the binary was missing in the package,
caused by the wrong macro being used to build it in "cmake".
create data dir correctly in initial_database target on Windows
handle case where INSTALL_MYSQLTESTDIR is empty (e.g someone does not want
to install tests)
thread-specific variables weren't set when we load error message files.
per-file comments:
libmysqld/lib_sql.cc
Bug#53251 mysql_library_init fails on second execution with embedded library
we need to call my_thread_init() once more. Normally it's called at the my_init()
stage but that doesn't happen on the second my_init() call.
sql/derror.cc
Bug#53251 mysql_library_init fails on second execution with embedded library
use default errors for the embedded server.
sql/mysqld.cc
Bug#53251 mysql_library_init fails on second execution with embedded library
unregister server errors in clean_up(). Without it the error list contains
that on the second mysql_server_init() which is not good.
sql/set_var.cc
Bug#53251 mysql_library_init fails on second execution with embedded library
sys_var::cleanup() call instead of the destructor
sql/set_var.h
Bug#53251 mysql_library_init fails on second execution with embedded library
sys_var::cleanup() introduced instead of the destructor
sql/sys_vars.h
Bug#53251 mysql_library_init fails on second execution with embedded library
Sys_var_charptr::cleanup() implemented