Bug#31931 Partitions: unjustified 'mix of handlers' error message

Problem was that the mix of handlers was not consistent between
CREATE and ALTER

changed so that it works like:
    - All partitions must use the same engine
      AND it must be the same as the table.
    - if one does NOT specify an engine on the table level
      then one must either NOT specify any engine on any
      partition/subpartition OR for ALL partitions/subpartitions

Note: that after a table have been created, the storage engine
is specified for all parts of the table (table/partition/subpartition)
and so when using alter, one does not need to specify it (unless one
wants to change the storage engine, then one have to specify it on the
table level)
parent 6836db1c
......@@ -536,11 +536,9 @@ t1 CREATE TABLE `t1` (
alter table t1
partition by key(a)
(partition p0, partition p1 engine=heap);
ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
alter table t1
partition by key(a)
(partition p0 engine=heap, partition p1);
ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
alter table t1
engine=heap
partition by key (a)
......
......@@ -79,8 +79,7 @@ engine = innodb
partition by list (a)
(partition p0 values in (0));
alter table t1 engine = x;
Warnings:
Warning 1286 Unknown table engine 'x'
ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
......@@ -151,9 +150,11 @@ DROP TABLE t1;
create table t1 (int_column int, char_column char(5))
PARTITION BY RANGE (int_column) subpartition by key (char_column) subpartitions 2
(PARTITION p1 VALUES LESS THAN (5) ENGINE = InnoDB);
alter table t1 PARTITION BY RANGE (int_column)
alter table t1
ENGINE = MyISAM
PARTITION BY RANGE (int_column)
subpartition by key (char_column) subpartitions 2
(PARTITION p1 VALUES LESS THAN (5) ENGINE = myisam);
(PARTITION p1 VALUES LESS THAN (5));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
......
......@@ -88,6 +88,12 @@ PARTITION BY KEY(a)
drop table t1;
CREATE TABLE t1 (a int not null primary key);
ALTER TABLE t1
ENGINE = NDB
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
drop table t1;
CREATE TABLE t1 (a int not null primary key) ENGINE = NDB;
ALTER TABLE t1
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
drop table t1;
......@@ -143,7 +149,6 @@ t1 CREATE TABLE `t1` (
alter table t1
partition by key(a)
(partition p0 engine=ndb, partition p1);
ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
alter table t1
engine=ndb
partition by key(a)
......
......@@ -75,6 +75,14 @@ drop table t1;
CREATE TABLE t1 (a int not null primary key);
ALTER TABLE t1
ENGINE = NDB
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
drop table t1;
CREATE TABLE t1 (a int not null primary key) ENGINE = NDB;
ALTER TABLE t1
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
......@@ -112,7 +120,10 @@ show create table t1;
alter table t1 remove partitioning;
show create table t1;
--error ER_MIX_HANDLER_ERROR
# after bug#31931 was fixed
# this is OK, since the storage engine is specified
# on table level before.
#--error ER_MIX_HANDLER_ERROR
alter table t1
partition by key(a)
(partition p0 engine=ndb, partition p1);
......
......@@ -83,6 +83,7 @@ DROP TABLE t1;
--echo # 3 Some but not all named partitions or subpartitions get a storage
--echo # engine assigned
--echo #------------------------------------------------------------------------
--error ER_MIX_HANDLER_ERROR
eval CREATE TABLE t1 (
$column_list
)
......@@ -90,10 +91,7 @@ PARTITION BY HASH(f_int1)
( PARTITION part1 STORAGE ENGINE = $engine,
PARTITION part2
);
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
--source suite/parts/inc/partition_check.inc
DROP TABLE t1;
--error ER_MIX_HANDLER_ERROR
eval CREATE TABLE t1 (
$column_list
)
......@@ -101,10 +99,7 @@ PARTITION BY HASH(f_int1)
( PARTITION part1 ,
PARTITION part2 STORAGE ENGINE = $engine
);
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
--source suite/parts/inc/partition_check.inc
DROP TABLE t1;
--error ER_MIX_HANDLER_ERROR
eval CREATE TABLE t1 (
$column_list
)
......@@ -117,10 +112,8 @@ SUBPARTITION BY HASH(f_int1)
(SUBPARTITION subpart21 STORAGE ENGINE = $engine,
SUBPARTITION subpart22 STORAGE ENGINE = $engine)
);
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
--source suite/parts/inc/partition_check.inc
DROP TABLE t1;
--echo # this should fail with ER_MIX_HANDLER_ERROR
--echo # after fixing Bug#33722
eval CREATE TABLE t1 (
$column_list
)
......@@ -142,6 +135,9 @@ DROP TABLE t1;
--echo # 4 Storage engine assignment after partition name + after name of
--echo # subpartitions belonging to another partition
--echo #------------------------------------------------------------------------
--echo # this should work
--echo # after fixing Bug#33722
--error ER_MIX_HANDLER_ERROR
eval CREATE TABLE t1 (
$column_list
)
......@@ -154,10 +150,13 @@ SUBPARTITION BY HASH(f_int1)
(SUBPARTITION subpart21 STORAGE ENGINE = $engine,
SUBPARTITION subpart22 STORAGE ENGINE = $engine)
);
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
--source suite/parts/inc/partition_check.inc
DROP TABLE t1;
#INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
#SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
#--source suite/parts/inc/partition_check.inc
#DROP TABLE t1;
--echo # this should work
--echo # after fixing Bug#33722
--error ER_MIX_HANDLER_ERROR
eval CREATE TABLE t1 (
$column_list
)
......@@ -170,10 +169,10 @@ SUBPARTITION BY HASH(f_int1)
(SUBPARTITION subpart21,
SUBPARTITION subpart22)
);
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
--source suite/parts/inc/partition_check.inc
DROP TABLE t1;
#INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
#SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
#--source suite/parts/inc/partition_check.inc
#DROP TABLE t1;
#
--echo #------------------------------------------------------------------------
--echo # 5 Precedence of storage engine assignments (if there is any)
......@@ -210,6 +209,9 @@ DROP TABLE t1;
--echo # 6.2 Storage engine assignment after partition name + after
--echo # subpartition name
# in partition part + in sub partition part
--echo # this should work
--echo # after fixing Bug#33722
--error ER_MIX_HANDLER_ERROR
eval CREATE TABLE t1 (
$column_list
)
......@@ -222,10 +224,10 @@ SUBPARTITION BY HASH(f_int1)
(SUBPARTITION subpart21 STORAGE ENGINE = $engine,
SUBPARTITION subpart22 STORAGE ENGINE = $engine)
);
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
--source suite/parts/inc/partition_check.inc
DROP TABLE t1;
#INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
#SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template;
#--source suite/parts/inc/partition_check.inc
#DROP TABLE t1;
--echo #------------------------------------------------------------------------
--echo # 6 Session default engine differs from engine used within create table
......
......@@ -88,6 +88,12 @@ PARTITION BY KEY(a)
drop table t1;
CREATE TABLE t1 (a int not null primary key);
ALTER TABLE t1
ENGINE = NDB
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
drop table t1;
CREATE TABLE t1 (a int not null primary key) ENGINE = NDB;
ALTER TABLE t1
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
drop table t1;
......@@ -143,7 +149,6 @@ t1 CREATE TABLE `t1` (
alter table t1
partition by key(a)
(partition p0 engine=ndb, partition p1);
ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
alter table t1
engine=ndb
partition by key(a)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -75,6 +75,14 @@ drop table t1;
CREATE TABLE t1 (a int not null primary key);
ALTER TABLE t1
ENGINE = NDB
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
drop table t1;
CREATE TABLE t1 (a int not null primary key) ENGINE = NDB;
ALTER TABLE t1
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
......@@ -112,7 +120,9 @@ show create table t1;
alter table t1 remove partitioning;
show create table t1;
--error ER_MIX_HANDLER_ERROR
#--error ER_MIX_HANDLER_ERROR
# after fixing bug#31931 this works
# since it already have ndb on table level
alter table t1
partition by key(a)
(partition p0 engine=ndb, partition p1);
......
......@@ -49,6 +49,7 @@ create table t1 (id int auto_increment, s1 int, primary key (id));
insert into t1 values (null,1);
insert into t1 values (null,6);
-- sorted_result
select * from t1;
alter table t1 partition by range (id) (
......@@ -618,12 +619,14 @@ partition by key (a)
(partition p0, partition p1);
show create table t1;
--error ER_MIX_HANDLER_ERROR
# Since alter, it already have ENGINE=HEAP from before on table level
# -> OK
alter table t1
partition by key(a)
(partition p0, partition p1 engine=heap);
--error ER_MIX_HANDLER_ERROR
# Since alter, it already have ENGINE=HEAP from before on table level
# -> OK
alter table t1
partition by key(a)
(partition p0 engine=heap, partition p1);
......
......@@ -86,6 +86,7 @@ engine = innodb
partition by list (a)
(partition p0 values in (0));
-- error ER_MIX_HANDLER_ERROR
alter table t1 engine = x;
show create table t1;
drop table t1;
......@@ -164,8 +165,10 @@ DROP TABLE t1;
create table t1 (int_column int, char_column char(5))
PARTITION BY RANGE (int_column) subpartition by key (char_column) subpartitions 2
(PARTITION p1 VALUES LESS THAN (5) ENGINE = InnoDB);
alter table t1 PARTITION BY RANGE (int_column)
alter table t1
ENGINE = MyISAM
PARTITION BY RANGE (int_column)
subpartition by key (char_column) subpartitions 2
(PARTITION p1 VALUES LESS THAN (5) ENGINE = myisam);
(PARTITION p1 VALUES LESS THAN (5));
show create table t1;
drop table t1;
This diff is collapsed.
......@@ -269,7 +269,7 @@ class partition_info : public Sql_alloc
bool set_up_defaults_for_partitioning(handler *file, HA_CREATE_INFO *info,
uint start_no);
char *has_unique_names();
static bool check_engine_mix(handlerton **engine_array, uint no_parts);
bool check_engine_mix(handlerton *engine_type, bool default_engine);
bool check_range_constants();
bool check_list_constants();
bool check_partition_info(THD *thd, handlerton **eng_type,
......
......@@ -3863,6 +3863,8 @@ bool mysql_unpack_partition(THD *thd,
if (!part_info->default_engine_type)
part_info->default_engine_type= default_db_type;
DBUG_ASSERT(part_info->default_engine_type == default_db_type);
DBUG_ASSERT(part_info->default_engine_type->db_type != DB_TYPE_UNKNOWN);
DBUG_ASSERT(part_info->default_engine_type != partition_hton);
{
/*
......@@ -3996,56 +3998,6 @@ static int fast_end_partition(THD *thd, ulonglong copied,
}
/*
Check engine mix that it is correct
SYNOPSIS
check_engine_condition()
p_elem Partition element
default_engine Have user specified engine on table level
inout::engine_type Current engine used
inout::first Is it first partition
RETURN VALUE
TRUE Failed check
FALSE Ok
DESCRIPTION
(specified partition handler ) specified table handler
(NDB, NDB) NDB OK
(MYISAM, MYISAM) - OK
(MYISAM, -) - NOT OK
(MYISAM, -) MYISAM OK
(- , MYISAM) - NOT OK
(- , -) MYISAM OK
(-,-) - OK
(NDB, MYISAM) * NOT OK
*/
static bool check_engine_condition(partition_element *p_elem,
bool default_engine,
handlerton **engine_type,
bool *first)
{
DBUG_ENTER("check_engine_condition");
DBUG_PRINT("enter", ("def_eng = %u, first = %u", default_engine, *first));
if (*first && default_engine)
{
*engine_type= p_elem->engine_type;
}
*first= FALSE;
if ((!default_engine &&
(p_elem->engine_type != (*engine_type) &&
p_elem->engine_type)) ||
(default_engine &&
p_elem->engine_type != (*engine_type)))
{
DBUG_RETURN(TRUE);
}
else
{
DBUG_RETURN(FALSE);
}
}
/*
We need to check if engine used by all partitions can handle
partitioning natively.
......@@ -4070,52 +4022,30 @@ static bool check_engine_condition(partition_element *p_elem,
static bool check_native_partitioned(HA_CREATE_INFO *create_info,bool *ret_val,
partition_info *part_info, THD *thd)
{
List_iterator<partition_element> part_it(part_info->partitions);
bool first= TRUE;
bool default_engine;
handlerton *engine_type= create_info->db_type;
bool table_engine_set;
handlerton *engine_type= part_info->default_engine_type;
handlerton *old_engine_type= engine_type;
uint i= 0;
uint no_parts= part_info->partitions.elements;
DBUG_ENTER("check_native_partitioned");
default_engine= (create_info->used_fields & HA_CREATE_USED_ENGINE) ?
FALSE : TRUE;
DBUG_PRINT("info", ("engine_type = %u, default = %u",
ha_legacy_type(engine_type),
default_engine));
if (no_parts)
if (create_info->used_fields & HA_CREATE_USED_ENGINE)
{
do
{
partition_element *part_elem= part_it++;
if (part_info->is_sub_partitioned() &&
part_elem->subpartitions.elements)
table_engine_set= TRUE;
engine_type= create_info->db_type;
}
else
{
uint no_subparts= part_elem->subpartitions.elements;
uint j= 0;
List_iterator<partition_element> sub_it(part_elem->subpartitions);
do
table_engine_set= FALSE;
if (thd->lex->sql_command != SQLCOM_CREATE_TABLE)
{
partition_element *sub_elem= sub_it++;
if (check_engine_condition(sub_elem, default_engine,
&engine_type, &first))
goto error;
} while (++j < no_subparts);
/*
In case of subpartitioning and defaults we allow that only
subparts have specified engines, as long as the parts haven't
specified the wrong engine it's ok.
*/
if (check_engine_condition(part_elem, FALSE,
&engine_type, &first))
goto error;
table_engine_set= TRUE;
DBUG_ASSERT(engine_type && engine_type != partition_hton);
}
else if (check_engine_condition(part_elem, default_engine,
&engine_type, &first))
goto error;
} while (++i < no_parts);
}
DBUG_PRINT("info", ("engine_type = %u, table_engine_set = %u",
ha_legacy_type(engine_type),
table_engine_set));
if (part_info->check_engine_mix(engine_type, table_engine_set))
goto error;
/*
All engines are of the same type. Check if this engine supports
......@@ -4212,7 +4142,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
DBUG_RETURN(TRUE);
}
if (alter_info->flags == ALTER_TABLE_REORG)
if (alter_info->flags & ALTER_TABLE_REORG)
{
uint new_part_no, curr_part_no;
if (tab_part_info->part_type != HASH_PARTITION ||
......@@ -4538,7 +4468,7 @@ that are reorganised.
tab_part_info->is_auto_partitioned= FALSE;
}
}
else if (alter_info->flags == ALTER_DROP_PARTITION)
else if (alter_info->flags & ALTER_DROP_PARTITION)
{
/*
Drop a partition from a range partition and list partitioning is
......@@ -4742,7 +4672,7 @@ state of p1.
tab_part_info->is_auto_partitioned= FALSE;
}
}
else if (alter_info->flags == ALTER_REORGANIZE_PARTITION)
else if (alter_info->flags & ALTER_REORGANIZE_PARTITION)
{
/*
Reorganise partitions takes a number of partitions that are next
......@@ -4923,8 +4853,8 @@ the generated partition syntax in a correct manner.
}
*partition_changed= TRUE;
thd->work_part_info= tab_part_info;
if (alter_info->flags == ALTER_ADD_PARTITION ||
alter_info->flags == ALTER_REORGANIZE_PARTITION)
if (alter_info->flags & ALTER_ADD_PARTITION ||
alter_info->flags & ALTER_REORGANIZE_PARTITION)
{
if (tab_part_info->use_default_subpartitions &&
!alt_part_info->use_default_subpartitions)
......@@ -5051,13 +4981,21 @@ the generated partition syntax in a correct manner.
DBUG_PRINT("info", ("partition changed"));
*partition_changed= TRUE;
}
if (create_info->db_type == partition_hton)
/*
Set up partition default_engine_type either from the create_info
or from the previus table
*/
if (create_info->used_fields & HA_CREATE_USED_ENGINE)
part_info->default_engine_type= create_info->db_type;
else
{
if (!part_info->default_engine_type)
if (table->part_info)
part_info->default_engine_type= table->part_info->default_engine_type;
}
else
part_info->default_engine_type= create_info->db_type;
}
DBUG_ASSERT(part_info->default_engine_type &&
part_info->default_engine_type != partition_hton);
if (check_native_partitioned(create_info, &is_native_partitioned,
part_info, thd))
{
......@@ -6164,7 +6102,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
goto err;
}
}
else if (alter_info->flags == ALTER_DROP_PARTITION)
else if (alter_info->flags & ALTER_DROP_PARTITION)
{
/*
Now after all checks and setting state on dropped partitions we can
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment