mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-24411: Trigger doesn't work correctly with bulk insert
Executing an INSERT statement in PS mode having positional parameter bound with an array could result in incorrect number of inserted rows in case there is a BEFORE INSERT trigger that executes yet another INSERT statement to put a copy of row being inserted into some table. The reason for incorrect number of inserted rows is that a data structure used for binding positional argument with its actual values is stored in THD (this is thd->bulk_param) and reused on processing every INSERT statement. It leads to consuming actual values bound with top-level INSERT statement by other INSERT statements used by triggers' body. To fix the issue, reset the thd->bulk_param temporary to the value nullptr before invoking triggers and restore its value on finishing its execution.
This commit is contained in:
@ -1021,10 +1021,19 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
||||
*/
|
||||
restore_record(table,s->default_values); // Get empty record
|
||||
table->reset_default_fields();
|
||||
/*
|
||||
Reset the sentinel thd->bulk_param in order not to consume the next
|
||||
values of a bound array in case one of statement executed by
|
||||
the trigger's body is INSERT statement.
|
||||
*/
|
||||
void *save_bulk_param= thd->bulk_param;
|
||||
thd->bulk_param= nullptr;
|
||||
|
||||
if (unlikely(fill_record_n_invoke_before_triggers(thd, table, fields,
|
||||
*values, 0,
|
||||
TRG_EVENT_INSERT)))
|
||||
{
|
||||
thd->bulk_param= save_bulk_param;
|
||||
if (values_list.elements != 1 && ! thd->is_error())
|
||||
{
|
||||
info.records++;
|
||||
@ -1038,6 +1047,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
||||
error=1;
|
||||
break;
|
||||
}
|
||||
thd->bulk_param= save_bulk_param;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1067,12 +1077,22 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
||||
}
|
||||
}
|
||||
table->reset_default_fields();
|
||||
|
||||
/*
|
||||
Reset the sentinel thd->bulk_param in order not to consume the next
|
||||
values of a bound array in case one of statement executed by
|
||||
the trigger's body is INSERT statement.
|
||||
*/
|
||||
void *save_bulk_param= thd->bulk_param;
|
||||
thd->bulk_param= nullptr;
|
||||
|
||||
if (unlikely(fill_record_n_invoke_before_triggers(thd, table,
|
||||
table->
|
||||
field_to_fill(),
|
||||
*values, 0,
|
||||
TRG_EVENT_INSERT)))
|
||||
{
|
||||
thd->bulk_param= save_bulk_param;
|
||||
if (values_list.elements != 1 && ! thd->is_error())
|
||||
{
|
||||
info.records++;
|
||||
@ -1081,6 +1101,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
||||
error=1;
|
||||
break;
|
||||
}
|
||||
thd->bulk_param= save_bulk_param;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user