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

ST_IsValid(NULL) and ST_IsEmpty(NULL) match both TRUE and NULL WHERE partitions

    XMLWordPrintable

Details

    Description

      1. MariaDB GIS NULL predicates violate three-valued filtering

      Status: reproduced on MariaDB 13.0.2, source commit `620a4b5624222048fece7fe1789978ae0675cae2`.

        1. Minimal reproducer

      ```sql
      SELECT ST_IsValid(NULL), ST_IsValid(NULL) IS NULL;
      SELECT 1 WHERE ST_IsValid(NULL);
      SELECT 1 WHERE NOT ST_IsValid(NULL);
      SELECT 1 WHERE ST_IsValid(NULL) IS NULL;

      SELECT ST_IsEmpty(NULL), ST_IsEmpty(NULL) IS NULL;
      SELECT 1 WHERE ST_IsEmpty(NULL);
      SELECT 1 WHERE NOT ST_IsEmpty(NULL);
      SELECT 1 WHERE ST_IsEmpty(NULL) IS NULL;
      ```

        1. Actual and expected results

      Both scalar GIS predicates evaluate to `NULL`, and `predicate IS NULL` evaluates to `1`.

      For each predicate, SQL three-valued logic therefore requires the TRUE/FALSE/NULL partitions to contain `0/0/1` rows. MariaDB instead returns `1/0/1`: the same row is accepted by both the bare predicate and its `IS NULL` partition.

      The result is stable without tables, data, special SQL mode, or optimizer-dependent query structure.

        1. Root cause

      In MariaDB 13.0.2:

      • `Item_func_isvalid::val_int()` sets `null_value=1` for a NULL/invalid argument but returns integer `1` (`sql/item_geofunc.cc:2136-2149`).
      • The integer `val_bool` fallback evaluates only `val_int()!=0` and does not reject the accompanying NULL flag (`sql/sql_type.cc:5323-5341`).
      • `Item_func_isempty::val_bool()` likewise sets the NULL flag and returns `1` (`sql/item_geofunc.cc:2226-2235`).

      Thus the expressions remain NULL for scalar NULL inspection but expose a true boolean payload when used directly as conditions.

        1. Impact

      Read-only queries can include rows that do not satisfy a GIS predicate. A NULL-valued condition is simultaneously selected by the TRUE and NULL partitions, violating SQL three-valued logic and making logically equivalent filters disagree.

        1. Duplicate audit

      MDEV-35960 is related: it changed scalar `ST_IsValid(NULL)` from an error to NULL and mentions `ST_IsEmpty(NULL)`, but it does not cover the bare `WHERE` truth-value behavior or the overlapping TRUE/NULL partitions. MDEV-40143 and related reports require VIEW/CTE/join optimizer structures and are not this table-free predicate path.

        1. Discovery

      Found by DBMS-StateFuzz using typed TLP checks. Two independent generated queries reduced to the two table-free expressions above.

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

      Attachments

        Activity

          People

            rucha174 Rucha Deodhar
            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.