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

SYSTEM VERSIONING NOT/CASE rewrite drops TIMESTAMP(6) precision and filters current rows

    XMLWordPrintable

Details

    Description

      1. MariaDB SYSTEM VERSIONING: `NOT` over a `CASE` comparison drops `TIMESTAMP(6)` precision in `WHERE`

      Status: reproduced on MariaDB 13.0.2. Relevant code reviewed on current `main`; current-main runtime was not tested.

        1. Reproduction environment
      • MariaDB source: `mariadb-13.0.2`, commit `620a4b5624222048fece7fe1789978ae0675cae2`
      • Current `main` reviewed at `9d7ab2c0092df4bc73b64b915464aecf7e5fe6c4`
      • Linux x86_64, Clang 14, trace-pc-guard coverage build
        1. Minimal reproducer

      ```sql
      SET time_zone = '+08:00';

      CREATE TABLE t (
      id INT PRIMARY KEY,
      v VARCHAR(8),
      valid_from TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
      valid_to TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
      PERIOD FOR SYSTEM_TIME (valid_from, valid_to)
      ) WITH SYSTEM VERSIONING;

      INSERT INTO t(id, v) VALUES (1, 'a'), (2, 'b');

      SELECT id, valid_to,
      (CASE WHEN TRUE THEN valid_to ELSE valid_to END) <> valid_to AS p,
      NOT ((CASE WHEN TRUE THEN valid_to ELSE valid_to END) <> valid_to) AS not_p
      FROM t;

      SELECT COUNT FROM t
      WHERE NOT ((CASE WHEN TRUE THEN valid_to ELSE valid_to END) <> valid_to);

      EXPLAIN EXTENDED
      SELECT * FROM t
      WHERE NOT ((CASE WHEN TRUE THEN valid_to ELSE valid_to END) <> valid_to);
      SHOW WARNINGS;
      ```

        1. Actual and expected results

      Each inserted current row has `valid_to = 2106-02-07 14:28:15.999999`. In projection, `p` is `0` and `not_p` is `1`. Nevertheless, the `WHERE NOT (...)` count is `0`; the expected count is `2`.

      Controls using the same predicate with `IS FALSE` or `= 0` both return `2` rows.

        1. EXPLAIN evidence

      `SHOW WARNINGS` exposes the rewritten condition as:

      ```sql
      valid_to = TIMESTAMP'2106-02-07 14:28:15.999999'
      AND '2106-02-07 14:28:15' = valid_to
      ```

      The injected current-row bound retains `.999999`, while the propagated equality is a seconds-only string literal. The rewritten condition therefore rejects the current rows.

        1. Root cause

      `NOT (A <> B)` is normalized during parsing: `negate_expression()` invokes the expression's negation transformer, and `Item_func_ne::negated_item()` constructs equality. That rewrite is valid by itself. The wrong result occurs when optimizer equality/temporal constant propagation interacts with the system-versioned current-row sentinel and the `CASE` expression, producing the seconds-only equality visible in `EXPLAIN`.

      Relevant current-main code:

      The minimized reproducer contains no GIS expression or `NULLIF`; this is unrelated to the `ST_IsValid(NULL)` predicate issue.

        1. Impact

      A read-only `SELECT` can silently omit valid current rows when a negated comparison over a `CASE` expression references a system-versioned `TIMESTAMP(6)` period end. Projection and filtering disagree. No write corruption has been demonstrated.

        1. Duplicate audit

      No exact public duplicate was found for the combination of the system-versioned `TIMESTAMP(6)` row-end sentinel, negated comparison, and precision-losing equality propagation. MDEV-36440 is related to `NOT NOT`/`WHERE` mismatches but does not contain this temporal sentinel or precision-propagation trigger. MDEV-8766 and MDEV-8706 are prior temporal `Item_equal` propagation bugs with different reproducers.

        1. Discovery

      Found by DBMS-StateFuzz while exercising typed, compositional MariaDB queries and three-valued-logic partitioning.

      Credit: Zheng Wang, Yanjie Zhao, and Yiyang Liu.

      Attachments

        Issue Links

          Activity

            People

              midenok Aleksey Midenkov
              hacker_zheng Wang Zheng
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

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