MDEV-18466 Unsafe to log updates on tables referenced by foreign keys with triggers in statement format

ignore FK-prelocked tables when looking for write-prelocked tables
with auto-increment to complain about "Statement is unsafe because
it invokes a trigger or a stored function that inserts into an
AUTO_INCREMENT column"
This commit is contained in:
Sergei Golubchik 2019-03-22 19:28:59 +01:00
parent d8084116b5
commit deff3f7572
3 changed files with 47 additions and 0 deletions

View File

@ -0,0 +1,17 @@
create table categories(
cat_id int not null primary key,
cat_name varchar(255) not null,
cat_description text
) engine=innodb;
create table products(
prd_id int not null auto_increment primary key,
prd_name varchar(355) not null,
prd_price decimal,
cat_id int not null,
foreign key fk_cat(cat_id)
references categories(cat_id)
on update cascade
) engine=innodb;
insert into categories values (1, 'drinks', 'drinks');
update categories set cat_description=2 where cat_id=1;
drop table products, categories;

View File

@ -0,0 +1,26 @@
source include/have_innodb.inc;
source include/have_binlog_format_statement.inc;
#
# MDEV-18466 Unsafe to log updates on tables referenced by foreign keys with triggers in statement format
#
create table categories(
cat_id int not null primary key,
cat_name varchar(255) not null,
cat_description text
) engine=innodb;
create table products(
prd_id int not null auto_increment primary key,
prd_name varchar(355) not null,
prd_price decimal,
cat_id int not null,
foreign key fk_cat(cat_id)
references categories(cat_id)
on update cascade
) engine=innodb;
insert into categories values (1, 'drinks', 'drinks');
update categories set cat_description=2 where cat_id=1;
drop table products, categories;

View File

@ -5542,6 +5542,9 @@ int xid_cache_iterate(THD *thd, my_hash_walk_action action, void *arg)
Call this function only when you have established the list of all tables
which you'll want to update (including stored functions, triggers, views
inside your statement).
Ignore tables prelocked for foreign key cascading actions, as these
actions cannot generate new auto_increment values.
*/
static bool
@ -5551,6 +5554,7 @@ has_write_table_with_auto_increment(TABLE_LIST *tables)
{
/* we must do preliminary checks as table->table may be NULL */
if (!table->placeholder() &&
table->prelocking_placeholder != TABLE_LIST::FK &&
table->table->found_next_number_field &&
(table->lock_type >= TL_WRITE_ALLOW_WRITE))
return 1;