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

Oracle mode INTERSECT followed by INTERSECT ALL returns a row absent from the middle operand

    XMLWordPrintable

Details

    Description

      In Oracle mode, an unparenthesized chain that transitions from INTERSECT to INTERSECT ALL returns a row that is absent from the middle operand. The equivalent explicitly parenthesized expression returns the correct result, as do the same inline and prepared queries in the default SQL mode.

      Steps to reproduce

      Run this SQL sequence:

      CREATE DATABASE IF NOT EXISTS set_test;
      USE set_test;
       
      CREATE TABLE a (x INT);
      CREATE TABLE b (x INT);
      CREATE TABLE c (x INT);
       
      INSERT INTO a VALUES (1),(2),(2);
      INSERT INTO b VALUES (1);
      INSERT INTO c VALUES (1),(2),(2);
       
      SET sql_mode='ORACLE';
       
      SELECT 'inline_oracle' AS phase;
      SELECT x FROM a
      INTERSECT
      SELECT x FROM b
      INTERSECT ALL
      SELECT x FROM c
      ORDER BY 1;
       
      SELECT 'nested_oracle' AS phase;
      (SELECT x FROM a INTERSECT SELECT x FROM b)
      INTERSECT ALL
      SELECT x FROM c
      ORDER BY 1;
       
      PREPARE p FROM 'SELECT x FROM a INTERSECT SELECT x FROM b INTERSECT ALL SELECT x FROM c ORDER BY 1';
      SELECT 'prepared_oracle_1' AS phase;
      EXECUTE p;
      SELECT 'prepared_oracle_2' AS phase;
      EXECUTE p;
      DEALLOCATE PREPARE p;
       
      SET sql_mode='';
       
      SELECT 'inline_default' AS phase;
      SELECT x FROM a
      INTERSECT
      SELECT x FROM b
      INTERSECT ALL
      SELECT x FROM c
      ORDER BY 1;
       
      PREPARE p FROM 'SELECT x FROM a INTERSECT SELECT x FROM b INTERSECT ALL SELECT x FROM c ORDER BY 1';
      SELECT 'prepared_default_1' AS phase;
      EXECUTE p;
      SELECT 'prepared_default_2' AS phase;
      EXECUTE p;
      DEALLOCATE PREPARE p;
       
      DROP DATABASE set_test;

      Actual result

      The inline Oracle-mode query and both executions of its prepared form return rows 1 and 2. The explicitly parenthesized Oracle-mode query and all default-mode queries return only row 1:

      inline_oracle
      1
      2
      nested_oracle
      1
      prepared_oracle_1
      1
      2
      prepared_oracle_2
      1
      2
      inline_default
      1
      prepared_default_1
      1
      prepared_default_2
      1

      Expected result

      For A = {1,2,2}, B = {1}, and C = {1,2,2}, A INTERSECT B contains only 1. Applying INTERSECT ALL C cannot add 2, so every query in the reproducer should return exactly one row containing 1. The parenthesized Oracle-mode result also demonstrates that the extra 2 is not explained by the input data or intended set semantics.

      This occurs when Oracle SQL mode evaluates an unparenthesized set-operation chain that transitions from INTERSECT DISTINCT to INTERSECT ALL.

      Attachments

        Activity

          People

            alice Alice Sherepa
            Milo liu
            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.