This commit is contained in:
Mattias Jonsson 2010-10-01 18:36:53 +02:00
commit ac5a175b92
40 changed files with 4586 additions and 294 deletions

View File

@ -447,7 +447,7 @@ struct st_command
char *query, *query_buf,*first_argument,*last_argument,*end;
DYNAMIC_STRING content;
int first_word_len, query_len;
my_bool abort_on_error;
my_bool abort_on_error, used_replace;
struct st_expected_errors expected_errors;
char require_file[FN_REFLEN];
enum enum_commands type;
@ -3414,7 +3414,7 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname,
if (ds_wild && ds_wild->length &&
wild_compare(file->name, ds_wild->str, 0))
continue;
dynstr_append(ds, file->name);
replace_dynstr_append(ds, file->name);
dynstr_append(ds, "\n");
}
set_wild_chars(0);
@ -3444,6 +3444,7 @@ static void do_list_files(struct st_command *command)
{"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"}
};
DBUG_ENTER("do_list_files");
command->used_replace= 1;
check_command_args(command, command->first_argument,
list_files_args,
@ -3485,6 +3486,7 @@ static void do_list_files_write_file_command(struct st_command *command,
{"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"}
};
DBUG_ENTER("do_list_files_write_file");
command->used_replace= 1;
check_command_args(command, command->first_argument,
list_files_args,
@ -8479,7 +8481,7 @@ int main(int argc, char **argv)
memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
}
if (command_executed != last_command_executed)
if (command_executed != last_command_executed || command->used_replace)
{
/*
As soon as any command has been executed,

View File

@ -24,8 +24,6 @@ main.sp @solaris # Bug#47791 2010-01-20 alik Several tes
main.type_float @freebsd # Bug#38965 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server
main.wait_timeout @solaris # Bug#51244 2010-04-26 alik wait_timeout fails on OpenSolaris
parts.partition_alter4_innodb # Bug#45299 2010-06-28 alik Test "partition_alter4_innodb" is taking too long, timeout
rpl.rpl_heartbeat_basic # BUG#54820 2010-06-26 alik rpl.rpl_heartbeat_basic fails sporadically again
rpl.rpl_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails sporadically
rpl.rpl_innodb_bug28430* # Bug#46029

View File

@ -1 +1,2 @@
perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st
perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st
perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.part_supported_sql_func_innodb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_ndb parts.partition_alter1_2_innodb parts.partition_alter1_2_ndb parts.partition_alter2_1_1_innodb parts.partition_alter2_1_2_innodb parts.partition_alter2_2_2_innodb parts.partition_alter4_innodb main.variables-big rpl_ndb.rpl_truncate_7ndb_2

View File

@ -1,5 +1,20 @@
drop table if exists t1, t2;
#
# Bug#57113: ha_partition::extra(ha_extra_function):
# Assertion `m_extra_cache' failed
CREATE TABLE t1
(id INT NOT NULL PRIMARY KEY,
name VARCHAR(16) NOT NULL,
year YEAR,
INDEX name (name(8))
)
PARTITION BY HASH(id) PARTITIONS 2;
INSERT INTO t1 VALUES ( 1, 'FooBar', '1924' );
CREATE TABLE t2 (id INT);
INSERT INTO t2 VALUES (1),(2);
UPDATE t1, t2 SET t1.year = '1955' WHERE t1.name = 'FooBar';
DROP TABLE t1, t2;
#
# Bug#55458: Partitioned MyISAM table gets crashed by multi-table update
#
CREATE TABLE t1 (
@ -551,12 +566,12 @@ create table t1 (a bigint)
partition by range (a)
(partition p0 values less than (0xFFFFFFFFFFFFFFFF),
partition p1 values less than (10));
ERROR HY000: VALUES value must be of same type as partition function
ERROR HY000: VALUES value for partition 'p0' must have type INT
create table t1 (a bigint)
partition by list (a)
(partition p0 values in (0xFFFFFFFFFFFFFFFF),
partition p1 values in (10));
ERROR HY000: VALUES value must be of same type as partition function
ERROR HY000: VALUES value for partition 'p0' must have type INT
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (100),

View File

@ -1,4 +1,124 @@
drop table if exists t1;
drop table if exists t1, t2;
#
# Bug#50036: Inconsistent errors when using TIMESTAMP
# columns/expressions
# 1. correct and appropriate errors in light of
# the fix for BUG#42849:
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE (TO_DAYS(c))
(PARTITION p0 VALUES LESS THAN (10000),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
CREATE TABLE t2 (c TIMESTAMP);
ALTER TABLE t2
PARTITION BY RANGE (TO_DAYS(c))
(PARTITION p0 VALUES LESS THAN (10000),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE COLUMNS(c)
(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning
ALTER TABLE t2 PARTITION BY RANGE COLUMNS(c)
(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning
DROP TABLE t2;
# 2. These errors where questionable before the fix:
# VALUES clause are checked first, clearified the error message.
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE (c)
(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
ERROR HY000: VALUES value for partition 'p0' must have type INT
# TIMESTAMP is not INT (e.g. UNIX_TIMESTAMP).
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE (UNIX_TIMESTAMP(c))
(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
ERROR HY000: VALUES value for partition 'p0' must have type INT
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE (UNIX_TIMESTAMP(c))
(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01 00:00:00')),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
DROP TABLE t1;
# Changed error from ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY HASH (c) PARTITIONS 4;
ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning
# Added test with existing TIMESTAMP partitioning (when it was allowed).
CREATE TABLE t1 (a TIMESTAMP)
PARTITION BY HASH (UNIX_TIMESTAMP(a));
INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
SELECT * FROM t1;
a
2000-01-02 03:04:05
FLUSH TABLES;
SELECT * FROM t1;
a
2000-01-02 03:04:05
Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
Warnings:
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (TO_DAYS(a)) */
INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
SELECT * FROM t1;
a
2000-01-02 03:04:05
2001-02-03 04:05:06
ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
Warnings:
Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
ALTER TABLE t1
PARTITION BY RANGE (TO_DAYS(a))
(PARTITION p0 VALUES LESS THAN (10000),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (TO_DAYS(a))
PARTITIONS 3 */
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (TO_DAYS(a))
PARTITIONS 3 */
Warnings:
Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
DROP TABLE t2;
CREATE TABLE t2 SELECT * FROM t1;
DROP TABLE t2;
ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a)) */
ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a))
PARTITIONS 3 */
SELECT * FROM t1;
a
2000-01-02 03:04:05
2001-02-03 04:05:06
DROP TABLE t1;
#
# Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
#
@ -497,7 +617,7 @@ partition by range (a)
partitions 2
(partition x1 values less than (4.0) tablespace ts1,
partition x2 values less than (8) tablespace ts2);
ERROR HY000: VALUES value must be of same type as partition function
ERROR HY000: VALUES value for partition 'x1' must have type INT
CREATE TABLE t1 (
a int not null,
b int not null,
@ -736,7 +856,7 @@ partition by list (a)
partitions 2
(partition x1 values in (4.0, 12+8),
partition x2 values in (3, 21));
ERROR HY000: VALUES value must be of same type as partition function
ERROR HY000: VALUES value for partition 'x1' must have type INT
CREATE TABLE t1 (
a int not null,
b int not null,
@ -796,12 +916,12 @@ CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
PARTITION BY RANGE (a) (
PARTITION p VALUES LESS THAN (20080819),
PARTITION pmax VALUES LESS THAN MAXVALUE);
ERROR HY000: The PARTITION function returns the wrong type
ERROR HY000: Field 'a' is of a not allowed type for this type of partitioning
ALTER TABLE old
PARTITION BY RANGE (a) (
PARTITION p VALUES LESS THAN (20080819),
PARTITION pmax VALUES LESS THAN MAXVALUE);
ERROR HY000: The PARTITION function returns the wrong type
ERROR HY000: Field 'a' is of a not allowed type for this type of partitioning
CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
PARTITION BY RANGE (a+0) (
PARTITION p VALUES LESS THAN (20080819),

Binary file not shown.

View File

@ -26,10 +26,12 @@ if ($do_file_tests)
{
let $ls_file= $MYSQLD_DATADIR/test/tmp2;
# List the files belonging to the table t1
--replace_result $MYSQLTEST_VARDIR \$MYSQLTEST_VARDIR #p# #P# #sp# #SP#
--list_files_write_file $ls_file $MYSQLD_DATADIR/test t1*
--chmod 0644 $ls_file
if ($with_directories)
{
--replace_result $MYSQLTEST_VARDIR \$MYSQLTEST_VARDIR #p# #P# #sp# #SP#
--list_files_append_file $ls_file $MYSQLTEST_VARDIR/tmp t1*
}
eval SET @aux = load_file('$ls_file');
@ -60,16 +62,15 @@ if ($found_garbage)
--echo # <alter partitioning> worked incomplete.
--echo # We found:
# Print the list of files into the protocol
eval SELECT REPLACE(file_list,'$MYSQLTEST_VARDIR','\$MYSQLTEST_VARDIR')
AS "unified filelist"
eval SELECT file_list AS "unified filelist"
FROM t0_definition WHERE state = 'old';
}
# Do a manual cleanup, because the following tests should not suffer from
# remaining files
--exec rm -f $MYSQLD_DATADIR/test/t1* || true
--remove_files_wildcard $MYSQLD_DATADIR/test t1*
if ($with_directories)
{
--exec rm -f $MYSQLTEST_VARDIR/tmp/t1* || true
--remove_files_wildcard $MYSQLTEST_VARDIR/tmp t1*
}
}
--enable_query_log

View File

@ -3,7 +3,7 @@
--eval $create_statement
--eval $insert_statement
--echo # State before crash
--replace_result #p# #P#
--replace_result #p# #P# #sp# #SP#
--list_files $DATADIR/test
SHOW CREATE TABLE t1;
--sorted_result
@ -14,13 +14,13 @@ SELECT * FROM t1;
--error 2013
--eval $crash_statement
--echo # State after crash (before recovery)
--replace_regex /sqlx.*\./sqlx-nnnn_nnnn./ /#p#/#P#/
--replace_regex /sqlx.*\./sqlx-nnnn_nnnn./ /#p#/#P#/ /#sp#/#SP#/ /#tmp#/#TMP#/
--list_files $DATADIR/test
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
--echo # State after crash recovery
--replace_result #p# #P#
--replace_result #p# #P# #sp# #SP#
--list_files $DATADIR/test
SHOW CREATE TABLE t1;
--sorted_result

View File

@ -3,6 +3,7 @@
--eval $create_statement
--eval $insert_statement
--echo # State before failure
--replace_result #p# #P# #sp# #SP#
--list_files $DATADIR/test
SHOW CREATE TABLE t1;
--sorted_result
@ -11,8 +12,29 @@ SELECT * FROM t1;
--eval $fail_statement
--enable_abort_on_error
--echo # State after failure
--replace_result #p# #P# #sp# #SP#
--list_files $DATADIR/test
SHOW CREATE TABLE t1;
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
--echo # Same test under LOCK TABLE
--eval $create_statement
--eval $insert_statement
--echo # State before failure
--list_files $DATADIR/test
SHOW CREATE TABLE t1;
--sorted_result
SELECT * FROM t1;
LOCK TABLE t1 WRITE;
--disable_abort_on_error
--eval $fail_statement
--enable_abort_on_error
--echo # State after failure
--list_files $DATADIR/test
SHOW CREATE TABLE t1;
--sorted_result
SELECT * FROM t1;
UNLOCK TABLES;
DROP TABLE t1;

View File

@ -10,6 +10,6 @@ eval SHOW CREATE TABLE t1;
if ($ls)
{
let $MYSQLD_DATADIR= `select @@datadir`;
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR #p# #P# #sp# #SP#
--list_files $MYSQLD_DATADIR/test t1*
}

View File

@ -69,7 +69,7 @@ if ($do_file_tests)
if ($ls)
{
# Print the list of files into the protocol
replace_result $MYSQLD_DATADIR MYSQLD_DATADIR $MYSQLTEST_VARDIR MYSQLTEST_VARDIR;
replace_result $MYSQLD_DATADIR MYSQLD_DATADIR $MYSQLTEST_VARDIR MYSQLTEST_VARDIR #p# #P# #sp# #SP# part_n part_N;
SELECT file_list AS "unified filelist"
FROM t0_definition WHERE state = 'old';
}

View File

@ -65,7 +65,7 @@ let $run= `SELECT @aux`;
if ($run)
{
--vertical_results
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR #p# #P# #sp# #SP#
SELECT state,
REPLACE(create_command,'\n',' ') AS "Table definition",
REPLACE(file_list ,'\n',' ') AS "File list"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
call mtr.add_suppression("./test/t1_will_crash");
call mtr.add_suppression("t1_will_crash");
call mtr.add_suppression("Got an error from unknown thread");
CREATE TABLE t1_will_crash (a INT, KEY (a)) ENGINE=MyISAM;
INSERT INTO t1_will_crash VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);

View File

@ -238,11 +238,10 @@ LOCK TABLE t1 READ;
# Third attempt: says that the table does not exist
ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
# Check table returns the same
# Check table returns the same (not after fixing bug#56172!)
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check Error Lock wait timeout exceeded; try restarting transaction
test.t1 check status Operation failed
test.t1 check status OK
UNLOCK TABLES;
DROP TABLE t1;
CREATE TABLE t2 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT )

View File

@ -214,7 +214,7 @@ SET lock_wait_timeout = 2;
ALTER TABLE t1 COALESCE PARTITION 2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
# Connection 3 tries to load into the table:
LOAD DATA LOCAL INFILE '/tmp/load.in' INTO TABLE t1 (f);
LOAD DATA INFILE 'load.in' INTO TABLE t1 (f);
# Connection 1 commits the transaction
COMMIT;
# Connection 3...

View File

@ -28,6 +28,9 @@ let $do_long_tests= 1;
# The server must support partitioning.
--source include/have_partition.inc
# This test takes long time, so only run it with the --big mtr-flag.
--source include/big_test.inc
#------------------------------------------------------------------------------#
# Engine specific settings and requirements

View File

@ -46,6 +46,9 @@ let $more_pk_ui_tests= 0;
# The server must support partitioning.
--source include/have_partition.inc
# This test takes long time, so only run it with the --big mtr-flag.
--source include/big_test.inc
#------------------------------------------------------------------------------#
# Engine specific settings and requirements

View File

@ -46,6 +46,9 @@ let $more_pk_ui_tests= 0;
# The server must support partitioning.
--source include/have_partition.inc
# This test takes long time, so only run it with the --big mtr-flag.
--source include/big_test.inc
#------------------------------------------------------------------------------#
# Engine specific settings and requirements

View File

@ -45,6 +45,9 @@ let $only_part_1= 1;
# The server must support partitioning.
--source include/have_partition.inc
# This test takes long time, so only run it with the --big mtr-flag.
--source include/big_test.inc
#------------------------------------------------------------------------------#
# Engine specific settings and requirements

View File

@ -45,6 +45,9 @@ let $only_part_2= 1;
# The server must support partitioning.
--source include/have_partition.inc
# This test takes long time, so only run it with the --big mtr-flag.
--source include/big_test.inc
#------------------------------------------------------------------------------#
# Engine specific settings and requirements

View File

@ -45,6 +45,9 @@ let $only_part_2= 1;
# The server must support partitioning.
--source include/have_partition.inc
# This test takes long time, so only run it with the --big mtr-flag.
--source include/big_test.inc
#------------------------------------------------------------------------------#
# Engine specific settings and requirements

View File

@ -43,6 +43,9 @@ let $more_pk_ui_tests= 0;
# The server must support partitioning.
--source include/have_partition.inc
# This test takes long time, so only run it with the --big mtr-flag.
--source include/big_test.inc
#------------------------------------------------------------------------------#
# Engine specific settings and requirements

View File

@ -56,6 +56,7 @@ partition by range (a)
insert into t1 values (1), (11), (21), (33);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
--replace_result #p# #P# #sp# #SP#
--list_files $MYSQLD_DATADIR/test
SET DEBUG_SYNC='before_open_in_get_all_tables SIGNAL parked WAIT_FOR open';
@ -78,6 +79,7 @@ ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
disconnect con1;
connection default;
--reap
--replace_result #p# #P# #sp# #SP#
--list_files $MYSQLD_DATADIR/test
SHOW CREATE TABLE t1;
SELECT * FROM t1;

View File

@ -1,6 +1,6 @@
# test the auto-recover (--myisam-recover) of partitioned myisam tables
call mtr.add_suppression("./test/t1_will_crash");
call mtr.add_suppression("t1_will_crash");
call mtr.add_suppression("Got an error from unknown thread");
--source include/have_partition.inc

View File

@ -111,7 +111,7 @@ LOCK TABLE t1 READ;
--echo # Third attempt: says that the table does not exist
--error ER_LOCK_WAIT_TIMEOUT
ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
--echo # Check table returns the same
--echo # Check table returns the same (not after fixing bug#56172!)
CHECK TABLE t1;
--connection con1

View File

@ -62,13 +62,14 @@ ALTER TABLE t1 COALESCE PARTITION 2;
--connect (con3,localhost,root,,)
perl;
open( LD, ">" . "/tmp/load.in" ) || die "Could not open file for writing " . $ENV{'MYSQLTEST_DATADIR'} . "/test/load.in";
print LD "1\n2\n3\n";
close( LD );
--let $MYSQLD_DATADIR= `SELECT @@datadir`
--write_file $MYSQLD_DATADIR/test/load.in
1
2
3
EOF
--echo # Connection 3 tries to load into the table:
send LOAD DATA LOCAL INFILE '/tmp/load.in' INTO TABLE t1 (f);
send LOAD DATA INFILE 'load.in' INTO TABLE t1 (f);
--connection default
--real_sleep 1

View File

@ -14,6 +14,28 @@
drop table if exists t1, t2;
--enable_warnings
--echo #
--echo # Bug#57113: ha_partition::extra(ha_extra_function):
--echo # Assertion `m_extra_cache' failed
CREATE TABLE t1
(id INT NOT NULL PRIMARY KEY,
name VARCHAR(16) NOT NULL,
year YEAR,
INDEX name (name(8))
)
PARTITION BY HASH(id) PARTITIONS 2;
INSERT INTO t1 VALUES ( 1, 'FooBar', '1924' );
CREATE TABLE t2 (id INT);
INSERT INTO t2 VALUES (1),(2);
UPDATE t1, t2 SET t1.year = '1955' WHERE t1.name = 'FooBar';
DROP TABLE t1, t2;
--echo #
--echo # Bug#55458: Partitioned MyISAM table gets crashed by multi-table update
--echo #
@ -458,12 +480,12 @@ drop table t1;
#
# BUG 16002: Handle unsigned integer functions properly
#
--error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
create table t1 (a bigint)
partition by range (a)
(partition p0 values less than (0xFFFFFFFFFFFFFFFF),
partition p1 values less than (10));
--error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
create table t1 (a bigint)
partition by list (a)
(partition p0 values in (0xFFFFFFFFFFFFFFFF),

View File

@ -8,10 +8,8 @@ DROP TABLE IF EXISTS t1;
--echo #
--echo # Bug#51851: Server with SBR locks mutex twice on LOAD DATA into
--echo # partitioned MyISAM table
perl;
open( INIT, ">init_file.txt");
print INIT "abcd\n";
close( INIT );
--write_file init_file.txt
abcd
EOF
CREATE TABLE t1

View File

@ -5,11 +5,103 @@
-- source include/have_partition.inc
--disable_warnings
drop table if exists t1;
drop table if exists t1, t2;
--enable_warnings
let $MYSQLD_DATADIR= `SELECT @@datadir`;
--echo #
--echo # Bug#50036: Inconsistent errors when using TIMESTAMP
--echo # columns/expressions
--echo # 1. correct and appropriate errors in light of
--echo # the fix for BUG#42849:
--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE (TO_DAYS(c))
(PARTITION p0 VALUES LESS THAN (10000),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
CREATE TABLE t2 (c TIMESTAMP);
--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
ALTER TABLE t2
PARTITION BY RANGE (TO_DAYS(c))
(PARTITION p0 VALUES LESS THAN (10000),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE COLUMNS(c)
(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
ALTER TABLE t2 PARTITION BY RANGE COLUMNS(c)
(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
DROP TABLE t2;
--echo # 2. These errors where questionable before the fix:
--echo # VALUES clause are checked first, clearified the error message.
--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE (c)
(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
--echo # TIMESTAMP is not INT (e.g. UNIX_TIMESTAMP).
--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE (UNIX_TIMESTAMP(c))
(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY RANGE (UNIX_TIMESTAMP(c))
(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01 00:00:00')),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
DROP TABLE t1;
--echo # Changed error from ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
CREATE TABLE t1 (c TIMESTAMP)
PARTITION BY HASH (c) PARTITIONS 4;
--echo # Added test with existing TIMESTAMP partitioning (when it was allowed).
CREATE TABLE t1 (a TIMESTAMP)
PARTITION BY HASH (UNIX_TIMESTAMP(a));
INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
--sorted_result
SELECT * FROM t1;
FLUSH TABLES;
--remove_file $MYSQLD_DATADIR/test/t1.frm
--copy_file std_data/parts/t1TIMESTAMP.frm $MYSQLD_DATADIR/test/t1.frm
--sorted_result
SELECT * FROM t1;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
--sorted_result
SELECT * FROM t1;
ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
ALTER TABLE t1
PARTITION BY RANGE (TO_DAYS(a))
(PARTITION p0 VALUES LESS THAN (10000),
PARTITION p1 VALUES LESS THAN (MAXVALUE));
SHOW CREATE TABLE t1;
CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 SELECT * FROM t1;
DROP TABLE t2;
ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
SHOW CREATE TABLE t1;
ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
SHOW CREATE TABLE t1;
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
--echo #
@ -536,7 +628,7 @@ partitions 2
#
# Partition by range, inconsistent partition function and constants
#
--error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
CREATE TABLE t1 (
a int not null,
b int not null,
@ -849,7 +941,7 @@ partitions 2
#
# Partition by list, wrong constant result type (not INT)
#
--error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
CREATE TABLE t1 (
a int not null,
b int not null,
@ -939,13 +1031,13 @@ PARTITION pmax VALUES LESS THAN MAXVALUE);
# Check that allowed arithmetic/math functions involving TIMESTAMP values result
# in ER_PARTITION_FUNC_NOT_ALLOWED_ERROR when used as a partitioning function
--error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR
--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
PARTITION BY RANGE (a) (
PARTITION p VALUES LESS THAN (20080819),
PARTITION pmax VALUES LESS THAN MAXVALUE);
--error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR
--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
ALTER TABLE old
PARTITION BY RANGE (a) (
PARTITION p VALUES LESS THAN (20080819),

View File

@ -5698,7 +5698,6 @@ int ha_partition::extra(enum ha_extra_function operation)
DBUG_RETURN(prepare_for_rename());
break;
case HA_EXTRA_PREPARE_FOR_UPDATE:
DBUG_ASSERT(m_extra_cache);
/*
Needs to be run on the first partition in the range now, and
later in late_extra_cache, when switching to a new partition to scan.
@ -5706,6 +5705,8 @@ int ha_partition::extra(enum ha_extra_function operation)
m_extra_prepare_for_update= TRUE;
if (m_part_spec.start_part != NO_CURRENT_PART_ID)
{
if (!m_extra_cache)
m_extra_cache_part_id= m_part_spec.start_part;
DBUG_ASSERT(m_extra_cache_part_id == m_part_spec.start_part);
(void) m_file[m_part_spec.start_part]->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
}
@ -5977,19 +5978,22 @@ void ha_partition::late_extra_cache(uint partition_id)
{
handler *file;
DBUG_ENTER("ha_partition::late_extra_cache");
DBUG_PRINT("info", ("extra_cache %u partid %u size %u", m_extra_cache,
DBUG_PRINT("info", ("extra_cache %u prepare %u partid %u size %u",
m_extra_cache, m_extra_prepare_for_update,
partition_id, m_extra_cache_size));
if (!m_extra_cache && !m_extra_prepare_for_update)
DBUG_VOID_RETURN;
file= m_file[partition_id];
if (m_extra_cache_size == 0)
(void) file->extra(HA_EXTRA_CACHE);
else
(void) file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size);
if (m_extra_cache)
{
if (m_extra_cache_size == 0)
(void) file->extra(HA_EXTRA_CACHE);
else
(void) file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size);
}
if (m_extra_prepare_for_update)
{
DBUG_ASSERT(m_extra_cache);
(void) file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
}
m_extra_cache_part_id= partition_id;

View File

@ -742,7 +742,6 @@ bool partition_info::check_range_constants(THD *thd)
longlong part_range_value;
bool signed_flag= !part_expr->unsigned_flag;
part_result_type= INT_RESULT;
range_int_array= (longlong*)sql_alloc(num_parts * sizeof(longlong));
if (unlikely(range_int_array == NULL))
{
@ -917,7 +916,6 @@ bool partition_info::check_list_constants(THD *thd)
List_iterator<partition_element> list_func_it(partitions);
DBUG_ENTER("partition_info::check_list_constants");
part_result_type= INT_RESULT;
num_list_values= 0;
/*
We begin by calculating the number of list values that have been
@ -1608,6 +1606,52 @@ id_err:
return 1;
}
/**
Check what kind of error to report
@param use_subpart_expr Use the subpart_expr instead of part_expr
@param part_str Name of partition to report error (or NULL)
*/
void partition_info::report_part_expr_error(bool use_subpart_expr)
{
Item *expr= part_expr;
DBUG_ENTER("partition_info::report_part_expr_error");
if (use_subpart_expr)
expr= subpart_expr;
if (expr->type() == Item::FIELD_ITEM)
{
partition_type type= part_type;
bool list_of_fields= list_of_part_fields;
Item_field *item_field= (Item_field*) expr;
/*
The expression consists of a single field.
It must be of integer type unless KEY or COLUMNS partitioning.
*/
if (use_subpart_expr)
{
type= subpart_type;
list_of_fields= list_of_subpart_fields;
}
if (!column_list &&
item_field->field &&
item_field->field->result_type() != INT_RESULT &&
!(type == HASH_PARTITION && list_of_fields))
{
my_error(ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD, MYF(0),
item_field->name);
DBUG_VOID_RETURN;
}
}
if (use_subpart_expr)
my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), "SUBPARTITION");
else
my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), "PARTITION");
DBUG_VOID_RETURN;
}
/*
Create a new column value in current list with maxvalue
Called from parser
@ -1891,7 +1935,7 @@ int partition_info::reorganize_into_single_field_col_val()
code.
SYNOPSIS
fix_func_partition()
fix_partition_values()
thd Thread object
col_val Array of one value
part_elem The partition instance
@ -1901,13 +1945,13 @@ int partition_info::reorganize_into_single_field_col_val()
TRUE Failure
FALSE Success
*/
int partition_info::fix_func_partition(THD *thd,
part_elem_value *val,
partition_element *part_elem,
uint part_id)
int partition_info::fix_partition_values(THD *thd,
part_elem_value *val,
partition_element *part_elem,
uint part_id)
{
part_column_list_val *col_val= val->col_val_array;
DBUG_ENTER("partition_info::fix_func_partition");
DBUG_ENTER("partition_info::fix_partition_values");
if (col_val->fixed)
{
@ -1953,7 +1997,8 @@ int partition_info::fix_func_partition(THD *thd,
}
else if (item_expr->result_type() != INT_RESULT)
{
my_error(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR, MYF(0));
my_error(ER_VALUES_IS_NOT_INT_TYPE_ERROR, MYF(0),
part_elem->partition_name);
DBUG_RETURN(TRUE);
}
if (part_type == RANGE_PARTITION)
@ -2168,7 +2213,7 @@ int partition_info::fix_parser_data(THD *thd)
}
else
{
if (fix_func_partition(thd, val, part_elem, i))
if (fix_partition_values(thd, val, part_elem, i))
{
DBUG_RETURN(TRUE);
}

View File

@ -166,7 +166,6 @@ public:
key_map some_fields_in_PF;
handlerton *default_engine_type;
Item_result part_result_type;
partition_type part_type;
partition_type subpart_type;
@ -226,7 +225,6 @@ public:
curr_part_elem(NULL), current_partition(NULL),
curr_list_object(0), num_columns(0),
default_engine_type(NULL),
part_result_type(INT_RESULT),
part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION),
part_info_len(0),
part_func_len(0), subpart_func_len(0),
@ -279,10 +277,10 @@ public:
void print_no_partition_found(TABLE *table);
void print_debug(const char *str, uint*);
Item* get_column_item(Item *item, Field *field);
int fix_func_partition(THD *thd,
part_elem_value *val,
partition_element *part_elem,
uint part_id);
int fix_partition_values(THD *thd,
part_elem_value *val,
partition_element *part_elem,
uint part_id);
bool fix_column_value_functions(THD *thd,
part_elem_value *val,
uint part_id);
@ -299,6 +297,7 @@ public:
bool init_column_part();
bool add_column_list_value(THD *thd, Item *item);
void set_show_version_string(String *packet);
void report_part_expr_error(bool use_subpart_expr);
private:
static int list_part_cmp(const void* a, const void* b);
bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info,

View File

@ -6346,3 +6346,7 @@ ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN
ER_FAILED_READ_FROM_PAR_FILE
eng "Failed to read from the .par file"
swe "Misslyckades läsa från .par filen"
ER_VALUES_IS_NOT_INT_TYPE_ERROR
eng "VALUES value for partition '%-.64s' must have type INT"
swe "Värden i VALUES för partition '%-.64s' måste ha typen INT"

View File

@ -70,6 +70,7 @@
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
/* TODO: Change abort() to DBUG_SUICIDE() when bug#52002 is pushed */
#define ERROR_INJECT_CRASH(code) \
DBUG_EVALUATE_IF(code, (abort(), 0), 0)
#define ERROR_INJECT_ERROR(code) \
@ -89,7 +90,6 @@ const LEX_STRING partition_keywords[]=
{ C_STRING_WITH_LEN(" COLUMNS") }
};
static const char *part_str= "PARTITION";
static const char *subpart_str= "SUBPARTITION";
static const char *sub_str= "SUB";
static const char *by_str= "BY";
static const char *space_str= " ";
@ -1762,8 +1762,7 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT))
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0),
subpart_str);
part_info->report_part_expr_error(TRUE);
goto end;
}
}
@ -1790,10 +1789,9 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0), part_str);
part_info->report_part_expr_error(FALSE);
goto end;
}
part_info->part_result_type= INT_RESULT;
}
part_info->fixed= TRUE;
}
@ -1839,18 +1837,22 @@ bool fix_partition_func(THD *thd, TABLE *table,
if (unlikely(!part_info->column_list &&
part_info->part_expr->result_type() != INT_RESULT))
{
my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), part_str);
part_info->report_part_expr_error(FALSE);
goto end;
}
}
if (((part_info->part_type != HASH_PARTITION ||
part_info->list_of_part_fields == FALSE) &&
(!part_info->column_list &&
check_part_func_fields(part_info->part_field_array, TRUE))) ||
part_info->list_of_part_fields == FALSE) &&
!part_info->column_list &&
check_part_func_fields(part_info->part_field_array, TRUE)) ||
(part_info->list_of_subpart_fields == FALSE &&
part_info->is_sub_partitioned() &&
check_part_func_fields(part_info->subpart_field_array, TRUE)))
{
/*
Range/List/HASH (but not KEY) and not COLUMNS or HASH subpartitioning
with columns in the partitioning expression using unallowed charset.
*/
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
goto end;
}
@ -4353,43 +4355,31 @@ set_engine_all_partitions(partition_info *part_info,
}
} while (++i < part_info->num_parts);
}
/*
SYNOPSIS
fast_end_partition()
thd Thread object
out:copied Number of records copied
out:deleted Number of records deleted
table_list Table list with the one table in it
empty Has nothing been done
lpt Struct to be used by error handler
RETURN VALUES
FALSE Success
TRUE Failure
DESCRIPTION
Support routine to handle the successful cases for partition
management.
/**
Support routine to handle the successful cases for partition management.
@param thd Thread object
@param copied Number of records copied
@param deleted Number of records deleted
@param table_list Table list with the one table in it
@return Operation status
@retval FALSE Success
@retval TRUE Failure
*/
static int fast_end_partition(THD *thd, ulonglong copied,
ulonglong deleted,
TABLE_LIST *table_list, bool is_empty,
ALTER_PARTITION_PARAM_TYPE *lpt,
bool written_bin_log)
TABLE_LIST *table_list)
{
char tmp_name[80];
DBUG_ENTER("fast_end_partition");
thd->proc_info="end";
if (!is_empty)
query_cache_invalidate3(thd, table_list, 0);
if ((!is_empty) && (!written_bin_log) &&
(!thd->lex->no_write_to_binlog) &&
write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
DBUG_RETURN(TRUE);
query_cache_invalidate3(thd, table_list, 0);
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) (copied + deleted),
@ -4511,29 +4501,25 @@ uint set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
}
/*
/**
Prepare for ALTER TABLE of partition structure
SYNOPSIS
prep_alter_part_table()
thd Thread object
table Table object
inout:alter_info Alter information
inout:create_info Create info for CREATE TABLE
old_db_type Old engine type
out:partition_changed Boolean indicating whether partition changed
out:fast_alter_partition Boolean indicating whether fast partition
change is requested
@param[in] thd Thread object
@param[in] table Table object
@param[in,out] alter_info Alter information
@param[in,out] create_info Create info for CREATE TABLE
@param[in] old_db_type Old engine type
@param[out] partition_changed Boolean indicating whether partition changed
@param[out] fast_alter_table Internal temporary table allowing fast
partition change or NULL if not possible
RETURN VALUES
TRUE Error
FALSE Success
partition_changed
fast_alter_partition
@return Operation status
@retval TRUE Error
@retval FALSE Success
DESCRIPTION
@note
This method handles all preparations for ALTER TABLE for partitioned
tables
tables.
We need to handle both partition management command such as Add Partition
and others here as well as an ALTER TABLE that completely changes the
partitioning and yet others that don't change anything at all. We start
@ -4545,8 +4531,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
HA_CREATE_INFO *create_info,
handlerton *old_db_type,
bool *partition_changed,
uint *fast_alter_partition)
char *db,
const char *table_name,
const char *path,
TABLE **fast_alter_table)
{
TABLE *new_table= NULL;
DBUG_ENTER("prep_alter_part_table");
/* Foreign keys on partitioned tables are not supported, waits for WL#148 */
@ -4555,15 +4545,9 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
my_error(ER_FOREIGN_KEY_ON_PARTITIONED, MYF(0));
DBUG_RETURN(TRUE);
}
/*
We are going to manipulate the partition info on the table object
so we need to ensure that the table instance is removed from the
table cache.
*/
if (table->part_info)
table->m_needs_reopen= TRUE;
thd->work_part_info= thd->lex->part_info;
if (thd->work_part_info &&
!(thd->work_part_info= thd->lex->part_info->get_clone()))
DBUG_RETURN(TRUE);
@ -4576,7 +4560,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
ALTER_COALESCE_PARTITION | ALTER_REORGANIZE_PARTITION |
ALTER_TABLE_REORG | ALTER_REBUILD_PARTITION))
{
partition_info *tab_part_info= table->part_info;
partition_info *tab_part_info;
partition_info *alt_part_info= thd->work_part_info;
uint flags= 0;
bool is_last_partition_reorged= FALSE;
@ -4584,11 +4568,32 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
part_elem_value *alt_max_elem_val= NULL;
longlong tab_max_range= 0, alt_max_range= 0;
if (!tab_part_info)
if (!table->part_info)
{
my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
DBUG_RETURN(TRUE);
}
/*
Open our intermediate table, we will operate on a temporary instance
of the original table, to be able to skip copying all partitions.
Open it as a copy of the original table, and modify its partition_info
object to allow fast_alter_partition_table to perform the changes.
*/
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name,
MDL_INTENTION_EXCLUSIVE));
new_table= open_table_uncached(thd, path, db, table_name, 0);
if (!new_table)
DBUG_RETURN(TRUE);
/*
This table may be used for copy rows between partitions
and also read/write columns when fixing the partition_info struct.
*/
new_table->use_all_columns();
tab_part_info= new_table->part_info;
if (alter_info->flags & ALTER_TABLE_REORG)
{
uint new_part_no, curr_part_no;
@ -4596,9 +4601,9 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
tab_part_info->use_default_num_partitions)
{
my_error(ER_REORG_NO_PARAM_ERROR, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
new_part_no= table->file->get_default_no_partitions(create_info);
new_part_no= new_table->file->get_default_no_partitions(create_info);
curr_part_no= tab_part_info->num_parts;
if (new_part_no == curr_part_no)
{
@ -4607,7 +4612,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
after the change as before. Thus we can reply ok immediately
without any changes at all.
*/
*fast_alter_partition= TRUE;
*fast_alter_table= new_table;
thd->work_part_info= tab_part_info;
DBUG_RETURN(FALSE);
}
else if (new_part_no > curr_part_no)
@ -4629,15 +4635,15 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
alter_info->num_parts= curr_part_no - new_part_no;
}
}
if (!(flags= table->file->alter_table_flags(alter_info->flags)))
if (!(flags= new_table->file->alter_table_flags(alter_info->flags)))
{
my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
DBUG_RETURN(1);
goto err;
}
*fast_alter_partition=
((flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE)) != 0);
DBUG_PRINT("info", ("*fast_alter_partition: %d flags: 0x%x",
*fast_alter_partition, flags));
if ((flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE)) != 0)
*fast_alter_table= new_table;
DBUG_PRINT("info", ("*fast_alter_table: %p flags: 0x%x",
*fast_alter_table, flags));
if ((alter_info->flags & ALTER_ADD_PARTITION) ||
(alter_info->flags & ALTER_REORGANIZE_PARTITION))
{
@ -4648,12 +4654,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
if (tab_part_info->part_type == RANGE_PARTITION)
{
my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "RANGE");
DBUG_RETURN(TRUE);
goto err;
}
else if (tab_part_info->part_type == LIST_PARTITION)
{
my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "LIST");
DBUG_RETURN(TRUE);
goto err;
}
/*
Hash partitions can be altered without parser finds out about
@ -4684,7 +4690,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
"LIST", "IN");
}
DBUG_RETURN(TRUE);
goto err;
}
}
if ((tab_part_info->column_list &&
@ -4698,12 +4704,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
alt_part_info->num_columns != 0))
{
my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
alt_part_info->column_list= tab_part_info->column_list;
if (alt_part_info->fix_parser_data(thd))
{
DBUG_RETURN(TRUE);
goto err;
}
}
if (alter_info->flags & ALTER_ADD_PARTITION)
@ -4726,17 +4732,17 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
tab_part_info->part_type != HASH_PARTITION)
{
my_error(ER_NO_BINLOG_ERROR, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
if (tab_part_info->defined_max_value)
{
my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
if (num_new_partitions == 0)
{
my_error(ER_ADD_PARTITION_NO_NEW_PARTITION, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
if (tab_part_info->is_sub_partitioned())
{
@ -4745,7 +4751,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
else if (alt_part_info->num_subparts != tab_part_info->num_subparts)
{
my_error(ER_ADD_PARTITION_SUBPART_ERROR, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
check_total_partitions= new_total_partitions*
alt_part_info->num_subparts;
@ -4753,15 +4759,15 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
if (check_total_partitions > MAX_PARTITIONS)
{
my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
alt_part_info->part_type= tab_part_info->part_type;
alt_part_info->subpart_type= tab_part_info->subpart_type;
if (alt_part_info->set_up_defaults_for_partitioning(table->file,
if (alt_part_info->set_up_defaults_for_partitioning(new_table->file,
ULL(0),
tab_part_info->num_parts))
{
DBUG_RETURN(TRUE);
goto err;
}
/*
Handling of on-line cases:
@ -4825,7 +4831,7 @@ adding and copying partitions, the second after completing the adding
and copying and finally the third line after also dropping the partitions
that are reorganised.
*/
if (*fast_alter_partition &&
if (*fast_alter_table &&
tab_part_info->part_type == HASH_PARTITION)
{
uint part_no= 0, start_part= 1, start_sec_part= 1;
@ -4930,12 +4936,12 @@ that are reorganised.
do
{
partition_element *part_elem= alt_it++;
if (*fast_alter_partition)
if (*fast_alter_table)
part_elem->part_state= PART_TO_BE_ADDED;
if (tab_part_info->partitions.push_back(part_elem))
{
mem_alloc_error(1);
DBUG_RETURN(TRUE);
goto err;
}
} while (++part_count < num_new_partitions);
tab_part_info->num_parts+= num_new_partitions;
@ -4976,12 +4982,12 @@ that are reorganised.
tab_part_info->part_type == LIST_PARTITION))
{
my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "DROP");
DBUG_RETURN(TRUE);
goto err;
}
if (num_parts_dropped >= tab_part_info->num_parts)
{
my_error(ER_DROP_LAST_PARTITION, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
do
{
@ -4999,12 +5005,12 @@ that are reorganised.
if (num_parts_found != num_parts_dropped)
{
my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "DROP");
DBUG_RETURN(TRUE);
goto err;
}
if (table->file->is_fk_defined_on_table_or_index(MAX_KEY))
if (new_table->file->is_fk_defined_on_table_or_index(MAX_KEY))
{
my_error(ER_ROW_IS_REFERENCED, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
tab_part_info->num_parts-= num_parts_dropped;
}
@ -5017,12 +5023,12 @@ that are reorganised.
(!(alter_info->flags & ALTER_ALL_PARTITION)))
{
my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REBUILD");
DBUG_RETURN(TRUE);
goto err;
}
if (!(*fast_alter_partition))
if (!(*fast_alter_table))
{
table->file->print_error(HA_ERR_WRONG_COMMAND, MYF(0));
DBUG_RETURN(TRUE);
new_table->file->print_error(HA_ERR_WRONG_COMMAND, MYF(0));
goto err;
}
}
else if (alter_info->flags & ALTER_COALESCE_PARTITION)
@ -5033,17 +5039,17 @@ that are reorganised.
if (tab_part_info->part_type != HASH_PARTITION)
{
my_error(ER_COALESCE_ONLY_ON_HASH_PARTITION, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
if (num_parts_coalesced == 0)
{
my_error(ER_COALESCE_PARTITION_NO_PARTITION, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
if (num_parts_coalesced >= tab_part_info->num_parts)
{
my_error(ER_DROP_LAST_PARTITION, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
/*
Online handling:
@ -5082,7 +5088,7 @@ state of p1.
uint part_count= 0, start_part= 1, start_sec_part= 1;
uint end_part= 0, end_sec_part= 0;
bool all_parts= TRUE;
if (*fast_alter_partition &&
if (*fast_alter_table &&
tab_part_info->linear_hash_ind)
{
uint upper_2n= tab_part_info->linear_hash_mask + 1;
@ -5108,14 +5114,14 @@ state of p1.
do
{
partition_element *p_elem= part_it++;
if (*fast_alter_partition &&
if (*fast_alter_table &&
(all_parts ||
(part_count >= start_part && part_count <= end_part) ||
(part_count >= start_sec_part && part_count <= end_sec_part)))
p_elem->part_state= PART_CHANGED;
if (++part_count > num_parts_remain)
{
if (*fast_alter_partition)
if (*fast_alter_table)
p_elem->part_state= PART_REORGED_DROPPED;
else
part_it.remove();
@ -5150,38 +5156,38 @@ state of p1.
if (num_parts_reorged > tab_part_info->num_parts)
{
my_error(ER_REORG_PARTITION_NOT_EXIST, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
if (!(tab_part_info->part_type == RANGE_PARTITION ||
tab_part_info->part_type == LIST_PARTITION) &&
(num_parts_new != num_parts_reorged))
{
my_error(ER_REORG_HASH_ONLY_ON_SAME_NO, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
if (tab_part_info->is_sub_partitioned() &&
alt_part_info->num_subparts &&
alt_part_info->num_subparts != tab_part_info->num_subparts)
{
my_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
check_total_partitions= tab_part_info->num_parts + num_parts_new;
check_total_partitions-= num_parts_reorged;
if (check_total_partitions > MAX_PARTITIONS)
{
my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
alt_part_info->part_type= tab_part_info->part_type;
alt_part_info->subpart_type= tab_part_info->subpart_type;
alt_part_info->num_subparts= tab_part_info->num_subparts;
DBUG_ASSERT(!alt_part_info->use_default_partitions);
if (alt_part_info->set_up_defaults_for_partitioning(table->file,
if (alt_part_info->set_up_defaults_for_partitioning(new_table->file,
ULL(0),
0))
{
DBUG_RETURN(TRUE);
goto err;
}
/*
Online handling:
@ -5240,13 +5246,13 @@ the generated partition syntax in a correct manner.
}
else
tab_max_range= part_elem->range_value;
if (*fast_alter_partition &&
if (*fast_alter_table &&
tab_part_info->temp_partitions.push_back(part_elem))
{
mem_alloc_error(1);
DBUG_RETURN(TRUE);
goto err;
}
if (*fast_alter_partition)
if (*fast_alter_table)
part_elem->part_state= PART_TO_BE_REORGED;
if (!found_first)
{
@ -5266,7 +5272,7 @@ the generated partition syntax in a correct manner.
else
alt_max_range= alt_part_elem->range_value;
if (*fast_alter_partition)
if (*fast_alter_table)
alt_part_elem->part_state= PART_TO_BE_ADDED;
if (alt_part_count == 0)
tab_it.replace(alt_part_elem);
@ -5277,7 +5283,7 @@ the generated partition syntax in a correct manner.
else if (found_last)
{
my_error(ER_CONSECUTIVE_REORG_PARTITIONS, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
else
tab_it.remove();
@ -5291,7 +5297,7 @@ the generated partition syntax in a correct manner.
if (drop_count != num_parts_reorged)
{
my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REORGANIZE");
DBUG_RETURN(TRUE);
goto err;
}
tab_part_info->num_parts= check_total_partitions;
}
@ -5312,9 +5318,9 @@ the generated partition syntax in a correct manner.
tab_part_info->use_default_num_subpartitions= FALSE;
}
if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
table->file, ULL(0), TRUE))
new_table->file, ULL(0), TRUE))
{
DBUG_RETURN(TRUE);
goto err;
}
/*
The check below needs to be performed after check_partition_info
@ -5346,7 +5352,7 @@ the generated partition syntax in a correct manner.
to create "holes".
*/
my_error(ER_REORG_OUTSIDE_RANGE, MYF(0));
DBUG_RETURN(TRUE);
goto err;
}
}
}
@ -5463,7 +5469,7 @@ the generated partition syntax in a correct manner.
*partition_changed= TRUE;
if (thd->work_part_info->fix_parser_data(thd))
{
DBUG_RETURN(TRUE);
goto err;
}
}
/*
@ -5484,7 +5490,7 @@ the generated partition syntax in a correct manner.
if (check_native_partitioned(create_info, &is_native_partitioned,
part_info, thd))
{
DBUG_RETURN(TRUE);
goto err;
}
if (!is_native_partitioned)
{
@ -5494,6 +5500,17 @@ the generated partition syntax in a correct manner.
}
}
DBUG_RETURN(FALSE);
err:
if (new_table)
{
/*
Only remove the intermediate table object and its share object,
do not remove the .frm file, since it is the original one.
*/
close_temporary(new_table, 1, 0);
}
*fast_alter_table= NULL;
DBUG_RETURN(TRUE);
}
@ -5536,6 +5553,11 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
if(mysql_trans_prepare_alter_copy_data(thd))
DBUG_RETURN(TRUE);
if (file->ha_external_lock(thd, F_WRLCK))
DBUG_RETURN(TRUE);
/* TODO: test if bulk_insert would increase the performance */
if ((error= file->ha_change_partitions(lpt->create_info, path, &lpt->copied,
&lpt->deleted, lpt->pack_frm_data,
lpt->pack_frm_len)))
@ -5544,7 +5566,10 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
}
if (mysql_trans_commit_alter_copy_data(thd))
DBUG_RETURN(TRUE); /* The error has been reported */
error= 1; /* The error has been reported */
if (file->ha_external_lock(thd, F_UNLCK))
error= 1;
DBUG_RETURN(test(error));
}
@ -6294,8 +6319,18 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
{
THD *thd= lpt->thd;
close_all_tables_for_name(thd, lpt->table->s, FALSE);
if (lpt->old_table)
close_all_tables_for_name(thd, lpt->old_table->s, FALSE);
if (lpt->table)
{
/*
Only remove the intermediate table object and its share object,
do not remove the .frm file, since it is the original one.
*/
close_temporary(lpt->table, 1, 0);
}
lpt->table= 0;
lpt->old_table= 0;
lpt->table_list->table= 0;
if (thd->locked_tables_list.reopen_tables(thd))
sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
@ -6307,62 +6342,40 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
SYNOPSIS
alter_close_tables()
lpt Struct carrying parameters
close_old Close original table too
RETURN VALUES
0
*/
static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt)
static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt, bool close_old)
{
TABLE_SHARE *share= lpt->table->s;
THD *thd= lpt->thd;
TABLE *table;
DBUG_ENTER("alter_close_tables");
/*
We must keep LOCK_open while manipulating with thd->open_tables.
Another thread may be working on it.
*/
mysql_mutex_lock(&LOCK_open);
/*
We can safely remove locks for all tables with the same name:
later they will all be closed anyway in
alter_partition_lock_handling().
*/
for (table= thd->open_tables; table ; table= table->next)
if (lpt->table->db_stat)
{
if (!strcmp(table->s->table_name.str, share->table_name.str) &&
!strcmp(table->s->db.str, share->db.str))
{
mysql_lock_remove(thd, thd->lock, table);
table->file->close();
table->db_stat= 0; // Mark file closed
/*
Ensure that we won't end up with a crippled table instance
in the table cache if an error occurs before we reach
alter_partition_lock_handling() and the table is closed
by close_thread_tables() instead.
*/
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
table->s->db.str,
table->s->table_name.str, TRUE);
}
lpt->table->file->close();
lpt->table->db_stat= 0; // Mark file closed
}
if (close_old && lpt->old_table)
{
close_all_tables_for_name(lpt->thd, lpt->old_table->s, FALSE);
lpt->old_table= 0;
}
mysql_mutex_unlock(&LOCK_open);
DBUG_RETURN(0);
}
/*
Handle errors for ALTER TABLE for partitioning
SYNOPSIS
handle_alter_part_error()
lpt Struct carrying parameters
not_completed Was request in complete phase when error occurred
RETURN VALUES
NONE
/**
Handle errors for ALTER TABLE for partitioning.
@param lpt Struct carrying parameters
@param action_completed The action must be completed, NOT reverted
@param drop_partition Partitions has not been dropped yet
@param frm_install The shadow frm-file has not yet been installed
@param close_table Table is still open, close it before reverting
*/
void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
bool not_completed,
bool action_completed,
bool drop_partition,
bool frm_install,
bool close_table)
@ -6379,7 +6392,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
so we clone it first to have a copy.
*/
part_info= lpt->part_info->get_clone();
alter_close_tables(lpt);
alter_close_tables(lpt, action_completed);
}
if (part_info->first_log_entry &&
@ -6392,7 +6405,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
*/
write_log_completed(lpt, FALSE);
release_log_entries(part_info);
if (not_completed)
if (!action_completed)
{
if (drop_partition)
{
@ -6457,7 +6470,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
else
{
release_log_entries(part_info);
if (not_completed)
if (!action_completed)
{
/*
We hit an error before things were completed but managed
@ -6500,25 +6513,24 @@ static void downgrade_mdl_if_lock_tables_mode(THD *thd, MDL_ticket *ticket,
}
/*
/**
Actually perform the change requested by ALTER TABLE of partitions
previously prepared.
SYNOPSIS
fast_alter_partition_table()
thd Thread object
table Table object
alter_info ALTER TABLE info
create_info Create info for CREATE TABLE
table_list List of the table involved
db Database name of new table
table_name Table name of new table
@param thd Thread object
@param table Original table object
@param alter_info ALTER TABLE info
@param create_info Create info for CREATE TABLE
@param table_list List of the table involved
@param db Database name of new table
@param table_name Table name of new table
@param fast_alter_table Prepared table object
RETURN VALUES
TRUE Error
FALSE Success
@return Operation status
@retval TRUE Error
@retval FALSE Success
DESCRIPTION
@note
Perform all ALTER TABLE operations for partitioned tables that can be
performed fast without a full copy of the original table.
*/
@ -6529,19 +6541,20 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
TABLE_LIST *table_list,
char *db,
const char *table_name,
uint fast_alter_partition)
TABLE *fast_alter_table)
{
/* Set-up struct used to write frm files */
partition_info *part_info= table->part_info;
partition_info *part_info;
ALTER_PARTITION_PARAM_TYPE lpt_obj;
ALTER_PARTITION_PARAM_TYPE *lpt= &lpt_obj;
bool written_bin_log= TRUE;
bool not_completed= TRUE;
bool action_completed= FALSE;
bool close_table_on_failure= FALSE;
bool frm_install= FALSE;
MDL_ticket *mdl_ticket= table->mdl_ticket;
DBUG_ASSERT(fast_alter_table);
DBUG_ENTER("fast_alter_partition_table");
part_info= fast_alter_table->part_info;
lpt->thd= thd;
lpt->table_list= table_list;
lpt->part_info= part_info;
@ -6550,7 +6563,8 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->db_options= create_info->table_options;
if (create_info->row_type == ROW_TYPE_DYNAMIC)
lpt->db_options|= HA_OPTION_PACK_RECORD;
lpt->table= table;
lpt->table= fast_alter_table;
lpt->old_table= table;
lpt->key_info_buffer= 0;
lpt->key_count= 0;
lpt->db= db;
@ -6559,12 +6573,12 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->deleted= 0;
lpt->pack_frm_data= NULL;
lpt->pack_frm_len= 0;
thd->work_part_info= part_info;
/* Never update timestamp columns when alter */
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
lpt->table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
if (fast_alter_partition & HA_PARTITION_ONE_PHASE)
if (table->file->alter_table_flags(alter_info->flags) &
HA_PARTITION_ONE_PHASE)
{
/*
In the case where the engine supports one phase online partition
@ -6681,11 +6695,11 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_ERROR("fail_drop_partition_3") ||
(close_table_on_failure= TRUE, FALSE) ||
write_log_drop_partition(lpt) ||
(action_completed= TRUE, FALSE) ||
ERROR_INJECT_CRASH("crash_drop_partition_4") ||
ERROR_INJECT_ERROR("fail_drop_partition_4") ||
alter_close_tables(lpt, action_completed) ||
(close_table_on_failure= FALSE, FALSE) ||
(not_completed= FALSE, FALSE) ||
alter_close_tables(lpt) ||
ERROR_INJECT_CRASH("crash_drop_partition_5") ||
ERROR_INJECT_ERROR("fail_drop_partition_5") ||
((!thd->lex->no_write_to_binlog) &&
@ -6706,7 +6720,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_ERROR("fail_drop_partition_9") ||
(alter_partition_lock_handling(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, TRUE, frm_install,
handle_alter_part_error(lpt, action_completed, TRUE, frm_install,
close_table_on_failure);
goto err;
}
@ -6761,7 +6775,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_add_partition_5") ||
ERROR_INJECT_ERROR("fail_add_partition_5") ||
(close_table_on_failure= FALSE, FALSE) ||
alter_close_tables(lpt) ||
alter_close_tables(lpt, action_completed) ||
ERROR_INJECT_CRASH("crash_add_partition_6") ||
ERROR_INJECT_ERROR("fail_add_partition_6") ||
((!thd->lex->no_write_to_binlog) &&
@ -6770,11 +6784,12 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_add_partition_7") ||
ERROR_INJECT_ERROR("fail_add_partition_7") ||
write_log_rename_frm(lpt) ||
(frm_install= TRUE, FALSE) ||
(not_completed= FALSE, FALSE) ||
(action_completed= TRUE, FALSE) ||
ERROR_INJECT_CRASH("crash_add_partition_8") ||
ERROR_INJECT_ERROR("fail_add_partition_8") ||
(frm_install= TRUE, FALSE) ||
mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
(frm_install= FALSE, FALSE) ||
ERROR_INJECT_CRASH("crash_add_partition_9") ||
ERROR_INJECT_ERROR("fail_add_partition_9") ||
(write_log_completed(lpt, FALSE), FALSE) ||
@ -6782,7 +6797,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_ERROR("fail_add_partition_10") ||
(alter_partition_lock_handling(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, FALSE, frm_install,
handle_alter_part_error(lpt, action_completed, FALSE, frm_install,
close_table_on_failure);
goto err;
}
@ -6831,10 +6846,10 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
can release all other locks on the table and since no one can open
the table, there can be no new threads accessing the table. They
will be hanging on this exclusive lock.
5) Close all instances of the table and remove them from the table cache.
6) Log that operation is completed and log all complete actions
5) Log that operation is completed and log all complete actions
needed to complete operation from here
7) Write bin log
6) Write bin log
7) Close all instances of the table and remove them from the table cache.
8) Prepare handlers for rename and delete of partitions
9) Rename and drop the reorged partitions such that they are no
longer used and rename those added to their real new names.
@ -6858,27 +6873,28 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN) ||
ERROR_INJECT_CRASH("crash_change_partition_5") ||
ERROR_INJECT_ERROR("fail_change_partition_5") ||
alter_close_tables(lpt) ||
(close_table_on_failure= FALSE) ||
write_log_final_change_partition(lpt) ||
(action_completed= TRUE, FALSE) ||
ERROR_INJECT_CRASH("crash_change_partition_6") ||
ERROR_INJECT_ERROR("fail_change_partition_6") ||
write_log_final_change_partition(lpt) ||
(not_completed= FALSE) ||
ERROR_INJECT_CRASH("crash_change_partition_7") ||
ERROR_INJECT_ERROR("fail_change_partition_7") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
thd->query(), thd->query_length()), FALSE)) ||
ERROR_INJECT_CRASH("crash_change_partition_7") ||
ERROR_INJECT_ERROR("fail_change_partition_7") ||
((frm_install= TRUE), FALSE) ||
mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
(frm_install= FALSE, FALSE) ||
ERROR_INJECT_CRASH("crash_change_partition_8") ||
ERROR_INJECT_ERROR("fail_change_partition_8") ||
mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
alter_close_tables(lpt, action_completed) ||
(close_table_on_failure= FALSE, FALSE) ||
ERROR_INJECT_CRASH("crash_change_partition_9") ||
ERROR_INJECT_ERROR("fail_change_partition_9") ||
mysql_drop_partitions(lpt) ||
ERROR_INJECT_CRASH("crash_change_partition_10") ||
ERROR_INJECT_ERROR("fail_change_partition_10") ||
mysql_rename_partitions(lpt) ||
((frm_install= TRUE), FALSE) ||
ERROR_INJECT_CRASH("crash_change_partition_11") ||
ERROR_INJECT_ERROR("fail_change_partition_11") ||
(write_log_completed(lpt, FALSE), FALSE) ||
@ -6886,7 +6902,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_ERROR("fail_change_partition_12") ||
(alter_partition_lock_handling(lpt), FALSE))
{
handle_alter_part_error(lpt, not_completed, FALSE, frm_install,
handle_alter_part_error(lpt, action_completed, FALSE, frm_install,
close_table_on_failure);
goto err;
}
@ -6896,12 +6912,25 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
A final step is to write the query to the binlog and send ok to the
user
*/
DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted,
table_list, FALSE, NULL,
written_bin_log));
DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted, table_list));
err:
if (action_completed)
{
/*
Although error occurred, the action was forced to retry for completion.
Therefore we must close+reopen all instances of the table.
*/
(void) alter_partition_lock_handling(lpt);
}
else
{
/*
The failed action was reverted, leave the original table as is and
close/destroy the intermediate table object and its share.
*/
close_temporary(lpt->table, 1, 0);
}
downgrade_mdl_if_lock_tables_mode(thd, mdl_ticket, MDL_SHARED_NO_READ_WRITE);
table->m_needs_reopen= TRUE;
DBUG_RETURN(TRUE);
}
#endif

View File

@ -54,6 +54,7 @@ typedef struct st_lock_param_type
HA_CREATE_INFO *create_info;
Alter_info *alter_info;
TABLE *table;
TABLE *old_table;
KEY *key_info_buffer;
const char *db;
const char *table_name;
@ -252,14 +253,17 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
TABLE_LIST *table_list,
char *db,
const char *table_name,
uint fast_alter_partition);
TABLE *fast_alter_table);
uint set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
enum partition_state part_state);
uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
HA_CREATE_INFO *create_info,
handlerton *old_db_type,
bool *partition_changed,
uint *fast_alter_partition);
char *db,
const char *table_name,
const char *path,
TABLE **fast_alter_table);
char *generate_partition_syntax(partition_info *part_info,
uint *buf_length, bool use_sql_alloc,
bool show_partition_options,

View File

@ -1725,8 +1725,6 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
CHF_DELETE_FLAG, NULL) ||
deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) ||
(sync_ddl_log(), FALSE) ||
#endif
#ifdef WITH_PARTITION_STORAGE_ENGINE
mysql_file_rename(key_file_frm,
shadow_frm_name, frm_name, MYF(MY_WME)) ||
lpt->table->file->ha_create_handler_files(path, shadow_path,
@ -5605,7 +5603,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
handlerton *old_db_type, *new_db_type, *save_old_db_type;
enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY;
#ifdef WITH_PARTITION_STORAGE_ENGINE
uint fast_alter_partition= 0;
TABLE *table_for_fast_alter_partition= NULL;
bool partition_changed= FALSE;
#endif
bool need_lock_for_indexes= TRUE;
@ -5975,7 +5973,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type,
&partition_changed, &fast_alter_partition))
&partition_changed,
db, table_name, path,
&table_for_fast_alter_partition))
goto err;
#endif
/*
@ -6208,12 +6208,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
create_info->frm_only= 1;
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (fast_alter_partition)
if (table_for_fast_alter_partition)
{
DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
create_info, table_list,
db, table_name,
fast_alter_partition));
table_for_fast_alter_partition));
}
#endif
@ -6693,6 +6693,11 @@ err_new_table_cleanup:
create_info->frm_only ? FN_IS_TMP | FRM_ONLY : FN_IS_TMP);
err:
#ifdef WITH_PARTITION_STORAGE_ENGINE
/* If prep_alter_part_table created an intermediate table, destroy it. */
if (table_for_fast_alter_partition)
close_temporary(table_for_fast_alter_partition, 1, 0);
#endif /* WITH_PARTITION_STORAGE_ENGINE */
/*
No default value was provided for a DATE/DATETIME field, the
current sql_mode doesn't allow the '0000-00-00' value and

View File

@ -4814,7 +4814,7 @@ part_value_expr_item:
if (!lex->safe_to_cache_query)
{
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
my_parse_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
MYSQL_YYABORT;
}
if (part_info->add_column_list_value(YYTHD, part_expr))

View File

@ -426,6 +426,18 @@ void TABLE_SHARE::destroy()
info_it->flags= 0;
}
}
if (ha_data_destroy)
{
ha_data_destroy(ha_data);
ha_data_destroy= NULL;
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (ha_part_data_destroy)
{
ha_part_data_destroy(ha_part_data);
ha_part_data_destroy= NULL;
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */
/*
Make a copy since the share is allocated in its own root,
and free_root() updates its argument after freeing the memory.
@ -1704,11 +1716,17 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
delete handler_file;
my_hash_free(&share->name_hash);
if (share->ha_data_destroy)
{
share->ha_data_destroy(share->ha_data);
share->ha_data_destroy= NULL;
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (share->ha_part_data_destroy)
{
share->ha_part_data_destroy(share->ha_part_data);
#endif
share->ha_data_destroy= NULL;
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */
open_table_error(share, error, share->open_errno, errarg);
DBUG_RETURN(error);