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

JSON_ARRAY_INTERSECT returns NULL when the nonconstant array is the first operand

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Minor
    • Resolution: Unresolved
    • 12.3, 13.1, 12.3.3
    • 12.3, 13.1
    • JSON
    • Linux/amd64

    Description

      JSON_ARRAY_INTERSECT(j, '[2]') returns NULL for rows whose stored JSON arrays overlap [2], while exchanging the operands returns [2]. This was observed with MariaDB 12.3.3 on Linux/amd64.

      Reproducer

      CREATE DATABASE IF NOT EXISTS test;
      USE test;
      SET NAMES utf8mb4;
       
      DROP TABLE IF EXISTS array_inputs;
      CREATE TABLE array_inputs (
        id INT PRIMARY KEY,
        j LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
          CHECK (JSON_VALID(j))
      ) ENGINE=InnoDB;
       
      INSERT INTO array_inputs VALUES
        (1, '[1,2]'),
        (2, '[2,3]'),
        (3, '[4]');
       
      CREATE TEMPORARY TABLE intersections AS
      SELECT id,
             JSON_ARRAY_INTERSECT(j, '[2]') AS candidate,
             JSON_ARRAY_INTERSECT('[2]', j) AS commuted_control
      FROM array_inputs;
       
      SELECT id, candidate, commuted_control
      FROM intersections
      ORDER BY id;
       
      SELECT 'disagreement_count',
             SUM(NOT (candidate <=> commuted_control))
      FROM intersections;
       
      DROP TEMPORARY TABLE intersections;
      DROP TABLE array_inputs;

      The query produces:

      id	candidate	commuted_control
      1	NULL	[2]
      2	NULL	[2]
      3	NULL	NULL
      disagreement_count	SUM(NOT (candidate <=> commuted_control))
      disagreement_count	2

      Rows 1 and 2 return NULL with the column first but [2] with the constant first. JSON array intersection is independent of operand order, so the two expressions should be NULL-safe equal for every row and the disagreement count should be 0. Rows 1 and 2 should return [2] from both expressions; row 3 may return NULL from both because it has no overlap.

      The available source analysis indicates that the first operand is evaluated before argument normalization can exchange the operands, after which a hash is initialized from the stale pre-swap value. Per-row parsing does not repair that state.

      This occurs when JSON_ARRAY_INTERSECT compares a JSON value stored in a column with a constant JSON array and the column is supplied as the first operand.

      Attachments

        Issue Links

          Activity

            People

              rucha174 Rucha Deodhar
              faner fan
              Votes:
              0 Vote for this issue
              Watchers:
              2 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.