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

Partitioning changes the query result after an ALTER TABLE to another collation of a partitioning column

    XMLWordPrintable

Details

    Description

      --source include/have_partition.inc
      --source include/have_innodb.inc
       
      CREATE TABLE t1 (a VARCHAR(10) COLLATE utf8mb4_general_ci) ENGINE=InnoDB PARTITION BY LIST COLUMNS (a) (PARTITION p0 VALUES IN ('a'), PARTITION p1 DEFAULT);
      INSERT INTO t1 VALUES ('A');
      # With utf8mb4_bin, the row 'A' belongs in p1
      ALTER TABLE t1 MODIFY a VARCHAR(10) COLLATE utf8mb4_bin;
      --let $c= query_get_value(SELECT COUNT(*) AS c FROM t1 WHERE a='A', c, 1)
      if ($c != 1)
      {
        --die The row 'A' is not found by a='A' after the collation of the LIST COLUMNS column was changed
      }
       
      CREATE TABLE t2 (a VARCHAR(10) COLLATE utf8mb4_general_ci) ENGINE=InnoDB PARTITION BY KEY (a) PARTITIONS 5;
      INSERT INTO t2 VALUES ('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h');
      ALTER TABLE t2 MODIFY a VARCHAR(10) COLLATE utf8mb4_bin;
      --let $c= query_get_value(SELECT COUNT(*) AS c FROM t2 WHERE a='a' OR a='b' OR a='c' OR a='d' OR a='e' OR a='f' OR a='g' OR a='h', c, 1)
      if ($c != 8)
      {
        --die The condition a='a' OR ... OR a='h' finds $c of the 8 rows after the collation of the KEY partitioning column was changed
      }
      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 row 'A' is not found by a='A' after the collation of the LIST COLUMNS column was changed

      Partitioning changes the query result. Without partitioning, a='A' finds the row after the same ALTER TABLE. The t2 part, with PARTITION BY KEY, fails in the same way when run on its own: the eight conditions find 4 of the 8 rows. With MyISAM, or with ALGORITHM=COPY, t1 gives the right result. With ALGORITHM=INPLACE, the row 'A' stays in p0. Optimized builds give the same result.

      MySQL

      +--------+----------------+
      | MySQL  | t2, rows found |
      +--------+----------------+
      | 5.5.62 | 8 of 8         |
      | 5.6.51 | 8 of 8         |
      | 5.7.44 | 8 of 8         |
      | 8.0.36 | 8 of 8         |
      | 9.1.0  | 8 of 8         |
      +--------+----------------+

      From the code it seems that the collation change is done without a copy, so the rows are not moved. ha_partition::can_convert_nocopy() in sql/ha_partition.cc asks only the engine of each partition, and ha_innobase::can_convert_varstring() accepts the change. ha_partition::can_convert_nocopy() does not check if the column is a partitioning column.

      Attachments

        Issue Links

          Activity

            People

              ycp Yuchen Pei
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              1 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 - 55m
                  55m

                  Git Integration

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