Skip to content

Commit 670775d

Browse files
author
Rahul Malik
committed
Merge branch 'mysql-8.0' into mysql-trunk
2 parents 5cbf4dd + 1796d62 commit 670775d

File tree

8 files changed

+226
-4
lines changed

8 files changed

+226
-4
lines changed

mysql-test/r/partition_exchange.result

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,3 +2061,70 @@ add column after exchange partition
20612061
ALTER TABLE t2 ADD COLUMN j INT,ALGORITHM=INSTANT;
20622062
ALTER TABLE t2 ADD COLUMN k INT,ALGORITHM=COPY;
20632063
DROP TABLE t1,t2;
2064+
#
2065+
Bug#28687608 exchange partition with different row_format
2066+
#
2067+
SET @orig_default_row_format = @@global.innodb_default_row_format;
2068+
SET GLOBAL innodb_default_row_format=COMPACT;
2069+
CREATE TABLE t1 (
2070+
col1 INT UNSIGNED,
2071+
col2 DATETIME
2072+
)
2073+
ENGINE=INNODB
2074+
PARTITION BY RANGE COLUMNS(col2)
2075+
(
2076+
PARTITION p0 VALUES LESS THAN ('1960-01-01'),
2077+
PARTITION p1 VALUES LESS THAN ('1980-01-01')
2078+
);
2079+
INSERT INTO t1 VALUES ('1','1958-02-17 06:25:34');
2080+
INSERT INTO t1 VALUES ('2','1962-11-23 11:06:06');
2081+
SET GLOBAL innodb_default_row_format=DYNAMIC;
2082+
ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES LESS THAN ('2000-01-01'));
2083+
INSERT INTO t1 VALUES ('3','1999-10-13 05:28:46'), ('4', '1996-09-26 20:00:00');
2084+
SELECT NAME,ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_TABLES
2085+
WHERE NAME LIKE '%t1%' ORDER BY TABLE_ID;
2086+
NAME ROW_FORMAT
2087+
test/t1#P#p0 Compact
2088+
test/t1#P#p1 Compact
2089+
test/t1#P#p2 Dynamic
2090+
CREATE TABLE t2 LIKE t1;
2091+
ALTER TABLE t2 REMOVE PARTITIONING;
2092+
exchange compact partition with dynamic;
2093+
ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
2094+
ERROR HY000: Non matching attribute 'ROW_FORMAT' between partition and table
2095+
ALTER TABLE t1 EXCHANGE PARTITION p2 WITH TABLE t2;
2096+
DROP TABLE t1,t2;
2097+
SET GLOBAL innodb_default_row_format=COMPACT;
2098+
CREATE TABLE t1 (a INT,
2099+
b VARCHAR(55),
2100+
PRIMARY KEY (a))
2101+
PARTITION BY RANGE (a)
2102+
SUBPARTITION BY HASH(a)
2103+
(PARTITION p0 VALUES LESS THAN (100)
2104+
(SUBPARTITION sp0,
2105+
SUBPARTITION sp1),
2106+
PARTITION p1 VALUES LESS THAN (200)
2107+
(SUBPARTITION sp2,
2108+
SUBPARTITION sp3));
2109+
SET GLOBAL innodb_default_row_format=DYNAMIC;
2110+
ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES LESS THAN (300)
2111+
(SUBPARTITION sp4,
2112+
SUBPARTITION sp5));
2113+
INSERT INTO t1(b,a) VALUES('first',40),('second',91),('third',140),
2114+
('forth',191);
2115+
SELECT NAME,ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_TABLES
2116+
WHERE NAME LIKE '%t1%' ORDER BY TABLE_ID;
2117+
NAME ROW_FORMAT
2118+
test/t1#P#p0#SP#sp0 Compact
2119+
test/t1#P#p0#SP#sp1 Compact
2120+
test/t1#P#p1#SP#sp2 Compact
2121+
test/t1#P#p1#SP#sp3 Compact
2122+
test/t1#P#p2#SP#sp4 Dynamic
2123+
test/t1#P#p2#SP#sp5 Dynamic
2124+
CREATE TABLE t2 like t1;
2125+
ALTER TABLE t2 REMOVE PARTITIONING;
2126+
ALTER TABLE t1 EXCHANGE PARTITION sp2 WITH TABLE t2;
2127+
ERROR HY000: Non matching attribute 'ROW_FORMAT' between partition and table
2128+
ALTER TABLE t1 EXCHANGE PARTITION sp4 WITH TABLE t2;
2129+
DROP TABLE t1,t2;
2130+
SET @@global.innodb_default_row_format=@orig_default_row_format;

mysql-test/t/partition_exchange.test

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,3 +997,80 @@ ALTER TABLE t2 ADD COLUMN k INT,ALGORITHM=COPY;
997997

998998
DROP TABLE t1,t2;
999999

1000+
--echo #
1001+
--echo Bug#28687608 exchange partition with different row_format
1002+
--echo #
1003+
1004+
SET @orig_default_row_format = @@global.innodb_default_row_format;
1005+
1006+
SET GLOBAL innodb_default_row_format=COMPACT;
1007+
CREATE TABLE t1 (
1008+
col1 INT UNSIGNED,
1009+
col2 DATETIME
1010+
)
1011+
ENGINE=INNODB
1012+
PARTITION BY RANGE COLUMNS(col2)
1013+
(
1014+
PARTITION p0 VALUES LESS THAN ('1960-01-01'),
1015+
PARTITION p1 VALUES LESS THAN ('1980-01-01')
1016+
);
1017+
1018+
INSERT INTO t1 VALUES ('1','1958-02-17 06:25:34');
1019+
INSERT INTO t1 VALUES ('2','1962-11-23 11:06:06');
1020+
1021+
SET GLOBAL innodb_default_row_format=DYNAMIC;
1022+
1023+
ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES LESS THAN ('2000-01-01'));
1024+
1025+
INSERT INTO t1 VALUES ('3','1999-10-13 05:28:46'), ('4', '1996-09-26 20:00:00');
1026+
1027+
--replace_result #p# #p# #sp# #sp#
1028+
SELECT NAME,ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_TABLES
1029+
WHERE NAME LIKE '%t1%' ORDER BY TABLE_ID;
1030+
1031+
CREATE TABLE t2 LIKE t1;
1032+
ALTER TABLE t2 REMOVE PARTITIONING;
1033+
1034+
--echo exchange compact partition with dynamic;
1035+
1036+
--error ER_PARTITION_EXCHANGE_DIFFERENT_OPTION
1037+
ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
1038+
1039+
ALTER TABLE t1 EXCHANGE PARTITION p2 WITH TABLE t2;
1040+
DROP TABLE t1,t2;
1041+
1042+
SET GLOBAL innodb_default_row_format=COMPACT;
1043+
CREATE TABLE t1 (a INT,
1044+
b VARCHAR(55),
1045+
PRIMARY KEY (a))
1046+
PARTITION BY RANGE (a)
1047+
SUBPARTITION BY HASH(a)
1048+
(PARTITION p0 VALUES LESS THAN (100)
1049+
(SUBPARTITION sp0,
1050+
SUBPARTITION sp1),
1051+
PARTITION p1 VALUES LESS THAN (200)
1052+
(SUBPARTITION sp2,
1053+
SUBPARTITION sp3));
1054+
1055+
SET GLOBAL innodb_default_row_format=DYNAMIC;
1056+
1057+
ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES LESS THAN (300)
1058+
(SUBPARTITION sp4,
1059+
SUBPARTITION sp5));
1060+
1061+
INSERT INTO t1(b,a) VALUES('first',40),('second',91),('third',140),
1062+
('forth',191);
1063+
1064+
--replace_result #p# #p# #sp# #sp#
1065+
SELECT NAME,ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_TABLES
1066+
WHERE NAME LIKE '%t1%' ORDER BY TABLE_ID;
1067+
1068+
CREATE TABLE t2 like t1;
1069+
ALTER TABLE t2 REMOVE PARTITIONING;
1070+
1071+
--error ER_PARTITION_EXCHANGE_DIFFERENT_OPTION
1072+
ALTER TABLE t1 EXCHANGE PARTITION sp2 WITH TABLE t2;
1073+
1074+
ALTER TABLE t1 EXCHANGE PARTITION sp4 WITH TABLE t2;
1075+
DROP TABLE t1,t2;
1076+
SET @@global.innodb_default_row_format=@orig_default_row_format;

sql/ha_ndbcluster.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16420,6 +16420,15 @@ static MYSQL_SYSVAR_ENUM(
1642016420
&distribution_typelib /* typelib */
1642116421
);
1642216422

16423+
/* Get partition row type
16424+
@param[in] table partition_table
16425+
@param[in] part_id Id of partition for which row type to be retrieved
16426+
@return Partition row type. */
16427+
enum row_type ha_ndbcluster::get_partition_row_type(
16428+
const dd::Table *table MY_ATTRIBUTE((unused)),
16429+
uint part_id MY_ATTRIBUTE((unused))) {
16430+
return table_share->real_row_type;
16431+
}
1642316432

1642416433
void ha_ndbcluster::set_auto_partitions(partition_info *part_info)
1642516434
{

sql/ha_ndbcluster.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,13 @@ class ha_ndbcluster: public handler, public Partition_handler
204204

205205
void append_create_info(String *packet) override;
206206

207+
/* Get partition row type
208+
@param[in] table partition table
209+
@param[in] part_id Id of partition for which row type to be retrieved
210+
@return Partition row type. */
211+
enum row_type get_partition_row_type(const dd::Table *table,
212+
uint part_id) override;
213+
207214
private:
208215
bool choose_mrr_impl(uint keyno, uint n_ranges, ha_rows n_rows,
209216
uint *bufsz, uint *flags, Cost_estimate *);

sql/partitioning/partition_handler.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,15 @@ class Partition_handler {
310310
return 0;
311311
}
312312

313+
/**
314+
Get partition row type from SE
315+
@param table partition table
316+
@param part_id Id of partition for which row type to be retrieved
317+
@return Partition row type.
318+
*/
319+
virtual enum row_type get_partition_row_type(const dd::Table *table,
320+
uint part_id) = 0;
321+
313322
private:
314323
/**
315324
Truncate partition.

sql/sql_partition_admin.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -174,10 +174,12 @@ static bool check_exchange_partition(TABLE *table, TABLE *part_table) {
174174
@param table Non partitioned table.
175175
@param part_table Partitioned table.
176176
@param part_elem Partition element to use for partition specific compare.
177+
@param part_id Id of specific partition
177178
*/
178179
static bool compare_table_with_partition(THD *thd, TABLE *table,
179180
TABLE *part_table,
180-
partition_element *part_elem) {
181+
partition_element *part_elem,
182+
uint part_id) {
181183
HA_CREATE_INFO table_create_info, part_create_info;
182184
Alter_info part_alter_info(thd->mem_root);
183185
Alter_table_ctx part_alter_ctx; // Not used
@@ -222,7 +224,12 @@ static bool compare_table_with_partition(THD *thd, TABLE *table,
222224
table_create_info.auto_increment_value;
223225

224226
/* Check compatible row_types and set create_info accordingly. */
225-
if (part_table->s->real_row_type != table->s->real_row_type) {
227+
Partition_handler *part_handler;
228+
part_handler = part_table->file->get_partition_handler();
229+
auto part_row_type =
230+
part_handler->get_partition_row_type(part_table_def, part_id);
231+
232+
if (part_row_type != table->s->real_row_type) {
226233
my_error(ER_PARTITION_EXCHANGE_DIFFERENT_OPTION, MYF(0), "ROW_FORMAT");
227234
DBUG_RETURN(true);
228235
}
@@ -384,7 +391,8 @@ bool Sql_cmd_alter_table_exchange_partition::exchange_partition(
384391
DBUG_RETURN(true);
385392
}
386393

387-
if (compare_table_with_partition(thd, swap_table, part_table, part_elem))
394+
if (compare_table_with_partition(thd, swap_table, part_table, part_elem,
395+
swap_part_id))
388396
DBUG_RETURN(true);
389397

390398
/* Table and partition has same structure/options */

storage/innobase/handler/ha_innopart.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2913,6 +2913,44 @@ int ha_innopart::extra(enum ha_extra_function operation) {
29132913
return (ha_innobase::extra(operation));
29142914
}
29152915

2916+
/* Get partition row type
2917+
@param[in] table partition_table
2918+
@param[in] part_id Id of partition for which row type to be retrieved
2919+
@return Partition row type. */
2920+
enum row_type ha_innopart::get_partition_row_type(const dd::Table *table,
2921+
uint part_id) {
2922+
dd::Table::enum_row_format format;
2923+
row_type real_type = ROW_TYPE_NOT_USED;
2924+
2925+
auto dd_table = table->leaf_partitions().at(part_id);
2926+
const dd::Properties &part_p = dd_table->se_private_data();
2927+
if (part_p.exists(dd_partition_key_strings[DD_PARTITION_ROW_FORMAT])) {
2928+
part_p.get(dd_partition_key_strings[DD_PARTITION_ROW_FORMAT],
2929+
reinterpret_cast<uint32 *>(&format));
2930+
switch (format) {
2931+
case dd::Table::RF_REDUNDANT:
2932+
real_type = ROW_TYPE_REDUNDANT;
2933+
break;
2934+
case dd::Table::RF_COMPACT:
2935+
real_type = ROW_TYPE_COMPACT;
2936+
break;
2937+
case dd::Table::RF_COMPRESSED:
2938+
real_type = ROW_TYPE_COMPRESSED;
2939+
break;
2940+
case dd::Table::RF_DYNAMIC:
2941+
real_type = ROW_TYPE_DYNAMIC;
2942+
break;
2943+
default:
2944+
ut_a(0);
2945+
}
2946+
}
2947+
if (real_type == ROW_TYPE_NOT_USED) {
2948+
return table_share->real_row_type;
2949+
} else {
2950+
return real_type;
2951+
}
2952+
};
2953+
29162954
int ha_innopart::truncate_impl(const char *name, TABLE *form,
29172955
dd::Table *table_def) {
29182956
DBUG_ENTER("ha_innopart::truncate_impl");

storage/innobase/handler/ha_innopart.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,13 @@ class ha_innopart : public ha_innobase,
516516
ulonglong nb_desired_values, ulonglong *first_value,
517517
ulonglong *nb_reserved_values) override;
518518

519+
/* Get partition row type
520+
@param[in] table partition table
521+
@param[in] part_id Id of partition for which row type to be retrieved
522+
@return Partition row type. */
523+
enum row_type get_partition_row_type(const dd::Table *table,
524+
uint part_id) override;
525+
519526
int cmp_ref(const uchar *ref1, const uchar *ref2) const override;
520527

521528
int read_range_first(const key_range *start_key, const key_range *end_key,

0 commit comments

Comments
 (0)