Skip to content

Commit

Permalink
MDEV-22164 without validation for exchange partition/convert in
Browse files Browse the repository at this point in the history
1. WITHOUT/WITH VALIDATION may be added to EXCHANGE PARTITION or CONVERT TABLE:

  alter table tp exchange partition p1 with table t with validation;
  alter table tp exchange partition p1 with table t; -- same as with validation
  alter table tp exchange partition p1 with table t without validation;

2. Optional THAN keyword for RANGE partitioning. Normally you type:

  create table tp (a int primary key) partition by range (a) (
    partition p0 values less than (100),
    partition p1 values less than maxvalue);

  Now you may type (PARTITION keyword is also optional):

  create table tp (a int primary key) partition by range (a) (
    p0 values less (100),
    p1 values less maxvalue);
  • Loading branch information
midenok committed Dec 7, 2023
1 parent 485773a commit 5462b61
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 5 deletions.
174 changes: 174 additions & 0 deletions mysql-test/suite/parts/r/alter_table.result
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,177 @@ disconnect con1;
connection default;
drop user u@localhost;
drop database db;
#
# MDEV-22164 without validation for exchange partition/convert in
#
create table validation(x int);
drop table validation;
create table t (a int primary key);
create table tp (a int primary key) partition by range (a) (
partition p0 values less than (100),
# Cunning syntax (same as above)
p1 values less (300));
insert into t values (1), (99);
insert into tp values (2), (200);
select * from t order by a;
a
1
99
select * from tp partition (p0) order by a;
a
2
select * from tp partition (p1) order by a;
a
200
alter table tp exchange partition p0 with table t;
select * from t order by a;
a
2
select * from tp partition (p0) order by a;
a
1
99
select * from tp partition (p1) order by a;
a
200
alter table tp exchange partition p0 with table t;
select * from t order by a;
a
1
99
select * from tp partition (p0) order by a;
a
2
select * from tp partition (p1) order by a;
a
200
alter table tp exchange partition p1 with table t;
ERROR HY000: Found a row that does not match the partition
alter table tp exchange partition p1 with table t with validation;
ERROR HY000: Found a row that does not match the partition
alter table tp exchange partition p1 with table t without validation;
select * from t order by a;
a
200
select * from tp partition (p1) order by a;
a
1
99
alter table tp check partition p0;
Table Op Msg_type Msg_text
test.tp check status OK
alter table tp check partition p1;
Table Op Msg_type Msg_text
test.tp check error Found a misplaced row
test.tp check error Partition p1 returned error
test.tp check error Upgrade required. Please do "REPAIR TABLE `tp`" or dump/reload to fix it!
alter table tp exchange partition p1 with table t with validation;
alter table tp exchange partition p1 with table t with validation;
ERROR HY000: Found a row that does not match the partition
select * from t order by a;
a
1
99
select * from tp partition (p1) order by a;
a
200
create or replace procedure validation()
alter table tp exchange partition p1 with table t with validation;
create or replace procedure without_validation()
alter table tp exchange partition p1 with table t without validation;
call validation;
ERROR HY000: Found a row that does not match the partition
call without_validation;
call validation;
call validation;
ERROR HY000: Found a row that does not match the partition
call without_validation;
select * from t order by a;
a
200
select * from tp partition (p1) order by a;
a
1
99
call validation;
select * from t order by a;
a
1
99
select * from tp partition (p1) order by a;
a
200
drop procedure validation;
drop procedure without_validation;
prepare validation from "alter table tp exchange partition p1 with table t with validation";
prepare without_validation from "alter table tp exchange partition p1 with table t without validation";
execute validation;
ERROR HY000: Found a row that does not match the partition
execute without_validation;
execute validation;
execute validation;
ERROR HY000: Found a row that does not match the partition
execute without_validation;
select * from t order by a;
a
200
select * from tp partition (p1) order by a;
a
1
99
execute validation;
select * from t order by a;
a
1
99
select * from tp partition (p1) order by a;
a
200
drop prepare validation;
drop prepare without_validation;
alter table tp convert table t to partition p2 values less (maxvalue);
ERROR HY000: Found a row that does not match the partition
alter table tp convert table t to partition p2 values less (maxvalue) with validation;
ERROR HY000: Found a row that does not match the partition
alter table tp convert table t to partition p2 values less (maxvalue) without validation;
select * from tp partition (p0) order by a;
a
2
select * from tp partition (p1) order by a;
a
200
select * from tp partition (p2) order by a;
a
1
99
create table t (a int primary key);
insert t values (1), (2);
create or replace table tp (a int primary key)
partition by hash(a) partitions 2;
insert tp values (1), (2), (3), (4);
alter table tp exchange partition p0 with table t;
ERROR HY000: Found a row that does not match the partition
alter table tp exchange partition p0 with table t without validation;
select * from t;
a
2
4
alter table tp exchange partition p0 with table t;
drop table tp;
create or replace table tp (a int primary key)
partition by list(a) (
partition p0 values in (2, 3, 4),
partition p1 values in (12, 13, 14),
partition p2 values in (52, 53, 54));
insert tp values (12), (2), (3), (4);
alter table tp exchange partition p0 with table t;
ERROR HY000: Table has no partition for value 0
alter table tp exchange partition p0 with table t without validation;
select * from t;
a
2
3
4
alter table tp exchange partition p0 with table t;
drop tables tp, t;
# End of 11.4 tests
129 changes: 129 additions & 0 deletions mysql-test/suite/parts/t/alter_table.test
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,132 @@ alter table t1 convert table tp to partition p2 values less than (1000);
--connection default
drop user u@localhost;
drop database db;

--echo #
--echo # MDEV-22164 without validation for exchange partition/convert in
--echo #

create table validation(x int);
drop table validation;

create table t (a int primary key);

create table tp (a int primary key) partition by range (a) (
partition p0 values less than (100),
# Cunning syntax (same as above)
p1 values less (300));

insert into t values (1), (99);
insert into tp values (2), (200);

select * from t order by a;
select * from tp partition (p0) order by a;
select * from tp partition (p1) order by a;

alter table tp exchange partition p0 with table t;
select * from t order by a;
select * from tp partition (p0) order by a;
select * from tp partition (p1) order by a;

alter table tp exchange partition p0 with table t;
select * from t order by a;
select * from tp partition (p0) order by a;
select * from tp partition (p1) order by a;

--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table tp exchange partition p1 with table t;
--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table tp exchange partition p1 with table t with validation;
alter table tp exchange partition p1 with table t without validation;
select * from t order by a;
select * from tp partition (p1) order by a;
alter table tp check partition p0;
alter table tp check partition p1;

alter table tp exchange partition p1 with table t with validation;
--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table tp exchange partition p1 with table t with validation;
select * from t order by a;
select * from tp partition (p1) order by a;

# SP
create or replace procedure validation()
alter table tp exchange partition p1 with table t with validation;
create or replace procedure without_validation()
alter table tp exchange partition p1 with table t without validation;
--error ER_ROW_DOES_NOT_MATCH_PARTITION
call validation;
call without_validation;
call validation;
--error ER_ROW_DOES_NOT_MATCH_PARTITION
call validation;
call without_validation;
select * from t order by a;
select * from tp partition (p1) order by a;
call validation;
select * from t order by a;
select * from tp partition (p1) order by a;
drop procedure validation;
drop procedure without_validation;

# PS
prepare validation from "alter table tp exchange partition p1 with table t with validation";
prepare without_validation from "alter table tp exchange partition p1 with table t without validation";
--error ER_ROW_DOES_NOT_MATCH_PARTITION
execute validation;
execute without_validation;
execute validation;
--error ER_ROW_DOES_NOT_MATCH_PARTITION
execute validation;
execute without_validation;
select * from t order by a;
select * from tp partition (p1) order by a;
execute validation;
select * from t order by a;
select * from tp partition (p1) order by a;
drop prepare validation;
drop prepare without_validation;

# CONVERT IN
--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table tp convert table t to partition p2 values less (maxvalue);
--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table tp convert table t to partition p2 values less (maxvalue) with validation;
alter table tp convert table t to partition p2 values less (maxvalue) without validation;
select * from tp partition (p0) order by a;
select * from tp partition (p1) order by a;
select * from tp partition (p2) order by a;

# Hash
create table t (a int primary key);
insert t values (1), (2);

create or replace table tp (a int primary key)
partition by hash(a) partitions 2;

insert tp values (1), (2), (3), (4);
--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table tp exchange partition p0 with table t;
alter table tp exchange partition p0 with table t without validation;
select * from t;
alter table tp exchange partition p0 with table t;
drop table tp;

# List
create or replace table tp (a int primary key)
partition by list(a) (
partition p0 values in (2, 3, 4),
partition p1 values in (12, 13, 14),
partition p2 values in (52, 53, 54));


insert tp values (12), (2), (3), (4);
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
alter table tp exchange partition p0 with table t;
alter table tp exchange partition p0 with table t without validation;
select * from t;
alter table tp exchange partition p0 with table t;

drop tables tp, t;

--echo # End of 11.4 tests
1 change: 1 addition & 0 deletions sql/lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,7 @@ SYMBOL symbols[] = {
{ "UTC_DATE", SYM(UTC_DATE_SYM)},
{ "UTC_TIME", SYM(UTC_TIME_SYM)},
{ "UTC_TIMESTAMP", SYM(UTC_TIMESTAMP_SYM)},
{ "VALIDATION", SYM(VALIDATION_SYM)},
{ "VALUE", SYM(VALUE_SYM)},
{ "VALUES", SYM(VALUES)},
{ "VARBINARY", SYM(VARBINARY)},
Expand Down
3 changes: 2 additions & 1 deletion sql/sql_lex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,7 @@ void LEX::start(THD *thd_arg)
default_used= 0;
with_rownum= FALSE;
is_lex_started= 1;
without_validation= 0;

create_info.lex_start();
name= null_clex_str;
Expand Down Expand Up @@ -3932,7 +3933,7 @@ LEX::LEX()
: explain(NULL), result(0), part_info(NULL), arena_for_set_stmt(0),
mem_root_for_set_stmt(0), json_table(NULL), analyze_stmt(0),
default_used(0),
with_rownum(0), is_lex_started(0), option_type(OPT_DEFAULT),
with_rownum(0), is_lex_started(0), without_validation(0), option_type(OPT_DEFAULT),
context_analysis_only(0), sphead(0), sp_mem_root_ptr(nullptr),
limit_rows_examined_cnt(ULONGLONG_MAX)
{
Expand Down
1 change: 1 addition & 0 deletions sql/sql_lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -3440,6 +3440,7 @@ struct LEX: public Query_tables_list
bool default_used:1; /* using default() function */
bool with_rownum:1; /* Using rownum() function */
bool is_lex_started:1; /* If lex_start() did run. For debugging. */
bool without_validation:1; /* exchange or convert partition WITHOUT VALIDATION */

/*
This variable is used in post-parse stage to declare that sum-functions,
Expand Down
3 changes: 3 additions & 0 deletions sql/sql_partition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4107,6 +4107,9 @@ bool verify_data_with_partition(TABLE *table, TABLE *part_table,
DBUG_ASSERT(table && table->file && part_table && part_table->part_info &&
part_table->file);

if (table->in_use->lex->without_validation)
DBUG_RETURN(false);

/*
Verify all table rows.
First implementation uses full scan + evaluates partition functions for
Expand Down

0 comments on commit 5462b61

Please sign in to comment.