Skip to content

Commit 4bc268d

Browse files
authored
MDEV-14632 Assertion `!((new_col->prtype ^ col->prtype) & ~256U)' failed in row_log_table_apply_convert_mrec
SQL, IB: proper fix is to disable unimplemented Online DDL for system-versioned tables inside InnoDB
1 parent b13f1cc commit 4bc268d

File tree

10 files changed

+118
-54
lines changed

10 files changed

+118
-54
lines changed

mysql-test/suite/versioning/r/alter.result

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,6 @@ a
305305
1
306306
call verify_vtq;
307307
No A B C D
308-
alter table t drop system versioning, algorithm=inplace;
309-
call verify_vtq;
310-
No A B C D
311-
alter table t add system versioning;
312308
alter table t drop system versioning, algorithm=copy;
313309
show create table t;
314310
Table Create Table
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
set system_versioning_alter_history=keep;
2+
create or replace table t (a int) engine=innodb;
3+
alter table t add system versioning, lock=none;
4+
ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED
5+
alter table t add system versioning;
6+
alter table t add index idx(a), lock=none;
7+
ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED
8+
alter table t drop system versioning, lock=none;
9+
ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED
10+
set global system_versioning_transaction_registry=on;
11+
Warnings:
12+
Warning 4144 Transaction-based system versioning is EXPERIMENTAL and is subject to change in future.
13+
create or replace table t (a int) engine=innodb;
14+
alter table t
15+
add s bigint unsigned as row start,
16+
add e bigint unsigned as row end,
17+
add period for system_time(s, e),
18+
add system versioning,
19+
lock=none;
20+
ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED
21+
alter table t
22+
add s bigint unsigned as row start,
23+
add e bigint unsigned as row end,
24+
add period for system_time(s, e),
25+
add system versioning;
26+
alter table t add index idx(a), lock=none;
27+
ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED
28+
alter table t drop column s, drop column e;
29+
alter table t drop system versioning, lock=none;
30+
ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED
31+
set global system_versioning_transaction_registry=off;
32+
drop table t;

mysql-test/suite/versioning/t/alter.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,12 @@ show create table t;
198198
select * from t for system_time all;
199199
call verify_vtq;
200200

201-
alter table t drop system versioning, algorithm=inplace;
202-
call verify_vtq;
203201
## FIXME: #414 IB: inplace for VERS_TIMESTAMP versioning
204202
if (0)
205203
{
204+
alter table t drop system versioning, algorithm=inplace;
205+
call verify_vtq;
206+
206207
alter table t add system versioning, algorithm=inplace;
207208
call verify_vtq;
208209
show create table t;
@@ -220,7 +221,6 @@ alter table t drop column b, algorithm=inplace;
220221
show create table t;
221222
select * from t for system_time all;
222223
}
223-
alter table t add system versioning;
224224
## FIXME END
225225

226226
alter table t drop system versioning, algorithm=copy;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--source include/have_innodb.inc
2+
3+
set system_versioning_alter_history=keep;
4+
5+
create or replace table t (a int) engine=innodb;
6+
7+
--error ER_ALTER_OPERATION_NOT_SUPPORTED
8+
alter table t add system versioning, lock=none;
9+
alter table t add system versioning;
10+
--error ER_ALTER_OPERATION_NOT_SUPPORTED
11+
alter table t add index idx(a), lock=none;
12+
--error ER_ALTER_OPERATION_NOT_SUPPORTED
13+
alter table t drop system versioning, lock=none;
14+
15+
16+
set global system_versioning_transaction_registry=on;
17+
create or replace table t (a int) engine=innodb;
18+
19+
--error ER_ALTER_OPERATION_NOT_SUPPORTED
20+
alter table t
21+
add s bigint unsigned as row start,
22+
add e bigint unsigned as row end,
23+
add period for system_time(s, e),
24+
add system versioning,
25+
lock=none;
26+
alter table t
27+
add s bigint unsigned as row start,
28+
add e bigint unsigned as row end,
29+
add period for system_time(s, e),
30+
add system versioning;
31+
--error ER_ALTER_OPERATION_NOT_SUPPORTED
32+
alter table t add index idx(a), lock=none;
33+
alter table t drop column s, drop column e;
34+
--error ER_ALTER_OPERATION_NOT_SUPPORTED
35+
alter table t drop system versioning, lock=none;
36+
37+
set global system_versioning_transaction_registry=off;
38+
39+
drop table t;

sql/handler.cc

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6885,7 +6885,7 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
68856885
List<Item> *items,
68866886
bool *versioned_write)
68876887
{
6888-
DBUG_ASSERT(!vers_info.without_system_versioning);
6888+
DBUG_ASSERT(!(alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING));
68896889
int vers_tables= 0;
68906890

68916891
if (select_tables)
@@ -6901,13 +6901,13 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
69016901
// then created table will be versioned.
69026902
if (thd->variables.vers_force)
69036903
{
6904-
vers_info.with_system_versioning= true;
6904+
alter_info->flags|= Alter_info::ALTER_ADD_SYSTEM_VERSIONING;
69056905
options|= HA_VERSIONED_TABLE;
69066906
}
69076907

69086908
// Possibly override default storage engine to match one used in source table.
6909-
if (vers_tables && vers_info.with_system_versioning &&
6910-
!(used_fields & HA_CREATE_USED_ENGINE))
6909+
if (vers_tables && alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING &&
6910+
!(used_fields & HA_CREATE_USED_ENGINE))
69116911
{
69126912
List_iterator_fast<Create_field> it(alter_info->create_list);
69136913
while (Create_field *f= it++)
@@ -6923,19 +6923,18 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
69236923
}
69246924
}
69256925

6926-
if (!vers_info.need_check())
6926+
if (!vers_info.need_check(alter_info))
69276927
return false;
69286928

6929-
if (!vers_info.versioned_fields &&
6930-
vers_info.unversioned_fields &&
6931-
!vers_info.with_system_versioning)
6929+
if (!vers_info.versioned_fields && vers_info.unversioned_fields &&
6930+
!(alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING))
69326931
{
69336932
// All is correct but this table is not versioned.
69346933
options&= ~HA_VERSIONED_TABLE;
69356934
return false;
69366935
}
69376936

6938-
if (!vers_info.with_system_versioning && vers_info)
6937+
if (!(alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING) && vers_info)
69396938
{
69406939
my_error(ER_MISSING, MYF(0), create_table.table_name, "WITH SYSTEM VERSIONING");
69416940
return true;
@@ -6953,7 +6952,7 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
69536952
while (Create_field *f= it++)
69546953
{
69556954
if ((f->versioning == Column_definition::VERSIONING_NOT_SET &&
6956-
!vers_info.with_system_versioning) ||
6955+
!(alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING)) ||
69576956
f->versioning == Column_definition::WITHOUT_VERSIONING)
69586957
{
69596958
f->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
@@ -7110,28 +7109,16 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info,
71107109
TABLE_SHARE *share= table->s;
71117110
const char *table_name= share->table_name.str;
71127111

7113-
if (!need_check() && !share->versioned)
7112+
if (!need_check(alter_info) && !share->versioned)
71147113
return false;
71157114

7116-
if (with_system_versioning || without_system_versioning)
7117-
{
7118-
// Disable Online DDL which is not implemented yet for ADD/DROP SYSTEM VERSIONING.
7119-
if (thd->mdl_context.upgrade_shared_lock(table->mdl_ticket, MDL_EXCLUSIVE,
7120-
thd->variables.lock_wait_timeout))
7121-
{
7122-
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
7123-
return true;
7124-
}
7125-
alter_info->requested_lock= Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE;
7126-
}
7127-
7128-
if (with_system_versioning && table->versioned())
7115+
if (alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING && table->versioned())
71297116
{
71307117
my_error(ER_VERS_ALREADY_VERSIONED, MYF(0), table_name);
71317118
return true;
71327119
}
71337120

7134-
if (without_system_versioning)
7121+
if (alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING)
71357122
{
71367123
if (!share->versioned)
71377124
{
@@ -7300,7 +7287,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info,
73007287
if (fix_implicit(thd, alter_info))
73017288
return true;
73027289

7303-
if (with_system_versioning)
7290+
if (alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING)
73047291
{
73057292
if (check_with_conditions(table_name))
73067293
return true;
@@ -7370,6 +7357,12 @@ Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_
73707357
return false;
73717358
}
73727359

7360+
bool Vers_parse_info::need_check(const Alter_info *alter_info) const
7361+
{
7362+
return versioned_fields || unversioned_fields ||
7363+
alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING ||
7364+
alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING || *this;
7365+
}
73737366

73747367
bool Vers_parse_info::check_with_conditions(const char *table_name) const
73757368
{

sql/handler.h

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,8 +1715,6 @@ class Create_field;
17151715
struct Vers_parse_info
17161716
{
17171717
Vers_parse_info() :
1718-
with_system_versioning(false),
1719-
without_system_versioning(false),
17201718
versioned_fields(false),
17211719
unversioned_fields(false)
17221720
{}
@@ -1762,15 +1760,7 @@ struct Vers_parse_info
17621760
{
17631761
return as_row.start || as_row.end || system_time.start || system_time.end;
17641762
}
1765-
bool need_check() const
1766-
{
1767-
return
1768-
versioned_fields ||
1769-
unversioned_fields ||
1770-
with_system_versioning ||
1771-
without_system_versioning ||
1772-
*this;
1773-
}
1763+
bool need_check(const Alter_info *alter_info) const;
17741764
bool check_with_conditions(const char *table_name) const;
17751765
bool check_sys_fields(const char *table_name, Alter_info *alter_info,
17761766
bool native) const;
@@ -1784,10 +1774,6 @@ struct Vers_parse_info
17841774
bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info,
17851775
TABLE_LIST &src_table, TABLE_LIST &table);
17861776

1787-
/** Table definition has 'WITH/WITHOUT SYSTEM VERSIONING' */
1788-
bool with_system_versioning : 1;
1789-
bool without_system_versioning : 1;
1790-
17911777
/**
17921778
At least one field was specified 'WITH/WITHOUT SYSTEM VERSIONING'.
17931779
Useful for error handling.
@@ -2170,6 +2156,10 @@ class Alter_inplace_info
21702156

21712157
static const HA_ALTER_FLAGS ALTER_COLUMN_UNVERSIONED = 1ULL << 42;
21722158

2159+
static const HA_ALTER_FLAGS ALTER_ADD_SYSTEM_VERSIONING= 1ULL << 43;
2160+
2161+
static const HA_ALTER_FLAGS ALTER_DROP_SYSTEM_VERSIONING= 1ULL << 44;
2162+
21732163
/**
21742164
Create options (like MAX_ROWS) for the new version of table.
21752165

sql/sql_alter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class Alter_info
9797
ALTER_ADD_CHECK_CONSTRAINT = 1L << 27,
9898
ALTER_DROP_CHECK_CONSTRAINT = 1L << 28,
9999
ALTER_COLUMN_UNVERSIONED = 1L << 29,
100+
ALTER_ADD_SYSTEM_VERSIONING = 1L << 30,
101+
ALTER_DROP_SYSTEM_VERSIONING= 1L << 31,
100102
};
101103

102104
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };

sql/sql_table.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6564,6 +6564,10 @@ static bool fill_alter_inplace_info(THD *thd,
65646564
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_DROP_HISTORICAL;
65656565
if (alter_info->flags & Alter_info::ALTER_COLUMN_UNVERSIONED)
65666566
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_UNVERSIONED;
6567+
if (alter_info->flags & Alter_info::ALTER_ADD_SYSTEM_VERSIONING)
6568+
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_ADD_SYSTEM_VERSIONING;
6569+
if (alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING)
6570+
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_DROP_SYSTEM_VERSIONING;
65676571

65686572
/*
65696573
If we altering table with old VARCHAR fields we will be automatically

sql/sql_yacc.yy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6242,7 +6242,7 @@ versioning_option:
62426242
}
62436243
else
62446244
{
6245-
Lex->vers_get_info().with_system_versioning= true;
6245+
Lex->alter_info.flags|= Alter_info::ALTER_ADD_SYSTEM_VERSIONING;
62466246
Lex->create_info.options|= HA_VERSIONED_TABLE;
62476247
}
62486248
}
@@ -8250,12 +8250,12 @@ alter_list_item:
82508250
| alter_lock_option
82518251
| ADD SYSTEM VERSIONING_SYM
82528252
{
8253-
Lex->vers_get_info().with_system_versioning= true;
8253+
Lex->alter_info.flags|= Alter_info::ALTER_ADD_SYSTEM_VERSIONING;
82548254
Lex->create_info.options|= HA_VERSIONED_TABLE;
82558255
}
82568256
| DROP SYSTEM VERSIONING_SYM
82578257
{
8258-
Lex->vers_get_info().without_system_versioning= true;
8258+
Lex->alter_info.flags|= Alter_info::ALTER_DROP_SYSTEM_VERSIONING;
82598259
}
82608260
;
82618261

storage/innobase/handler/handler0alter.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ instant_alter_column_possible(
633633
const TABLE* table)
634634
{
635635
// Making table system-versioned instantly is not implemented yet.
636-
if (ha_alter_info->create_info->vers_info.with_system_versioning) {
636+
if (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_ADD_SYSTEM_VERSIONING) {
637637
return false;
638638
}
639639

@@ -694,9 +694,10 @@ ha_innobase::check_if_supported_inplace_alter(
694694
{
695695
DBUG_ENTER("check_if_supported_inplace_alter");
696696

697-
if (altered_table->versioned(VERS_TIMESTAMP)) {
697+
if (altered_table->versioned(VERS_TIMESTAMP)
698+
|| ha_alter_info->handler_flags & Alter_inplace_info::ALTER_DROP_SYSTEM_VERSIONING) {
698699
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
699-
}
700+
}
700701

701702
/* Before 10.2.2 information about virtual columns was not stored in
702703
system tables. We need to do a full alter to rebuild proper 10.2.2+
@@ -1226,6 +1227,13 @@ ha_innobase::check_if_supported_inplace_alter(
12261227
}
12271228
}
12281229

1230+
// FIXME: implement Online DDL for system-versioned tables
1231+
DBUG_ASSERT(!altered_table->versioned(VERS_TIMESTAMP));
1232+
if (altered_table->versioned(VERS_TRX_ID)
1233+
|| ha_alter_info->handler_flags & Alter_inplace_info::ALTER_DROP_SYSTEM_VERSIONING) {
1234+
online = false;
1235+
}
1236+
12291237
DBUG_RETURN(online
12301238
? HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE
12311239
: HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE);

0 commit comments

Comments
 (0)