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

Index does not handle null-safe equals operator correctly in join

    XMLWordPrintable

Details

    Description

      A table with an index with nullable fields does not correctly handle the "<=>" null-safe equals operator when used in an inner join "on" clause. This issue does not seem to occur in version 11.0.2.

      Setup:

      CREATE TEMPORARY TABLE `Building` (
        `id` int(10) unsigned NOT NULL,
        `number` int(10) unsigned DEFAULT 0,
        `name` varchar(47) DEFAULT NULL,
        `street` mediumint(8) unsigned DEFAULT NULL,
        PRIMARY KEY (`id`),
        KEY `streetNumber` (`street`,`number`,`name`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
       
      INSERT INTO Building (id, number, name, street) VALUES (100733476, 14, NULL, 1115569);
      

      The following query is expected to return one row, but instead returns no rows:

      SELECT
          b1.id
      FROM
          Building b1
          INNER JOIN Building b2 ON (
              b1.street = b2.street
              AND b1.number <=> b2.number
              AND b1.name <=> b2.name
          )
      

      Expected: 1 row "id: 100733476"
      Found: no rows

      The same query without using the "streetNumber" index does return a single row:

      SELECT
          b1.id
      FROM
          Building b1 IGNORE INDEX (streetNumber)
          INNER JOIN Building b2 IGNORE INDEX (streetNumber) ON (
              b1.street = b2.street
              AND b1.number <=> b2.number
              AND b1.name <=> b2.name
          )
      

      Expected: 1 row "id: 100733476"
      Returns: 1 row "id: 100733476"

      The same query with <=> operator replaced with an equivalent expression does return a single row:

      SELECT
          b1.id
      FROM
          Building b1
          INNER JOIN Building b2 ON (
              b1.street = b2.street
              AND b1.number <=> b2.number
              AND (b1.name = b2.name OR (b1.name IS NULL AND b2.name IS NULL))
          )
      

      Expected: 1 row "id: 100733476"
      Returns: 1 row "id: 100733476"

      Attachments

        Issue Links

          Activity

            People

              Gosselin Dave Gosselin
              pimbroekhof Pim Broekhof
              Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

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