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

LOAD DATA leaves a stale STORED generated column after a BEFORE INSERT trigger changes its base column

    XMLWordPrintable

Details

    • Unexpected results
    • Hide
      On the successful {{LOAD DATA LOCAL INFILE}} path, a {{BEFORE INSERT}} trigger can change a base column while a {{STORED}} generated column retains the value computed before that trigger change. The persisted row therefore violates its own generated-column expression.
      Show
      On the successful {{LOAD DATA LOCAL INFILE}} path, a {{BEFORE INSERT}} trigger can change a base column while a {{STORED}} generated column retains the value computed before that trigger change. The persisted row therefore violates its own generated-column expression.

    Description

      Environment

      • Product: MariaDB Server
      • Observed affected versions: 10.3, 10.6, and 12.2.2
      • Storage engine: InnoDB
      • Client prerequisite: enable LOCAL INFILE for the client used below (for
        example, start the MariaDB client with --local-infile=1).
      • Clean comparison: MySQL 8.0.36 computes the expected stored value for the
        same schedule.

      Steps to reproduce

      1. In a shell on the client host, create the one-row input file. This is only
      local test input; no attachment is needed.

      printf '2\t12\tnew\n' > /tmp/mdev_load_generated.tsv
      

      2. Connect with a MariaDB client that permits LOCAL INFILE and run this
      complete SQL block:

      DROP DATABASE IF EXISTS mdev_load_generated;
      CREATE DATABASE mdev_load_generated;
      USE mdev_load_generated;
       
      CREATE TABLE t(
        id   INT PRIMARY KEY,
        v    INT NOT NULL,
        g    INT GENERATED ALWAYS AS (v * 2) STORED,
        note VARCHAR(20)
      ) ENGINE=InnoDB;
       
      DELIMITER //
      CREATE TRIGGER t_bi BEFORE INSERT ON t FOR EACH ROW
      BEGIN
        SET NEW.v = 20;
      END//
      DELIMITER ;
       
      LOAD DATA LOCAL INFILE '/tmp/mdev_load_generated.tsv'
      INTO TABLE t
      FIELDS TERMINATED BY '\t'
      LINES TERMINATED BY '\n'
      (id, v, note);
       
      SELECT VERSION() AS version, id, v, g, v * 2 AS expected_g, g = v * 2 AS invariant_holds
      FROM t;
      

      Expected result

      The trigger makes the final v value 20. A stored column defined as
      v * 2 must consequently be 40:

      id  v   g   expected_g  invariant_holds
      2   20  40  40          1
      

      Actual result on MariaDB 10.3, 10.6, and 12.2.2

      id  v   g   expected_g  invariant_holds
      2   20  24  40          0
      

      The stored value 24 is 12 * 2, i.e. it reflects the input value before
      the trigger changed NEW.v. The row was inserted successfully and the
      trigger's base-column change is visible, so this is not a failure to invoke the
      trigger.

      Relevant controls

      • Replacing LOAD DATA with
        INSERT INTO t(id, v, note) VALUES(2, 12, 'new') yields
        v=20, g=40 on the same MariaDB schema.
      • LOAD DATA ... SET v=20 yields v=20, g=40.
      • Removing the trigger yields v=12, g=24, which satisfies the generated
        expression.
      • The IGNORE modifier is not required for the symptom.
      • The same LOAD DATA schedule on MySQL 8.0.36 yields v=20, g=40.

      Repetition and scope

      The minimal schedule reproduced three times each on MariaDB 10.3, 10.6, and
      12.2.2, with no setup errors. The effect is specific to the combination of a
      bulk-import path, a BEFORE INSERT mutation of a base column, and a stored
      generated column.

      Nearby issues checked

      I found related LOAD DATA/generated-column reports, but none describes a
      successful load in which the trigger runs, visibly rewrites a base column, and
      the persisted stored generated value remains pre-trigger:

      • MDEV-7968 concerns a virtual generated column becoming NULL.
      • MDEV-8818 concerns trigger invocation by LOAD DATA; here the trigger is
        demonstrably invoked.
      • MDEV-24665 and MDEV-27224 concern failure/crash paths with other feature
        combinations.

      Attachments

        Issue Links

          Activity

            People

              midenok Aleksey Midenkov
              JaysonL Zhensheng Luo
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - 0d
                  0d
                  Remaining:
                  Time Spent - 5h Remaining Estimate - 1d 7h
                  1d 7h
                  Logged:
                  Time Spent - 5h Remaining Estimate - 1d 7h
                  5h

                  Git Integration

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