MDEV-18627 Wrong result after instant size change of integer
If we instantly change the size of a fixed-length field and treat it as kind-of variable-length, then we will need conversions between old column values and new ones. I tried adding such a conversion to row_build(), but then I noticed that more conversions would be needed, because old values still appeared in a freshly rebuilt secondary index, causing a mismatch when trying to search with the correct longer value that was converted in my provisional fix to row_build(). So, we will revert the essential part of MDEV-15563: Instant ROW_FORMAT=REDUNDANT column extension (commit 22feb179ae166500ec91feec6246c8154e33f9a2), but not remove any tests.
This commit is contained in:
parent
f0b65102b2
commit
2c74799d64
@ -741,8 +741,8 @@ CREATE TABLE t1 (f TINYINT, g SMALLINT UNSIGNED) ENGINE=InnoDB ROW_FORMAT=REDUND
|
||||
INSERT INTO t1 VALUES(127,6502),(-128,33101);
|
||||
ALTER TABLE t1 MODIFY f SMALLINT DEFAULT 12345,
|
||||
MODIFY g BIGINT UNSIGNED DEFAULT 1234567;
|
||||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
affected rows: 2
|
||||
info: Records: 2 Duplicates: 0 Warnings: 0
|
||||
SELECT * FROM t1;
|
||||
f g
|
||||
127 6502
|
||||
@ -803,8 +803,8 @@ info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
ALTER TABLE t1 MODIFY f MEDIUMINT NOT NULL DEFAULT 64802,
|
||||
MODIFY c VARCHAR(20) NOT NULL DEFAULT 'gory',
|
||||
ADD d DATETIME;
|
||||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
affected rows: 1
|
||||
info: Records: 1 Duplicates: 0 Warnings: 0
|
||||
INSERT INTO t1() VALUES();
|
||||
INSERT INTO t1 (c,f,d) VALUES ('fury', -8388608, now());
|
||||
SELECT * FROM t1;
|
||||
@ -818,23 +818,25 @@ SELECT table_id INTO @table_id1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
|
||||
WHERE name = 'test/t1';
|
||||
INSERT INTO t1 VALUES (-42, -123456);
|
||||
ALTER TABLE t1 CHANGE t s SMALLINT;
|
||||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
affected rows: 1
|
||||
info: Records: 1 Duplicates: 0 Warnings: 0
|
||||
SELECT table_id INTO @table_id2 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
|
||||
WHERE name = 'test/t1';
|
||||
affected rows: 1
|
||||
ALTER TABLE t1 CHANGE m i INT, ALGORITHM=INSTANT;
|
||||
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
|
||||
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
|
||||
ALTER TABLE t1 CHANGE m i INT;
|
||||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
affected rows: 1
|
||||
info: Records: 1 Duplicates: 0 Warnings: 0
|
||||
SELECT table_id INTO @table_id3 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
|
||||
WHERE name = 'test/t1';
|
||||
affected rows: 1
|
||||
SELECT @table_id1 = @table_id2, @table_id2 = @table_id3;
|
||||
@table_id1 = @table_id2 @table_id2 = @table_id3
|
||||
0 1
|
||||
0 0
|
||||
INSERT IGNORE INTO t1 VALUES (0, -123456);
|
||||
Warnings:
|
||||
Warning 1062 Duplicate entry '-123456' for key 'm'
|
||||
REPLACE INTO t1 VALUES(-42, 123456);
|
||||
INSERT IGNORE INTO t1 VALUES(32768, 2147483648);
|
||||
Warnings:
|
||||
@ -842,11 +844,25 @@ Warning 1264 Out of range value for column 's' at row 1
|
||||
Warning 1264 Out of range value for column 'i' at row 1
|
||||
SELECT * FROM t1;
|
||||
s i
|
||||
-42 -123456
|
||||
0 -123456
|
||||
-42 123456
|
||||
32767 2147483647
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a SERIAL, b INT, c TINYINT UNIQUE) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
|
||||
INSERT INTO t1 (c) VALUES(1),(2),(3);
|
||||
ALTER TABLE t1 MODIFY c BIGINT;
|
||||
affected rows: 3
|
||||
info: Records: 3 Duplicates: 0 Warnings: 0
|
||||
UPDATE t1 SET b=1 WHERE c=2;
|
||||
UPDATE t1 SET c=4 WHERE a=3;
|
||||
UPDATE t1 SET b=2 WHERE c>3;
|
||||
UPDATE t1 SET c=c+1;
|
||||
ERROR 23000: Duplicate entry '2' for key 'c'
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 NULL 1
|
||||
2 1 2
|
||||
3 2 4
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1
|
||||
(id INT PRIMARY KEY, c2 INT UNIQUE,
|
||||
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
|
||||
@ -1640,6 +1656,22 @@ s i
|
||||
-42 123456
|
||||
32767 2147483647
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a SERIAL, b INT, c TINYINT UNIQUE) ENGINE=InnoDB ROW_FORMAT=COMPACT;
|
||||
INSERT INTO t1 (c) VALUES(1),(2),(3);
|
||||
ALTER TABLE t1 MODIFY c BIGINT;
|
||||
affected rows: 3
|
||||
info: Records: 3 Duplicates: 0 Warnings: 0
|
||||
UPDATE t1 SET b=1 WHERE c=2;
|
||||
UPDATE t1 SET c=4 WHERE a=3;
|
||||
UPDATE t1 SET b=2 WHERE c>3;
|
||||
UPDATE t1 SET c=c+1;
|
||||
ERROR 23000: Duplicate entry '2' for key 'c'
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 NULL 1
|
||||
2 1 2
|
||||
3 2 4
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1
|
||||
(id INT PRIMARY KEY, c2 INT UNIQUE,
|
||||
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
|
||||
@ -2433,10 +2465,26 @@ s i
|
||||
-42 123456
|
||||
32767 2147483647
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a SERIAL, b INT, c TINYINT UNIQUE) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
|
||||
INSERT INTO t1 (c) VALUES(1),(2),(3);
|
||||
ALTER TABLE t1 MODIFY c BIGINT;
|
||||
affected rows: 3
|
||||
info: Records: 3 Duplicates: 0 Warnings: 0
|
||||
UPDATE t1 SET b=1 WHERE c=2;
|
||||
UPDATE t1 SET c=4 WHERE a=3;
|
||||
UPDATE t1 SET b=2 WHERE c>3;
|
||||
UPDATE t1 SET c=c+1;
|
||||
ERROR 23000: Duplicate entry '2' for key 'c'
|
||||
SELECT * FROM t1;
|
||||
a b c
|
||||
1 NULL 1
|
||||
2 1 2
|
||||
3 2 4
|
||||
DROP TABLE t1;
|
||||
disconnect analyze;
|
||||
SELECT variable_value-@old_instant instants
|
||||
FROM information_schema.global_status
|
||||
WHERE variable_name = 'innodb_instant_alter_column';
|
||||
instants
|
||||
175
|
||||
174
|
||||
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
|
||||
|
@ -1,23 +1,5 @@
|
||||
--- instant_alter_charset.result
|
||||
+++ instant_alter_charset,redundant.result
|
||||
@@ -143,7 +143,7 @@
|
||||
drop index ab,
|
||||
add unique key ab(a,c),
|
||||
algorithm=instant;
|
||||
-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
|
||||
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
|
||||
drop table key_part_change;
|
||||
create table key_part_change_and_rename (
|
||||
a char(100) charset ascii,
|
||||
@@ -156,7 +156,7 @@
|
||||
drop index ab,
|
||||
add unique key ab(a,b),
|
||||
algorithm=instant;
|
||||
-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
|
||||
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
|
||||
drop table key_part_change_and_rename;
|
||||
create table enum_and_set (
|
||||
a enum('one', 'two') charset utf8mb3,
|
||||
@@ -254,7 +254,6 @@
|
||||
alter table boundary_255
|
||||
modify b varchar(200) charset utf8mb3,
|
||||
|
Binary file not shown.
@ -715,6 +715,19 @@ INSERT IGNORE INTO t1 VALUES(32768, 2147483648);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
eval CREATE TABLE t1 (a SERIAL, b INT, c TINYINT UNIQUE) $engine;
|
||||
INSERT INTO t1 (c) VALUES(1),(2),(3);
|
||||
--enable_info
|
||||
ALTER TABLE t1 MODIFY c BIGINT;
|
||||
--disable_info
|
||||
UPDATE t1 SET b=1 WHERE c=2;
|
||||
UPDATE t1 SET c=4 WHERE a=3;
|
||||
UPDATE t1 SET b=2 WHERE c>3;
|
||||
--error ER_DUP_ENTRY
|
||||
UPDATE t1 SET c=c+1;
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
dec $format;
|
||||
}
|
||||
disconnect analyze;
|
||||
|
@ -1,8 +1,10 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/innodb_row_format.inc
|
||||
--source include/maybe_debug.inc
|
||||
|
||||
-- echo #
|
||||
-- echo # MDEV-15563: Instant ROW_FORMAT=REDUNDANT column type change&extension
|
||||
-- echo # (reverted in MDEV-18627)
|
||||
-- echo #
|
||||
|
||||
# Use character-set-server in test db
|
||||
@ -10,8 +12,6 @@ create or replace database test;
|
||||
use test;
|
||||
|
||||
set default_storage_engine=innodb;
|
||||
set @save_format= @@GLOBAL.innodb_default_row_format;
|
||||
SET GLOBAL innodb_default_row_format=redundant;
|
||||
set @bigval= repeat('0123456789', 30);
|
||||
|
||||
delimiter ~~;
|
||||
@ -45,7 +45,9 @@ set @save_debug= @@SESSION.debug_dbug;
|
||||
set debug_dbug= '+d,ib_instant_error';
|
||||
--enable_query_log
|
||||
}
|
||||
alter table t modify a char(200), algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify a char(200);
|
||||
--disable_info
|
||||
select count(a) from t where a = @bigval;
|
||||
select a, length(a) from t where a = 'z';
|
||||
|
||||
@ -53,7 +55,9 @@ check table t extended;
|
||||
call check_table('t');
|
||||
|
||||
--echo # CHAR enlargement
|
||||
alter table t modify a char(220), algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify a char(220);
|
||||
--disable_info
|
||||
select count(a) from t where a = @bigval;
|
||||
select a, length(a) from t where a = 'z';
|
||||
|
||||
@ -61,10 +65,10 @@ check table t extended;
|
||||
call check_table('t');
|
||||
|
||||
--echo # Convert from VARCHAR to a bigger CHAR
|
||||
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||
alter table t modify a varchar(200), algorithm=instant;
|
||||
alter table t modify a varchar(200), algorithm=copy;
|
||||
alter table t modify a char(255), algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify a varchar(200);
|
||||
alter table t modify a char(255);
|
||||
--disable_info
|
||||
select count(a) from t where a = @bigval;
|
||||
select a, length(a) from t where a = 'z';
|
||||
|
||||
@ -74,14 +78,17 @@ call check_table('t');
|
||||
|
||||
--echo # BINARY/VARBINARY test
|
||||
create or replace table t (a varbinary(300));
|
||||
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||
alter table t modify a binary(255), algorithm=instant;
|
||||
alter table t modify a binary(255), algorithm=copy;
|
||||
insert into t values(NULL);
|
||||
--enable_info
|
||||
alter table t modify a binary(255);
|
||||
--disable_info
|
||||
|
||||
create or replace table t (a varbinary(200));
|
||||
insert into t values (@bigval);
|
||||
insert into t values ('z');
|
||||
alter table t modify a binary(200), algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify a binary(200);
|
||||
--disable_info
|
||||
select count(a) from t where a = @bigval;
|
||||
select length(a) from t where left(a, 1) = 'z';
|
||||
|
||||
@ -89,16 +96,18 @@ check table t extended;
|
||||
call check_table('t');
|
||||
|
||||
--echo # BINARY enlargement
|
||||
alter table t modify a binary(220), algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify a binary(220);
|
||||
--disable_info
|
||||
|
||||
check table t extended;
|
||||
call check_table('t');
|
||||
|
||||
--echo # Convert from VARBINARY to a bigger BINARY
|
||||
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||
alter table t modify a varbinary(220), algorithm=instant;
|
||||
alter table t modify a varbinary(220), algorithm=copy;
|
||||
alter table t modify a binary(255), algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify a varbinary(220);
|
||||
alter table t modify a binary(255);
|
||||
--disable_info
|
||||
select count(a) from t where a = @bigval;
|
||||
select a, length(a) from t where a = 'z';
|
||||
|
||||
@ -110,25 +119,33 @@ call check_table('t');
|
||||
--echo # Integer conversions
|
||||
create or replace table t (x tinyint);
|
||||
insert into t values (127);
|
||||
alter table t modify x smallint, algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify x smallint;
|
||||
--disable_info
|
||||
select * from t;
|
||||
check table t extended;
|
||||
call check_table('t');
|
||||
|
||||
update t set x= 32767;
|
||||
alter table t modify x mediumint, algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify x mediumint;
|
||||
--disable_info
|
||||
select * from t;
|
||||
check table t extended;
|
||||
call check_table('t');
|
||||
|
||||
update t set x= 8388607;
|
||||
alter table t modify x int, algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify x int;
|
||||
--disable_info
|
||||
select * from t;
|
||||
check table t extended;
|
||||
call check_table('t');
|
||||
|
||||
update t set x= 2147483647;
|
||||
alter table t modify x bigint, algorithm=instant;
|
||||
--enable_info
|
||||
alter table t modify x bigint;
|
||||
--disable_info
|
||||
select * from t;
|
||||
check table t extended;
|
||||
call check_table('t');
|
||||
@ -163,13 +180,19 @@ call check_table('t2');
|
||||
create or replace table t1 (x mediumint);
|
||||
insert into t1 values (1);
|
||||
insert into t1 values (1);
|
||||
alter table t1 add column y int first, modify x int, algorithm instant;
|
||||
--enable_info
|
||||
alter table t1 add column y int first, modify x int;
|
||||
--error ER_DUP_ENTRY
|
||||
alter table t1 add column z int first, add primary key (x);
|
||||
--disable_info
|
||||
|
||||
--echo # Check assertion in wrong instant operation
|
||||
create or replace table t1 (a varchar(26) not null) default character set utf8mb4;
|
||||
alter table t1 modify a varchar(25) not null;
|
||||
insert into t1 values ('abcdef'), (repeat('x',26));
|
||||
--enable_info
|
||||
alter ignore table t1 modify a varchar(25) not null;
|
||||
--disable_info
|
||||
select * from t1;
|
||||
|
||||
--echo # Check row_mysql_store_col_in_innobase_format()
|
||||
create or replace table t1(x int primary key, a varchar(20));
|
||||
@ -181,30 +204,46 @@ update t1 set a= 'foo' where x = 2;
|
||||
--echo #
|
||||
create or replace table t1 (x int, y int);
|
||||
insert into t1 (x, y) values (11, 22);
|
||||
alter table t1 modify x bigint, algorithm instant;
|
||||
alter table t1 add primary key (x), algorithm inplace;
|
||||
--enable_info
|
||||
alter table t1 modify x bigint;
|
||||
alter table t1 add primary key (x);
|
||||
--disable_info
|
||||
select * from t1;
|
||||
check table t1;
|
||||
|
||||
create or replace table t1 (a varchar(10), y int);
|
||||
insert into t1 (a, y) values ("0123456789", 33);
|
||||
alter table t1 modify a char(15), algorithm instant;
|
||||
alter table t1 add primary key (a), algorithm inplace;
|
||||
--enable_info
|
||||
alter table t1 modify a char(15);
|
||||
alter table t1 add primary key (a);
|
||||
--disable_info
|
||||
select * from t1;
|
||||
check table t1;
|
||||
|
||||
create or replace table t1 (x int primary key, y int);
|
||||
insert into t1 (x, y) values (44, 55);
|
||||
alter table t1 modify x bigint, algorithm inplace;
|
||||
--enable_info
|
||||
alter table t1 modify x bigint;
|
||||
--disable_info
|
||||
select * from t1;
|
||||
check table t1;
|
||||
|
||||
create or replace table t1 (x int primary key, y int);
|
||||
insert into t1 values (66, 77);
|
||||
alter table t1 add column z int, algorithm instant;
|
||||
alter table t1 drop column y, algorithm instant;
|
||||
--enable_info
|
||||
alter table t1 add column z int;
|
||||
alter table t1 drop column y;
|
||||
--disable_info
|
||||
select * from t1;
|
||||
check table t1;
|
||||
|
||||
create or replace table t1 (x integer, a varchar(20));
|
||||
alter table t1 add index idx3 (a);
|
||||
--enable_info
|
||||
insert into t1 (x, a) values (73, 'a');
|
||||
alter table t1 add index idx3 (a);
|
||||
alter table t1 modify a char(20);
|
||||
--disable_info
|
||||
select * from t1;
|
||||
check table t1;
|
||||
|
||||
create or replace database test charset latin1;
|
||||
SET GLOBAL innodb_default_row_format=@save_format;
|
||||
|
24
sql/field.cc
24
sql/field.cc
@ -7084,9 +7084,6 @@ uint Field_str::is_equal(Create_field *new_field)
|
||||
return new_field->charset == field_charset
|
||||
? IS_EQUAL_YES : IS_EQUAL_PACK_LENGTH;
|
||||
|
||||
if (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION)
|
||||
return IS_EQUAL_PACK_LENGTH_EXT;
|
||||
|
||||
return IS_EQUAL_NO;
|
||||
}
|
||||
|
||||
@ -7947,11 +7944,6 @@ uint Field_varstring::is_equal(Create_field *new_field)
|
||||
(table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION))
|
||||
return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer length
|
||||
}
|
||||
else if (new_type_handler == &type_handler_string) // converting to CHAR
|
||||
{
|
||||
if (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION)
|
||||
return IS_EQUAL_PACK_LENGTH_EXT;
|
||||
}
|
||||
|
||||
return IS_EQUAL_NO;
|
||||
}
|
||||
@ -9568,22 +9560,6 @@ uint Field_num::is_equal(Create_field *new_field)
|
||||
format for integers, we can only return IS_EQUAL_YES for the TINYINT
|
||||
conversion. */
|
||||
|
||||
if (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION)
|
||||
{
|
||||
/* For now, prohibit instant conversion between BIT and integers.
|
||||
Note: pack_length(), which is compared below, is measured in
|
||||
bytes, and for BIT the last byte may be partially occupied. We
|
||||
must not allow instant conversion to BIT such that the last byte
|
||||
is partially occupied.
|
||||
We could allow converting TINYINT UNSIGNED to BIT(8) or wider. */
|
||||
if (th != new_th &&
|
||||
(th == &type_handler_bit || new_th == &type_handler_bit))
|
||||
return IS_EQUAL_NO;
|
||||
if (th->result_type() == new_th->result_type() &&
|
||||
new_field->pack_length >= pack_length())
|
||||
return IS_EQUAL_PACK_LENGTH_EXT;
|
||||
}
|
||||
|
||||
return IS_EQUAL_NO;
|
||||
}
|
||||
|
||||
|
@ -751,14 +751,6 @@ typedef ulonglong alter_table_operations;
|
||||
*/
|
||||
#define ALTER_COLUMN_INDEX_LENGTH (1ULL << 60)
|
||||
|
||||
/**
|
||||
Change the column length or type such that no rebuild is needed.
|
||||
Only set if ALTER_COLUMN_EQUAL_PACK_LENGTH does not apply, and
|
||||
if HA_EXTENDED_TYPES_CONVERSION holds.
|
||||
@see IS_EQUAL_PACK_LENGTH_EXT
|
||||
*/
|
||||
#define ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT (1ULL << 61)
|
||||
|
||||
/*
|
||||
Flags set in partition_flags when altering partitions
|
||||
*/
|
||||
|
@ -358,11 +358,6 @@
|
||||
data dictionary without changing table rows
|
||||
*/
|
||||
#define IS_EQUAL_PACK_LENGTH 2
|
||||
/**
|
||||
new_field has a representation that is compatible with the old type
|
||||
when the storage engine advertises HA_EXTENDED_TYPES_CONVERSION
|
||||
*/
|
||||
#define IS_EQUAL_PACK_LENGTH_EXT 3
|
||||
|
||||
enum enum_parsing_place
|
||||
{
|
||||
|
@ -6605,9 +6605,6 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
*/
|
||||
ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH;
|
||||
break;
|
||||
case IS_EQUAL_PACK_LENGTH_EXT:
|
||||
ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT;
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
/* Safety. */
|
||||
|
@ -4839,9 +4839,7 @@ n_field_mismatch:
|
||||
if (len_is_stored(len)
|
||||
&& (field->prefix_len
|
||||
? len > field->prefix_len
|
||||
: (fixed_size && (page_is_comp(page)
|
||||
? len != fixed_size
|
||||
: len > fixed_size)))) {
|
||||
: (fixed_size && len != fixed_size))) {
|
||||
len_mismatch:
|
||||
btr_index_rec_validate_report(page, rec, index);
|
||||
ib::error error;
|
||||
|
@ -486,14 +486,8 @@ incompatible:
|
||||
For the metadata record, variable-length columns are
|
||||
always written with zero length. The DB_TRX_ID will
|
||||
start right after any fixed-length columns. */
|
||||
if (index->table->not_redundant()) {
|
||||
for (uint i = index->n_uniq; i--; ) {
|
||||
trx_id_offset += index->fields[i]
|
||||
.fixed_len;
|
||||
}
|
||||
} else {
|
||||
trx_id_offset = rec_get_field_start_offs(
|
||||
rec, index->n_uniq);
|
||||
for (uint i = index->n_uniq; i--; ) {
|
||||
trx_id_offset += index->fields[i].fixed_len;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,22 +100,6 @@ dtype_validate(
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
bool dict_col_t::same_charset(const dict_col_t& other) const
|
||||
{
|
||||
if (dtype_is_non_binary_string_type(mtype, prtype)
|
||||
&& dtype_is_non_binary_string_type(other.mtype, other.prtype)) {
|
||||
uint csn1 = (uint) dtype_get_charset_coll(prtype);
|
||||
uint csn2 = (uint) dtype_get_charset_coll(other.prtype);
|
||||
CHARSET_INFO* cs1 = get_charset(csn1, MYF(MY_WME));
|
||||
CHARSET_INFO* cs2 = get_charset(csn2, MYF(MY_WME));
|
||||
if (!my_charset_same(cs1, cs2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/** Print a data type structure.
|
||||
@param[in] type data type */
|
||||
|
@ -2203,14 +2203,6 @@ dict_index_too_big_for_tree(
|
||||
}
|
||||
|
||||
field_max_size = dict_col_get_max_size(col);
|
||||
if (!comp && (col->mtype == DATA_INT
|
||||
|| col->mtype == DATA_CHAR
|
||||
|| col->mtype == DATA_FIXBINARY)) {
|
||||
/* DATA_INT, DATA_FIXBINARY and DATA_CHAR are variable-
|
||||
length (enlarged instantly), but are stored locally. */
|
||||
field_ext_max_size = 0;
|
||||
goto add_field_size;
|
||||
}
|
||||
field_ext_max_size = field_max_size < 256 ? 1 : 2;
|
||||
|
||||
if (field->prefix_len) {
|
||||
|
@ -9977,7 +9977,7 @@ innobase_fts_create_doc_id_key(
|
||||
/* The unique Doc ID field should be an eight-bytes integer */
|
||||
dict_field_t* field = dict_index_get_nth_field(index, 0);
|
||||
ut_a(field->col->mtype == DATA_INT);
|
||||
ut_ad(sizeof(*doc_id) == field->col->len);
|
||||
ut_ad(sizeof(*doc_id) == field->fixed_len);
|
||||
ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX_NAME));
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
|
@ -135,7 +135,6 @@ static const alter_table_operations INNOBASE_ALTER_INSTANT
|
||||
| ALTER_ADD_VIRTUAL_COLUMN
|
||||
| INNOBASE_FOREIGN_OPERATIONS
|
||||
| ALTER_COLUMN_EQUAL_PACK_LENGTH
|
||||
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
||||
| ALTER_COLUMN_UNVERSIONED
|
||||
| ALTER_DROP_VIRTUAL_COLUMN;
|
||||
|
||||
@ -270,7 +269,7 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
|
||||
ut_ad(!not_redundant());
|
||||
for (unsigned i = index.n_fields; i--; ) {
|
||||
ut_ad(index.fields[i].col->same_format(
|
||||
*oindex.fields[i].col, true));
|
||||
*oindex.fields[i].col));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -458,13 +457,9 @@ inline void dict_index_t::instant_add_field(const dict_index_t& instant)
|
||||
as this index. Fields for any added columns are appended at the end. */
|
||||
#ifndef DBUG_OFF
|
||||
for (unsigned i = 0; i < n_fields; i++) {
|
||||
DBUG_ASSERT(fields[i].prefix_len
|
||||
== instant.fields[i].prefix_len);
|
||||
DBUG_ASSERT(fields[i].fixed_len
|
||||
== instant.fields[i].fixed_len
|
||||
|| !table->not_redundant());
|
||||
DBUG_ASSERT(instant.fields[i].col->same_format(
|
||||
*fields[i].col, !table->not_redundant()));
|
||||
DBUG_ASSERT(fields[i].same(instant.fields[i]));
|
||||
DBUG_ASSERT(instant.fields[i].col->same_format(*fields[i]
|
||||
.col));
|
||||
/* Instant conversion from NULL to NOT NULL is not allowed. */
|
||||
DBUG_ASSERT(!fields[i].col->is_nullable()
|
||||
|| instant.fields[i].col->is_nullable());
|
||||
@ -540,7 +535,10 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
|
||||
|
||||
if (const dict_col_t* o = find(old_cols, col_map, n_cols, i)) {
|
||||
c.def_val = o->def_val;
|
||||
ut_ad(c.same_format(*o, !not_redundant()));
|
||||
DBUG_ASSERT(!((c.prtype ^ o->prtype)
|
||||
& ~(DATA_NOT_NULL | DATA_VERSIONED)));
|
||||
DBUG_ASSERT(c.mtype == o->mtype);
|
||||
DBUG_ASSERT(c.len >= o->len);
|
||||
|
||||
if (o->vers_sys_start()) {
|
||||
ut_ad(o->ind == vers_start);
|
||||
@ -1752,10 +1750,6 @@ ha_innobase::check_if_supported_inplace_alter(
|
||||
{
|
||||
DBUG_ENTER("check_if_supported_inplace_alter");
|
||||
|
||||
DBUG_ASSERT(!(ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
||||
& ha_alter_info->handler_flags)
|
||||
|| !m_prebuilt->table->not_redundant());
|
||||
|
||||
if ((ha_alter_info->handler_flags
|
||||
& INNOBASE_ALTER_VERSIONED_REBUILD)
|
||||
&& altered_table->versioned(VERS_TIMESTAMP)) {
|
||||
@ -2951,7 +2945,7 @@ innobase_col_to_mysql(
|
||||
|
||||
switch (col->mtype) {
|
||||
case DATA_INT:
|
||||
ut_ad(len <= flen);
|
||||
ut_ad(len == flen);
|
||||
|
||||
/* Convert integer data from Innobase to little-endian
|
||||
format, sign bit restored to normal */
|
||||
@ -5592,8 +5586,7 @@ static bool innobase_instant_try(
|
||||
|
||||
bool update = old && (!ctx->first_alter_pos
|
||||
|| i < ctx->first_alter_pos - 1);
|
||||
ut_ad(!old || col->same_format(
|
||||
*old, !user_table->not_redundant()));
|
||||
DBUG_ASSERT(!old || col->same_format(*old));
|
||||
if (update
|
||||
&& old->prtype == d->type.prtype) {
|
||||
/* The record is already present in SYS_COLUMNS. */
|
||||
@ -5682,8 +5675,6 @@ add_all_virtual:
|
||||
NULL, trx, ctx->heap, NULL);
|
||||
|
||||
dberr_t err = DB_SUCCESS;
|
||||
DBUG_EXECUTE_IF("ib_instant_error",
|
||||
err = DB_OUT_OF_FILE_SPACE; goto func_exit;);
|
||||
if (rec_is_metadata(rec, *index)) {
|
||||
ut_ad(page_rec_is_user_rec(rec));
|
||||
if (!page_has_next(block->frame)
|
||||
@ -9061,7 +9052,7 @@ innobase_rename_or_enlarge_column_try(
|
||||
and ROW_FORMAT is not REDUNDANT and mbminlen<mbmaxlen.
|
||||
That is, we treat a UTF-8 CHAR(n) column somewhat like
|
||||
a VARCHAR. */
|
||||
ut_ad(!user_table->not_redundant() || col->len == len);
|
||||
ut_ad(col->len == len);
|
||||
break;
|
||||
case DATA_BINARY:
|
||||
case DATA_VARCHAR:
|
||||
@ -9069,11 +9060,6 @@ innobase_rename_or_enlarge_column_try(
|
||||
case DATA_DECIMAL:
|
||||
case DATA_BLOB:
|
||||
break;
|
||||
case DATA_INT:
|
||||
if (!user_table->not_redundant()) {
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
ut_ad(col->prtype == prtype);
|
||||
ut_ad(col->mtype == mtype);
|
||||
@ -9129,7 +9115,6 @@ innobase_rename_or_enlarge_columns_try(
|
||||
|
||||
if (!(ha_alter_info->handler_flags
|
||||
& (ALTER_COLUMN_EQUAL_PACK_LENGTH
|
||||
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
||||
| ALTER_COLUMN_NAME))) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
@ -9178,7 +9163,6 @@ innobase_rename_or_enlarge_columns_cache(
|
||||
{
|
||||
if (!(ha_alter_info->handler_flags
|
||||
& (ALTER_COLUMN_EQUAL_PACK_LENGTH
|
||||
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
||||
| ALTER_COLUMN_NAME))) {
|
||||
return;
|
||||
}
|
||||
|
@ -472,18 +472,12 @@ dtype_get_fixed_size_low(
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
/* fall through */
|
||||
case DATA_CHAR:
|
||||
case DATA_FIXBINARY:
|
||||
case DATA_INT:
|
||||
case DATA_FLOAT:
|
||||
case DATA_DOUBLE:
|
||||
return(len);
|
||||
case DATA_FIXBINARY:
|
||||
case DATA_CHAR:
|
||||
case DATA_INT:
|
||||
/* Treat these types as variable length for redundant
|
||||
row format. We can't rely on fixed_len anymore because record
|
||||
can have shorter length from before instant enlargement
|
||||
[MDEV-15563]. Note, that importing such tablespace to
|
||||
earlier MariaDB versions produces ER_TABLE_SCHEMA_MISMATCH. */
|
||||
return comp ? len : 0;
|
||||
case DATA_MYSQL:
|
||||
if (prtype & DATA_BINARY_TYPE) {
|
||||
return(len);
|
||||
@ -631,14 +625,6 @@ dtype_get_sql_null_size(
|
||||
const dtype_t* type, /*!< in: type */
|
||||
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
|
||||
{
|
||||
switch (type->mtype) {
|
||||
case DATA_INT:
|
||||
case DATA_CHAR:
|
||||
case DATA_FIXBINARY:
|
||||
return(type->len);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
|
||||
type->mbminlen, type->mbmaxlen, comp));
|
||||
}
|
||||
|
@ -682,52 +682,18 @@ public:
|
||||
def_val.data = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
/** Determine if the columns have the same character set
|
||||
@param[in] other column to compare to
|
||||
@return whether the columns have the same character set */
|
||||
bool same_charset(const dict_col_t& other) const;
|
||||
public:
|
||||
/** Determine if the columns have the same format
|
||||
except for is_nullable() and is_versioned().
|
||||
@param[in] other column to compare to
|
||||
@param[in] redundant table is redundant row format
|
||||
@return whether the columns have the same format */
|
||||
bool same_format(const dict_col_t& other, bool redundant = false) const
|
||||
bool same_format(const dict_col_t& other) const
|
||||
{
|
||||
if (len < other.len
|
||||
|| mbminlen != other.mbminlen
|
||||
|| mbmaxlen != other.mbmaxlen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!((prtype ^ other.prtype)
|
||||
& ~(DATA_NOT_NULL | DATA_VERSIONED))) {
|
||||
return mtype == other.mtype;
|
||||
}
|
||||
|
||||
if (redundant) {
|
||||
switch (other.mtype) {
|
||||
case DATA_CHAR:
|
||||
case DATA_MYSQL:
|
||||
case DATA_VARCHAR:
|
||||
case DATA_VARMYSQL:
|
||||
return (mtype == DATA_CHAR
|
||||
|| mtype == DATA_MYSQL
|
||||
|| mtype == DATA_VARCHAR
|
||||
|| mtype == DATA_VARMYSQL)
|
||||
&& same_charset(other);
|
||||
case DATA_FIXBINARY:
|
||||
case DATA_BINARY:
|
||||
return (mtype == DATA_FIXBINARY
|
||||
|| mtype == DATA_BINARY)
|
||||
&& same_charset(other);
|
||||
case DATA_INT:
|
||||
return mtype == DATA_INT;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return mtype == other.mtype
|
||||
&& len >= other.len
|
||||
&& mbminlen == other.mbminlen
|
||||
&& mbmaxlen == other.mbmaxlen
|
||||
&& !((prtype ^ other.prtype)
|
||||
& ~(DATA_NOT_NULL | DATA_VERSIONED));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2014, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2014, 2019, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -706,6 +706,11 @@ row_merge_buf_add(
|
||||
row_field, field, col->len,
|
||||
old_table->space->zip_size(),
|
||||
conv_heap);
|
||||
} else {
|
||||
/* Field length mismatch should not
|
||||
happen when rebuilding redundant row
|
||||
format table. */
|
||||
ut_ad(index->table->not_redundant());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -887,15 +887,10 @@ row_create_prebuilt(
|
||||
== MAX_REF_PARTS););
|
||||
uint temp_len = 0;
|
||||
for (uint i = 0; i < temp_index->n_uniq; i++) {
|
||||
const dict_field_t& f = temp_index->fields[i];
|
||||
if (f.col->mtype == DATA_INT) {
|
||||
ut_ad(f.col->len >= f.fixed_len);
|
||||
/* dtype_get_fixed_size_low() returns 0
|
||||
for ROW_FORMAT=REDUNDANT */
|
||||
ut_ad(table->not_redundant()
|
||||
? f.col->len == f.fixed_len
|
||||
: f.fixed_len == 0);
|
||||
temp_len += f.col->len;
|
||||
ulint type = temp_index->fields[i].col->mtype;
|
||||
if (type == DATA_INT) {
|
||||
temp_len +=
|
||||
temp_index->fields[i].fixed_len;
|
||||
}
|
||||
}
|
||||
srch_key_len = std::max(srch_key_len,temp_len);
|
||||
|
@ -2723,8 +2723,6 @@ row_sel_field_store_in_mysql_format_func(
|
||||
|
||||
switch (templ->type) {
|
||||
const byte* field_end;
|
||||
case DATA_CHAR:
|
||||
case DATA_FIXBINARY:
|
||||
case DATA_VARCHAR:
|
||||
case DATA_VARMYSQL:
|
||||
case DATA_BINARY:
|
||||
@ -2822,8 +2820,7 @@ row_sel_field_store_in_mysql_format_func(
|
||||
ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len
|
||||
|| (field_no == templ->icp_rec_field_no
|
||||
&& field->prefix_len > 0)
|
||||
|| templ->rec_field_is_prefix
|
||||
|| !index->table->not_redundant());
|
||||
|| templ->rec_field_is_prefix);
|
||||
|
||||
ut_ad(templ->is_virtual
|
||||
|| !(field->prefix_len % templ->mbmaxlen));
|
||||
@ -2845,6 +2842,8 @@ row_sel_field_store_in_mysql_format_func(
|
||||
ut_ad(0);
|
||||
/* fall through */
|
||||
|
||||
case DATA_CHAR:
|
||||
case DATA_FIXBINARY:
|
||||
case DATA_FLOAT:
|
||||
case DATA_DOUBLE:
|
||||
case DATA_DECIMAL:
|
||||
@ -2859,18 +2858,13 @@ row_sel_field_store_in_mysql_format_func(
|
||||
case DATA_INT:
|
||||
/* Convert InnoDB big-endian integer to little-endian
|
||||
format, sign bit restored to 2's complement form */
|
||||
DBUG_ASSERT(templ->mysql_col_len >= len);
|
||||
DBUG_ASSERT(templ->mysql_col_len == len);
|
||||
|
||||
byte* ptr = pad;
|
||||
do *--ptr = *data++; while (ptr != dest);
|
||||
byte b = templ->is_unsigned || !((pad[-1] ^= 0x80) & 0x80)
|
||||
? 0 : 0xff;
|
||||
|
||||
if (ulint l = templ->mysql_col_len - len) {
|
||||
DBUG_ASSERT(!index->table->not_redundant());
|
||||
memset(pad, b, l);
|
||||
if (!templ->is_unsigned) {
|
||||
pad[-1] ^= 0x80;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user