[MDEV-29769] CREATE .. PARTITION .. AS SELECT creates a partition, but non-partitioned table Created: 2022-10-11  Updated: 2023-11-28

Status: Open
Project: MariaDB Server
Component/s: Partitioning
Affects Version/s: 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10
Fix Version/s: 10.4, 10.5, 10.6

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Alexey Botchkov
Resolution: Unresolved Votes: 0
Labels: None


 Description   

--source include/have_partition.inc
--source include/have_sequence.inc
 
create table t (a int) partition by hash (a) as select seq as a from seq_1_to_10;
show create table t;
 
select count(*) from information_schema.partitions where table_schema = 'test' and table_name = 't';
select count(*) from t partition (p0);
 
drop table t;

10.3 32bab2ce

show create table t;
Table	Create Table
t	CREATE TABLE `t` (
  `a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
select count(*) from information_schema.partitions where table_schema = 'test' and table_name = 't';
count(*)
1
 
mysqltest: At line 8: query 'select count(*) from t partition (p0)' failed: 1747: PARTITION () clause on non partitioned table

So, the partition got created, but SHOW CREATE TABLE does not show it, and the table appears to be non-partitioned.
Reproducible on active versions, including older minor releases; reproducible on 10.2, too.



 Comments   
Comment by Sergei Golubchik [ 2022-10-11 ]

This happens because partitioning stores the partitioning data on CREATE TABLE between the parser and build_frm_image() in thd->work_part_info. This is a fairly fragile hack and in this case it is broken by the discovery of seq_1_to_10 table. In particular, TABLE_SHARE::init_from_sql_statement_string() does

  thd->lex->create_info.db_type= hton;
#ifdef WITH_PARTITION_STORAGE_ENGINE
  thd->work_part_info= 0;                       // For partitioning
#endif

because partitioned tables cannot be discovered.

There are two ways to fix it. A quick fix would be to save and restore thd->work_part_info in TABLE_SHARE::init_from_sql_statement_string(). A correct approach would be to get rid of thd->work_part_info. Perhaps it should be in LEX? That's where the parser puts everything else.

Generated at Thu Feb 08 10:11:09 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.