Commit 9dc81f7d authored by Eugene Kosov's avatar Eugene Kosov Committed by Marko Mäkelä

MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute

Changing columns WITH/WITHOUT SYSTEM VERSIONING doens't require to read data at
all. Thus it should be an instant operation.

Patch also fixes a bug when ALTER_COLUMN_UNVERSIONED wasn't passed to InnoDB
to change its internal structures.

change_field_versioning_try(): apply WITH/WITHOUT SYSTEM VERSIONING
change in SYS_COLUMNS for one field.

change_fields_versioning_try(): apply WITH/WITHOUT SYSTEM VERSIONING
change in SYS_COLUMNS for every changed field in a table.

change_fields_versioning_cache(): update cache for versioning property
of columns.
parent ff09512e
...@@ -379,3 +379,99 @@ DROP TABLE tts; ...@@ -379,3 +379,99 @@ DROP TABLE tts;
DROP TABLE ttx; DROP TABLE ttx;
DROP FUNCTION fts; DROP FUNCTION fts;
DROP FUNCTION ftx; DROP FUNCTION ftx;
#
# MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute
#
SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP;
CREATE TABLE t (
a INT,
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
INSERT INTO t VALUES (1,1);
# without table rebuild
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='a';
prtype
50179
ALTER TABLE t
CHANGE a a INT WITHOUT SYSTEM VERSIONING;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='a';
prtype
1027
UPDATE t SET a=11;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
COUNT(*)
1
# with table rebuild
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='a';
prtype
1027
ALTER TABLE t
CHANGE a a INT WITH SYSTEM VERSIONING,
ADD PRIMARY KEY pk(a);
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='a';
prtype
50435
UPDATE t SET a=1;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
COUNT(*)
2
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
`row_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START INVISIBLE,
`row_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END INVISIBLE,
PRIMARY KEY (`a`,`row_end`),
PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
# handles VIRTUAL columns too
CREATE OR REPLACE TABLE t (
a INT AS (b + 1),
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
INSERT INTO t VALUES (DEFAULT, 1);
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='b';
prtype
50179
ALTER TABLE t
CHANGE b b INT WITHOUT SYSTEM VERSIONING;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='b';
prtype
1027
UPDATE t SET b=11;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
COUNT(*)
1
DROP TABLE t;
SET @@SYSTEM_VERSIONING_ALTER_HISTORY=ERROR;
CREATE OR REPLACE TABLE t1 (
a INT,
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
CREATE OR REPLACE TABLE t2 (
a INT WITHOUT SYSTEM VERSIONING,
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
INSERT INTO t1 VALUES (1,1);
INSERT INTO t2 VALUES (1,1);
SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP;
# without rebuild
ALTER TABLE t1
CHANGE a a INT WITHOUT SYSTEM VERSIONING,
ALGORITHM=INSTANT;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE t2
CHANGE a a INT WITH SYSTEM VERSIONING,
ADD PRIMARY KEY pk (a),
ALGORITHM=INSTANT;
ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE
# with rebuild
ALTER TABLE t2
CHANGE a a INT WITH SYSTEM VERSIONING,
ADD PRIMARY KEY pk (a);
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
UPDATE t1 SET a=2;
SELECT COUNT(*) FROM t1 FOR SYSTEM_TIME ALL;
COUNT(*)
1
UPDATE t2 SET a=2;
SELECT COUNT(*) FROM t2 FOR SYSTEM_TIME ALL;
COUNT(*)
2
DROP TABLE t1, t2;
# rollback ALTER TABLE: nothing should change
CREATE TABLE t (
a INT,
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
INSERT INTO t VALUES (1, 1);
SELECT C.PRTYPE FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS C
JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t ON C.TABLE_ID=t.TABLE_ID
WHERE t.NAME='test/t' AND C.NAME='b';
PRTYPE
50179
SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP;
SET @SAVED_DEBUG_DBUG = @@SESSION.DEBUG_DBUG;
SET DEBUG_DBUG='+d,ib_commit_inplace_fail_1';
ALTER TABLE t
CHANGE b b INT WITHOUT SYSTEM VERSIONING;
ERROR HY000: Internal error: Injected error!
SET DEBUG_DBUG = @SAVED_DEBUG_DBUG;
SELECT C.PRTYPE FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS C
JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t ON C.TABLE_ID=t.TABLE_ID
WHERE t.NAME='test/t' AND C.NAME='b';
PRTYPE
50179
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`row_start` bigint(20) unsigned GENERATED ALWAYS AS ROW START INVISIBLE,
`row_end` bigint(20) unsigned GENERATED ALWAYS AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
COUNT(*)
1
UPDATE t SET b=11;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
COUNT(*)
2
DROP TABLE t;
-- source include/have_innodb.inc -- source include/have_innodb.inc
-- source include/not_embedded.inc
set default_storage_engine= innodb; set default_storage_engine= innodb;
...@@ -411,3 +410,85 @@ DROP TABLE tts; ...@@ -411,3 +410,85 @@ DROP TABLE tts;
DROP TABLE ttx; DROP TABLE ttx;
DROP FUNCTION fts; DROP FUNCTION fts;
DROP FUNCTION ftx; DROP FUNCTION ftx;
--echo #
--echo # MDEV-16330 Allow instant change of WITH SYSTEM VERSIONING column attribute
--echo #
SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP;
CREATE TABLE t (
a INT,
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
INSERT INTO t VALUES (1,1);
--echo # without table rebuild
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='a';
--enable_info
ALTER TABLE t
CHANGE a a INT WITHOUT SYSTEM VERSIONING;
--disable_info
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='a';
UPDATE t SET a=11;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
--echo # with table rebuild
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='a';
--enable_info
ALTER TABLE t
CHANGE a a INT WITH SYSTEM VERSIONING,
ADD PRIMARY KEY pk(a);
--disable_info
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='a';
UPDATE t SET a=1;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
SHOW CREATE TABLE t;
-- echo # handles VIRTUAL columns too
CREATE OR REPLACE TABLE t (
a INT AS (b + 1),
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
INSERT INTO t VALUES (DEFAULT, 1);
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='b';
--enable_info
ALTER TABLE t
CHANGE b b INT WITHOUT SYSTEM VERSIONING;
--disable_info
SELECT c.prtype FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t
ON c.table_id=t.table_id
WHERE t.name='test/t' AND c.name='b';
UPDATE t SET b=11;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
DROP TABLE t;
SET @@SYSTEM_VERSIONING_ALTER_HISTORY=ERROR;
-- source include/have_innodb.inc
-- source include/have_debug.inc
CREATE OR REPLACE TABLE t1 (
a INT,
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
CREATE OR REPLACE TABLE t2 (
a INT WITHOUT SYSTEM VERSIONING,
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
INSERT INTO t1 VALUES (1,1);
INSERT INTO t2 VALUES (1,1);
SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP;
--enable_info
--echo # without rebuild
ALTER TABLE t1
CHANGE a a INT WITHOUT SYSTEM VERSIONING,
ALGORITHM=INSTANT;
--error ER_ALTER_OPERATION_NOT_SUPPORTED
ALTER TABLE t2
CHANGE a a INT WITH SYSTEM VERSIONING,
ADD PRIMARY KEY pk (a),
ALGORITHM=INSTANT;
--echo # with rebuild
ALTER TABLE t2
CHANGE a a INT WITH SYSTEM VERSIONING,
ADD PRIMARY KEY pk (a);
--disable_info
--source include/restart_mysqld.inc
UPDATE t1 SET a=2;
SELECT COUNT(*) FROM t1 FOR SYSTEM_TIME ALL;
UPDATE t2 SET a=2;
SELECT COUNT(*) FROM t2 FOR SYSTEM_TIME ALL;
DROP TABLE t1, t2;
--echo # rollback ALTER TABLE: nothing should change
CREATE TABLE t (
a INT,
b INT,
row_start BIGINT UNSIGNED AS ROW START INVISIBLE,
row_end BIGINT UNSIGNED AS ROW END INVISIBLE,
PERIOD FOR SYSTEM_TIME(row_start, row_end)
) WITH SYSTEM VERSIONING ENGINE=INNODB;
INSERT INTO t VALUES (1, 1);
SELECT C.PRTYPE FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS C
JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t ON C.TABLE_ID=t.TABLE_ID
WHERE t.NAME='test/t' AND C.NAME='b';
SET @@SYSTEM_VERSIONING_ALTER_HISTORY=KEEP;
SET @SAVED_DEBUG_DBUG = @@SESSION.DEBUG_DBUG;
SET DEBUG_DBUG='+d,ib_commit_inplace_fail_1';
--error ER_INTERNAL_ERROR
ALTER TABLE t
CHANGE b b INT WITHOUT SYSTEM VERSIONING;
SET DEBUG_DBUG = @SAVED_DEBUG_DBUG;
SELECT C.PRTYPE FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS AS C
JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLES AS t ON C.TABLE_ID=t.TABLE_ID
WHERE t.NAME='test/t' AND C.NAME='b';
SHOW CREATE TABLE t;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
UPDATE t SET b=11;
SELECT COUNT(*) FROM t FOR SYSTEM_TIME ALL;
DROP TABLE t;
...@@ -6535,15 +6535,15 @@ static bool fill_alter_inplace_info(THD *thd, ...@@ -6535,15 +6535,15 @@ static bool fill_alter_inplace_info(THD *thd,
ALTER_DROP_INDEX are replaced with versions that have higher granuality. ALTER_DROP_INDEX are replaced with versions that have higher granuality.
*/ */
ha_alter_info->handler_flags|= (alter_info->flags & alter_table_operations flags_to_remove=
~(ALTER_ADD_INDEX | ALTER_ADD_INDEX | ALTER_DROP_INDEX | ALTER_PARSER_ADD_COLUMN |
ALTER_DROP_INDEX | ALTER_PARSER_DROP_COLUMN | ALTER_COLUMN_ORDER | ALTER_RENAME_COLUMN |
ALTER_PARSER_ADD_COLUMN | ALTER_CHANGE_COLUMN;
ALTER_PARSER_DROP_COLUMN |
ALTER_COLUMN_ORDER | if (!table->file->native_versioned())
ALTER_RENAME_COLUMN | flags_to_remove|= ALTER_COLUMN_UNVERSIONED;
ALTER_CHANGE_COLUMN |
ALTER_COLUMN_UNVERSIONED)); ha_alter_info->handler_flags|= (alter_info->flags & ~flags_to_remove);
/* /*
Comparing new and old default values of column is cumbersome. Comparing new and old default values of column is cumbersome.
So instead of using such a comparison for detecting if default So instead of using such a comparison for detecting if default
......
...@@ -87,7 +87,6 @@ static const alter_table_operations INNOBASE_ALTER_REBUILD ...@@ -87,7 +87,6 @@ static const alter_table_operations INNOBASE_ALTER_REBUILD
/* /*
| ALTER_STORED_COLUMN_TYPE | ALTER_STORED_COLUMN_TYPE
*/ */
| ALTER_COLUMN_UNVERSIONED
| ALTER_ADD_SYSTEM_VERSIONING | ALTER_ADD_SYSTEM_VERSIONING
| ALTER_DROP_SYSTEM_VERSIONING | ALTER_DROP_SYSTEM_VERSIONING
; ;
...@@ -128,6 +127,7 @@ static const alter_table_operations INNOBASE_ALTER_INSTANT ...@@ -128,6 +127,7 @@ static const alter_table_operations INNOBASE_ALTER_INSTANT
| ALTER_ADD_VIRTUAL_COLUMN | ALTER_ADD_VIRTUAL_COLUMN
| INNOBASE_FOREIGN_OPERATIONS | INNOBASE_FOREIGN_OPERATIONS
| ALTER_COLUMN_EQUAL_PACK_LENGTH | ALTER_COLUMN_EQUAL_PACK_LENGTH
| ALTER_COLUMN_UNVERSIONED
| ALTER_DROP_VIRTUAL_COLUMN; | ALTER_DROP_VIRTUAL_COLUMN;
struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
...@@ -8433,6 +8433,188 @@ innobase_update_foreign_cache( ...@@ -8433,6 +8433,188 @@ innobase_update_foreign_cache(
DBUG_RETURN(err); DBUG_RETURN(err);
} }
/** Changes SYS_COLUMNS.PRTYPE for one column.
@param[in,out] trx transaction
@param[in] table_name table name
@param[in] tableid table ID as in SYS_TABLES
@param[in] pos column position
@param[in] prtype new precise type
@return boolean flag
@retval true on failure
@retval false on success */
static
bool
change_field_versioning_try(
trx_t* trx,
const char* table_name,
const table_id_t tableid,
const ulint pos,
const ulint prtype)
{
DBUG_ENTER("change_field_versioning_try");
pars_info_t* info = pars_info_create();
pars_info_add_int4_literal(info, "prtype", prtype);
pars_info_add_ull_literal(info,"tableid", tableid);
pars_info_add_int4_literal(info, "pos", pos);
dberr_t error = que_eval_sql(info,
"PROCEDURE CHANGE_COLUMN_MTYPE () IS\n"
"BEGIN\n"
"UPDATE SYS_COLUMNS SET PRTYPE=:prtype\n"
"WHERE TABLE_ID=:tableid AND POS=:pos;\n"
"END;\n",
false, trx);
if (error != DB_SUCCESS) {
my_error_innodb(error, table_name, 0);
trx->error_state = DB_SUCCESS;
trx->op_info = "";
DBUG_RETURN(true);
}
DBUG_RETURN(false);
}
/** Changes fields WITH/WITHOUT SYSTEM VERSIONING property in SYS_COLUMNS.
@param[in] ha_alter_info alter info
@param[in] ctx alter inplace context
@param[in] trx transaction
@param[in] table old table
@return boolean flag
@retval true on failure
@retval false on success */
static
bool
change_fields_versioning_try(
const Alter_inplace_info* ha_alter_info,
const ha_innobase_inplace_ctx* ctx,
trx_t* trx,
const TABLE* table)
{
DBUG_ENTER("change_fields_versioning_try");
DBUG_ASSERT(ha_alter_info);
DBUG_ASSERT(ctx);
if (!(ha_alter_info->handler_flags & ALTER_COLUMN_UNVERSIONED)){
DBUG_RETURN(false);
}
uint virtual_count = 0;
List_iterator_fast<Create_field> it(
ha_alter_info->alter_info->create_list);
for (uint i = 0; i < table->s->fields; i++) {
const Field* field = table->field[i];
if (innobase_is_v_fld(field)) {
virtual_count++;
continue;
}
const Create_field* create_field = NULL;
while (const Create_field* cf = it++) {
if (cf->field == field) {
create_field = cf;
break;
}
}
it.rewind();
DBUG_ASSERT(create_field);
if (create_field->versioning
== Column_definition::VERSIONING_NOT_SET) {
continue;
}
const dict_table_t* new_table = ctx->new_table;
ulint pos = i - virtual_count;
const dict_col_t* col = dict_table_get_nth_col(new_table, pos);
DBUG_ASSERT(!col->vers_sys_start());
DBUG_ASSERT(!col->vers_sys_end());
ulint new_prtype
= create_field->versioning
== Column_definition::WITHOUT_VERSIONING
? col->prtype & ~DATA_VERSIONED
: col->prtype | DATA_VERSIONED;
if (change_field_versioning_try(trx, table->s->table_name.str,
new_table->id, pos,
new_prtype)) {
DBUG_RETURN(true);
}
}
DBUG_RETURN(false);
}
/** Changes WITH/WITHOUT SYSTEM VERSIONING for fields
in the data dictionary cache.
@param ha_alter_info Data used during in-place alter
@param ctx In-place ALTER TABLE context
@param table MySQL table as it is before the ALTER operation */
static
void
change_fields_versioning_cache(
Alter_inplace_info* ha_alter_info,
const ha_innobase_inplace_ctx* ctx,
const TABLE* table)
{
DBUG_ENTER("change_fields_versioning");
DBUG_ASSERT(ha_alter_info);
DBUG_ASSERT(ctx);
DBUG_ASSERT(ha_alter_info->handler_flags & ALTER_COLUMN_UNVERSIONED);
uint virtual_count = 0;
List_iterator_fast<Create_field> it(
ha_alter_info->alter_info->create_list);
for (uint i = 0; i < table->s->fields; i++) {
const Field* field = table->field[i];
if (innobase_is_v_fld(field)) {
virtual_count++;
continue;
}
const Create_field* create_field = NULL;
while (const Create_field* cf = it++) {
if (cf->field == field) {
create_field = cf;
break;
}
}
it.rewind();
DBUG_ASSERT(create_field);
dict_col_t* col
= dict_table_get_nth_col(ctx->new_table, i - virtual_count);
if (create_field->versioning
== Column_definition::WITHOUT_VERSIONING) {
DBUG_ASSERT(!col->vers_sys_start());
DBUG_ASSERT(!col->vers_sys_end());
col->prtype &= ~DATA_VERSIONED;
} else if (create_field->versioning
== Column_definition::WITH_VERSIONING) {
DBUG_ASSERT(!col->vers_sys_start());
DBUG_ASSERT(!col->vers_sys_end());
col->prtype |= DATA_VERSIONED;
}
}
DBUG_VOID_RETURN;
}
/** Commit the changes made during prepare_inplace_alter_table() /** Commit the changes made during prepare_inplace_alter_table()
and inplace_alter_table() inside the data dictionary tables, and inplace_alter_table() inside the data dictionary tables,
when rebuilding the table. when rebuilding the table.
...@@ -8742,6 +8924,10 @@ commit_try_norebuild( ...@@ -8742,6 +8924,10 @@ commit_try_norebuild(
DBUG_RETURN(true); DBUG_RETURN(true);
} }
if (change_fields_versioning_try(ha_alter_info, ctx, trx, old_table)) {
DBUG_RETURN(true);
}
dberr_t error; dberr_t error;
/* We altered the table in place. Mark the indexes as committed. */ /* We altered the table in place. Mark the indexes as committed. */
...@@ -8947,6 +9133,10 @@ commit_cache_norebuild( ...@@ -8947,6 +9133,10 @@ commit_cache_norebuild(
ha_alter_info, table, ctx->new_table); ha_alter_info, table, ctx->new_table);
} }
if (ha_alter_info->handler_flags & ALTER_COLUMN_UNVERSIONED) {
change_fields_versioning_cache(ha_alter_info, ctx, table);
}
#ifdef MYSQL_RENAME_INDEX #ifdef MYSQL_RENAME_INDEX
rename_indexes_in_cache(ctx, ha_alter_info); rename_indexes_in_cache(ctx, ha_alter_info);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment