1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge branch '10.4' into bb-10.4-mdev17096

This commit is contained in:
Igor Babaev
2019-02-13 14:59:34 -08:00
49 changed files with 1023 additions and 198 deletions

View File

@@ -31,7 +31,7 @@ ENDIF()
IF(update_result OR NOT EXISTS ${CMAKE_SOURCE_DIR}/libmariadb/CMakeLists.txt) IF(update_result OR NOT EXISTS ${CMAKE_SOURCE_DIR}/libmariadb/CMakeLists.txt)
MESSAGE(FATAL_ERROR "No MariaDB Connector/C! Run MESSAGE(FATAL_ERROR "No MariaDB Connector/C! Run
git submodule update --init git submodule update --init --recursive
Then restart the build. Then restart the build.
") ")
ENDIF() ENDIF()

View File

@@ -32,6 +32,12 @@ IF(WITH_WSREP)
# Set the patch version # Set the patch version
SET(WSREP_PATCH_VERSION "22") SET(WSREP_PATCH_VERSION "22")
IF(NOT EXISTS "${CMAKE_SOURCE_DIR}/wsrep-lib/wsrep-API/v26/wsrep_api.h")
MESSAGE(FATAL_ERROR "No MariaDB wsrep-API code! Run
${GIT_EXECUTABLE} submodule update --init --recursive
Then restart the build.
")
ENDIF()
# Obtain wsrep API version # Obtain wsrep API version
FILE(STRINGS "${CMAKE_SOURCE_DIR}/wsrep-lib/wsrep-API/v26/wsrep_api.h" WSREP_API_VERSION FILE(STRINGS "${CMAKE_SOURCE_DIR}/wsrep-lib/wsrep-API/v26/wsrep_api.h" WSREP_API_VERSION
LIMIT_COUNT 1 REGEX "WSREP_INTERFACE_VERSION") LIMIT_COUNT 1 REGEX "WSREP_INTERFACE_VERSION")

View File

@@ -36,6 +36,7 @@ GLOBAL_VARIABLES VARIABLE_NAME
INDEX_STATISTICS TABLE_SCHEMA INDEX_STATISTICS TABLE_SCHEMA
KEY_CACHES KEY_CACHE_NAME KEY_CACHES KEY_CACHE_NAME
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
OPTIMIZER_TRACE QUERY
PARAMETERS SPECIFIC_SCHEMA PARAMETERS SPECIFIC_SCHEMA
PARTITIONS TABLE_SCHEMA PARTITIONS TABLE_SCHEMA
PLUGINS PLUGIN_NAME PLUGINS PLUGIN_NAME
@@ -94,6 +95,7 @@ GLOBAL_VARIABLES VARIABLE_NAME
INDEX_STATISTICS TABLE_SCHEMA INDEX_STATISTICS TABLE_SCHEMA
KEY_CACHES KEY_CACHE_NAME KEY_CACHES KEY_CACHE_NAME
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
OPTIMIZER_TRACE QUERY
PARAMETERS SPECIFIC_SCHEMA PARAMETERS SPECIFIC_SCHEMA
PARTITIONS TABLE_SCHEMA PARTITIONS TABLE_SCHEMA
PLUGINS PLUGIN_NAME PLUGINS PLUGIN_NAME

View File

@@ -2,7 +2,7 @@ create or replace table t1(a json);
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL `a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`a`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
create or replace table t1(a json character set utf8); create or replace table t1(a json character set utf8);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'character set utf8)' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'character set utf8)' at line 1
@@ -10,7 +10,7 @@ create or replace table t1(a json default '{a:1}');
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '{a:1}' `a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '{a:1}' CHECK (json_valid(`a`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
create or replace table t1(a json not null check (json_valid(a))); create or replace table t1(a json not null check (json_valid(a)));
show create table t1; show create table t1;
@@ -21,18 +21,79 @@ t1 CREATE TABLE `t1` (
insert t1 values ('[]'); insert t1 values ('[]');
insert t1 values ('a'); insert t1 values ('a');
ERROR 23000: CONSTRAINT `t1.a` failed for `test`.`t1` ERROR 23000: CONSTRAINT `t1.a` failed for `test`.`t1`
create or replace table t1(a json not null);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`a`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert t1 values ('[]');
insert t1 values ('a');
ERROR 23000: CONSTRAINT `t1.a` failed for `test`.`t1`
set timestamp=unix_timestamp('2010:11:12 13:14:15'); set timestamp=unix_timestamp('2010:11:12 13:14:15');
create or replace table t1(a json default(json_object('now', now()))); create or replace table t1(a json default(json_object('now', now())));
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT json_object('now',current_timestamp()) `a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT json_object('now',current_timestamp()) CHECK (json_valid(`a`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert t1 values (); insert t1 values ();
select * from t1; select * from t1;
a a
{"now": "2010-11-12 13:14:15"} {"now": "2010-11-12 13:14:15"}
drop table t1; drop table t1;
create table t1 (t json) as select json_quote('foo') as t;
create table t2 (a json) as select json_quote('foo') as t;
create table t3 like t1;
select * from t1;
t
"foo"
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`t`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`a`)),
`t` varchar(38) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`t` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`t`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2,t3;
create table t1 (t json check (length(t) > 0));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (octet_length(`t`) > 0)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (t text) engine=myisam;
insert into t1 values ("{}"),("");
create table t2 (t json) select t from t1;
ERROR 23000: CONSTRAINT `t2.t` failed for `test`.`t2`
select * from t2;
ERROR 42S02: Table 'test.t2' doesn't exist
drop table t1;
create or replace table t1(a json default(json_object('now', 1)) check (json_valid(a)));
insert into t1 values ();
insert into t1 values ("{}");
insert into t1 values ("xxx");
ERROR 23000: CONSTRAINT `t1.a` failed for `test`.`t1`
select * from t1;
a
{"now": 1}
{}
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT json_object('now',1) CHECK (json_valid(`a`))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select cast('{a:1}' as text); select cast('{a:1}' as text);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'text)' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'text)' at line 1
select cast('{a:1}' as json); select cast('{a:1}' as json);

View File

@@ -17,12 +17,47 @@ insert t1 values ('[]');
--error ER_CONSTRAINT_FAILED --error ER_CONSTRAINT_FAILED
insert t1 values ('a'); insert t1 values ('a');
create or replace table t1(a json not null);
show create table t1;
insert t1 values ('[]');
--error ER_CONSTRAINT_FAILED
insert t1 values ('a');
set timestamp=unix_timestamp('2010:11:12 13:14:15'); set timestamp=unix_timestamp('2010:11:12 13:14:15');
create or replace table t1(a json default(json_object('now', now()))); create or replace table t1(a json default(json_object('now', now())));
show create table t1; show create table t1;
insert t1 values (); insert t1 values ();
select * from t1; select * from t1;
drop table t1;
create table t1 (t json) as select json_quote('foo') as t;
create table t2 (a json) as select json_quote('foo') as t;
create table t3 like t1;
select * from t1;
show create table t1;
show create table t2;
show create table t3;
drop table t1,t2,t3;
create table t1 (t json check (length(t) > 0));
show create table t1;
drop table t1;
create table t1 (t text) engine=myisam;
insert into t1 values ("{}"),("");
--error ER_CONSTRAINT_FAILED
create table t2 (t json) select t from t1;
--error ER_NO_SUCH_TABLE
select * from t2;
drop table t1;
create or replace table t1(a json default(json_object('now', 1)) check (json_valid(a)));
insert into t1 values ();
insert into t1 values ("{}");
--error ER_CONSTRAINT_FAILED
insert into t1 values ("xxx");
select * from t1;
show create table t1;
drop table t1; drop table t1;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR

View File

@@ -34,7 +34,7 @@ WSREP_FORCED_BINLOG_FORMAT NONE
WSREP_GTID_DOMAIN_ID 0 WSREP_GTID_DOMAIN_ID 0
WSREP_GTID_MODE OFF WSREP_GTID_MODE OFF
WSREP_IGNORE_APPLY_ERRORS 7 WSREP_IGNORE_APPLY_ERRORS 7
WSREP_LOAD_DATA_SPLITTING ON WSREP_LOAD_DATA_SPLITTING OFF
WSREP_LOG_CONFLICTS OFF WSREP_LOG_CONFLICTS OFF
WSREP_MAX_WS_ROWS 0 WSREP_MAX_WS_ROWS 0
WSREP_MAX_WS_SIZE 2147483647 WSREP_MAX_WS_SIZE 2147483647

View File

@@ -12,7 +12,11 @@ COUNT(*) = 95000
wsrep_last_committed_diff wsrep_last_committed_diff
1 1
connection node_1; connection node_1;
SET GLOBAL wsrep_load_data_splitting = 1;; SET GLOBAL wsrep_load_data_splitting = 0;;
Warnings:
Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release
connection node_2;
SET GLOBAL wsrep_load_data_splitting = 0;;
Warnings: Warnings:
Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release
DROP TABLE t1; DROP TABLE t1;

View File

@@ -159,7 +159,7 @@ wsrep_last_committed_diff
AS_EXPECTED_1_or_2 AS_EXPECTED_1_or_2
DROP TABLE t1; DROP TABLE t1;
connection node_1; connection node_1;
SET GLOBAL wsrep_load_data_splitting = 1;; SET GLOBAL wsrep_load_data_splitting = 0;;
Warnings: Warnings:
Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release
disconnect node_2; disconnect node_2;

View File

@@ -36,4 +36,7 @@ SELECT COUNT(*) = 95000 FROM t1;
--connection node_1 --connection node_1
--eval SET GLOBAL wsrep_load_data_splitting = $wsrep_load_data_splitting_orig; --eval SET GLOBAL wsrep_load_data_splitting = $wsrep_load_data_splitting_orig;
--connection node_2
--eval SET GLOBAL wsrep_load_data_splitting = $wsrep_load_data_splitting_orig;
DROP TABLE t1; DROP TABLE t1;

View File

@@ -9,5 +9,5 @@ SELECT COUNT(*) = 20000 FROM t1;
COUNT(*) = 20000 COUNT(*) = 20000
1 1
wsrep_last_committed_diff wsrep_last_committed_diff
0 1
DROP TABLE t1; DROP TABLE t1;

View File

@@ -1,9 +1,19 @@
connection node_2;
connection node_1;
SET SESSION wsrep_trx_fragment_size = 512; SET SESSION wsrep_trx_fragment_size = 512;
SET GLOBAL wsrep_load_data_splitting = TRUE; SET GLOBAL wsrep_load_data_splitting = TRUE;
Warnings:
Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
connection node_2;
connection node_1;
connection node_2;
SELECT COUNT(*) = 95000 FROM t1; SELECT COUNT(*) = 95000 FROM t1;
COUNT(*) = 95000 COUNT(*) = 95000
1 1
wsrep_last_committed_diff wsrep_last_committed_diff
1 1
connection node_1;
Warnings:
Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release
DROP TABLE t1; DROP TABLE t1;

View File

@@ -33,7 +33,7 @@ CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
SELECT COUNT(*) = 20000 FROM t1; SELECT COUNT(*) = 20000 FROM t1;
# LOAD-ing 20K rows causes 3 commits to be registered # LOAD-ing 20K rows causes 3 commits to be registered
--disable_query_log --disable_query_log
--eval SELECT $wsrep_last_committed_after - $wsrep_last_committed_before = 3 AS wsrep_last_committed_diff; --eval SELECT $wsrep_last_committed_after - $wsrep_last_committed_before = 3 AS wsrep_last_committed_diff
--enable_query_log --enable_query_log
DROP TABLE t1; DROP TABLE t1;

View File

@@ -412,6 +412,23 @@ ALTER TABLE t1 MODIFY f2 VARCHAR(300);
CALL get_table_id("test/t1", @tbl1_id); CALL get_table_id("test/t1", @tbl1_id);
SELECT @tbl1_id = @tbl_id; SELECT @tbl1_id = @tbl_id;
@tbl1_id = @tbl_id @tbl1_id = @tbl_id
1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL,
`f2` varchar(300) DEFAULT NULL,
KEY `idx` (`f2`(40))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1(f1 INT NOT NULL,
f2 VARCHAR(128),
INDEX idx(f2(40)))ENGINE=InnoDB;
CALL get_table_id("test/t1", @tbl_id);
ALTER TABLE t1 MODIFY f2 VARCHAR(300);
CALL get_table_id("test/t1", @tbl1_id);
SELECT @tbl1_id = @tbl_id;
@tbl1_id = @tbl_id
0 0
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
@@ -422,6 +439,23 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(f1 INT NOT NULL, CREATE TABLE t1(f1 INT NOT NULL,
f2 VARCHAR(128),
INDEX idx(f2(40)))ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
CALL get_table_id("test/t1", @tbl_id);
ALTER TABLE t1 MODIFY f2 VARCHAR(300);
CALL get_table_id("test/t1", @tbl1_id);
SELECT @tbl1_id = @tbl_id;
@tbl1_id = @tbl_id
1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL,
`f2` varchar(300) DEFAULT NULL,
KEY `idx` (`f2`(40))
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT
DROP TABLE t1;
CREATE TABLE t1(f1 INT NOT NULL,
f2 VARCHAR(100), f2 VARCHAR(100),
INDEX idx(f2(40)))ENGINE=InnoDB; INDEX idx(f2(40)))ENGINE=InnoDB;
CALL get_table_id("test/t1", @tbl_id); CALL get_table_id("test/t1", @tbl_id);

View File

@@ -0,0 +1,29 @@
--- instant_alter_convert.result
+++ instant_alter_convert,utf8.result
@@ -37,7 +37,7 @@
test.t check status OK
call check_table('t');
name mtype prtype len
-a 2 800FE 200
+a 13 2100FE 600
# CHAR enlargement
alter table t modify a char(220), algorithm=instant;
select count(a) from t where a = @bigval;
@@ -51,7 +51,7 @@
test.t check status OK
call check_table('t');
name mtype prtype len
-a 2 800FE 200
+a 13 2100FE 600
# Convert from VARCHAR to a bigger CHAR
alter table t modify a varchar(200), algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
@@ -72,7 +72,7 @@
test.t check status OK
call check_table('t');
name mtype prtype len
-a 2 800FE 255
+a 13 2100FE 765
# BINARY/VARBINARY test
create or replace table t (a varbinary(300));
alter table t modify a binary(255), algorithm=instant;

View File

@@ -0,0 +1,235 @@
#
# MDEV-15563: Instant ROW_FORMAT=REDUNDANT column type change&extension
#
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);
create or replace procedure check_table(table_name varchar(255))
begin
select table_id into @table_id
from information_schema.innodb_sys_tables
where name = concat('test/', table_name);
select name, mtype, hex(prtype) as prtype, len
from information_schema.innodb_sys_columns
where table_id = @table_id;
end~~
# VARCHAR -> CHAR, VARBINARY -> BINARY conversion
set @bigval= repeat('0123456789', 20);
create or replace table t (a varchar(300));
alter table t modify a char(255), algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
alter table t modify a char(255), algorithm=copy;
create or replace table t (a varchar(200));
insert into t values (@bigval);
insert into t values ('z');
alter table t modify a char(200), algorithm=instant;
select count(a) from t where a = @bigval;
count(a)
1
select a, length(a) from t where a = 'z';
a length(a)
z 1
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
a 2 800FE 200
# CHAR enlargement
alter table t modify a char(220), algorithm=instant;
select count(a) from t where a = @bigval;
count(a)
1
select a, length(a) from t where a = 'z';
a length(a)
z 1
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
a 2 800FE 200
# Convert from VARCHAR to a bigger CHAR
alter table t modify a varchar(200), algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
alter table t modify a varchar(200), algorithm=copy;
alter table t modify a char(255), algorithm=instant;
select count(a) from t where a = @bigval;
count(a)
1
select a, length(a) from t where a = 'z';
a length(a)
z 1
select * from t;
a
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
z
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
a 2 800FE 255
# BINARY/VARBINARY test
create or replace table t (a varbinary(300));
alter table t modify a binary(255), algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
alter table t modify a binary(255), algorithm=copy;
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;
select count(a) from t where a = @bigval;
count(a)
1
select length(a) from t where left(a, 1) = 'z';
length(a)
200
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
a 3 3F04FE 200
# BINARY enlargement
alter table t modify a binary(220), algorithm=instant;
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
a 3 3F04FE 200
# Convert from VARBINARY to a bigger BINARY
alter table t modify a varbinary(220), algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
alter table t modify a varbinary(220), algorithm=copy;
alter table t modify a binary(255), algorithm=instant;
select count(a) from t where a = @bigval;
count(a)
0
select a, length(a) from t where a = 'z';
a length(a)
select * from t;
a
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
z
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
a 3 3F04FE 255
# Integer conversions
create or replace table t (x tinyint);
insert into t values (127);
alter table t modify x smallint, algorithm=instant;
select * from t;
x
127
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
x 6 402 2
update t set x= 32767;
alter table t modify x mediumint, algorithm=instant;
select * from t;
x
32767
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
x 6 409 3
update t set x= 8388607;
alter table t modify x int, algorithm=instant;
select * from t;
x
8388607
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
x 6 403 4
update t set x= 2147483647;
alter table t modify x bigint, algorithm=instant;
select * from t;
x
2147483647
check table t extended;
Table Op Msg_type Msg_text
test.t check status OK
call check_table('t');
name mtype prtype len
x 6 408 8
# Check IMPORT TABLESPACE
create or replace table t2 (x int);
alter table t2 discard tablespace;
create or replace table t1 (x tinyint);
insert into t1 set x= 42;
alter table t1 modify x int;
flush tables t1 for export;
unlock tables;
alter table t2 import tablespace;
select * from t2;
x
42
check table t2 extended;
Table Op Msg_type Msg_text
test.t2 check status OK
call check_table('t2');
name mtype prtype len
x 6 403 4
# Check innobase_col_to_mysql() len < flen
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;
alter table t1 add column z int first, add primary key (x);
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
# 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;
# Check row_mysql_store_col_in_innobase_format()
create or replace table t1(x int primary key, a varchar(20));
insert into t1 (x) values (1);
update t1 set a= 'foo' where x = 2;
#
# MDEV-18124 PK on inplace-enlarged type fails
#
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;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
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;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
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;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
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;
create or replace table t1 (x integer, a varchar(20));
alter table t1 add index idx3 (a);
insert into t1 (x, a) values (73, 'a');
alter table t1 modify a char(20);
create or replace database test charset latin1;
SET GLOBAL innodb_default_row_format=@save_format;

View File

@@ -306,6 +306,30 @@ SELECT @tbl1_id = @tbl_id;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(f1 INT NOT NULL,
f2 VARCHAR(128),
INDEX idx(f2(40)))ENGINE=InnoDB;
CALL get_table_id("test/t1", @tbl_id);
ALTER TABLE t1 MODIFY f2 VARCHAR(300);
CALL get_table_id("test/t1", @tbl1_id);
SELECT @tbl1_id = @tbl_id;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1(f1 INT NOT NULL,
f2 VARCHAR(128),
INDEX idx(f2(40)))ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
CALL get_table_id("test/t1", @tbl_id);
ALTER TABLE t1 MODIFY f2 VARCHAR(300);
CALL get_table_id("test/t1", @tbl1_id);
SELECT @tbl1_id = @tbl_id;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1(f1 INT NOT NULL, CREATE TABLE t1(f1 INT NOT NULL,
f2 VARCHAR(100), f2 VARCHAR(100),
INDEX idx(f2(40)))ENGINE=InnoDB; INDEX idx(f2(40)))ENGINE=InnoDB;

View File

@@ -0,0 +1,5 @@
[latin1]
character-set-server=latin1
[utf8]
character-set-server=utf8

View File

@@ -0,0 +1,226 @@
--source include/have_innodb.inc
--source include/maybe_debug.inc
-- echo #
-- echo # MDEV-15563: Instant ROW_FORMAT=REDUNDANT column type change&extension
-- echo #
# Use character-set-server in test db
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 ~~;
create or replace procedure check_table(table_name varchar(255))
begin
select table_id into @table_id
from information_schema.innodb_sys_tables
where name = concat('test/', table_name);
select name, mtype, hex(prtype) as prtype, len
from information_schema.innodb_sys_columns
where table_id = @table_id;
end~~
delimiter ;~~
--echo # VARCHAR -> CHAR, VARBINARY -> BINARY conversion
set @bigval= repeat('0123456789', 20);
create or replace table t (a varchar(300));
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify a char(255), algorithm=instant;
alter table t modify a char(255), algorithm=copy;
create or replace table t (a varchar(200));
if ($have_debug) {
--disable_query_log
--disable_result_log
set debug_dbug= '+d,ib_instant_error';
--error ER_RECORD_FILE_FULL
alter table t modify a char(200);
set debug_dbug= default;
--enable_query_log
--enable_result_log
}
insert into t values (@bigval);
insert into t values ('z');
alter table t modify a char(200), algorithm=instant;
select count(a) from t where a = @bigval;
select a, length(a) from t where a = 'z';
check table t extended;
call check_table('t');
--echo # CHAR enlargement
alter table t modify a char(220), algorithm=instant;
select count(a) from t where a = @bigval;
select a, length(a) from t where a = 'z';
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;
select count(a) from t where a = @bigval;
select a, length(a) from t where a = 'z';
select * from t;
check table t extended;
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;
create or replace table t (a varbinary(200));
if ($have_debug) {
--disable_query_log
--disable_result_log
set debug_dbug= '+d,ib_instant_error';
--error ER_RECORD_FILE_FULL
alter table t modify a binary(200);
set debug_dbug= default;
--enable_query_log
--enable_result_log
}
insert into t values (@bigval);
insert into t values ('z');
alter table t modify a binary(200), algorithm=instant;
select count(a) from t where a = @bigval;
select length(a) from t where left(a, 1) = 'z';
check table t extended;
call check_table('t');
--echo # BINARY enlargement
alter table t modify a binary(220), algorithm=instant;
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;
select count(a) from t where a = @bigval;
select a, length(a) from t where a = 'z';
select * from t;
check table t extended;
call check_table('t');
--echo # Integer conversions
create or replace table t (x tinyint);
if ($have_debug) {
--disable_query_log
--disable_result_log
set debug_dbug= '+d,ib_instant_error';
--error ER_RECORD_FILE_FULL
alter table t modify x smallint;
set debug_dbug= default;
--enable_query_log
--enable_result_log
}
insert into t values (127);
alter table t modify x smallint, algorithm=instant;
select * from t;
check table t extended;
call check_table('t');
update t set x= 32767;
alter table t modify x mediumint, algorithm=instant;
select * from t;
check table t extended;
call check_table('t');
update t set x= 8388607;
alter table t modify x int, algorithm=instant;
select * from t;
check table t extended;
call check_table('t');
update t set x= 2147483647;
alter table t modify x bigint, algorithm=instant;
select * from t;
check table t extended;
call check_table('t');
--echo # Check IMPORT TABLESPACE
--let $MYSQLD_DATADIR= `select @@datadir`
create or replace table t2 (x int);
alter table t2 discard tablespace;
create or replace table t1 (x tinyint);
insert into t1 set x= 42;
alter table t1 modify x int;
flush tables t1 for export;
--move_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg
--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd
unlock tables;
alter table t2 import tablespace;
select * from t2;
check table t2 extended;
call check_table('t2');
--echo # Check innobase_col_to_mysql() len < flen
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;
--error ER_DUP_ENTRY
alter table t1 add column z int first, add primary key (x);
--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;
--echo # Check row_mysql_store_col_in_innobase_format()
create or replace table t1(x int primary key, a varchar(20));
insert into t1 (x) values (1);
update t1 set a= 'foo' where x = 2;
--echo #
--echo # MDEV-18124 PK on inplace-enlarged type fails
--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;
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;
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;
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;
create or replace table t1 (x integer, a varchar(20));
alter table t1 add index idx3 (a);
insert into t1 (x, a) values (73, 'a');
alter table t1 modify a char(20);
create or replace database test charset latin1;
SET GLOBAL innodb_default_row_format=@save_format;

View File

@@ -227,9 +227,9 @@ READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME WSREP_LOAD_DATA_SPLITTING VARIABLE_NAME WSREP_LOAD_DATA_SPLITTING
SESSION_VALUE NULL SESSION_VALUE NULL
GLOBAL_VALUE ON GLOBAL_VALUE OFF
GLOBAL_VALUE_ORIGIN COMPILE-TIME GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE ON DEFAULT_VALUE OFF
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN VARIABLE_TYPE BOOLEAN
VARIABLE_COMMENT To commit LOAD DATA transaction after every 10K rows inserted (deprecated) VARIABLE_COMMENT To commit LOAD DATA transaction after every 10K rows inserted (deprecated)

View File

@@ -6,7 +6,7 @@ SET @wsrep_load_data_splitting_global_saved = @@global.wsrep_load_data_splitting
# default # default
SELECT @@global.wsrep_load_data_splitting; SELECT @@global.wsrep_load_data_splitting;
@@global.wsrep_load_data_splitting @@global.wsrep_load_data_splitting
1 0
# scope # scope
SELECT @@session.wsrep_load_data_splitting; SELECT @@session.wsrep_load_data_splitting;
@@ -42,7 +42,7 @@ Warnings:
Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release
SELECT @@global.wsrep_load_data_splitting; SELECT @@global.wsrep_load_data_splitting;
@@global.wsrep_load_data_splitting @@global.wsrep_load_data_splitting
1 0
# invalid values # invalid values
SET @@global.wsrep_load_data_splitting=NULL; SET @@global.wsrep_load_data_splitting=NULL;

View File

@@ -1,6 +1,6 @@
/* /*
Copyright (c) 2000, 2017, Oracle and/or its affiliates. Copyright (c) 2000, 2017, Oracle and/or its affiliates.
Copyright (c) 2008, 2017, MariaDB Copyright (c) 2008, 2019, MariaDB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -7063,9 +7063,16 @@ uint Field::is_equal(Create_field *new_field)
uint Field_str::is_equal(Create_field *new_field) uint Field_str::is_equal(Create_field *new_field)
{ {
return new_field->type_handler() == type_handler() && if (new_field->type_handler() == type_handler() &&
new_field->charset == field_charset && new_field->charset == field_charset)
new_field->length == max_display_length(); {
if (new_field->length == max_display_length())
return IS_EQUAL_YES;
if (new_field->length > max_display_length() &&
(table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION))
return IS_EQUAL_PACK_LENGTH_EXT;
}
return IS_EQUAL_NO;
} }
@@ -7901,16 +7908,28 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root, TABLE *new_table,
uint Field_varstring::is_equal(Create_field *new_field) uint Field_varstring::is_equal(Create_field *new_field)
{ {
if (new_field->type_handler() == type_handler() && if (new_field->length < field_length)
new_field->charset == field_charset && return IS_EQUAL_NO;
if (new_field->charset == field_charset &&
!new_field->compression_method() == !compression_method()) !new_field->compression_method() == !compression_method())
{ {
if (new_field->length == field_length) const Type_handler *new_type_handler= new_field->type_handler();
return IS_EQUAL_YES; if (new_type_handler == type_handler())
if (new_field->length > field_length && {
((new_field->length <= 255 && field_length <= 255) || if (new_field->length == field_length)
(new_field->length > 255 && field_length > 255))) return IS_EQUAL_YES;
return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer variable length if (field_length <= 127 ||
new_field->length <= 255 ||
field_length > 255 ||
(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; return IS_EQUAL_NO;
} }
@@ -9480,12 +9499,22 @@ bool Field_num::eq_def(const Field *field) const
uint Field_num::is_equal(Create_field *new_field) uint Field_num::is_equal(Create_field *new_field)
{ {
return ((new_field->type_handler() == type_handler()) && if ((new_field->flags ^ flags) & (UNSIGNED_FLAG | AUTO_INCREMENT_FLAG))
((new_field->flags & UNSIGNED_FLAG) == return IS_EQUAL_NO;
(uint) (flags & UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) == const Type_handler *th= type_handler(), *new_th = new_field->type_handler();
(uint) (flags & AUTO_INCREMENT_FLAG)) &&
(new_field->pack_length == pack_length())); if (th == new_th && new_field->pack_length == pack_length())
return IS_EQUAL_YES;
if (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION)
{
if (th->result_type() == new_th->result_type() &&
new_field->pack_length >= pack_length())
return IS_EQUAL_PACK_LENGTH_EXT;
}
return IS_EQUAL_NO;
} }
@@ -10733,6 +10762,7 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field,
interval= dup_field->interval; interval= dup_field->interval;
vcol_info= dup_field->vcol_info; vcol_info= dup_field->vcol_info;
invisible= dup_field->invisible; invisible= dup_field->invisible;
check_constraint= dup_field->check_constraint;
} }

View File

@@ -4564,7 +4564,7 @@ public:
:Type_handler_hybrid_field_type(&type_handler_null), :Type_handler_hybrid_field_type(&type_handler_null),
compression_method_ptr(0), compression_method_ptr(0),
comment(null_clex_str), comment(null_clex_str),
on_update(NULL), invisible(VISIBLE), decimals(0), on_update(NULL), invisible(VISIBLE), char_length(0), decimals(0),
flags(0), pack_length(0), key_length(0), flags(0), pack_length(0), key_length(0),
option_list(NULL), option_list(NULL),
vcol_info(0), default_value(0), check_constraint(0), vcol_info(0), default_value(0), check_constraint(0),

View File

@@ -2,7 +2,7 @@
#define HANDLER_INCLUDED #define HANDLER_INCLUDED
/* /*
Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2009, 2018, MariaDB Copyright (c) 2009, 2019, MariaDB
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
@@ -319,6 +319,11 @@ enum enum_alter_inplace_result {
/* Safe for online backup */ /* Safe for online backup */
#define HA_CAN_ONLINE_BACKUPS (1ULL << 56) #define HA_CAN_ONLINE_BACKUPS (1ULL << 56)
/** whether every data field explicitly stores length
(holds for InnoDB ROW_FORMAT=REDUNDANT) */
#define HA_EXTENDED_TYPES_CONVERSION (1ULL << 57)
#define HA_LAST_TABLE_FLAG HA_EXTENDED_TYPES_CONVERSION
/* bits in index_flags(index_number) for what you can do with index */ /* bits in index_flags(index_number) for what you can do with index */
#define HA_READ_NEXT 1 /* TODO really use this flag */ #define HA_READ_NEXT 1 /* TODO really use this flag */
#define HA_READ_PREV 2 /* supports ::index_prev */ #define HA_READ_PREV 2 /* supports ::index_prev */
@@ -741,6 +746,14 @@ typedef ulonglong alter_table_operations;
*/ */
#define ALTER_COLUMN_INDEX_LENGTH (1ULL << 60) #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 Flags set in partition_flags when altering partitions
*/ */
@@ -3158,7 +3171,11 @@ public:
/** /**
The cached_table_flags is set at ha_open and ha_external_lock The cached_table_flags is set at ha_open and ha_external_lock
*/ */
Table_flags ha_table_flags() const { return cached_table_flags; } Table_flags ha_table_flags() const
{
DBUG_ASSERT(cached_table_flags < (HA_LAST_TABLE_FLAG << 1));
return cached_table_flags;
}
/** /**
These functions represent the public interface to *users* of the These functions represent the public interface to *users* of the
handler class, hence they are *not* virtual. For the inheritance handler class, hence they are *not* virtual. For the inheritance

View File

@@ -111,7 +111,7 @@ class String_with_limit
{ {
public: public:
String_with_limit() : size_limit(SIZE_MAX), truncated_len(0) String_with_limit() : size_limit(SIZE_T_MAX), truncated_len(0)
{ {
str.length(0); str.length(0);
} }

View File

@@ -9587,3 +9587,21 @@ bool LEX::sp_proc_stmt_statement_finalize(THD *thd, bool no_lookahead)
lip->get_tok_start()); lip->get_tok_start());
return LEX::sp_proc_stmt_statement_finalize_buf(thd, qbuf); return LEX::sp_proc_stmt_statement_finalize_buf(thd, qbuf);
} }
/**
Create JSON_VALID(field_name) expression
*/
Virtual_column_info *make_json_valid_expr(THD *thd, LEX_CSTRING *field_name)
{
Lex_ident_sys_st str;
Item *field, *expr;
str.set_valid_utf8(field_name);
if (unlikely(!(field= thd->lex->create_item_ident_field(thd, NullS, NullS,
&str))))
return 0;
if (unlikely(!(expr= new (thd->mem_root) Item_func_json_valid(thd, field))))
return 0;
return add_virtual_expression(thd, expr);
}

View File

@@ -148,6 +148,12 @@ public:
bool copy_or_convert(THD *thd, const Lex_ident_cli_st *str, CHARSET_INFO *cs); bool copy_or_convert(THD *thd, const Lex_ident_cli_st *str, CHARSET_INFO *cs);
bool is_null() const { return str == NULL; } bool is_null() const { return str == NULL; }
bool to_size_number(ulonglong *to) const; bool to_size_number(ulonglong *to) const;
void set_valid_utf8(LEX_CSTRING *name)
{
DBUG_ASSERT(Well_formed_prefix(system_charset_info, name->str,
name->length).length() == name->length);
str= name->str ; length= name->length;
}
}; };
@@ -4610,5 +4616,6 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
void sp_create_assignment_lex(THD *thd, bool no_lookahead); void sp_create_assignment_lex(THD *thd, bool no_lookahead);
bool sp_create_assignment_instr(THD *thd, bool no_lookahead); bool sp_create_assignment_instr(THD *thd, bool no_lookahead);
Virtual_column_info *make_json_valid_expr(THD *thd, LEX_CSTRING *field_name);
#endif /* MYSQL_SERVER */ #endif /* MYSQL_SERVER */
#endif /* SQL_LEX_INCLUDED */ #endif /* SQL_LEX_INCLUDED */

View File

@@ -100,41 +100,39 @@ public:
#define PUSH(A) *(stack_pos++)=(A) #define PUSH(A) *(stack_pos++)=(A)
#ifdef WITH_WSREP #ifdef WITH_WSREP
/** If requested by wsrep_load_data_splitting, commit and restart /** If requested by wsrep_load_data_splitting and streaming replication is
the transaction after every 10,000 inserted rows. */ not enabled, replicate a streaming fragment every 10,000 rows.*/
class Wsrep_load_data_split
static bool wsrep_load_data_split(THD *thd, const TABLE *table,
const COPY_INFO &info)
{ {
DBUG_ENTER("wsrep_load_data_split"); public:
Wsrep_load_data_split(THD *thd)
if (!wsrep_load_data_splitting || !WSREP(thd) : m_thd(thd)
|| !info.records || (info.records % 10000) , m_load_data_splitting(wsrep_load_data_splitting)
|| !thd->transaction.stmt.ha_list , m_fragment_unit(thd->wsrep_trx().streaming_context().fragment_unit())
|| thd->transaction.stmt.ha_list->ht() != binlog_hton , m_fragment_size(thd->wsrep_trx().streaming_context().fragment_size())
|| !thd->transaction.stmt.ha_list->next()
|| thd->transaction.stmt.ha_list->next()->next())
DBUG_RETURN(false);
if (handlerton* hton= thd->transaction.stmt.ha_list->next()->ht())
{ {
if (!(hton->flags & HTON_WSREP_REPLICATION)) if (WSREP(m_thd) && m_load_data_splitting)
DBUG_RETURN(false); {
WSREP_DEBUG("intermediate transaction commit in LOAD DATA"); /* Override streaming settings with backward compatible values for
wsrep_tc_log_commit(thd); load data splitting */
table->file->extra(HA_EXTRA_FAKE_START_STMT); m_thd->wsrep_cs().streaming_params(wsrep::streaming_context::row, 10000);
}
} }
DBUG_RETURN(false); ~Wsrep_load_data_split()
} {
# define WSREP_LOAD_DATA_SPLIT(thd,table,info) \ if (WSREP(m_thd) && m_load_data_splitting)
if (wsrep_load_data_split(thd,table,info)) \ {
{ \ /* Restore original settings */
table->auto_increment_field_not_null= FALSE; \ m_thd->wsrep_cs().streaming_params(m_fragment_unit, m_fragment_size);
DBUG_RETURN(1); \ }
} }
#else /* WITH_WSREP */ private:
#define WSREP_LOAD_DATA_SPLIT(thd,table,info) /* empty */ THD *m_thd;
my_bool m_load_data_splitting;
enum wsrep::streaming_context::fragment_unit m_fragment_unit;
size_t m_fragment_size;
};
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
class READ_INFO: public Load_data_param class READ_INFO: public Load_data_param
@@ -354,6 +352,9 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list,
bool transactional_table __attribute__((unused)); bool transactional_table __attribute__((unused));
DBUG_ENTER("mysql_load"); DBUG_ENTER("mysql_load");
#ifdef WITH_WSREP
Wsrep_load_data_split wsrep_load_data_split(thd);
#endif /* WITH_WSREP */
/* /*
Bug #34283 Bug #34283
mysqlbinlog leaves tmpfile after termination if binlog contains mysqlbinlog leaves tmpfile after termination if binlog contains
@@ -1005,7 +1006,6 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
WSREP_LOAD_DATA_SPLIT(thd, table, info);
err= write_record(thd, table, &info); err= write_record(thd, table, &info);
table->auto_increment_field_not_null= FALSE; table->auto_increment_field_not_null= FALSE;
if (err) if (err)
@@ -1148,7 +1148,6 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
WSREP_LOAD_DATA_SPLIT(thd, table, info);
err= write_record(thd, table, &info); err= write_record(thd, table, &info);
table->auto_increment_field_not_null= FALSE; table->auto_increment_field_not_null= FALSE;
if (err) if (err)
@@ -1271,7 +1270,6 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
WSREP_LOAD_DATA_SPLIT(thd, table, info);
err= write_record(thd, table, &info); err= write_record(thd, table, &info);
table->auto_increment_field_not_null= false; table->auto_increment_field_not_null= false;
if (err) if (err)

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. /* Copyright (c) 2000, 2018, Oracle and/or its affiliates.
Copyright (c) 2010, 2018, Monty Program Ab. Copyright (c) 2010, 2019, MariaDB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -345,11 +345,21 @@
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
/* /*
Some defines for exit codes for ::is_equal class functions. Field::is_equal() return codes.
*/ */
#define IS_EQUAL_NO 0 #define IS_EQUAL_NO 0
#define IS_EQUAL_YES 1 #define IS_EQUAL_YES 1
/**
new_field has compatible packed representation with old type,
so it is theoretically possible to perform change by only updating
data dictionary without changing table rows
*/
#define IS_EQUAL_PACK_LENGTH 2 #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 enum enum_parsing_place
{ {

View File

@@ -6615,6 +6615,9 @@ static bool fill_alter_inplace_info(THD *thd,
*/ */
ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH; ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH;
break; break;
case IS_EQUAL_PACK_LENGTH_EXT:
ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT;
break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
/* Safety. */ /* Safety. */

View File

@@ -66,6 +66,7 @@ Type_handler_tiny_blob type_handler_tiny_blob;
Type_handler_medium_blob type_handler_medium_blob; Type_handler_medium_blob type_handler_medium_blob;
Type_handler_long_blob type_handler_long_blob; Type_handler_long_blob type_handler_long_blob;
Type_handler_blob type_handler_blob; Type_handler_blob type_handler_blob;
Type_handler_json type_handler_json;
static Type_handler_blob_compressed type_handler_blob_compressed; static Type_handler_blob_compressed type_handler_blob_compressed;
Type_handler_interval_DDhhmmssff type_handler_interval_DDhhmmssff; Type_handler_interval_DDhhmmssff type_handler_interval_DDhhmmssff;

View File

@@ -3280,6 +3280,7 @@ public:
return true; return true;
} }
virtual bool is_scalar_type() const { return true; } virtual bool is_scalar_type() const { return true; }
virtual bool is_json_type() const { return false; }
virtual bool can_return_int() const { return true; } virtual bool can_return_int() const { return true; }
virtual bool can_return_decimal() const { return true; } virtual bool can_return_decimal() const { return true; }
virtual bool can_return_real() const { return true; } virtual bool can_return_real() const { return true; }
@@ -5890,6 +5891,14 @@ public:
}; };
class Type_handler_json: public Type_handler_long_blob
{
public:
virtual ~Type_handler_json() {}
virtual bool is_json_type() const { return true; }
};
class Type_handler_blob: public Type_handler_blob_common class Type_handler_blob: public Type_handler_blob_common
{ {
static const Name m_name_blob; static const Name m_name_blob;
@@ -6218,6 +6227,7 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_hex_hybrid type_handler_hex_hybrid;
extern MYSQL_PLUGIN_IMPORT Type_handler_tiny_blob type_handler_tiny_blob; extern MYSQL_PLUGIN_IMPORT Type_handler_tiny_blob type_handler_tiny_blob;
extern MYSQL_PLUGIN_IMPORT Type_handler_medium_blob type_handler_medium_blob; extern MYSQL_PLUGIN_IMPORT Type_handler_medium_blob type_handler_medium_blob;
extern MYSQL_PLUGIN_IMPORT Type_handler_long_blob type_handler_long_blob; extern MYSQL_PLUGIN_IMPORT Type_handler_long_blob type_handler_long_blob;
extern MYSQL_PLUGIN_IMPORT Type_handler_json type_handler_json;
extern MYSQL_PLUGIN_IMPORT Type_handler_blob type_handler_blob; extern MYSQL_PLUGIN_IMPORT Type_handler_blob type_handler_blob;
extern MYSQL_PLUGIN_IMPORT Type_handler_bool type_handler_bool; extern MYSQL_PLUGIN_IMPORT Type_handler_bool type_handler_bool;
@@ -6243,11 +6253,6 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_datetime2 type_handler_datetime2;
extern MYSQL_PLUGIN_IMPORT Type_handler_timestamp type_handler_timestamp; extern MYSQL_PLUGIN_IMPORT Type_handler_timestamp type_handler_timestamp;
extern MYSQL_PLUGIN_IMPORT Type_handler_timestamp2 type_handler_timestamp2; extern MYSQL_PLUGIN_IMPORT Type_handler_timestamp2 type_handler_timestamp2;
extern MYSQL_PLUGIN_IMPORT Type_handler_tiny_blob type_handler_tiny_blob;
extern MYSQL_PLUGIN_IMPORT Type_handler_blob type_handler_blob;
extern MYSQL_PLUGIN_IMPORT Type_handler_medium_blob type_handler_medium_blob;
extern MYSQL_PLUGIN_IMPORT Type_handler_long_blob type_handler_long_blob;
extern MYSQL_PLUGIN_IMPORT Type_handler_interval_DDhhmmssff extern MYSQL_PLUGIN_IMPORT Type_handler_interval_DDhhmmssff
type_handler_interval_DDhhmmssff; type_handler_interval_DDhhmmssff;

View File

@@ -6690,6 +6690,10 @@ field_spec:
$$= $<create_field>2; $$= $<create_field>2;
$$->check_constraint= $4; $$->check_constraint= $4;
if (!$4 && lex->last_field->type_handler()->is_json_type() &&
!($$->check_constraint= make_json_valid_expr(thd,
&$$->field_name)))
MYSQL_YYABORT;
if (unlikely($$->check(thd))) if (unlikely($$->check(thd)))
MYSQL_YYABORT; MYSQL_YYABORT;
@@ -7083,7 +7087,7 @@ field_type_lob:
| JSON_SYM | JSON_SYM
{ {
Lex->charset= &my_charset_utf8mb4_bin; Lex->charset= &my_charset_utf8mb4_bin;
$$.set(&type_handler_long_blob); $$.set(&type_handler_json);
} }
; ;

View File

@@ -6628,6 +6628,10 @@ field_spec:
$$= $<create_field>2; $$= $<create_field>2;
$$->check_constraint= $4; $$->check_constraint= $4;
if (!$4 && lex->last_field->type_handler()->is_json_type() &&
!($$->check_constraint= make_json_valid_expr(thd,
&$$->field_name)))
MYSQL_YYABORT;
if (unlikely($$->check(thd))) if (unlikely($$->check(thd)))
MYSQL_YYABORT; MYSQL_YYABORT;
@@ -7073,7 +7077,7 @@ field_type_lob:
| JSON_SYM | JSON_SYM
{ {
Lex->charset= &my_charset_utf8mb4_bin; Lex->charset= &my_charset_utf8mb4_bin;
$$.set(&type_handler_long_blob); $$.set(&type_handler_json);
} }
; ;

View File

@@ -5540,7 +5540,7 @@ static Sys_var_mybool Sys_wsrep_load_data_splitting(
"wsrep_load_data_splitting", "To commit LOAD DATA " "wsrep_load_data_splitting", "To commit LOAD DATA "
"transaction after every 10K rows inserted (deprecated)", "transaction after every 10K rows inserted (deprecated)",
GLOBAL_VAR(wsrep_load_data_splitting), GLOBAL_VAR(wsrep_load_data_splitting),
CMD_LINE(OPT_ARG), DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, CMD_LINE(OPT_ARG), DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
ON_CHECK(0), ON_UPDATE(0), DEPRECATED("")); ON_CHECK(0), ON_UPDATE(0), DEPRECATED(""));
static Sys_var_mybool Sys_wsrep_slave_FK_checks( static Sys_var_mybool Sys_wsrep_slave_FK_checks(

View File

@@ -52,7 +52,8 @@
static Virtual_column_info * unpack_vcol_info_from_frm(THD *, MEM_ROOT *, static Virtual_column_info * unpack_vcol_info_from_frm(THD *, MEM_ROOT *,
TABLE *, String *, Virtual_column_info **, bool *); TABLE *, String *, Virtual_column_info **, bool *);
static bool check_vcol_forward_refs(Field *, Virtual_column_info *); static bool check_vcol_forward_refs(Field *, Virtual_column_info *,
bool check_constraint);
/* INFORMATION_SCHEMA name */ /* INFORMATION_SCHEMA name */
LEX_CSTRING INFORMATION_SCHEMA_NAME= {STRING_WITH_LEN("information_schema")}; LEX_CSTRING INFORMATION_SCHEMA_NAME= {STRING_WITH_LEN("information_schema")};
@@ -1189,9 +1190,9 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
for (field_ptr= table->field; *field_ptr; field_ptr++) for (field_ptr= table->field; *field_ptr; field_ptr++)
{ {
Field *field= *field_ptr; Field *field= *field_ptr;
if (check_vcol_forward_refs(field, field->vcol_info) || if (check_vcol_forward_refs(field, field->vcol_info, 0) ||
check_vcol_forward_refs(field, field->check_constraint) || check_vcol_forward_refs(field, field->check_constraint, 1) ||
check_vcol_forward_refs(field, field->default_value)) check_vcol_forward_refs(field, field->default_value, 0))
goto end; goto end;
} }
@@ -3133,11 +3134,19 @@ end:
DBUG_RETURN(vcol_info); DBUG_RETURN(vcol_info);
} }
static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol) static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol,
bool check_constraint)
{ {
bool res= vcol && bool res;
vcol->expr->walk(&Item::check_field_expression_processor, 0, uint32 flags= field->flags;
field); if (check_constraint)
{
/* Check constraints can refer it itself */
field->flags|= NO_DEFAULT_VALUE_FLAG;
}
res= (vcol &&
vcol->expr->walk(&Item::check_field_expression_processor, 0, field));
field->flags= flags;
return res; return res;
} }

View File

@@ -2499,57 +2499,6 @@ int wsrep_ordered_commit_if_no_binlog(THD* thd, bool all)
return 0; return 0;
} }
wsrep_status_t wsrep_tc_log_commit(THD* thd)
{
int cookie;
my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
DBUG_ASSERT(thd->lex->sql_command == SQLCOM_LOAD);
if (wsrep_before_commit(thd, true))
{
WSREP_DEBUG("wsrep_tc_log_commit: wsrep_before_commit failed %llu",
thd->thread_id);
return WSREP_TRX_FAIL;
}
cookie= tc_log->log_and_order(thd, xid, 1, false, true);
if (wsrep_after_commit(thd, true))
{
WSREP_DEBUG("wsrep_tc_log_commit: wsrep_after_commit failed %llu",
thd->thread_id);
return WSREP_TRX_FAIL;
}
if (!cookie)
{
WSREP_DEBUG("log_and_order has failed %llu %d", thd->thread_id, cookie);
return WSREP_TRX_FAIL;
}
if (tc_log->unlog(cookie, xid))
{
WSREP_DEBUG("log_and_order has failed %llu %d", thd->thread_id, cookie);
return WSREP_TRX_FAIL;
}
if (wsrep_after_statement(thd))
{
return WSREP_TRX_FAIL;
}
/* Set wsrep transaction id if not set. */
if (thd->wsrep_trx_id() == WSREP_UNDEFINED_TRX_ID)
{
if (thd->wsrep_next_trx_id() == WSREP_UNDEFINED_TRX_ID)
{
thd->set_wsrep_next_trx_id(thd->query_id);
}
DBUG_ASSERT(thd->wsrep_next_trx_id() != WSREP_UNDEFINED_TRX_ID);
}
if (wsrep_start_transaction(thd, thd->wsrep_next_trx_id()))
{
return WSREP_TRX_FAIL;
}
DBUG_ASSERT(thd->wsrep_trx_id() != WSREP_UNDEFINED_TRX_ID);
return WSREP_OK;
}
int wsrep_thd_retry_counter(const THD *thd) int wsrep_thd_retry_counter(const THD *thd)
{ {
return thd->wsrep_retry_counter; return thd->wsrep_retry_counter;

View File

@@ -444,15 +444,6 @@ bool wsrep_provider_is_SR_capable();
*/ */
int wsrep_ordered_commit_if_no_binlog(THD*, bool); int wsrep_ordered_commit_if_no_binlog(THD*, bool);
/**
* Commit the current transaction with the
* MySQL "Transaction Coordinator Log" (see `class TC_LOG` in sql/log.h).
* Calling this function will generate and assign a new wsrep transaction id
* for `thd`.
* @return WSREP_OK on success or other WSREP_* error code on failure
*/
wsrep_status_t wsrep_tc_log_commit(THD* thd);
/** /**
* Initialize WSREP server instance. * Initialize WSREP server instance.
* *

View File

@@ -4839,7 +4839,9 @@ n_field_mismatch:
if (len_is_stored(len) if (len_is_stored(len)
&& (field->prefix_len && (field->prefix_len
? len > field->prefix_len ? len > field->prefix_len
: (fixed_size && len != fixed_size))) { : (fixed_size && (page_is_comp(page)
? len != fixed_size
: len > fixed_size)))) {
len_mismatch: len_mismatch:
btr_index_rec_validate_report(page, rec, index); btr_index_rec_validate_report(page, rec, index);
ib::error error; ib::error error;

View File

@@ -486,8 +486,14 @@ incompatible:
For the metadata record, variable-length columns are For the metadata record, variable-length columns are
always written with zero length. The DB_TRX_ID will always written with zero length. The DB_TRX_ID will
start right after any fixed-length columns. */ start right after any fixed-length columns. */
for (uint i = index->n_uniq; i--; ) { if (index->table->not_redundant()) {
trx_id_offset += index->fields[i].fixed_len; 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);
} }
} }

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation. Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -24,7 +24,8 @@ Data types
Created 1/16/1996 Heikki Tuuri Created 1/16/1996 Heikki Tuuri
*******************************************************/ *******************************************************/
#include "data0type.h" #include "dict0mem.h"
#include "my_sys.h"
/** The DB_TRX_ID,DB_ROLL_PTR values for "no history is available" */ /** The DB_TRX_ID,DB_ROLL_PTR values for "no history is available" */
const byte reset_trx_id[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN] = { const byte reset_trx_id[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN] = {
@@ -160,6 +161,22 @@ dtype_validate(
return(TRUE); 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 #ifdef UNIV_DEBUG
/** Print a data type structure. /** Print a data type structure.
@param[in] type data type */ @param[in] type data type */

View File

@@ -2203,6 +2203,14 @@ dict_index_too_big_for_tree(
} }
field_max_size = dict_col_get_max_size(col); 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; field_ext_max_size = field_max_size < 256 ? 1 : 2;
if (field->prefix_len) { if (field->prefix_len) {

View File

@@ -6121,6 +6121,11 @@ no_such_table:
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
} }
if (!ib_table->not_redundant()) {
m_int_table_flags |= HA_EXTENDED_TYPES_CONVERSION;
cached_table_flags |= HA_EXTENDED_TYPES_CONVERSION;
}
size_t n_fields = omits_virtual_cols(*table_share) size_t n_fields = omits_virtual_cols(*table_share)
? table_share->stored_fields : table_share->fields; ? table_share->stored_fields : table_share->fields;
size_t n_cols = dict_table_get_n_user_cols(ib_table) size_t n_cols = dict_table_get_n_user_cols(ib_table)
@@ -9962,7 +9967,7 @@ innobase_fts_create_doc_id_key(
/* The unique Doc ID field should be an eight-bytes integer */ /* The unique Doc ID field should be an eight-bytes integer */
dict_field_t* field = dict_index_get_nth_field(index, 0); dict_field_t* field = dict_index_get_nth_field(index, 0);
ut_a(field->col->mtype == DATA_INT); ut_a(field->col->mtype == DATA_INT);
ut_ad(sizeof(*doc_id) == field->fixed_len); ut_ad(sizeof(*doc_id) == field->col->len);
ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX_NAME)); ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX_NAME));
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */

View File

@@ -84,6 +84,7 @@ static const alter_table_operations INNOBASE_ALTER_REBUILD
| ALTER_OPTIONS | ALTER_OPTIONS
/* ALTER_OPTIONS needs to check alter_options_need_rebuild() */ /* ALTER_OPTIONS needs to check alter_options_need_rebuild() */
| ALTER_COLUMN_NULLABLE | ALTER_COLUMN_NULLABLE
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
| INNOBASE_DEFAULTS | INNOBASE_DEFAULTS
| ALTER_STORED_COLUMN_ORDER | ALTER_STORED_COLUMN_ORDER
| ALTER_DROP_STORED_COLUMN | ALTER_DROP_STORED_COLUMN
@@ -268,7 +269,7 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
ut_ad(!not_redundant()); ut_ad(!not_redundant());
for (unsigned i = index.n_fields; i--; ) { for (unsigned i = index.n_fields; i--; ) {
ut_ad(index.fields[i].col->same_format( ut_ad(index.fields[i].col->same_format(
*oindex.fields[i].col)); *oindex.fields[i].col, true));
} }
} }
#endif #endif
@@ -456,9 +457,13 @@ 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. */ as this index. Fields for any added columns are appended at the end. */
#ifndef DBUG_OFF #ifndef DBUG_OFF
for (unsigned i = 0; i < n_fields; i++) { for (unsigned i = 0; i < n_fields; i++) {
DBUG_ASSERT(fields[i].same(instant.fields[i])); DBUG_ASSERT(fields[i].prefix_len
DBUG_ASSERT(instant.fields[i].col->same_format(*fields[i] == instant.fields[i].prefix_len);
.col)); 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()));
/* Instant conversion from NULL to NOT NULL is not allowed. */ /* Instant conversion from NULL to NOT NULL is not allowed. */
DBUG_ASSERT(!fields[i].col->is_nullable() DBUG_ASSERT(!fields[i].col->is_nullable()
|| instant.fields[i].col->is_nullable()); || instant.fields[i].col->is_nullable());
@@ -534,10 +539,7 @@ 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)) { if (const dict_col_t* o = find(old_cols, col_map, n_cols, i)) {
c.def_val = o->def_val; c.def_val = o->def_val;
DBUG_ASSERT(!((c.prtype ^ o->prtype) ut_ad(c.same_format(*o, !not_redundant()));
& ~(DATA_NOT_NULL | DATA_VERSIONED)));
DBUG_ASSERT(c.mtype == o->mtype);
DBUG_ASSERT(c.len >= o->len);
if (o->vers_sys_start()) { if (o->vers_sys_start()) {
ut_ad(o->ind == vers_start); ut_ad(o->ind == vers_start);
@@ -1505,7 +1507,8 @@ instant_alter_column_possible(
= ALTER_ADD_STORED_BASE_COLUMN = ALTER_ADD_STORED_BASE_COLUMN
| ALTER_DROP_STORED_COLUMN | ALTER_DROP_STORED_COLUMN
| ALTER_STORED_COLUMN_ORDER | ALTER_STORED_COLUMN_ORDER
| ALTER_COLUMN_NULLABLE; | ALTER_COLUMN_NULLABLE
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT;
if (!(ha_alter_info->handler_flags & avoid_rebuild)) { if (!(ha_alter_info->handler_flags & avoid_rebuild)) {
alter_table_operations flags = ha_alter_info->handler_flags alter_table_operations flags = ha_alter_info->handler_flags
@@ -1548,6 +1551,7 @@ instant_alter_column_possible(
& ~ALTER_STORED_COLUMN_ORDER & ~ALTER_STORED_COLUMN_ORDER
& ~ALTER_ADD_STORED_BASE_COLUMN & ~ALTER_ADD_STORED_BASE_COLUMN
& ~ALTER_COLUMN_NULLABLE & ~ALTER_COLUMN_NULLABLE
& ~ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
& ~ALTER_OPTIONS)) { & ~ALTER_OPTIONS)) {
return false; return false;
} }
@@ -1748,6 +1752,10 @@ ha_innobase::check_if_supported_inplace_alter(
{ {
DBUG_ENTER("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 if ((ha_alter_info->handler_flags
& INNOBASE_ALTER_VERSIONED_REBUILD) & INNOBASE_ALTER_VERSIONED_REBUILD)
&& altered_table->versioned(VERS_TIMESTAMP)) { && altered_table->versioned(VERS_TIMESTAMP)) {
@@ -2943,7 +2951,7 @@ innobase_col_to_mysql(
switch (col->mtype) { switch (col->mtype) {
case DATA_INT: case DATA_INT:
ut_ad(len == flen); ut_ad(len <= flen);
/* Convert integer data from Innobase to little-endian /* Convert integer data from Innobase to little-endian
format, sign bit restored to normal */ format, sign bit restored to normal */
@@ -5583,7 +5591,8 @@ static bool innobase_instant_try(
bool update = old && (!ctx->first_alter_pos bool update = old && (!ctx->first_alter_pos
|| i < ctx->first_alter_pos - 1); || i < ctx->first_alter_pos - 1);
DBUG_ASSERT(!old || col->same_format(*old)); ut_ad(!old || col->same_format(
*old, !user_table->not_redundant()));
if (update if (update
&& old->prtype == d->type.prtype) { && old->prtype == d->type.prtype) {
/* The record is already present in SYS_COLUMNS. */ /* The record is already present in SYS_COLUMNS. */
@@ -5672,6 +5681,8 @@ add_all_virtual:
NULL, trx, ctx->heap, NULL); NULL, trx, ctx->heap, NULL);
dberr_t err = DB_SUCCESS; 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)) { if (rec_is_metadata(rec, *index)) {
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
if (!page_has_next(block->frame) if (!page_has_next(block->frame)
@@ -9050,12 +9061,16 @@ innobase_enlarge_column_try(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
ut_ad(col->len < new_len); ut_ad(col->len < new_len);
switch (col->mtype) { switch (col->mtype) {
case DATA_FIXBINARY:
case DATA_CHAR:
case DATA_MYSQL: case DATA_MYSQL:
/* NOTE: we could allow this when !(prtype & DATA_BINARY_TYPE) /* NOTE: we could allow this when !(prtype & DATA_BINARY_TYPE)
and ROW_FORMAT is not REDUNDANT and mbminlen<mbmaxlen. and ROW_FORMAT is not REDUNDANT and mbminlen<mbmaxlen.
That is, we treat a UTF-8 CHAR(n) column somewhat like That is, we treat a UTF-8 CHAR(n) column somewhat like
a VARCHAR. */ a VARCHAR. */
ut_error; if (user_table->not_redundant()) {
ut_error;
}
case DATA_BINARY: case DATA_BINARY:
case DATA_VARCHAR: case DATA_VARCHAR:
case DATA_VARMYSQL: case DATA_VARMYSQL:
@@ -9188,14 +9203,16 @@ innobase_rename_or_enlarge_columns_cache(
ulint col_n = is_virtual ? num_v : i - num_v; ulint col_n = is_virtual ? num_v : i - num_v;
if ((*fp)->is_equal(cf) == IS_EQUAL_PACK_LENGTH) { if ((*fp)->is_equal(cf) == IS_EQUAL_PACK_LENGTH) {
if (is_virtual) { dict_col_t *col = is_virtual ?
dict_table_get_nth_v_col( &dict_table_get_nth_v_col(
user_table, col_n)->m_col.len user_table, col_n)->m_col
= cf->length; : dict_table_get_nth_col(
} else { user_table, col_n);
dict_table_get_nth_col( col->len = cf->length;
user_table, col_n)->len if (col->len > 255
= cf->length; && (col->prtype & DATA_MYSQL_TRUE_VARCHAR)
== DATA_MYSQL_TRUE_VARCHAR) {
col->prtype |= DATA_LONG_TRUE_VARCHAR;
} }
} }

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation. Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -472,12 +472,18 @@ dtype_get_fixed_size_low(
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/* fall through */ /* fall through */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_INT:
case DATA_FLOAT: case DATA_FLOAT:
case DATA_DOUBLE: case DATA_DOUBLE:
return(len); 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: case DATA_MYSQL:
if (prtype & DATA_BINARY_TYPE) { if (prtype & DATA_BINARY_TYPE) {
return(len); return(len);
@@ -625,6 +631,14 @@ dtype_get_sql_null_size(
const dtype_t* type, /*!< in: type */ const dtype_t* type, /*!< in: type */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ 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, return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
type->mbminlen, type->mbmaxlen, comp)); type->mbminlen, type->mbmaxlen, comp));
} }

View File

@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2018, MariaDB Corporation. Copyright (c) 2013, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -682,18 +682,52 @@ public:
def_val.data = NULL; 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 /** Determine if the columns have the same format
except for is_nullable() and is_versioned(). except for is_nullable() and is_versioned().
@param[in] other column to compare to @param[in] other column to compare to
@param[in] redundant table is redundant row format
@return whether the columns have the same format */ @return whether the columns have the same format */
bool same_format(const dict_col_t& other) const bool same_format(const dict_col_t& other, bool redundant = false) const
{ {
return mtype == other.mtype if (len < other.len
&& len >= other.len || mbminlen != other.mbminlen
&& mbminlen == other.mbminlen || mbmaxlen != other.mbmaxlen) {
&& mbmaxlen == other.mbmaxlen return false;
&& !((prtype ^ other.prtype) }
& ~(DATA_NOT_NULL | DATA_VERSIONED));
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;
} }
}; };

View File

@@ -706,11 +706,6 @@ row_merge_buf_add(
row_field, field, col->len, row_field, field, col->len,
old_table->space->zip_size(), old_table->space->zip_size(),
conv_heap); conv_heap);
} else {
/* Field length mismatch should not
happen when rebuilding redundant row
format table. */
ut_ad(dict_table_is_comp(index->table));
} }
} }
} }

View File

@@ -887,10 +887,15 @@ row_create_prebuilt(
== MAX_REF_PARTS);); == MAX_REF_PARTS););
uint temp_len = 0; uint temp_len = 0;
for (uint i = 0; i < temp_index->n_uniq; i++) { for (uint i = 0; i < temp_index->n_uniq; i++) {
ulint type = temp_index->fields[i].col->mtype; const dict_field_t& f = temp_index->fields[i];
if (type == DATA_INT) { if (f.col->mtype == DATA_INT) {
temp_len += ut_ad(f.col->len >= f.fixed_len);
temp_index->fields[i].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;
} }
} }
srch_key_len = std::max(srch_key_len,temp_len); srch_key_len = std::max(srch_key_len,temp_len);

View File

@@ -2742,12 +2742,15 @@ row_sel_field_store_in_mysql_format_func(
dest[len - 1] = (byte) (dest[len - 1] ^ 128); dest[len - 1] = (byte) (dest[len - 1] ^ 128);
} }
ut_ad(templ->mysql_col_len == len); ut_ad(templ->mysql_col_len == len
|| !index->table->not_redundant());
break; break;
case DATA_VARCHAR: case DATA_VARCHAR:
case DATA_VARMYSQL: case DATA_VARMYSQL:
case DATA_BINARY: case DATA_BINARY:
case DATA_CHAR:
case DATA_FIXBINARY:
field_end = dest + templ->mysql_col_len; field_end = dest + templ->mysql_col_len;
if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) { if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
@@ -2835,7 +2838,8 @@ row_sel_field_store_in_mysql_format_func(
ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len
|| (field_no == templ->icp_rec_field_no || (field_no == templ->icp_rec_field_no
&& field->prefix_len > 0) && field->prefix_len > 0)
|| templ->rec_field_is_prefix); || templ->rec_field_is_prefix
|| !index->table->not_redundant());
ut_ad(templ->is_virtual ut_ad(templ->is_virtual
|| !(field->prefix_len % templ->mbmaxlen)); || !(field->prefix_len % templ->mbmaxlen));
@@ -2857,8 +2861,6 @@ row_sel_field_store_in_mysql_format_func(
ut_ad(0); ut_ad(0);
/* fall through */ /* fall through */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_FLOAT: case DATA_FLOAT:
case DATA_DOUBLE: case DATA_DOUBLE:
case DATA_DECIMAL: case DATA_DECIMAL: