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

UNIQUE USING HASH on a partitioned table accepts a duplicate when the statement is pruned

    XMLWordPrintable

Details

    Description

      --source include/have_partition.inc
       
      CREATE TABLE t1 (a INT, b VARCHAR(10), UNIQUE (b) USING HASH) PARTITION BY HASH (a) PARTITIONS 4;
      INSERT INTO t1 VALUES (1,'x'),(3,'y');
      # The row with b='x' is in p1. The WHERE clause prunes the UPDATE to p3
      --error 0,ER_DUP_ENTRY
      UPDATE t1 SET b='x' WHERE a=3;
      --let $c= query_get_value(SELECT COUNT(*) AS c FROM t1 WHERE b='x', c, 1)
      if ($c != 1)
      {
        --die The UNIQUE USING HASH column b holds $c rows with the value 'x' after UPDATE ... WHERE a=3
      }
       
      CREATE TABLE t2 (a INT, b VARCHAR(10), UNIQUE (b) USING HASH) PARTITION BY HASH (a) PARTITIONS 4;
      INSERT INTO t2 VALUES (1,'x');
      --error 0,ER_DUP_ENTRY
      INSERT INTO t2 PARTITION (p2) VALUES (2,'x');
      --let $c= query_get_value(SELECT COUNT(*) AS c FROM t2 WHERE b='x', c, 1)
      if ($c != 1)
      {
        --die The UNIQUE USING HASH column b holds $c rows with the value 'x' after INSERT ... PARTITION (p2)
      }
      DROP TABLE t1, t2;

      Leads to:

      CS 13.1.0 da18481158c81ca94689702073c3e04aad85a6a3 (Debug, Clang 22.1.8-20260622) Build 18/08/2026

      mysqltest: At line 11: The UNIQUE USING HASH column b holds 2 rows with the value 'x' after UPDATE ... WHERE a=3

      Partition pruning breaks the unique key. The server gives ER_DUP_ENTRY when the UPDATE is not pruned (WHERE a+0=3), and for a plain INSERT. The t2 part, with INSERT ... PARTITION (p2), fails in the same way when run on its own. The same happens with a WITHOUT OVERLAPS key, when the table is partitioned on the period start column. An INSERT ... PARTITION or a pruned UPDATE then accepts an overlapping period. Optimized builds give the same result.

      From the code it seems that the duplicate check reads only the partitions left after pruning. handler::check_duplicate_long_entry_key() in sql/handler.cc looks up the hash through lookup_handler. For a partitioned table, create_lookup_handler() makes it with ha_partition::clone() in sql/ha_partition.cc, and the clone uses the m_part_info of the original handler, with its pruned set of partitions.

      Attachments

        Issue Links

          Activity

            People

              ycp Yuchen Pei
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - Not Specified
                  Not Specified
                  Logged:
                  Time Spent - 1h
                  1h

                  Git Integration

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