SYNTAX TRIGGERS IN ANY WAY
Table with triggers which were using deprecated (5.0-only) syntax became
unavailable for any DML and DDL after upgrade to 5.1 version of server.
Attempt to execute any statement on such a table resulted in parsing
error reported. Since this included DROP TRIGGER and DROP TABLE
statements (actually, the latter was allowed but was not functioning
properly for such tables) it was impossible to fix the problem without
manual operations on .TRG and .TRN files in data directory.
The problem was that failure to parse trigger body (due to 5.0-only
syntax) when opening trigger file for a table prevented the table
from being open. This made all operations on the table impossible
(except DROP TABLE which due to peculiarity in its implementation
dropped the table but left trigger files around).
This patch solves this problem by silencing error which occurs when
we parse trigger body during table open. Error message is preserved
for the future use and table is marked as having a broken trigger.
We also try to analyze parse tree to recover trigger name, which
will be needed in order to drop the broken trigger. DML statements
which invoke triggers on the table marked as having broken trigger
are prohibited and emit saved error message. The same happens for
DDL which change triggers except DROP TRIGGER and DROP TABLE which
try their best to do what was requested. Table becomes no longer
marked as having broken trigger when last such trigger is dropped.
mysql-test/r/trigger-compat.result:
Add results for test case for bug#45235
mysql-test/t/trigger-compat.test:
Add test case for bug#45235.
sql/sp_head.cc:
Added protection against MEM_ROOT double restoring to
sp_head::restore_thd_mem_root() method. Since this
method can be sometimes called twice during parsing
of stored routine (the first time during normal flow
of parsing, and the second time when a syntax error
is detected) we need to shortcut execution of the
method to avoid damaging MEM_ROOT by the second
consecutive call to this method.
sql/sql_trigger.cc:
Added error handler Deprecated_trigger_syntax_handler to
catch non-OOM errors during parsing of trigger body.
Added handling of parse errors into method
Table_triggers_list::check_n_load().
sql/sql_trigger.h:
Added new members to handle broken triggers and error messages.
THE EVENT STATUS.
Any ALTER EVENT statement on a disabled event enabled it back
(unless this ALTER EVENT statement explicitly disabled the event).
The problem was that during processing of an ALTER EVENT statement
value of status field was overwritten unconditionally even if new
value was not specified explicitly. As a consequence this field
was set to default value for status which corresponds to ENABLE.
The solution is to check if status field was explicitly specified in
ALTER EVENT statement before assigning new value to status field.
mysql-test/r/events_bugs.result:
test's result for Bug#11764334 was added.
mysql-test/t/events_bugs.test:
new test for Bug#11764334 was added.
sql/event_db_repository.cc:
mysql_event_fill_row() was modified: set value for status field
in events tables only in case if statement CREATE EVENT
is being processed or if this value was set in ALTER EVENT
statement.
Event_db_repository::create_event was modified: removed redundant
setting of status field after return from call to mysql_event_fill_row().
sql/event_parse_data.h:
Event_parse_data structure was modified: added flag
status_changed that is set to true if status's value
was changed in ALTER EVENT statement.
sql/sql_yacc.yy:
Set flag status_changed if status was set in ALTER EVENT
statement.
SEEMS TO BE 'LEAKING' INTO THE SCHEMA NAME SPACE)
and bug#12428824 (Parser stack overflow and crash in sp_add_used_routine
with obscure query).
The first problem was that attempts to call a stored function by
its fully qualified name ended up with unwarranted error "ERROR 1305
(42000): FUNCTION someMixedCaseDb.my_function_name does not exist"
if this function belonged to a schema that had uppercase letters in
its name AND --lower_case_table_names was equal to either 1 or 2.
The second problem was that 5.5 version of MySQL server might have
crashed when a user tried to call stored function with too long name
or too long database name (i.e if a function and database name combined
occupied more than 2*3*64 bytes in utf8). This issue didn't affect
versions of server < 5.5.
The first problem was caused by the fact that in cases when a stored
function was called by its fully qualified name we didn't lowercase
name of its schema before performing look up of the function in
mysql.proc table even although lower_case_table_names mode was on.
As result we were unable to find this function since during its
creation we store lowercased version of schema name in the system
table in this mode and field for schema name uses binary collation.
Calls to stored functions were unaffected by this problem since for
them schema name is converted to lowercase as necessary.
The reason for the second bug was that MySQL Server didn't check length
of function name and database name before proceeding with execution of
stored function. As a consequence too long database name or function
name caused buffer overruns in places where the code assumes that their
length is within fixed limits, like mdl_key_init() in 5.5.
Again this issue didn't affect calls to stored procedures as for them
length of schema name and procedure name are properly checked.
This patch fixes both these bugs by adding calls to check_db_name()
and check_routine_name() to grammar rule which corresponds to a call
to a stored function. These functions ensure that length of database
name and function name for routine called is within standard limit.
Moreover call to check_db_name() handles conversion of database name
to lowercase if --lower_case_table_names mode is on.
Note that even although the second issue seems to be only reproducible
in 5.5 we still add code fixing it to 5.1 to be on the safe side (and
make code a bit more robust against possible future changes).
mysql-test/r/sp-error.result:
Added testcase results for bug#12428824.
mysql-test/r/sp.result:
Added testcase result for bug#11840395.
mysql-test/t/sp-error.test:
Added testcase for bug#12428824.
mysql-test/t/sp.test:
Added testcase for bug#11840395.
sql/sql_yacc.yy:
Modified 'function_call_generic' rule to call check_db_name() and
check_routine_name() in order to ensure that lengths of database name
and function name are within limits. check_db_name() is also responsible
for normalizing function's database name for lookup in cases when
lowercase_table_names mode is on.
STATEMENTS FAIL".
Attempt to execute CREATE TABLE LIKE statement on a MyISAM
table with INDEX or DATA DIRECTORY options specified as a
source resulted in "MyISAM table '...' is in use..." error.
According to our documentation such a statement should create
a copy of source table with DATA/INDEX DIRECTORY options
omitted.
The problem was that new implementation of CREATE TABLE LIKE
statement in 5.5 tried to copy value of INDEX and DATA DIRECTORY
parameters from the source table. Since in description of source
table this parameters also included name of this table, attempt
to create target table with these parameter led to file name
conflict and error.
This fix addresses the problem by preserving documented and
backward-compatible behavior. I.e. by ensuring that contents
of DATA/INDEX DIRECTORY clauses for the source table is
ignored when target table is created.
mysql-test/r/symlink.result:
Added test for bug #11759990 - "52354: 'CREATE TABLE ..
LIKE ... ' STATEMENTS FAIL".
mysql-test/t/symlink.test:
Added test for bug #11759990 - "52354: 'CREATE TABLE ..
LIKE ... ' STATEMENTS FAIL".
sql/sql_table.cc:
Changed CREATE TABLE LIKE implementation to ignore contents
of DATA/INDEX DIRECTORY clauses for source table when target
table is created. This is documented and backward-compatible
behavior.
FUNCTION DOES NOT EXIST IF NOT-PRIV USER RECONNECTS".
The bug itself was fixed by the same patch as bug@11747137
"30977: CONCURRENT STATEMENT USING STORED FUNCTION AND DROP
FUNCTION BREAKS SBR".
Problem: in case of wrong data insert into indexed GEOMETRY fields
(e.g. NULL value for a not NULL field) MyISAM reported
"ERROR 126 (HY000): Incorrect key file for table; try to repair it"
due to misuse of the key deletion function.
Fix: always use R-tree key functions for R-tree based indexes
and B-tree key functions for B-tree based indexes.
mysql-test/r/gis-rtree.result:
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
- test result.
mysql-test/t/gis-rtree.test:
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
- test case.
storage/myisam/mi_update.c:
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
- handling update errors check for HA_ERR_NULL_IN_SPATIAL as well to be
consistent with mi_write();
- always use keyinfo->ck_delete()/ck_insert() instead of _mi_ck_delete()/_mi_ck_write()
to handle index properly, as it may be of B-tree or R-tree type.
storage/myisam/mi_write.c:
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
- always use keyinfo->ck_delete() instead of _mi_ck_delete() to handle
index properly, as it may be of B-tree or R-tree type.
Re-enable a test that was disabled as collateral damage.
Starting with MySQL 5.5, queries will acquire and hold a shared meta-data lock
(MDL) on tables they process, until the transaction is committed or
rolled back. This will prevent DDL operations on the tables, such as creating
an index.
innodb-index.test: Use a second table for creating the index. The index will
still be "too new" for the transaction that was started before the index
creation was started.
Bug 12430414 - THE TEST PERFSCHEMA.SELECTS.TEST CAN AFFECT SUCCEEDING TESTS
Bug 12430599 - THE TEST PERFSCHEMA.ONE_THREAD_PER_CON. CAN AFFECT SUCCEEDING TESTS
Bug 12431153 - THE TEST PERFSCHEMA.PFS_UPGRADE CAN AFFECT SUCCEEDING TEST
GRADUALLY IF A TRIGGER EXISTS".
This bug manifested itself in two ways:
- Firstly execution of any data-changing statement which
required prelocking (i.e. involved stored function or
trigger) as part of transaction slowed down a bit all
subsequent statements in this transaction. So performance
in transaction which periodically involved such statements
gradually degraded over time.
- Secondly execution of any data-changing statement which
required prelocking as part of transaction prevented
concurrent FLUSH TABLES WITH READ LOCK from proceeding
until the end of transaction instead of end of particular
statement.
The problem was caused by incorrect handling of metadata lock
used in FTWRL implementation for statements requiring prelocked
mode.
Each statement which changes data acquires global IX lock
with STATEMENT duration. This lock is supposed to block
concurrent FTWRL from proceeding until the statement ends.
When entering prelocked mode, durations of all metadata locks
acquired so far were changed to EXPLICIT, to prevent
substatements from releasing these locks. When prelocked mode
was left, durations of metadata locks were changed to
TRANSACTIONAL (with a few exceptions) so they can be properly
released at the end of transaction.
Unfortunately, this meant that the global IX lock blocking
FTWRL with STATEMENT duration was moved to TRANSACTIONAL
duration after execution of statement requiring prelocking.
Since each subsequent statement that required prelocking and
tried to acquire global IX lock with STATEMENT duration got
a new instance of MDL_ticket, which was later moved to
TRANSACTIONAL duration, this led to unwarranted growth of
number of tickets with TRANSACITONAL duration in this
connection's MDL_context. As result searching for other
tickets in it became slow and acquisition of other metadata
locks by this transaction started to hog CPU.
Moreover, this also meant that after execution of statement
requiring prelocking concurrent FTWRL was blocked
until the end of transaction instead of end of statement.
This patch solves this problem by not moving locks to EXPLICIT
duration when thread enters prelocked mode (unless it is a real
LOCK TABLES mode). This step turned out to be not really
necessary as substatements don't try to release metadata locks.
Consequently, the global IX lock blocking FTWRL keeps its
STATEMENT duration and is properly released at the end of
statement and the above issue goes away.
mysql-test/r/flush.result:
Added test for bug #12641342 - "61401: UPDATE PERFORMANCE
DEGRADES GRADUALLY IF A TRIGGER EXISTS".
mysql-test/t/flush.test:
Added test for bug #12641342 - "61401: UPDATE PERFORMANCE
DEGRADES GRADUALLY IF A TRIGGER EXISTS".
sql/mdl.h:
Added comment describing various types of metadata lock
duration.
sql/sql_class.cc:
Since we no longer change duration of metadata locks to EXPLICIT
when entering prelocked mode (unless it is a real LOCK TABLES)
there is no need to restore proper duration of the locks when
leaving prelocked mode.
sql/sql_class.h:
Do not change duration of metadata locks to EXPLICIT when
entering prelocking mode (unless it is a real LOCK TABLES).
This allows to avoid problems with restoring correct duration
when leaving this mode. It is possible to do this as
substatements won't release metadata locks in any case.
sql/sql_parse.cc:
Added assert checking that we won't release metadata locks
when in substatement.
Issue:
------
New test case mysql_embedded.test was failing on pb2.
Description:
------------
To run this test case executable libmysqld/examples/mysql_embedded is required.
But as per /libmysqld/examples/cmake_install.cmake this executable doesn't get
copied to <install_dir> when mysql is installed at <install_dir>.That is the
reason it was passing in my local branch and failed on pb2 when pushed.
Solution;
---------
Added code in mysql-test-run.pl, which will try to see if this file exists.If
It doesn't exist, test case will be skipped with a skip message. New code in
mysql-test-run.pl looks only for directory libmysqld/examples/mysql_embedded
because this is the only place where this file could/does exist.
mysql-test/mysql-test-run.pl:
Added new variable for mysql_embedded executable.
mysql-test/t/disabled.def:
enabled mysql_embedded.test which was disabled earlier.
mysql-test/t/mysql_embedded.test:
Modified test case to first verify if mysql_embedded executable exists. If
it does not, skip the test.
FAIL IN EMBEDDED SERVER
FreeBSD 64 bit needs the FP_X_DNML to fpsetmask() to prevent exceptions from
propagating into mysql (as a threaded application).
However fpsetmask() itself is deprecated in favor of fedisableexcept().
1. Fixed the #ifdef to check for FP_X_DNML instead of i386.
2. Added a configure.in check for fedisableexcept() and, if present,
this function is called insted of the fpsetmask().
No need for new tests, as the existing tests cover this already.
Removed the affected tests from the experimental list.
The check for empty password in the user account was checking the wrong field.
Fixed to check the proper password hash.
Test case added.
Fixed native_password and old_password plugins that suffered from the same
problems.
Unambuguated the auth_string ACL_USER member : previously it was used for
both password and the authentication string (depending on the plugin). Now
fixed to contain either the authentication string specified or empty string.
SECONDARY INDEX IN INNODB
This is a follow-up patch.
This patch moves part of the new test coverage to a test
file that is only run on debug builds since it used debug-
only features and therefore broke the test case on
release builds.
SECONDARY INDEX IN INNODB
The patches for Bug#11751388 and Bug#11784056 enabled concurrent
reads while creating secondary indexes in InnoDB. However, they
introduced a regression. This regression occured if ALTER TABLE
failed after the index had been added, for example during the
lock upgrade needed to update .FRM. If this happened, InnoDB
and the server got out of sync with regards to which indexes
actually existed. Therefore the patch for Bug#11815600 again
disabled concurrent reads.
This patch re-enables concurrent reads. The original regression
is fixed by splitting the ADD INDEX operation into two parts.
First the new index is created but not made active. This is
done while concurrent reads are allowed. The second part of
the operation makes the index active (or reverts the change).
This is done after lock upgrade, which prevents the original
regression.
In order to implement this change, the patch changes the storage
API for in-place index creation. handler::add_index() is split
into two functions, handler_add_index() and
handler::final_add_index(). The former for creating indexes without
making them visible and the latter for commiting (i.e. making
visible) new indexes or reverting the changes.
Large parts of this patch were written by Marko Mäkelä.
Test case added to innodb_mysql_lock.test.
With this change, the index prefix column length lifted from 767 bytes
to 3072 bytes if "innodb_large_prefix" is set to "true".
rb://603 approved by Marko
The test case problem stemmed from the fact that a debug sync
signal is a global variable that persists until overwritten
by a new signal. This means that if two different signals
are raised in sequence, a thread waiting for the first signal
might miss it if the second signal sets the global variable
before the thread wakes up.
The solution is to deliver a subsequent signal only after the
waiting thread has received it.
mysql-test/t/query_cache_debug.test:
Wait for signal to be delivered.
will create multiple running events.
A CREATE IF NOT EXIST on an event that existed and was enabled caused
multiple instances of the event to run. Disabling the event didn't help.
If the event was dropped, the event stopped running, but when created
again, multiple instances of the event were still running. The only way
to get out of this situation was to restart the server.
The problem was that Event_db_repository::create_event() didn't return
enough information to discriminate between situation when event didn't
exist and was created and when event did exist and was not created
(but a warning was emitted). As result in the latter case event
was added to in-memory queue of events second time. And this led to
unwarranted multiple executions of the same event.
The solution is to add out-parameter to Event_db_repository::create_event()
method which will signal that event was not created because it already
exists and so it should not be added to the in-memory queue.
mysql-test/r/events_bugs.result:
Added results for test for Bug#12546938.
mysql-test/t/events_bugs.test:
Added test for Bug#12546938.
sql/event_db_repository.cc:
Event_db_repository::create_event was modified: set newly added out-parameter
event_already_exists to true value if event wasn't created because event
already existed and IF NOT EXIST clause was present.
sql/event_db_repository.h:
Added out-parameter 'event_already_exists' to create_event() method.
sql/events.cc:
Events::create_event was modified: insert new element into
event queue only if event was actually created.
HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
Attempt to update an InnoDB temporary table under LOCK TABLES
led to assertion failure in both debug and production builds
if this temporary table was explicitly locked for READ. The
same scenario works fine for MyISAM temporary tables.
The assertion failure was caused by discrepancy between lock
that was requested on the rows of temporary table at LOCK TABLES
time and by update operation. Since SQL-layer requested a
read-lock at LOCK TABLES time InnoDB engine assumed that upcoming
statements which are going to be executed under LOCK TABLES will
only read table and therefore should acquire only S-lock.
An update operation broken this assumption by requesting X-lock.
Possible approaches to fixing this problem are:
1) Skip locking of temporary tables as locking doesn't make any
sense for connection-local objects.
2) Prohibit changing of temporary table locked by LOCK TABLES ...
READ.
Unfortunately both of these approaches have drawbacks which make
them unviable for stable versions of server.
So this patch takes another approach and changes code in such way
that LOCK TABLES for a temporary table will always request write
lock. In 5.5 version of this patch switch from read lock to write
lock is done on SQL-layer.
mysql-test/suite/innodb/r/innodb_mysql.result:
Added test for bug #11762012 - "54553: INNODB ASSERTS IN
HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
mysql-test/suite/innodb/t/innodb_mysql.test:
Added test for bug #11762012 - "54553: INNODB ASSERTS IN
HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
sql/sql_parse.cc:
Since a temporary table locked by LOCK TABLES can be updated even
if it was only locked for read we always request TL_WRITE locks
for such tables at LOCK TABLES time. This allows to avoid
discrepancy between locks acquired at LOCK TABLES time and by
a statement executed under LOCK TABLES. Such a discrepancy has
caused problems for InnoDB storage engine.
To support this change a part of code implementing LOCK TABLES
has been moved to a helper function.
HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
Attempt to update an InnoDB temporary table under LOCK TABLES
led to assertion failure in both debug and production builds
if this temporary table was explicitly locked for READ. The
same scenario works fine for MyISAM temporary tables.
The assertion failure was caused by discrepancy between lock
that was requested on the rows of temporary table at LOCK TABLES
time and by update operation. Since SQL-layer requested a
read-lock at LOCK TABLES time InnoDB engine assumed that upcoming
statements which are going to be executed under LOCK TABLES will
only read table and therefore should acquire only S-lock.
An update operation broken this assumption by requesting X-lock.
Possible approaches to fixing this problem are:
1) Skip locking of temporary tables as locking doesn't make any
sense for connection-local objects.
2) Prohibit changing of temporary table locked by LOCK TABLES ...
READ.
Unfortunately both of these approaches have drawbacks which make
them unviable for stable versions of server.
So this patch takes another approach and changes code in such way
that LOCK TABLES for a temporary table will always request write
lock. In 5.1 version of this patch switch from read lock to write
lock is done inside of InnoDBs handler methods as doing it on
SQL-layer causes compatibility troubles with FLUSH TABLES WITH
READ LOCK.
mysql-test/suite/innodb/r/innodb_mysql.result:
Added test for bug #11762012 - "54553: INNODB ASSERTS IN
HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
mysql-test/suite/innodb/t/innodb_mysql.test:
Added test for bug #11762012 - "54553: INNODB ASSERTS IN
HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
mysql-test/suite/innodb_plugin/r/innodb_mysql.result:
Added test for bug #11762012 - "54553: INNODB ASSERTS IN
HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
mysql-test/suite/innodb_plugin/t/innodb_mysql.test:
Added test for bug #11762012 - "54553: INNODB ASSERTS IN
HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK".
storage/innobase/handler/ha_innodb.cc:
Assume that a temporary table locked by LOCK TABLES can be updated
even if it was only locked for read and therefore an X-lock should
be always requested for such tables.
storage/innodb_plugin/handler/ha_innodb.cc:
Assume that a temporary table locked by LOCK TABLES can be updated
even if it was only locked for read and therefore an X-lock should
be always requested for such tables.
Problem: MYSQL_BIN_LOG::reset_logs acquires mutexes in wrong order.
The correct order is first LOCK_thread_count and then LOCK_log. This function
does it the other way around. This leads to deadlock when run in parallel
with a thread that takes the two locks in correct order. For example, a thread
that disconnects will take the locks in the correct order.
Fix: change order of the locks in MYSQL_BIN_LOG::reset_logs:
first LOCK_thread_count and then LOCK_log.
mysql-test/suite/binlog/r/binlog_reset_master.result:
added result file
mysql-test/suite/binlog/t/binlog_reset_master.test:
Added test case that demonstrates deadlock because of wrong mutex order.
The deadlock is between two threads:
- RESET MASTER acquires mutexes in wrong order.
- client thread shutdown code acquires mutexes in right order.
Actually, this test case does not produce deadlock in 5.1, probably
the client thread shutdown code does not hold both mutexes at the same
time. However, the bug existed in 5.1 (mutexes are taken in the wrong
order) so we push the test case to 5.1 too, to prevent future
regressions.
sql/log.cc:
Change mutex acquisition to the correct order:
first LOCK_thread_count, then LOCK_log.
sql/mysqld.cc:
Add debug code to synchronize test case.
Assertion happens due to missing NULL value check in
Item_func_round::fix_length_and_dec() function.
The fix: added NULL value check for second parameter.
mysql-test/r/func_math.result:
test case
mysql-test/t/func_math.test:
test case
sql/item_func.cc:
added NULL value check for second parameter.