Skip to content

Commit 1200228

Browse files
author
Mattias Jonsson
committed
Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
Problem was that it tried to run partitioning function calls when opening a partitioned table, when it was explicitly disabled. Solution is to check if the partitioning plugin is ready to use before using any partitioning specific calls.
1 parent c924592 commit 1200228

9 files changed

+261
-3
lines changed
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Variable_name Value
2+
have_partitioning DISABLED

mysql-test/r/not_partition.result

+45
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
DROP TABLE IF EXISTS t1;
2+
FLUSH TABLES;
3+
SELECT * FROM t1;
4+
ERROR 42000: Unknown table engine 'partition'
5+
TRUNCATE TABLE t1;
6+
ERROR 42000: Unknown table engine 'partition'
7+
ANALYZE TABLE t1;
8+
Table Op Msg_type Msg_text
9+
test.t1 analyze Error Unknown table engine 'partition'
10+
test.t1 analyze error Corrupt
11+
CHECK TABLE t1;
12+
Table Op Msg_type Msg_text
13+
test.t1 check Error Unknown table engine 'partition'
14+
test.t1 check error Corrupt
15+
OPTIMIZE TABLE t1;
16+
Table Op Msg_type Msg_text
17+
test.t1 optimize Error Unknown table engine 'partition'
18+
test.t1 optimize error Corrupt
19+
REPAIR TABLE t1;
20+
Table Op Msg_type Msg_text
21+
test.t1 repair Error Unknown table engine 'partition'
22+
test.t1 repair error Corrupt
23+
ALTER TABLE t1 REPAIR PARTITION ALL;
24+
Table Op Msg_type Msg_text
25+
test.t1 repair Error Unknown table engine 'partition'
26+
test.t1 repair error Corrupt
27+
ALTER TABLE t1 CHECK PARTITION ALL;
28+
Table Op Msg_type Msg_text
29+
test.t1 check Error Unknown table engine 'partition'
30+
test.t1 check error Corrupt
31+
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
32+
Table Op Msg_type Msg_text
33+
test.t1 optimize Error Unknown table engine 'partition'
34+
test.t1 optimize error Corrupt
35+
ALTER TABLE t1 ANALYZE PARTITION ALL;
36+
Table Op Msg_type Msg_text
37+
test.t1 analyze Error Unknown table engine 'partition'
38+
test.t1 analyze error Corrupt
39+
ALTER TABLE t1 REBUILD PARTITION ALL;
40+
ERROR 42000: Unknown table engine 'partition'
41+
ALTER TABLE t1 ENGINE Memory;
42+
ERROR 42000: Unknown table engine 'partition'
43+
ALTER TABLE t1 ADD (new INT);
44+
ERROR 42000: Unknown table engine 'partition'
45+
DROP TABLE t1;
146
CREATE TABLE t1 (
247
firstname VARCHAR(25) NOT NULL,
348
lastname VARCHAR(25) NOT NULL,
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
DROP TABLE IF EXISTS t1;
2+
FLUSH TABLES;
3+
SELECT * FROM t1;
4+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
5+
TRUNCATE TABLE t1;
6+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
7+
ANALYZE TABLE t1;
8+
Table Op Msg_type Msg_text
9+
test.t1 analyze Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
10+
test.t1 analyze error Corrupt
11+
CHECK TABLE t1;
12+
Table Op Msg_type Msg_text
13+
test.t1 check Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
14+
test.t1 check error Corrupt
15+
OPTIMIZE TABLE t1;
16+
Table Op Msg_type Msg_text
17+
test.t1 optimize Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
18+
test.t1 optimize error Corrupt
19+
REPAIR TABLE t1;
20+
Table Op Msg_type Msg_text
21+
test.t1 repair Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
22+
test.t1 repair error Corrupt
23+
ALTER TABLE t1 REPAIR PARTITION ALL;
24+
Table Op Msg_type Msg_text
25+
test.t1 repair Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
26+
test.t1 repair error Corrupt
27+
ALTER TABLE t1 CHECK PARTITION ALL;
28+
Table Op Msg_type Msg_text
29+
test.t1 check Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
30+
test.t1 check error Corrupt
31+
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
32+
Table Op Msg_type Msg_text
33+
test.t1 optimize Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
34+
test.t1 optimize error Corrupt
35+
ALTER TABLE t1 ANALYZE PARTITION ALL;
36+
Table Op Msg_type Msg_text
37+
test.t1 analyze Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
38+
test.t1 analyze error Corrupt
39+
ALTER TABLE t1 REBUILD PARTITION ALL;
40+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
41+
ALTER TABLE t1 ENGINE Memory;
42+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
43+
ALTER TABLE t1 ADD (new INT);
44+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
45+
DROP TABLE t1;
46+
CREATE TABLE t1 (
47+
firstname VARCHAR(25) NOT NULL,
48+
lastname VARCHAR(25) NOT NULL,
49+
username VARCHAR(16) NOT NULL,
50+
email VARCHAR(35),
51+
joined DATE NOT NULL
52+
)
53+
PARTITION BY KEY(joined)
54+
PARTITIONS 6;
55+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
56+
ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2;
57+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
58+
drop table t1;
59+
ERROR 42S02: Unknown table 't1'
60+
CREATE TABLE t1 (
61+
firstname VARCHAR(25) NOT NULL,
62+
lastname VARCHAR(25) NOT NULL,
63+
username VARCHAR(16) NOT NULL,
64+
email VARCHAR(35),
65+
joined DATE NOT NULL
66+
)
67+
PARTITION BY RANGE( YEAR(joined) ) (
68+
PARTITION p0 VALUES LESS THAN (1960),
69+
PARTITION p1 VALUES LESS THAN (1970),
70+
PARTITION p2 VALUES LESS THAN (1980),
71+
PARTITION p3 VALUES LESS THAN (1990),
72+
PARTITION p4 VALUES LESS THAN MAXVALUE
73+
);
74+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
75+
drop table t1;
76+
ERROR 42S02: Unknown table 't1'
77+
CREATE TABLE t1 (id INT, purchased DATE)
78+
PARTITION BY RANGE( YEAR(purchased) )
79+
SUBPARTITION BY HASH( TO_DAYS(purchased) )
80+
SUBPARTITIONS 2 (
81+
PARTITION p0 VALUES LESS THAN (1990),
82+
PARTITION p1 VALUES LESS THAN (2000),
83+
PARTITION p2 VALUES LESS THAN MAXVALUE
84+
);
85+
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
86+
drop table t1;
87+
ERROR 42S02: Unknown table 't1'
88+
create table t1 (a varchar(10) charset latin1 collate latin1_bin);
89+
insert into t1 values (''),(' '),('a'),('a '),('a ');
90+
explain partitions select * from t1 where a='a ' OR a='a';
91+
id select_type table partitions type possible_keys key key_len ref rows Extra
92+
1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 5 Using where
93+
drop table t1;

mysql-test/std_data/parts/t1.frm

8.35 KB
Binary file not shown.

mysql-test/t/not_partition.test

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
11
--disable_abort_on_error
2-
# Run this tets only when mysqld don't has partitioning
2+
# Run this test only when mysqld don't has partitioning (not compiled with)
33
# the statements are not expected to work, just check that we
44
# can't crash the server
55
-- require r/not_partition.require
66
disable_query_log;
77
show variables like "have_partitioning";
88
enable_query_log;
9+
--disable_warnings
10+
DROP TABLE IF EXISTS t1;
11+
--enable_warnings
12+
let $MYSQLD_DATADIR= `SELECT @@datadir`;
913

14+
#
15+
# Bug#39893: Crash if select on a partitioned table,
16+
# when partitioning is disabled
17+
FLUSH TABLES;
18+
--copy_file $MYSQLTEST_VARDIR/std_data_ln/parts/t1.frm $MYSQLD_DATADIR/test/t1.frm
19+
SELECT * FROM t1;
20+
TRUNCATE TABLE t1;
21+
ANALYZE TABLE t1;
22+
CHECK TABLE t1;
23+
OPTIMIZE TABLE t1;
24+
REPAIR TABLE t1;
25+
ALTER TABLE t1 REPAIR PARTITION ALL;
26+
ALTER TABLE t1 CHECK PARTITION ALL;
27+
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
28+
ALTER TABLE t1 ANALYZE PARTITION ALL;
29+
ALTER TABLE t1 REBUILD PARTITION ALL;
30+
ALTER TABLE t1 ENGINE Memory;
31+
ALTER TABLE t1 ADD (new INT);
32+
DROP TABLE t1;
1033

1134
--error ER_FEATURE_DISABLED
1235
CREATE TABLE t1 (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--loose-skip-partition

mysql-test/t/partition_disabled.test

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
--disable_abort_on_error
2+
# Run this test only when mysqld has partitioning, but it is disabled.
3+
# The statements are not expected to work, just check that we
4+
# can't crash the server.
5+
--require r/disabled_partition.require
6+
--disable_query_log
7+
show variables like "have_partitioning";
8+
--enable_query_log
9+
--disable_warnings
10+
DROP TABLE IF EXISTS t1;
11+
--enable_warnings
12+
let $MYSQLD_DATADIR= `SELECT @@datadir`;
13+
14+
#
15+
# Bug#39893: Crash if select on a partitioned table,
16+
# when partitioning is disabled
17+
FLUSH TABLES;
18+
--copy_file $MYSQLTEST_VARDIR/std_data_ln/parts/t1.frm $MYSQLD_DATADIR/test/t1.frm
19+
SELECT * FROM t1;
20+
TRUNCATE TABLE t1;
21+
ANALYZE TABLE t1;
22+
CHECK TABLE t1;
23+
OPTIMIZE TABLE t1;
24+
REPAIR TABLE t1;
25+
ALTER TABLE t1 REPAIR PARTITION ALL;
26+
ALTER TABLE t1 CHECK PARTITION ALL;
27+
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
28+
ALTER TABLE t1 ANALYZE PARTITION ALL;
29+
ALTER TABLE t1 REBUILD PARTITION ALL;
30+
ALTER TABLE t1 ENGINE Memory;
31+
ALTER TABLE t1 ADD (new INT);
32+
DROP TABLE t1;
33+
34+
--error ER_OPTION_PREVENTS_STATEMENT
35+
CREATE TABLE t1 (
36+
firstname VARCHAR(25) NOT NULL,
37+
lastname VARCHAR(25) NOT NULL,
38+
username VARCHAR(16) NOT NULL,
39+
email VARCHAR(35),
40+
joined DATE NOT NULL
41+
)
42+
PARTITION BY KEY(joined)
43+
PARTITIONS 6;
44+
45+
--error ER_OPTION_PREVENTS_STATEMENT
46+
ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2;
47+
48+
--error ER_BAD_TABLE_ERROR
49+
drop table t1;
50+
51+
--error ER_OPTION_PREVENTS_STATEMENT
52+
CREATE TABLE t1 (
53+
firstname VARCHAR(25) NOT NULL,
54+
lastname VARCHAR(25) NOT NULL,
55+
username VARCHAR(16) NOT NULL,
56+
email VARCHAR(35),
57+
joined DATE NOT NULL
58+
)
59+
PARTITION BY RANGE( YEAR(joined) ) (
60+
PARTITION p0 VALUES LESS THAN (1960),
61+
PARTITION p1 VALUES LESS THAN (1970),
62+
PARTITION p2 VALUES LESS THAN (1980),
63+
PARTITION p3 VALUES LESS THAN (1990),
64+
PARTITION p4 VALUES LESS THAN MAXVALUE
65+
);
66+
--error ER_BAD_TABLE_ERROR
67+
drop table t1;
68+
69+
--error ER_OPTION_PREVENTS_STATEMENT
70+
CREATE TABLE t1 (id INT, purchased DATE)
71+
PARTITION BY RANGE( YEAR(purchased) )
72+
SUBPARTITION BY HASH( TO_DAYS(purchased) )
73+
SUBPARTITIONS 2 (
74+
PARTITION p0 VALUES LESS THAN (1990),
75+
PARTITION p1 VALUES LESS THAN (2000),
76+
PARTITION p2 VALUES LESS THAN MAXVALUE
77+
);
78+
--error ER_BAD_TABLE_ERROR
79+
drop table t1;
80+
81+
# Create a table without partitions to test "EXPLAIN PARTITIONS"
82+
create table t1 (a varchar(10) charset latin1 collate latin1_bin);
83+
insert into t1 values (''),(' '),('a'),('a '),('a ');
84+
explain partitions select * from t1 where a='a ' OR a='a';
85+
drop table t1;

sql/sql_yacc.yy

+2-2
Original file line numberDiff line numberDiff line change
@@ -3750,8 +3750,8 @@ partitioning:
37503750
LEX_STRING partition_name={C_STRING_WITH_LEN("partition")};
37513751
if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))
37523752
{
3753-
my_error(ER_FEATURE_DISABLED, MYF(0),
3754-
"partitioning", "--with-partition");
3753+
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
3754+
"--skip-partition");
37553755
MYSQL_YYABORT;
37563756
}
37573757
lex->part_info= new partition_info();

sql/table.cc

+9
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
914914
we unlock the old value of share->db_plugin before
915915
replacing it with a globally locked version of tmp_plugin
916916
*/
917+
/* Check if the partitioning engine is ready */
918+
if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN))
919+
{
920+
error= 8;
921+
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
922+
"--skip-partition");
923+
my_free(buff, MYF(0));
924+
goto err;
925+
}
917926
plugin_unlock(NULL, share->db_plugin);
918927
share->db_plugin= ha_lock_engine(NULL, partition_hton);
919928
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",

0 commit comments

Comments
 (0)