Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
Description
When a prepared statement is executed with array binding and one of its expressions calls a stored function that runs an INSERT, the function's INSERT consumes the parameter sets of the outer bulk statement. The outer statement then runs fewer iterations than the client sent, silently: no error, no warning, and the affected-rows count matches what was done rather than what was requested.
Cause: thd->bulk_param stays set while the function body runs. The INSERT code loops on bulk_parameters_set() / bulk_parameters_iterations() (sql_insert.cc), which read the next parameter set through thd->bulk_param without checking whether the caller is the bulk statement itself. Triggers were protected against this in MDEV-34958 by clearing thd->bulk_param in Table_triggers_list::process_triggers; sp_head::execute_function has no such protection.
How to repeat
CREATE TABLE t1 (a INT); |
CREATE TABLE t2 (a INT); |
CREATE FUNCTION f1(x INT) RETURNS INT DETERMINISTIC MODIFIES SQL DATA |
BEGIN
|
INSERT INTO t2 VALUES (x), (x); |
RETURN x; |
END; |
Bulk-execute
INSERT INTO t1 VALUES (f1(?))
|
with the bound array
{1, 2, 3}(any connector with array binding, for example Connector/C with STMT_ATTR_ARRAY_SIZE = 3).
Actual: t1 contains one row (1); t2 contains four rows, all with value 1.
Expected: t1 contains (1), (2), (3); t2 contains (1), (1), (2), (2), (3), (3).
Bulk UPDATE and DELETE statements calling such a function are affected in the same way.