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)
MESSAGE(FATAL_ERROR "No MariaDB Connector/C! Run
git submodule update --init
git submodule update --init --recursive
Then restart the build.
")
ENDIF()

View File

@@ -32,6 +32,12 @@ IF(WITH_WSREP)
# Set the patch version
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
FILE(STRINGS "${CMAKE_SOURCE_DIR}/wsrep-lib/wsrep-API/v26/wsrep_api.h" WSREP_API_VERSION
LIMIT_COUNT 1 REGEX "WSREP_INTERFACE_VERSION")

View File

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

View File

@@ -2,7 +2,7 @@ create or replace table t1(a json);
show create table t1;
Table Create Table
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
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
@@ -10,7 +10,7 @@ create or replace table t1(a json default '{a:1}');
show create table t1;
Table Create Table
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
create or replace table t1(a json not null check (json_valid(a)));
show create table t1;
@@ -21,18 +21,79 @@ t1 CREATE TABLE `t1` (
insert t1 values ('[]');
insert t1 values ('a');
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');
create or replace table t1(a json default(json_object('now', now())));
show create table t1;
Table Create Table
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
insert t1 values ();
select * from t1;
a
{"now": "2010-11-12 13:14:15"}
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);
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);

View File

@@ -17,12 +17,47 @@ insert t1 values ('[]');
--error ER_CONSTRAINT_FAILED
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');
create or replace table t1(a json default(json_object('now', now())));
show create table t1;
insert t1 values ();
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;
--error ER_PARSE_ERROR

View File

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

View File

@@ -12,7 +12,11 @@ COUNT(*) = 95000
wsrep_last_committed_diff
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:
Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release
DROP TABLE t1;

View File

@@ -159,7 +159,7 @@ wsrep_last_committed_diff
AS_EXPECTED_1_or_2
DROP TABLE t1;
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
disconnect node_2;

View File

@@ -36,4 +36,7 @@ SELECT COUNT(*) = 95000 FROM t1;
--connection node_1
--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;

View File

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

View File

@@ -1,9 +1,19 @@
connection node_2;
connection node_1;
SET SESSION wsrep_trx_fragment_size = 512;
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;
connection node_2;
connection node_1;
connection node_2;
SELECT COUNT(*) = 95000 FROM t1;
COUNT(*) = 95000
1
wsrep_last_committed_diff
1
connection node_1;
Warnings:
Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release
DROP TABLE t1;

View File

@@ -33,7 +33,7 @@ CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
SELECT COUNT(*) = 20000 FROM t1;
# LOAD-ing 20K rows causes 3 commits to be registered
--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
DROP TABLE t1;

View File

@@ -412,6 +412,23 @@ 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
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
SHOW CREATE TABLE t1;
Table Create Table
@@ -422,6 +439,23 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
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;
@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),
INDEX idx(f2(40)))ENGINE=InnoDB;
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;
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,
f2 VARCHAR(100),
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
VARIABLE_NAME WSREP_LOAD_DATA_SPLITTING
SESSION_VALUE NULL
GLOBAL_VALUE ON
GLOBAL_VALUE OFF
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE ON
DEFAULT_VALUE OFF
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN
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
SELECT @@global.wsrep_load_data_splitting;
@@global.wsrep_load_data_splitting
1
0
# scope
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
SELECT @@global.wsrep_load_data_splitting;
@@global.wsrep_load_data_splitting
1
0
# invalid values
SET @@global.wsrep_load_data_splitting=NULL;

View File

@@ -1,6 +1,6 @@
/*
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
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)
{
return new_field->type_handler() == type_handler() &&
new_field->charset == field_charset &&
new_field->length == max_display_length();
if (new_field->type_handler() == type_handler() &&
new_field->charset == field_charset)
{
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)
{
if (new_field->type_handler() == type_handler() &&
new_field->charset == field_charset &&
if (new_field->length < field_length)
return IS_EQUAL_NO;
if (new_field->charset == field_charset &&
!new_field->compression_method() == !compression_method())
{
if (new_field->length == field_length)
return IS_EQUAL_YES;
if (new_field->length > field_length &&
((new_field->length <= 255 && field_length <= 255) ||
(new_field->length > 255 && field_length > 255)))
return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer variable length
const Type_handler *new_type_handler= new_field->type_handler();
if (new_type_handler == type_handler())
{
if (new_field->length == field_length)
return IS_EQUAL_YES;
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;
}
@@ -9480,12 +9499,22 @@ bool Field_num::eq_def(const Field *field) const
uint Field_num::is_equal(Create_field *new_field)
{
return ((new_field->type_handler() == type_handler()) &&
((new_field->flags & UNSIGNED_FLAG) ==
(uint) (flags & UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) ==
(uint) (flags & AUTO_INCREMENT_FLAG)) &&
(new_field->pack_length == pack_length()));
if ((new_field->flags ^ flags) & (UNSIGNED_FLAG | AUTO_INCREMENT_FLAG))
return IS_EQUAL_NO;
const Type_handler *th= type_handler(), *new_th = new_field->type_handler();
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;
vcol_info= dup_field->vcol_info;
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),
compression_method_ptr(0),
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),
option_list(NULL),
vcol_info(0), default_value(0), check_constraint(0),

View File

@@ -2,7 +2,7 @@
#define HANDLER_INCLUDED
/*
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
modify it under the terms of the GNU General Public License
@@ -319,6 +319,11 @@ enum enum_alter_inplace_result {
/* Safe for online backup */
#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 */
#define HA_READ_NEXT 1 /* TODO really use this flag */
#define HA_READ_PREV 2 /* supports ::index_prev */
@@ -741,6 +746,14 @@ 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
*/
@@ -3158,7 +3171,11 @@ public:
/**
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
handler class, hence they are *not* virtual. For the inheritance

View File

@@ -111,7 +111,7 @@ class String_with_limit
{
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);
}

View File

@@ -9587,3 +9587,21 @@ bool LEX::sp_proc_stmt_statement_finalize(THD *thd, bool no_lookahead)
lip->get_tok_start());
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 is_null() const { return str == NULL; }
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);
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 /* SQL_LEX_INCLUDED */

View File

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

View File

@@ -1,5 +1,5 @@
/* 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
it under the terms of the GNU General Public License as published by
@@ -345,11 +345,21 @@
#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_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
/**
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
{

View File

@@ -6615,6 +6615,9 @@ 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. */

View File

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

View File

@@ -3280,6 +3280,7 @@ public:
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_decimal() 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
{
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_medium_blob type_handler_medium_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_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_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
type_handler_interval_DDhhmmssff;

View File

@@ -6690,6 +6690,10 @@ field_spec:
$$= $<create_field>2;
$$->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)))
MYSQL_YYABORT;
@@ -7083,7 +7087,7 @@ field_type_lob:
| JSON_SYM
{
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;
$$->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)))
MYSQL_YYABORT;
@@ -7073,7 +7077,7 @@ field_type_lob:
| JSON_SYM
{
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 "
"transaction after every 10K rows inserted (deprecated)",
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(""));
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 *,
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 */
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++)
{
Field *field= *field_ptr;
if (check_vcol_forward_refs(field, field->vcol_info) ||
check_vcol_forward_refs(field, field->check_constraint) ||
check_vcol_forward_refs(field, field->default_value))
if (check_vcol_forward_refs(field, field->vcol_info, 0) ||
check_vcol_forward_refs(field, field->check_constraint, 1) ||
check_vcol_forward_refs(field, field->default_value, 0))
goto end;
}
@@ -3133,11 +3134,19 @@ end:
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 &&
vcol->expr->walk(&Item::check_field_expression_processor, 0,
field);
bool res;
uint32 flags= field->flags;
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;
}

View File

@@ -2499,57 +2499,6 @@ int wsrep_ordered_commit_if_no_binlog(THD* thd, bool all)
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)
{
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);
/**
* 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.
*

View File

@@ -4839,7 +4839,9 @@ n_field_mismatch:
if (len_is_stored(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:
btr_index_rec_validate_report(page, rec, index);
ib::error error;

View File

@@ -486,8 +486,14 @@ 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. */
for (uint i = index->n_uniq; i--; ) {
trx_id_offset += index->fields[i].fixed_len;
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);
}
}

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
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
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
*******************************************************/
#include "data0type.h"
#include "dict0mem.h"
#include "my_sys.h"
/** 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] = {
@@ -160,6 +161,22 @@ 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 */

View File

@@ -2203,6 +2203,14 @@ 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) {

View File

@@ -6121,6 +6121,11 @@ 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)
? table_share->stored_fields : table_share->fields;
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 */
dict_field_t* field = dict_index_get_nth_field(index, 0);
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));
#endif /* UNIV_DEBUG */

View File

@@ -84,6 +84,7 @@ static const alter_table_operations INNOBASE_ALTER_REBUILD
| ALTER_OPTIONS
/* ALTER_OPTIONS needs to check alter_options_need_rebuild() */
| ALTER_COLUMN_NULLABLE
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
| INNOBASE_DEFAULTS
| ALTER_STORED_COLUMN_ORDER
| ALTER_DROP_STORED_COLUMN
@@ -268,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));
*oindex.fields[i].col, true));
}
}
#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. */
#ifndef DBUG_OFF
for (unsigned i = 0; i < n_fields; i++) {
DBUG_ASSERT(fields[i].same(instant.fields[i]));
DBUG_ASSERT(instant.fields[i].col->same_format(*fields[i]
.col));
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()));
/* Instant conversion from NULL to NOT NULL is not allowed. */
DBUG_ASSERT(!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)) {
c.def_val = o->def_val;
DBUG_ASSERT(!((c.prtype ^ o->prtype)
& ~(DATA_NOT_NULL | DATA_VERSIONED)));
DBUG_ASSERT(c.mtype == o->mtype);
DBUG_ASSERT(c.len >= o->len);
ut_ad(c.same_format(*o, !not_redundant()));
if (o->vers_sys_start()) {
ut_ad(o->ind == vers_start);
@@ -1505,7 +1507,8 @@ instant_alter_column_possible(
= ALTER_ADD_STORED_BASE_COLUMN
| ALTER_DROP_STORED_COLUMN
| ALTER_STORED_COLUMN_ORDER
| ALTER_COLUMN_NULLABLE;
| ALTER_COLUMN_NULLABLE
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT;
if (!(ha_alter_info->handler_flags & avoid_rebuild)) {
alter_table_operations flags = ha_alter_info->handler_flags
@@ -1548,6 +1551,7 @@ instant_alter_column_possible(
& ~ALTER_STORED_COLUMN_ORDER
& ~ALTER_ADD_STORED_BASE_COLUMN
& ~ALTER_COLUMN_NULLABLE
& ~ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
& ~ALTER_OPTIONS)) {
return false;
}
@@ -1748,6 +1752,10 @@ 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)) {
@@ -2943,7 +2951,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 */
@@ -5583,7 +5591,8 @@ static bool innobase_instant_try(
bool update = old && (!ctx->first_alter_pos
|| 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
&& old->prtype == d->type.prtype) {
/* The record is already present in SYS_COLUMNS. */
@@ -5672,6 +5681,8 @@ 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)
@@ -9050,12 +9061,16 @@ innobase_enlarge_column_try(
#ifdef UNIV_DEBUG
ut_ad(col->len < new_len);
switch (col->mtype) {
case DATA_FIXBINARY:
case DATA_CHAR:
case DATA_MYSQL:
/* NOTE: we could allow this when !(prtype & DATA_BINARY_TYPE)
and ROW_FORMAT is not REDUNDANT and mbminlen<mbmaxlen.
That is, we treat a UTF-8 CHAR(n) column somewhat like
a VARCHAR. */
ut_error;
if (user_table->not_redundant()) {
ut_error;
}
case DATA_BINARY:
case DATA_VARCHAR:
case DATA_VARMYSQL:
@@ -9188,14 +9203,16 @@ innobase_rename_or_enlarge_columns_cache(
ulint col_n = is_virtual ? num_v : i - num_v;
if ((*fp)->is_equal(cf) == IS_EQUAL_PACK_LENGTH) {
if (is_virtual) {
dict_table_get_nth_v_col(
user_table, col_n)->m_col.len
= cf->length;
} else {
dict_table_get_nth_col(
user_table, col_n)->len
= cf->length;
dict_col_t *col = is_virtual ?
&dict_table_get_nth_v_col(
user_table, col_n)->m_col
: dict_table_get_nth_col(
user_table, col_n);
col->len = cf->length;
if (col->len > 255
&& (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) 2017, 2018, MariaDB Corporation.
Copyright (c) 2017, 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
@@ -472,12 +472,18 @@ 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);
@@ -625,6 +631,14 @@ 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));
}

View File

@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
the terms of the GNU General Public License as published by the Free Software
@@ -682,18 +682,52 @@ 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) const
bool same_format(const dict_col_t& other, bool redundant = false) const
{
return mtype == other.mtype
&& len >= other.len
&& mbminlen == other.mbminlen
&& mbmaxlen == other.mbmaxlen
&& !((prtype ^ other.prtype)
& ~(DATA_NOT_NULL | DATA_VERSIONED));
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;
}
};

View File

@@ -706,11 +706,6 @@ 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(dict_table_is_comp(index->table));
}
}
}

View File

@@ -887,10 +887,15 @@ row_create_prebuilt(
== MAX_REF_PARTS););
uint temp_len = 0;
for (uint i = 0; i < temp_index->n_uniq; i++) {
ulint type = temp_index->fields[i].col->mtype;
if (type == DATA_INT) {
temp_len +=
temp_index->fields[i].fixed_len;
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;
}
}
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);
}
ut_ad(templ->mysql_col_len == len);
ut_ad(templ->mysql_col_len == len
|| !index->table->not_redundant());
break;
case DATA_VARCHAR:
case DATA_VARMYSQL:
case DATA_BINARY:
case DATA_CHAR:
case DATA_FIXBINARY:
field_end = dest + templ->mysql_col_len;
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
|| (field_no == templ->icp_rec_field_no
&& field->prefix_len > 0)
|| templ->rec_field_is_prefix);
|| templ->rec_field_is_prefix
|| !index->table->not_redundant());
ut_ad(templ->is_virtual
|| !(field->prefix_len % templ->mbmaxlen));
@@ -2857,8 +2861,6 @@ 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: