• Dmitry Shulga's avatar
    MDEV-34718: Trigger doesn't work correctly with bulk update · ba5482ff
    Dmitry Shulga authored
    Running an UPDATE statement in PS mode and having positional
    parameter(s) bound with an array of actual values (that is
    prepared to be run in bulk mode) results in incorrect behaviour
    in presence of on update trigger that also executes an UPDATE
    statement. The same is true for handling a DELETE statement in
    presence of on delete trigger. Typically, the visible effect of
    such incorrect behaviour is expressed in a wrong number of
    updated/deleted rows of a target table. Additionally, in case UPDATE
    statement, a number of modified rows and a state message returned
    by a statement contains wrong information about a number of modified rows.
    
    The reason for incorrect number of updated/deleted 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/UPDATE/DELETE statement. It leads to
    consuming actual values bound with top-level UPDATE/DELETE statement
    by other DML 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.
    
    The second part of the problem relating with wrong value of affected
    rows reported by Connector/C API is caused by the fact that diagnostics
    area is reused by an original DML statement and a statement invoked
    by a trigger. This fact should be take into account on finalizing a
    state of diagnostics area on completion running of a statement.
    
    Important remark: in case the macros DBUG_OFF is on, call of the method
      Diagnostics_area::reset_diagnostics_area()
    results in reset of the data members
      m_affected_rows, m_statement_warn_count.
    Values of these data members of the class Diagnostics_area are used on
    sending OK and EOF messages. In case DML statement is executed in PS bulk
    mode such resetting results in sending wrong result values to a client
    for affected rows in case the DML statement fires a triggers. So, reset
    these data members only in case the current statement being processed
    is not run in bulk mode.
    ba5482ff
sql_base.cc 305 KB