diff options
-rw-r--r-- | mysql-test/r/ndb_partition_key.result | 63 | ||||
-rw-r--r-- | mysql-test/r/partition.result | 129 | ||||
-rw-r--r-- | mysql-test/t/ndb_partition_key.test | 46 | ||||
-rw-r--r-- | mysql-test/t/partition.test | 90 | ||||
-rw-r--r-- | sql/lex.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_partition.cc | 147 | ||||
-rw-r--r-- | sql/sql_table.cc | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 14 |
9 files changed, 453 insertions, 40 deletions
diff --git a/mysql-test/r/ndb_partition_key.result b/mysql-test/r/ndb_partition_key.result index 451b3522bc7..ef3f9e05890 100644 --- a/mysql-test/r/ndb_partition_key.result +++ b/mysql-test/r/ndb_partition_key.result @@ -89,3 +89,66 @@ ALTER TABLE t1 PARTITION BY KEY(a) (PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB); drop table t1; +create table t1 (a int) +engine=ndb +partition by key(a) +(partition p0, partition p1); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster) +alter table t1 engine=heap; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY) +alter table t1 engine=ndb; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster) +alter table t1 engine=heap remove partitioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +alter table t1 engine=ndb +partition by key(a) +(partition p0, partition p1 engine = ndb); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster) +alter table t1 +partition by key (a) +(partition p0 engine=ndb, partition p1 engine=ndb); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster) +alter table t1 remove partitioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY () +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) +(partition p0 engine=ndb, partition p1 engine = ndb); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster) +drop table t1; diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index af600c62aeb..adb512c8a59 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -315,6 +315,135 @@ drop table t1; create table t1 (s1 int, unique (s1)) partition by list (s1) (partition x1 VALUES in (10), partition x2 values in (20)); alter table t1 add partition (partition x3 values in (30)); drop table t1; +create table t1 (a int) +partition by key(a) +partitions 2 +(partition p0 engine=myisam, partition p1 engine=myisam); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM) +alter table t1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM) +alter table t1 engine=myisam; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM) +alter table t1 engine=heap; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY) +alter table t1 remove partitioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int) +engine=myisam +partition by key(a) +partitions 2 +(partition p0 engine=myisam, partition p1 engine=myisam); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM) +alter table t1 add column b int remove partitioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 +engine=myisam +partition by key(a) +(partition p0 engine=myisam, partition p1); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM) +alter table t1 +engine=heap +partition by key(a) +(partition p0, partition p1 engine=heap); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY) +alter table t1 engine=myisam, add column c int remove partitioning; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL, + `c` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 +engine=heap +partition by key (a) +(partition p0, partition p1); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL, + `c` int(11) default NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY) +alter table t1 +partition by key (a) +(partition p0, partition p1); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL, + `c` int(11) default NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY) +alter table t1 +engine=heap +partition by key (a) +(partition p0, partition p1); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` int(11) default NULL, + `c` int(11) default NULL +) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY) +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) +(partition p0 engine=heap, partition p1 engine=myisam); +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 engine=myisam); +ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL +drop table t1; CREATE TABLE t1 ( f_int1 INTEGER, f_int2 INTEGER, f_char1 CHAR(10), f_char2 CHAR(10), f_charbig VARCHAR(1000) diff --git a/mysql-test/t/ndb_partition_key.test b/mysql-test/t/ndb_partition_key.test index 7f6120fe094..25afa65cbaf 100644 --- a/mysql-test/t/ndb_partition_key.test +++ b/mysql-test/t/ndb_partition_key.test @@ -79,3 +79,49 @@ PARTITION BY KEY(a) (PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB); drop table t1; + +# +# Bug #17754 Improper handling of removal of partitioning in ALTER TABLE +# Also added a number of general test cases in the same area +# +create table t1 (a int) +engine=ndb +partition by key(a) +(partition p0, partition p1); +show create table t1; + +alter table t1 engine=heap; +show create table t1; + +alter table t1 engine=ndb; +show create table t1; + +alter table t1 engine=heap remove partitioning; +show create table t1; + +alter table t1 engine=ndb +partition by key(a) +(partition p0, partition p1 engine = ndb); +show create table t1; + +alter table t1 +partition by key (a) +(partition p0 engine=ndb, partition p1 engine=ndb); +show create table t1; + +alter table t1 remove partitioning; +show create table t1; + +--error ER_MIX_HANDLER_ERROR +alter table t1 +partition by key(a) +(partition p0 engine=ndb, partition p1); + +alter table t1 +engine=ndb +partition by key(a) +(partition p0 engine=ndb, partition p1 engine = ndb); +show create table t1; + +drop table t1; + diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 47c25652ae9..f0004146599 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -409,6 +409,96 @@ alter table t1 add partition (partition x3 values in (30)); drop table t1; # +# Bug #17754 Change to explicit removal of partitioning scheme +# Also added a number of tests to ensure that proper engine is +# choosen in all kinds of scenarios. +# + +create table t1 (a int) +partition by key(a) +partitions 2 +(partition p0 engine=myisam, partition p1 engine=myisam); +show create table t1; + +alter table t1; +show create table t1; + +alter table t1 engine=myisam; +show create table t1; + +alter table t1 engine=heap; +show create table t1; + +alter table t1 remove partitioning; +show create table t1; + +drop table t1; + +create table t1 (a int) +engine=myisam +partition by key(a) +partitions 2 +(partition p0 engine=myisam, partition p1 engine=myisam); +show create table t1; + +alter table t1 add column b int remove partitioning; +show create table t1; + +alter table t1 +engine=myisam +partition by key(a) +(partition p0 engine=myisam, partition p1); +show create table t1; + +alter table t1 +engine=heap +partition by key(a) +(partition p0, partition p1 engine=heap); +show create table t1; + +alter table t1 engine=myisam, add column c int remove partitioning; +show create table t1; + +alter table t1 +engine=heap +partition by key (a) +(partition p0, partition p1); +show create table t1; + +alter table t1 +partition by key (a) +(partition p0, partition p1); +show create table t1; + +alter table t1 +engine=heap +partition by key (a) +(partition p0, partition p1); +show create table t1; + +--error ER_MIX_HANDLER_ERROR +alter table t1 +partition by key(a) +(partition p0, partition p1 engine=heap); + +--error ER_MIX_HANDLER_ERROR +alter table t1 +partition by key(a) +(partition p0 engine=heap, partition p1); + +--error ER_MIX_HANDLER_ERROR +alter table t1 +engine=heap +partition by key (a) +(partition p0 engine=heap, partition p1 engine=myisam); + +--error ER_MIX_HANDLER_ERROR +alter table t1 +partition by key (a) +(partition p0 engine=heap, partition p1 engine=myisam); + +drop table t1; + # Bug #17432: Partition functions containing NULL values should return # LONGLONG_MIN # diff --git a/sql/lex.h b/sql/lex.h index 574d7036c8a..9fd8cae1325 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -391,6 +391,7 @@ static SYMBOL symbols[] = { { "PARSER", SYM(PARSER_SYM)}, { "PARTIAL", SYM(PARTIAL)}, { "PARTITION", SYM(PARTITION_SYM)}, + { "PARTITIONING", SYM(PARTITIONING_SYM)}, { "PARTITIONS", SYM(PARTITIONS_SYM)}, { "PASSWORD", SYM(PASSWORD)}, { "PHASE", SYM(PHASE_SYM)}, @@ -428,6 +429,7 @@ static SYMBOL symbols[] = { { "RELAY_THREAD", SYM(RELAY_THREAD)}, { "RELEASE", SYM(RELEASE_SYM)}, { "RELOAD", SYM(RELOAD)}, + { "REMOVE", SYM(REMOVE_SYM)}, { "RENAME", SYM(RENAME)}, { "REORGANIZE", SYM(REORGANIZE_SYM)}, { "REPAIR", SYM(REPAIR)}, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 08167f8b6d2..5ae82812578 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -696,6 +696,7 @@ typedef class st_select_lex SELECT_LEX; #define ALTER_ANALYZE_PARTITION (1L << 22) #define ALTER_CHECK_PARTITION (1L << 23) #define ALTER_REPAIR_PARTITION (1L << 24) +#define ALTER_REMOVE_PARTITIONING (1L << 25) typedef struct st_alter_info { diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 728efb82b9f..15ba95feae0 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -3764,6 +3764,42 @@ end: /* + Set engine type on all partition element objects + SYNOPSIS + set_engine_all_partitions() + part_info Partition info + engine_type Handlerton reference of engine + RETURN VALUES + NONE +*/ + +static +void +set_engine_all_partitions(partition_info *part_info, + handlerton *engine_type) +{ + uint i= 0; + List_iterator<partition_element> part_it(part_info->partitions); + do + { + partition_element *part_elem= part_it++; + + part_elem->engine_type= engine_type; + if (part_info->is_sub_partitioned()) + { + List_iterator<partition_element> sub_it(part_elem->subpartitions); + uint j= 0; + + do + { + partition_element *sub_elem= sub_it++; + + sub_elem->engine_type= engine_type; + } while (++j < part_info->no_subparts); + } + } while (++i < part_info->no_parts); +} +/* SYNOPSIS fast_alter_partition_error_handler() lpt Container for parameters @@ -3865,17 +3901,34 @@ static bool check_engine_condition(partition_element *p_elem, handlerton **engine_type, bool *first) { + DBUG_ENTER("check_engine_condition"); + + DBUG_PRINT("enter", ("def_eng = %u, first = %u", default_engine, *first)); + if (*engine_type) + DBUG_PRINT("info", ("engine_type = %s", (*engine_type)->name)); + else + DBUG_PRINT("info", ("engine_type = NULL")); if (*first && default_engine) + { *engine_type= p_elem->engine_type; + if (*engine_type) + DBUG_PRINT("info", ("engine_type changed to = %s", (*engine_type)->name)); + else + DBUG_PRINT("info", ("engine_type changed to = NULL")); + } *first= FALSE; if ((!default_engine && - (p_elem->engine_type != *engine_type && - !p_elem->engine_type)) || + (p_elem->engine_type != (*engine_type) && + p_elem->engine_type)) || (default_engine && - p_elem->engine_type != *engine_type)) - return TRUE; + p_elem->engine_type != (*engine_type))) + { + DBUG_RETURN(TRUE); + } else - return FALSE; + { + DBUG_RETURN(FALSE); + } } /* @@ -3912,8 +3965,8 @@ static bool check_native_partitioned(HA_CREATE_INFO *create_info,bool *ret_val, uint no_parts= part_info->partitions.elements; DBUG_ENTER("check_native_partitioned"); - default_engine= (create_info->used_fields | HA_CREATE_USED_ENGINE) ? - TRUE : FALSE; + 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)); @@ -3972,6 +4025,7 @@ error: Mixed engines not yet supported but when supported it will need the partition handler */ + my_error(ER_MIX_HANDLER_ERROR, MYF(0)); *ret_val= FALSE; DBUG_RETURN(TRUE); } @@ -4713,7 +4767,7 @@ the generated partition syntax in a correct manner. Case IIa: There was a partitioning before and there is no new one defined. - Also the user has not specified an explicit engine to use. + Also the user has not specified to remove partitioning explicitly. We use the old partitioning also for the new table. We do this by assigning the partition_info from the table loaded in @@ -4722,12 +4776,11 @@ the generated partition syntax in a correct manner. Case IIb: There was a partitioning before and there is no new one defined. - The user has specified an explicit engine to use. + The user has specified explicitly to remove partitioning - Since the user has specified an explicit engine to use we override - the old partitioning info and create a new table using the specified - engine. This is the reason for the extra check if old and new engine - is equal. + Since the user has specified explicitly to remove partitioning + we override the old partitioning info and create a new table using + the specified engine. In this case the partition also is changed. Case III: @@ -4750,12 +4803,41 @@ the generated partition syntax in a correct manner. */ if (table->part_info) { - if (!thd->lex->part_info && - create_info->db_type == old_db_type) + if (thd->lex->alter_info.flags & ALTER_REMOVE_PARTITIONING) + { + DBUG_PRINT("info", ("Remove partitioning")); + if (!(thd->lex->create_info.used_fields & HA_CREATE_USED_ENGINE)) + { + DBUG_PRINT("info", ("No explicit engine used")); + create_info->db_type= table->part_info->default_engine_type; + } + DBUG_PRINT("info", ("New engine type = %s", + create_info->db_type->name)); + thd->lex->part_info= NULL; + *partition_changed= TRUE; + } + else if (!thd->lex->part_info) + { + /* + Retain partitioning but possibly with a new storage engine + beneath. + */ thd->lex->part_info= table->part_info; + if (thd->lex->create_info.used_fields & HA_CREATE_USED_ENGINE && + create_info->db_type != table->part_info->default_engine_type) + { + /* + Make sure change of engine happens to all partitions. + */ + set_engine_all_partitions(thd->lex->part_info, create_info->db_type); + *partition_changed= TRUE; + } + } } if (thd->lex->part_info) { + partition_info *part_info= thd->lex->part_info; + bool is_native_partitioned= FALSE; /* Need to cater for engine types that can handle partition without using the partition handler. @@ -4763,35 +4845,20 @@ the generated partition syntax in a correct manner. if (thd->lex->part_info != table->part_info) *partition_changed= TRUE; if (create_info->db_type == &partition_hton) + part_info->default_engine_type= table->part_info->default_engine_type; + else + part_info->default_engine_type= create_info->db_type; + if (check_native_partitioned(create_info, &is_native_partitioned, + part_info, thd)) { - if (table->part_info) - { - thd->lex->part_info->default_engine_type= - table->part_info->default_engine_type; - } - else - { - thd->lex->part_info->default_engine_type= - ha_checktype(thd, DB_TYPE_DEFAULT, FALSE, FALSE); - } + DBUG_RETURN(TRUE); } - else + if (!is_native_partitioned) { - bool is_native_partitioned= FALSE; - partition_info *part_info= thd->lex->part_info; - part_info->default_engine_type= create_info->db_type; - if (check_native_partitioned(create_info, &is_native_partitioned, - part_info, thd)) - { - DBUG_RETURN(TRUE); - } - if (!is_native_partitioned) - { - DBUG_ASSERT(create_info->db_type != &default_hton); - create_info->db_type= &partition_hton; - } + DBUG_ASSERT(create_info->db_type != &default_hton); + create_info->db_type= &partition_hton; } - DBUG_PRINT("info", ("default_db_type = %s", + DBUG_PRINT("info", ("default_engine_type = %s", thd->lex->part_info->default_engine_type->name)); } } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 757321b5ccf..a9fdefa0772 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2053,6 +2053,7 @@ bool mysql_create_table_internal(THD *thd, DBUG_RETURN(TRUE); } file->set_auto_partitions(part_info); + part_info->default_engine_type= create_info->db_type; } if (part_info) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0cdf859c7a1..b14d1976881 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -493,6 +493,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token PARSER_SYM %token PARTIAL %token PARTITION_SYM +%token PARTITIONING_SYM %token PARTITIONS_SYM %token PASSWORD %token PARAM_MARKER @@ -535,6 +536,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token RELAY_THREAD %token RELEASE_SYM %token RELOAD +%token REMOVE_SYM %token RENAME %token REORGANIZE_SYM %token REPAIR @@ -4930,6 +4932,9 @@ alter_commands: | IMPORT TABLESPACE { Lex->alter_info.tablespace_op= IMPORT_TABLESPACE; } | alter_list opt_partitioning + | alter_list + remove_partitioning + | remove_partitioning | partitioning /* This part was added for release 5.1 by Mikael Ronström. @@ -4995,6 +5000,13 @@ alter_commands: | reorg_partition_rule ; +remove_partitioning: + REMOVE_SYM PARTITIONING_SYM + { + Lex->alter_info.flags|= ALTER_REMOVE_PARTITIONING; + } + ; + all_or_alt_part_name_list: | ALL { @@ -9346,6 +9358,7 @@ keyword: | PARTITION_SYM {} | PLUGIN_SYM {} | PREPARE_SYM {} + | REMOVE_SYM {} | REPAIR {} | RESET_SYM {} | RESTORE_SYM {} @@ -9520,6 +9533,7 @@ keyword_sp: | ONE_SYM {} | PACK_KEYS_SYM {} | PARTIAL {} + | PARTITIONING_SYM {} | PARTITIONS_SYM {} | PASSWORD {} | PHASE_SYM {} |