Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-41938

Trigger SAVEPOINT leaves one row from a failed multi-row INSERT visible

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Duplicate
    • 12.3.3
    • N/A
    • None
    • Linux x86_64, MariaDB.org Ubuntu 24.04 binary distribution
    • Not for Release Notes

    Description

      A multi-row InnoDB INSERT is not statement-atomic when an AFTER INSERT trigger creates a savepoint and then raises an error. After the statement fails, one inserted row remains visible in the active transaction.

      This occurs when a trigger creates a savepoint during a multi-row statement and a later trigger operation raises an error.

      Steps to reproduce

      The following was reproduced on MariaDB 12.3.3.

      1. Save this script as case.sql:

      DROP DATABASE IF EXISTS trigger_atomicity;
      CREATE DATABASE trigger_atomicity;
      USE trigger_atomicity;
       
      CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
       
      DELIMITER //
      CREATE TRIGGER after_insert
      AFTER INSERT ON t1
      FOR EACH ROW
      BEGIN
        SAVEPOINT row_sp;
        DELETE FROM missing_table;
      END//
       
      CREATE PROCEDURE run_case()
      BEGIN
        DECLARE v_error BOOL DEFAULT FALSE;
        DECLARE v_errno INT DEFAULT 0;
        DECLARE v_message TEXT DEFAULT '';
        DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
        BEGIN
          SET v_error=TRUE;
          GET DIAGNOSTICS CONDITION 1
            v_errno=MYSQL_ERRNO, v_message=MESSAGE_TEXT;
        END;
       
        START TRANSACTION;
        INSERT INTO t1 VALUES (1),(2);
        SELECT 'result' AS marker,
               v_error AS statement_failed,
               v_errno AS error_number,
               v_message AS error_message,
               (SELECT COUNT(*) FROM t1) AS rows_after_failed_statement;
        ROLLBACK;
      END//
      DELIMITER ;
       
      CALL run_case();
      DROP DATABASE trigger_atomicity;

      1. Run the script in a MariaDB client:

      mariadb < case.sql

      Actual result

      The trigger's reference to the absent table raises error 1146, but the count inside the same transaction is 1:

      marker  statement_failed  error_number  error_message                                      rows_after_failed_statement
      result  1                 1146          Table 'trigger_atomicity.missing_table' doesn't exist  1

      Expected result

      The error should roll back every change made by the failed INSERT statement. The transaction may remain active for the handler, but rows_after_failed_statement must be 0. A count of 1 shows that the trigger-created savepoint displaced the statement's rollback boundary and allowed a partial change from the failed statement to remain visible. The explicit ROLLBACK at the end prevents that partial change from being committed by the reproducer.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              Milo liu
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.