Commit 48e0325c authored by Mattias Jonsson's avatar Mattias Jonsson

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.

mysql-test/r/disabled_partition.require:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  New require file to use when partitioning is disabled (but compiled in)
mysql-test/r/not_partition.result:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  Updated testcase
mysql-test/r/partition_disabled.result:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  New result file
mysql-test/std_data/parts/t1.frm:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  frm file for 'create table t1 (a int) partition by hash (a)'
mysql-test/t/not_partition.test:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  Updated test cases
mysql-test/t/partition_disabled-master.opt:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  New opt file
mysql-test/t/partition_disabled.test:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  New test file (looks like not_partition.test, but with different errors)
sql/sql_yacc.yy:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  Better error message (it is already built with partitioning, but is explicitly
  disabled).
sql/table.cc:
  Bug#39893: Crash if select on a partitioned table, when partitioning is disabled
  
  If the partitioning plugin is not ready, fail to open the table.
parent 47c0ec50
Variable_name Value
have_partitioning DISABLED
DROP TABLE IF EXISTS t1;
FLUSH TABLES;
SELECT * FROM t1;
ERROR 42000: Unknown table engine 'partition'
TRUNCATE TABLE t1;
ERROR 42000: Unknown table engine 'partition'
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze Error Unknown table engine 'partition'
test.t1 analyze error Corrupt
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check Error Unknown table engine 'partition'
test.t1 check error Corrupt
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize Error Unknown table engine 'partition'
test.t1 optimize error Corrupt
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair Error Unknown table engine 'partition'
test.t1 repair error Corrupt
ALTER TABLE t1 REPAIR PARTITION ALL;
Table Op Msg_type Msg_text
test.t1 repair Error Unknown table engine 'partition'
test.t1 repair error Corrupt
ALTER TABLE t1 CHECK PARTITION ALL;
Table Op Msg_type Msg_text
test.t1 check Error Unknown table engine 'partition'
test.t1 check error Corrupt
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
test.t1 optimize Error Unknown table engine 'partition'
test.t1 optimize error Corrupt
ALTER TABLE t1 ANALYZE PARTITION ALL;
Table Op Msg_type Msg_text
test.t1 analyze Error Unknown table engine 'partition'
test.t1 analyze error Corrupt
ALTER TABLE t1 REBUILD PARTITION ALL;
ERROR 42000: Unknown table engine 'partition'
ALTER TABLE t1 ENGINE Memory;
ERROR 42000: Unknown table engine 'partition'
ALTER TABLE t1 ADD (new INT);
ERROR 42000: Unknown table engine 'partition'
DROP TABLE t1;
CREATE TABLE t1 ( CREATE TABLE t1 (
firstname VARCHAR(25) NOT NULL, firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL, lastname VARCHAR(25) NOT NULL,
......
DROP TABLE IF EXISTS t1;
FLUSH TABLES;
SELECT * FROM t1;
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
TRUNCATE TABLE t1;
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
test.t1 analyze error Corrupt
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
test.t1 check error Corrupt
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
test.t1 optimize error Corrupt
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
test.t1 repair error Corrupt
ALTER TABLE t1 REPAIR PARTITION ALL;
Table Op Msg_type Msg_text
test.t1 repair Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
test.t1 repair error Corrupt
ALTER TABLE t1 CHECK PARTITION ALL;
Table Op Msg_type Msg_text
test.t1 check Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
test.t1 check error Corrupt
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
test.t1 optimize Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
test.t1 optimize error Corrupt
ALTER TABLE t1 ANALYZE PARTITION ALL;
Table Op Msg_type Msg_text
test.t1 analyze Error The MySQL server is running with the --skip-partition option so it cannot execute this statement
test.t1 analyze error Corrupt
ALTER TABLE t1 REBUILD PARTITION ALL;
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
ALTER TABLE t1 ENGINE Memory;
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
ALTER TABLE t1 ADD (new INT);
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
DROP TABLE t1;
CREATE TABLE t1 (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY KEY(joined)
PARTITIONS 6;
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2;
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
drop table t1;
ERROR 42S02: Unknown table 't1'
CREATE TABLE t1 (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p0 VALUES LESS THAN (1960),
PARTITION p1 VALUES LESS THAN (1970),
PARTITION p2 VALUES LESS THAN (1980),
PARTITION p3 VALUES LESS THAN (1990),
PARTITION p4 VALUES LESS THAN MAXVALUE
);
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
drop table t1;
ERROR 42S02: Unknown table 't1'
CREATE TABLE t1 (id INT, purchased DATE)
PARTITION BY RANGE( YEAR(purchased) )
SUBPARTITION BY HASH( TO_DAYS(purchased) )
SUBPARTITIONS 2 (
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN MAXVALUE
);
ERROR HY000: The MySQL server is running with the --skip-partition option so it cannot execute this statement
drop table t1;
ERROR 42S02: Unknown table 't1'
create table t1 (a varchar(10) charset latin1 collate latin1_bin);
insert into t1 values (''),(' '),('a'),('a '),('a ');
explain partitions select * from t1 where a='a ' OR a='a';
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 5 Using where
drop table t1;
--disable_abort_on_error --disable_abort_on_error
# Run this tets only when mysqld don't has partitioning # Run this test only when mysqld don't has partitioning (not compiled with)
# the statements are not expected to work, just check that we # the statements are not expected to work, just check that we
# can't crash the server # can't crash the server
-- require r/not_partition.require -- require r/not_partition.require
disable_query_log; disable_query_log;
show variables like "have_partitioning"; show variables like "have_partitioning";
enable_query_log; enable_query_log;
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
let $MYSQLD_DATADIR= `SELECT @@datadir`;
#
# Bug#39893: Crash if select on a partitioned table,
# when partitioning is disabled
FLUSH TABLES;
--copy_file $MYSQLTEST_VARDIR/std_data_ln/parts/t1.frm $MYSQLD_DATADIR/test/t1.frm
SELECT * FROM t1;
TRUNCATE TABLE t1;
ANALYZE TABLE t1;
CHECK TABLE t1;
OPTIMIZE TABLE t1;
REPAIR TABLE t1;
ALTER TABLE t1 REPAIR PARTITION ALL;
ALTER TABLE t1 CHECK PARTITION ALL;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
ALTER TABLE t1 ANALYZE PARTITION ALL;
ALTER TABLE t1 REBUILD PARTITION ALL;
ALTER TABLE t1 ENGINE Memory;
ALTER TABLE t1 ADD (new INT);
DROP TABLE t1;
--error ER_FEATURE_DISABLED --error ER_FEATURE_DISABLED
CREATE TABLE t1 ( CREATE TABLE t1 (
......
--disable_abort_on_error
# Run this test only when mysqld has partitioning, but it is disabled.
# The statements are not expected to work, just check that we
# can't crash the server.
--require r/disabled_partition.require
--disable_query_log
show variables like "have_partitioning";
--enable_query_log
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
let $MYSQLD_DATADIR= `SELECT @@datadir`;
#
# Bug#39893: Crash if select on a partitioned table,
# when partitioning is disabled
FLUSH TABLES;
--copy_file $MYSQLTEST_VARDIR/std_data_ln/parts/t1.frm $MYSQLD_DATADIR/test/t1.frm
SELECT * FROM t1;
TRUNCATE TABLE t1;
ANALYZE TABLE t1;
CHECK TABLE t1;
OPTIMIZE TABLE t1;
REPAIR TABLE t1;
ALTER TABLE t1 REPAIR PARTITION ALL;
ALTER TABLE t1 CHECK PARTITION ALL;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
ALTER TABLE t1 ANALYZE PARTITION ALL;
ALTER TABLE t1 REBUILD PARTITION ALL;
ALTER TABLE t1 ENGINE Memory;
ALTER TABLE t1 ADD (new INT);
DROP TABLE t1;
--error ER_OPTION_PREVENTS_STATEMENT
CREATE TABLE t1 (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY KEY(joined)
PARTITIONS 6;
--error ER_OPTION_PREVENTS_STATEMENT
ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2;
--error ER_BAD_TABLE_ERROR
drop table t1;
--error ER_OPTION_PREVENTS_STATEMENT
CREATE TABLE t1 (
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p0 VALUES LESS THAN (1960),
PARTITION p1 VALUES LESS THAN (1970),
PARTITION p2 VALUES LESS THAN (1980),
PARTITION p3 VALUES LESS THAN (1990),
PARTITION p4 VALUES LESS THAN MAXVALUE
);
--error ER_BAD_TABLE_ERROR
drop table t1;
--error ER_OPTION_PREVENTS_STATEMENT
CREATE TABLE t1 (id INT, purchased DATE)
PARTITION BY RANGE( YEAR(purchased) )
SUBPARTITION BY HASH( TO_DAYS(purchased) )
SUBPARTITIONS 2 (
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN MAXVALUE
);
--error ER_BAD_TABLE_ERROR
drop table t1;
# Create a table without partitions to test "EXPLAIN PARTITIONS"
create table t1 (a varchar(10) charset latin1 collate latin1_bin);
insert into t1 values (''),(' '),('a'),('a '),('a ');
explain partitions select * from t1 where a='a ' OR a='a';
drop table t1;
...@@ -3750,8 +3750,8 @@ partitioning: ...@@ -3750,8 +3750,8 @@ partitioning:
LEX_STRING partition_name={C_STRING_WITH_LEN("partition")}; LEX_STRING partition_name={C_STRING_WITH_LEN("partition")};
if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN)) if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))
{ {
my_error(ER_FEATURE_DISABLED, MYF(0), my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"partitioning", "--with-partition"); "--skip-partition");
MYSQL_YYABORT; MYSQL_YYABORT;
} }
lex->part_info= new partition_info(); lex->part_info= new partition_info();
......
...@@ -914,6 +914,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, ...@@ -914,6 +914,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
we unlock the old value of share->db_plugin before we unlock the old value of share->db_plugin before
replacing it with a globally locked version of tmp_plugin replacing it with a globally locked version of tmp_plugin
*/ */
/* Check if the partitioning engine is ready */
if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN))
{
error= 8;
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--skip-partition");
my_free(buff, MYF(0));
goto err;
}
plugin_unlock(NULL, share->db_plugin); plugin_unlock(NULL, share->db_plugin);
share->db_plugin= ha_lock_engine(NULL, partition_hton); share->db_plugin= ha_lock_engine(NULL, partition_hton);
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
......
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