Merge remote-tracking branch 'origin/10.4' into 10.5

This commit is contained in:
Monty 2019-06-27 01:21:41 +03:00
commit 1a41fc77dd
54 changed files with 1739 additions and 2891 deletions

View file

@ -873,17 +873,10 @@ static char *my_fgets(char * s, int n, FILE * stream, int *len)
/*
Wrapper for popen().
On Windows, uses binary mode to workaround
C runtime bug mentioned in MDEV-9409
*/
static FILE* my_popen(const char *cmd, const char *mode)
{
FILE *f= popen(cmd, mode);
#ifdef _WIN32
if (f)
_setmode(fileno(f), O_BINARY);
#endif
return f;
return popen(cmd, mode);
}
#ifdef EMBEDDED_LIBRARY

View file

@ -52,7 +52,7 @@ SET(BOOTSTRAP_COMMAND
--datadir=.
--default-storage-engine=MyISAM
--max_allowed_packet=8M
--net_buffer_length=16K
--net_buffer_length=32K
)
GET_FILENAME_COMPONENT(CWD . ABSOLUTE)

View file

@ -5019,5 +5019,21 @@ ERROR HY000: Illegal parameter data types int and geometry for operation 'in'
SELECT (1,(0,0)) IN ((1,(POINT(1,1),0)),(0,(0,0)));
ERROR HY000: Illegal parameter data types int and geometry for operation 'in'
#
# MDEV-19819 ALTER from POINT to LINESTRING erroneously preserves POINT values
#
CREATE TABLE t1 (a POINT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (Point(0,0));
ALTER TABLE t1 MODIFY a LINESTRING;
ERROR 22007: Incorrect LINESTRING value: 'POINT' for column `test`.`t1`.`a` at row 1
DROP TABLE t1;
CREATE TABLE t1 (a LINESTRING);
CREATE TABLE t2 (a POINT);
INSERT INTO t2 VALUES (POINT(0,0));
INSERT INTO t1 SELECT * FROM t2;
ERROR 22007: Incorrect LINESTRING value: 'POINT' for column `test`.`t1`.`a` at row 1
SELECT AsText(a) FROM t1;
AsText(a)
DROP TABLE t1, t2;
#
# End of 10.4 tests
#

View file

@ -3094,6 +3094,25 @@ SELECT (1,0) IN ((POINT(1,1),0),(0,0));
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT (1,(0,0)) IN ((1,(POINT(1,1),0)),(0,(0,0)));
--echo #
--echo # MDEV-19819 ALTER from POINT to LINESTRING erroneously preserves POINT values
--echo #
CREATE TABLE t1 (a POINT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (Point(0,0));
--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
ALTER TABLE t1 MODIFY a LINESTRING;
DROP TABLE t1;
CREATE TABLE t1 (a LINESTRING);
CREATE TABLE t2 (a POINT);
INSERT INTO t2 VALUES (POINT(0,0));
--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
INSERT INTO t1 SELECT * FROM t2;
SELECT AsText(a) FROM t1;
DROP TABLE t1, t2;
--echo #
--echo # End of 10.4 tests
--echo #

View file

@ -184,8 +184,8 @@ t1 CREATE TABLE `t1` (
`a` blob DEFAULT NULL,
`c` int(11) DEFAULT NULL,
`db_row_hash_1` int(11) DEFAULT NULL,
UNIQUE KEY `a` (`a`) USING HASH,
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`)
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
UNIQUE KEY `a` (`a`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values(45,1,55),(46,1,55);
ERROR 23000: Duplicate entry '55' for key 'db_row_hash_1'
@ -507,13 +507,13 @@ t1 CREATE TABLE `t1` (
`db_row_hash_1` int(11) DEFAULT NULL,
`db_row_hash_2` int(11) DEFAULT NULL,
`db_row_hash_3` int(11) DEFAULT NULL,
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
UNIQUE KEY `db_row_hash_3` (`db_row_hash_3`),
UNIQUE KEY `a` (`a`) USING HASH,
UNIQUE KEY `c` (`c`) USING HASH,
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `e` (`e`) USING HASH,
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
UNIQUE KEY `db_row_hash_3` (`db_row_hash_3`)
UNIQUE KEY `e` (`e`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
alter table t1 add column db_row_hash_7 int, add column db_row_hash_5 int , add column db_row_hash_4 int ;
alter table t1 drop column db_row_hash_7,drop column db_row_hash_3, drop column db_row_hash_4;
@ -543,17 +543,17 @@ t1 CREATE TABLE `t1` (
`db_row_hash_1` int(11) DEFAULT NULL,
`db_row_hash_2` int(11) DEFAULT NULL,
`db_row_hash_5` int(11) DEFAULT NULL,
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `e` (`e`) USING HASH,
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`)
UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `e` (`e`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 d 1 d A NULL NULL NULL YES HASH
t1 0 e 1 e A NULL NULL NULL YES HASH
t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE
t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE
t1 0 d 1 d A NULL NULL NULL YES HASH
t1 0 e 1 e A NULL NULL NULL YES HASH
#add column with unique index on blob;
alter table t1 add column a blob unique;
show create table t1;
@ -567,18 +567,18 @@ t1 CREATE TABLE `t1` (
`db_row_hash_2` int(11) DEFAULT NULL,
`db_row_hash_5` int(11) DEFAULT NULL,
`a` blob DEFAULT NULL,
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `e` (`e`) USING HASH,
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `e` (`e`) USING HASH,
UNIQUE KEY `a` (`a`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 d 1 d A NULL NULL NULL YES HASH
t1 0 e 1 e A NULL NULL NULL YES HASH
t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE
t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE
t1 0 d 1 d A NULL NULL NULL YES HASH
t1 0 e 1 e A NULL NULL NULL YES HASH
t1 0 a 1 a A NULL NULL NULL YES HASH
#try to change the blob unique column name;
#this will change index to b tree;
@ -594,19 +594,19 @@ t1 CREATE TABLE `t1` (
`db_row_hash_2` int(11) DEFAULT NULL,
`db_row_hash_5` int(11) DEFAULT NULL,
`a` int(11) DEFAULT NULL,
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `e` (`e`),
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
UNIQUE KEY `a` (`a`)
UNIQUE KEY `e` (`e`),
UNIQUE KEY `a` (`a`),
UNIQUE KEY `d` (`d`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 d 1 d A NULL NULL NULL YES HASH
t1 0 e 1 e A NULL NULL NULL YES BTREE
t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE
t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE
t1 0 e 1 e A NULL NULL NULL YES BTREE
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 0 d 1 d A NULL NULL NULL YES HASH
alter table t1 add column clm1 blob unique,add column clm2 blob unique;
#try changing the name;
alter table t1 change column clm1 clm_changed1 blob, change column clm2 clm_changed2 blob;
@ -623,21 +623,21 @@ t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`clm_changed1` blob DEFAULT NULL,
`clm_changed2` blob DEFAULT NULL,
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `e` (`e`),
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
UNIQUE KEY `e` (`e`),
UNIQUE KEY `a` (`a`),
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `clm1` (`clm_changed1`) USING HASH,
UNIQUE KEY `clm2` (`clm_changed2`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 d 1 d A NULL NULL NULL YES HASH
t1 0 e 1 e A NULL NULL NULL YES BTREE
t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE
t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE
t1 0 e 1 e A NULL NULL NULL YES BTREE
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 0 d 1 d A NULL NULL NULL YES HASH
t1 0 clm1 1 clm_changed1 A NULL NULL NULL YES HASH
t1 0 clm2 1 clm_changed2 A NULL NULL NULL YES HASH
#now drop the unique key;
@ -655,19 +655,19 @@ t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`clm_changed1` blob DEFAULT NULL,
`clm_changed2` blob DEFAULT NULL,
UNIQUE KEY `d` (`d`) USING HASH,
UNIQUE KEY `e` (`e`),
UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
UNIQUE KEY `a` (`a`)
UNIQUE KEY `e` (`e`),
UNIQUE KEY `a` (`a`),
UNIQUE KEY `d` (`d`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 d 1 d A NULL NULL NULL YES HASH
t1 0 e 1 e A NULL NULL NULL YES BTREE
t1 0 db_row_hash_1 1 db_row_hash_1 A NULL NULL NULL YES BTREE
t1 0 db_row_hash_2 1 db_row_hash_2 A NULL NULL NULL YES BTREE
t1 0 e 1 e A NULL NULL NULL YES BTREE
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 0 d 1 d A NULL NULL NULL YES HASH
drop table t1;
#now the table with key on multiple columns; the ultimate test;
create table t1(a blob, b int , c varchar(2000) , d text , e varchar(3000) , f longblob , g int , h text ,
@ -1130,17 +1130,17 @@ t1 CREATE TABLE `t1` (
`c` blob DEFAULT NULL,
`d` blob DEFAULT NULL,
`e` int(11) DEFAULT NULL,
UNIQUE KEY `e` (`e`),
UNIQUE KEY `a` (`a`,`c`) USING HASH,
UNIQUE KEY `b` (`b`,`d`) USING HASH,
UNIQUE KEY `e` (`e`)
UNIQUE KEY `b` (`b`,`d`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 e 1 e A NULL NULL NULL YES BTREE
t1 0 a 1 a A NULL NULL NULL YES HASH
t1 0 a 2 c A NULL NULL NULL YES HASH
t1 0 b 1 b A NULL NULL NULL YES HASH
t1 0 b 2 d A NULL NULL NULL YES HASH
t1 0 e 1 e A 0 NULL NULL YES BTREE
drop table t1;
#visibility of db_row_hash
create table t1 (a blob unique , b blob unique);

View file

@ -9,8 +9,8 @@ Table Create Table
t1 CREATE TABLE `t1` (
`a` blob DEFAULT NULL,
`c` int(11) DEFAULT NULL,
UNIQUE KEY `a` (`a`) USING HASH,
UNIQUE KEY `c` (`c`)
UNIQUE KEY `c` (`c`),
UNIQUE KEY `a` (`a`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t1;
#test for concurrent insert of long unique in innodb

View file

@ -71,8 +71,8 @@ create table t1 (a int primary key, b blob unique , c int unique );
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 PRIMARY 1 a A 0 NULL NULL BTREE
t1 0 b 1 b A NULL NULL NULL YES HASH
t1 0 c 1 c A NULL NULL NULL YES BTREE
t1 0 b 1 b A NULL NULL NULL YES HASH
insert into t1 values(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7);
select * from t1 limit 3;
a b c
@ -220,18 +220,18 @@ t1 CREATE TABLE `t1` (
`f` int(11) DEFAULT NULL,
`g` text DEFAULT NULL,
PRIMARY KEY (`a`),
UNIQUE KEY `b` (`b`,`c`) USING HASH,
UNIQUE KEY `b_2` (`b`,`f`),
UNIQUE KEY `b` (`b`,`c`) USING HASH,
UNIQUE KEY `e` (`e`,`g`) USING HASH,
UNIQUE KEY `a` (`a`,`b`,`c`,`d`,`e`,`f`,`g`) USING HASH
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 0 PRIMARY 1 a A 0 NULL NULL BTREE
t1 0 b 1 b A NULL NULL NULL YES HASH
t1 0 b 2 c A NULL NULL NULL YES HASH
t1 0 b_2 1 b A NULL NULL NULL YES BTREE
t1 0 b_2 2 f A NULL NULL NULL YES BTREE
t1 0 b 1 b A NULL NULL NULL YES HASH
t1 0 b 2 c A NULL NULL NULL YES HASH
t1 0 e 1 e A NULL NULL NULL YES HASH
t1 0 e 2 g A NULL NULL NULL YES HASH
t1 0 a 1 a A NULL NULL NULL HASH

View file

@ -6554,4 +6554,12 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
}
]
drop table t1, t0, one_k;
#
# MDEV-19776: Assertion `to_len >= 8' failed in convert_to_printable with optimizer trace enabled
#
CREATE TABLE t1 (f VARBINARY(16) NOT NULL, KEY(f));
INSERT INTO t1 VALUES ('a'),('b');
SET optimizer_trace = 'enabled=on';
DELETE FROM t1 WHERE f = 'x';
DROP TABLE t1;
set optimizer_trace='enabled=off';

View file

@ -498,4 +498,14 @@ explain format=json select * from t1 force index(start_date) where start_date >=
select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
drop table t1, t0, one_k;
--echo #
--echo # MDEV-19776: Assertion `to_len >= 8' failed in convert_to_printable with optimizer trace enabled
--echo #
CREATE TABLE t1 (f VARBINARY(16) NOT NULL, KEY(f));
INSERT INTO t1 VALUES ('a'),('b');
SET optimizer_trace = 'enabled=on';
DELETE FROM t1 WHERE f = 'x';
DROP TABLE t1;
set optimizer_trace='enabled=off';

View file

@ -1,7 +1,7 @@
MariaDB error code 150: Foreign key constraint is incorrectly formed
Win32 error code 150: System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed.
Win32 error code 150: System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed.
OS error code 23: Too many open files in system
Win32 error code 23: Data error (cyclic redundancy check).
Win32 error code 23: Data error (cyclic redundancy check).
MariaDB error code 1062 (ER_DUP_ENTRY): Duplicate entry '%-.192s' for key %d
Win32 error code 1062: The service has not been started.
Win32 error code 1062: The service has not been started.
Illegal error code: 30000

View file

@ -2162,4 +2162,51 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select 1 AS `id`,`test`.`t2`.`y` AS `y`,`test`.`t2`.`x` AS `x` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`y` = 2 and `test`.`t2`.`x` = 1
drop table t1, t2;
#
# MDEV-19820: use of rowid filter for innodb table without primary key
#
create table t1 (a int, b int, key (b), key (a)) engine=innodb;
insert into t1
select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
set @save_optimizer_switch= @@optimizer_switch;
set optimizer_switch='rowid_filter=off';
select count(*) from t1 where a in (22,83,11) and b=2;
count(*)
6
explain extended select count(*) from t1 where a in (22,83,11) and b=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref b,a b 5 const 59 55.93 Using where
Warnings:
Note 1003 select count(0) AS `count(*)` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (22,83,11)
select * from t1 where a in (22,83,11) and b=2;
a b
11 2
11 2
83 2
11 2
83 2
22 2
set optimizer_switch='rowid_filter=on';
select count(*) from t1 where a in (22,83,11) and b=2;
count(*)
6
explain extended select count(*) from t1 where a in (22,83,11) and b=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref|filter b,a b|a 5|5 const 59 (3%) 55.93 Using where; Using rowid filter
Warnings:
Note 1003 select count(0) AS `count(*)` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (22,83,11)
select * from t1 where a in (22,83,11) and b=2;
a b
11 2
11 2
83 2
11 2
83 2
22 2
drop table t1;
set optimizer_switch=@save_optimizer_switch;
SET SESSION STORAGE_ENGINE=DEFAULT;

View file

@ -3,6 +3,7 @@
SET SESSION STORAGE_ENGINE='InnoDB';
--source rowid_filter.test
--source include/have_sequence.inc
--echo #
--echo # MDEV-18755: possible RORI-plan and possible plan with range filter
@ -65,4 +66,33 @@ eval explain extended $q;
drop table t1, t2;
--echo #
--echo # MDEV-19820: use of rowid filter for innodb table without primary key
--echo #
create table t1 (a int, b int, key (b), key (a)) engine=innodb;
insert into t1
select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000;
analyze table t1;
let $q=
select count(*) from t1 where a in (22,83,11) and b=2;
let $q1=
select * from t1 where a in (22,83,11) and b=2;
set @save_optimizer_switch= @@optimizer_switch;
set optimizer_switch='rowid_filter=off';
eval $q;
eval explain extended $q;
eval $q1;
set optimizer_switch='rowid_filter=on';
eval $q;
eval explain extended $q;
eval $q1;
drop table t1;
set optimizer_switch=@save_optimizer_switch;
SET SESSION STORAGE_ENGINE=DEFAULT;

View file

@ -1,10 +1,51 @@
--- instant_alter_charset.result 2019-04-23 17:42:23.324326518 +0400
+++ instant_alter_charset,redundant.result 2019-04-23 17:42:46.047531591 +0400
--- instant_alter_charset.result 2019-06-17 14:36:02.311515062 +0300
+++ instant_alter_charset,redundant.result 2019-06-17 14:50:11.888705725 +0300
@@ -279,7 +279,6 @@
alter table boundary_255
modify a varchar(70) charset utf8mb4,
algorithm=instant;
-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
drop table boundary_255;
create table fully_compatible (
id int auto_increment unique key,
create table t (
a char(10) collate utf8mb3_general_ci,
@@ -297,32 +296,21 @@
repeat('a', 10), repeat('a', 10)
);
alter table t modify a char(10) collate utf8mb4_general_ci, algorithm=instant;
-check table t;
-Table Op Msg_type Msg_text
-test.t check status OK
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify b char(70) collate utf8mb4_general_ci, algorithm=instant;
-check table t;
-Table Op Msg_type Msg_text
-test.t check status OK
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify c char(100) collate utf8mb4_general_ci, algorithm=instant;
-check table t;
-Table Op Msg_type Msg_text
-test.t check status OK
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant;
-check table t;
-Table Op Msg_type Msg_text
-test.t check status OK
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant;
-check table t;
-Table Op Msg_type Msg_text
-test.t check status OK
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant;
-check table t;
-Table Op Msg_type Msg_text
-test.t check status OK
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify d char(10) collate utf8mb4_spanish_ci, algorithm=instant;
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify dd char(10) collate utf8mb4_spanish_ci, algorithm=instant;
-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
select * from t;
a b c aa bb cc d dd
aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaa

View file

@ -281,6 +281,52 @@ modify a varchar(70) charset utf8mb4,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
drop table boundary_255;
create table t (
a char(10) collate utf8mb3_general_ci,
b char(70) collate utf8mb3_general_ci,
c char(100) collate utf8mb3_general_ci,
aa char(10) collate utf8mb3_general_ci unique,
bb char(70) collate utf8mb3_general_ci unique,
cc char(100) collate utf8mb3_general_ci unique,
d char(10) collate utf8mb3_general_ci,
dd char(10) collate utf8mb3_general_ci unique
) engine=innodb;
insert into t values
(repeat('a', 10), repeat('a', 70), repeat('a', 100),
repeat('a', 10), repeat('a', 70), repeat('a', 100),
repeat('a', 10), repeat('a', 10)
);
alter table t modify a char(10) collate utf8mb4_general_ci, algorithm=instant;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
alter table t modify b char(70) collate utf8mb4_general_ci, algorithm=instant;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
alter table t modify c char(100) collate utf8mb4_general_ci, algorithm=instant;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
alter table t modify d char(10) collate utf8mb4_spanish_ci, algorithm=instant;
alter table t modify dd char(10) collate utf8mb4_spanish_ci, algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
select * from t;
a b c aa bb cc d dd
aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaa aaaaaaaaaa
drop table t;
create table fully_compatible (
id int auto_increment unique key,
from_charset char(255),
@ -784,7 +830,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci,
algorithm=instant;
@ -801,7 +847,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci,
algorithm=instant;
@ -818,7 +864,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci,
algorithm=instant;
@ -835,7 +881,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf8mb4 collate utf8mb4_vietnamese_ci,
algorithm=instant;
@ -852,7 +898,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset ascii collate ascii_bin,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset ascii collate ascii_bin,
algorithm=instant;
@ -869,7 +915,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf8mb3 collate utf8mb3_lithuanian_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf8mb3 collate utf8mb3_lithuanian_ci,
algorithm=instant;
@ -886,7 +932,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf8mb4 collate utf8mb4_persian_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf8mb4 collate utf8mb4_persian_ci,
algorithm=instant;
@ -903,7 +949,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf8mb4 collate utf8mb4_german2_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf8mb4 collate utf8mb4_german2_ci,
algorithm=instant;
@ -920,7 +966,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf8mb3 collate utf8mb3_unicode_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf8mb3 collate utf8mb3_unicode_ci,
algorithm=instant;
@ -937,7 +983,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset latin1 collate latin1_general_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset latin1 collate latin1_general_ci,
algorithm=instant;
@ -954,7 +1000,7 @@ algorithm=instant;
alter table tmp
modify b varchar(50) charset utf16 collate utf16_german2_ci,
algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table tmp
modify c varchar(50) charset utf16 collate utf16_german2_ci,
algorithm=instant;
@ -1827,3 +1873,48 @@ CREATE TABLE t1 (a VARCHAR(1), UNIQUE(a)) ENGINE=InnoDB;
ALTER TABLE t1 MODIFY a INT, ADD b INT, ADD UNIQUE (b), ALGORITHM=INSTANT;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
DROP TABLE t1;
#
# MDEV-17301 Change of COLLATE unnecessarily requires ALGORITHM=COPY
#
create table t (
a char(10) collate latin1_general_ci primary key,
b char(10) collate latin1_general_ci,
c char(10) collate latin1_general_ci,
unique key b_key(b)
) engine=innodb;
insert into t values
('aaa', 'aaa', 'aaa'), ('ccc', 'ccc', 'ccc'), ('bbb', 'bbb', 'bbb');
alter table t modify a char(10) collate latin1_general_cs, algorithm=inplace;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify b char(10) collate latin1_general_cs, algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table t modify b char(10) collate latin1_general_cs, algorithm=nocopy;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
alter table t modify c char(10) collate latin1_general_cs, algorithm=instant;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
drop table t;
create table t (
a varchar(10) collate latin1_general_ci primary key,
b varchar(10) collate latin1_general_ci,
c varchar(10) collate latin1_general_ci,
unique key b_key(b)
) engine=innodb;
insert into t values
('aaa', 'aaa', 'aaa'), ('ccc', 'ccc', 'ccc'), ('bbb', 'bbb', 'bbb');
alter table t modify a varchar(10) collate latin1_general_cs, algorithm=inplace;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
alter table t modify b varchar(10) collate latin1_general_cs, algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY
alter table t modify b varchar(10) collate latin1_general_cs, algorithm=nocopy;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
alter table t modify c varchar(10) collate latin1_general_cs, algorithm=instant;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
drop table t;

View file

@ -321,6 +321,67 @@ alter table boundary_255
drop table boundary_255;
create table t (
a char(10) collate utf8mb3_general_ci,
b char(70) collate utf8mb3_general_ci,
c char(100) collate utf8mb3_general_ci,
aa char(10) collate utf8mb3_general_ci unique,
bb char(70) collate utf8mb3_general_ci unique,
cc char(100) collate utf8mb3_general_ci unique,
d char(10) collate utf8mb3_general_ci,
dd char(10) collate utf8mb3_general_ci unique
) engine=innodb;
insert into t values
(repeat('a', 10), repeat('a', 70), repeat('a', 100),
repeat('a', 10), repeat('a', 70), repeat('a', 100),
repeat('a', 10), repeat('a', 10)
);
if ($row_format != 'redundant') {
alter table t modify a char(10) collate utf8mb4_general_ci, algorithm=instant;
check table t;
alter table t modify b char(70) collate utf8mb4_general_ci, algorithm=instant;
check table t;
alter table t modify c char(100) collate utf8mb4_general_ci, algorithm=instant;
check table t;
alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant;
check table t;
alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant;
check table t;
alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant;
check table t;
alter table t modify d char(10) collate utf8mb4_spanish_ci, algorithm=instant;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify dd char(10) collate utf8mb4_spanish_ci, algorithm=instant;
}
if ($row_format == 'redundant') {
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify a char(10) collate utf8mb4_general_ci, algorithm=instant;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify b char(70) collate utf8mb4_general_ci, algorithm=instant;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify c char(100) collate utf8mb4_general_ci, algorithm=instant;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify aa char(10) collate utf8mb4_general_ci, algorithm=instant;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify bb char(70) collate utf8mb4_general_ci, algorithm=instant;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify cc char(100) collate utf8mb4_general_ci, algorithm=instant;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify d char(10) collate utf8mb4_spanish_ci, algorithm=instant;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify dd char(10) collate utf8mb4_spanish_ci, algorithm=instant;
}
select * from t;
drop table t;
create table fully_compatible (
id int auto_increment unique key,
from_charset char(255),
@ -604,3 +665,53 @@ CREATE TABLE t1 (a VARCHAR(1), UNIQUE(a)) ENGINE=InnoDB;
ALTER TABLE t1 MODIFY a INT, ADD b INT, ADD UNIQUE (b), ALGORITHM=INSTANT;
DROP TABLE t1;
--echo #
--echo # MDEV-17301 Change of COLLATE unnecessarily requires ALGORITHM=COPY
--echo #
create table t (
a char(10) collate latin1_general_ci primary key,
b char(10) collate latin1_general_ci,
c char(10) collate latin1_general_ci,
unique key b_key(b)
) engine=innodb;
insert into t values
('aaa', 'aaa', 'aaa'), ('ccc', 'ccc', 'ccc'), ('bbb', 'bbb', 'bbb');
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify a char(10) collate latin1_general_cs, algorithm=inplace;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify b char(10) collate latin1_general_cs, algorithm=instant;
alter table t modify b char(10) collate latin1_general_cs, algorithm=nocopy;
check table t;
alter table t modify c char(10) collate latin1_general_cs, algorithm=instant;
check table t;
drop table t;
create table t (
a varchar(10) collate latin1_general_ci primary key,
b varchar(10) collate latin1_general_ci,
c varchar(10) collate latin1_general_ci,
unique key b_key(b)
) engine=innodb;
insert into t values
('aaa', 'aaa', 'aaa'), ('ccc', 'ccc', 'ccc'), ('bbb', 'bbb', 'bbb');
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify a varchar(10) collate latin1_general_cs, algorithm=inplace;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t modify b varchar(10) collate latin1_general_cs, algorithm=instant;
alter table t modify b varchar(10) collate latin1_general_cs, algorithm=nocopy;
check table t;
alter table t modify c varchar(10) collate latin1_general_cs, algorithm=instant;
check table t;
drop table t;

View file

@ -485,8 +485,7 @@ ALTER TABLE tab MODIFY COLUMN c2 GEOMETRY NOT NULL;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE tab MODIFY COLUMN c3 POLYGON NOT NULL;
affected rows: 10
info: Records: 10 Duplicates: 0 Warnings: 0
ERROR 22007: Incorrect POLYGON value: 'LINESTRING' for column `test`.`tab`.`c3` at row 1
ALTER TABLE tab add COLUMN c7 POINT NOT NULL;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
@ -528,7 +527,7 @@ Table Create Table
tab CREATE TABLE `tab` (
`c1` int(11) NOT NULL,
`c2` geometry NOT NULL,
`c3` polygon NOT NULL,
`c3` linestring NOT NULL,
`c4` polygon NOT NULL,
`c5` geometry NOT NULL,
`c7` point NOT NULL,
@ -565,7 +564,7 @@ Table Create Table
tab CREATE TABLE `tab` (
`c1` int(11) NOT NULL,
`c2` geometry NOT NULL,
`c3` polygon NOT NULL,
`c3` linestring NOT NULL,
`c4` geometry NOT NULL,
`c5` geometry NOT NULL,
`c7` point NOT NULL,
@ -614,9 +613,6 @@ SET @g2 = ST_GeomFromText('LINESTRING(1 1,2 2,3 3)');
ALTER TABLE tab MODIFY COLUMN c2 POINT NOT NULL;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
ALTER TABLE tab MODIFY COLUMN c3 LINESTRING NOT NULL;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
ALTER TABLE tab MODIFY COLUMN c4 POLYGON NOT NULL;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0

View file

@ -476,6 +476,7 @@ ALTER TABLE tab ADD INDEX idx6(c4(10)) USING BTREE;
ALTER TABLE tab MODIFY COLUMN c2 GEOMETRY NOT NULL;
--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
ALTER TABLE tab MODIFY COLUMN c3 POLYGON NOT NULL;
ALTER TABLE tab add COLUMN c7 POINT NOT NULL;
@ -552,8 +553,6 @@ SET @g2 = ST_GeomFromText('LINESTRING(1 1,2 2,3 3)');
--enable_info
ALTER TABLE tab MODIFY COLUMN c2 POINT NOT NULL;
ALTER TABLE tab MODIFY COLUMN c3 LINESTRING NOT NULL;
ALTER TABLE tab MODIFY COLUMN c4 POLYGON NOT NULL;
--disable_info

View file

@ -9,7 +9,7 @@ DEFAULT_VALUE 8192
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Block size to be used for Aria index pages.
NUMERIC_MIN_VALUE 1024
NUMERIC_MIN_VALUE 4096
NUMERIC_MAX_VALUE 32768
NUMERIC_BLOCK_SIZE 1024
ENUM_VALUE_LIST NULL

View file

@ -74,6 +74,8 @@ char *fgets_fn(char *buffer, size_t size, fgets_input_t input, int *error)
return line;
}
#define MAX_COLUMN 16000
static void print_query(FILE *out, const char *query)
{
const char *ptr= query;
@ -82,6 +84,12 @@ static void print_query(FILE *out, const char *query)
fprintf(out, "\"");
while (*ptr)
{
if(column >= MAX_COLUMN)
{
/* Wrap to the next line, tabulated. */
fprintf(out, "\"\n \"");
column= 2;
}
switch(*ptr)
{
case '\n':
@ -97,10 +105,11 @@ static void print_query(FILE *out, const char *query)
break;
case '\"':
fprintf(out, "\\\"");
column++;
column+=2;
break;
case '\\':
fprintf(out, "\\\\");
column+=2;
break;
default:
putc(*ptr, out);

File diff suppressed because one or more lines are too long

View file

@ -253,6 +253,7 @@ static bool backup_block_ddl(THD *thd)
backup stage even if we got an error.
*/
(void) flush_tables(thd, FLUSH_NON_TRANS_TABLES);
thd->clear_error();
/*
block new DDL's, in addition to all previous blocks
@ -286,7 +287,11 @@ static bool backup_block_commit(THD *thd)
MDL_BACKUP_WAIT_COMMIT,
thd->variables.lock_wait_timeout))
DBUG_RETURN(1);
flush_tables(thd, FLUSH_SYS_TABLES);
/* We can ignore errors from flush_tables () */
(void) flush_tables(thd, FLUSH_SYS_TABLES);
thd->clear_error();
DBUG_RETURN(0);
}

View file

@ -2449,12 +2449,12 @@ void Field_null::sql_type(String &res) const
}
uint Field_null::is_equal(Create_field *new_field)
bool Field_null::is_equal(const Column_definition &new_field) const
{
DBUG_ASSERT(!compression_method());
return new_field->type_handler() == type_handler() &&
new_field->charset == field_charset &&
new_field->length == max_display_length();
return new_field.type_handler() == type_handler() &&
new_field.charset == field_charset &&
new_field.length == max_display_length();
}
@ -3492,15 +3492,15 @@ bool Field_new_decimal::compatible_field_size(uint field_metadata,
}
uint Field_new_decimal::is_equal(Create_field *new_field)
bool Field_new_decimal::is_equal(const Column_definition &new_field) const
{
return ((new_field->type_handler() == type_handler()) &&
((new_field->flags & UNSIGNED_FLAG) ==
return ((new_field.type_handler() == type_handler()) &&
((new_field.flags & UNSIGNED_FLAG) ==
(uint) (flags & UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) <=
((new_field.flags & AUTO_INCREMENT_FLAG) <=
(uint) (flags & AUTO_INCREMENT_FLAG)) &&
(new_field->length == max_display_length()) &&
(new_field->decimals == dec));
(new_field.length == max_display_length()) &&
(new_field.decimals == dec));
}
@ -5585,10 +5585,10 @@ bool Field_timestampf::val_native(Native *to)
/*************************************************************/
uint Field_temporal::is_equal(Create_field *new_field)
bool Field_temporal::is_equal(const Column_definition &new_field) const
{
return new_field->type_handler() == type_handler() &&
new_field->length == max_display_length();
return new_field.type_handler() == type_handler() &&
new_field.length == max_display_length();
}
@ -6949,6 +6949,7 @@ Field_longstr::check_string_copy_error(const String_copier *copier,
if (!is_stat_field)
{
DBUG_ASSERT(sizeof(tmp) >= convert_to_printable_required_length(6));
convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6);
set_warning_truncated_wrong_value("string", tmp);
}
@ -7072,36 +7073,13 @@ int Field_str::store(double nr)
return store(buff, (uint)length, &my_charset_numeric);
}
bool Field_longstr::
csinfo_change_allows_instant_alter(const Create_field *to) const
{
Charset cs(field_charset);
const bool part_of_a_key= !to->field->part_of_key.is_clear_all();
return part_of_a_key ?
cs.encoding_and_order_allow_reinterpret_as(to->charset) :
cs.encoding_allows_reinterpret_as(to->charset);
}
uint Field_string::is_equal(Create_field *new_field)
bool Field_string::is_equal(const Column_definition &new_field) const
{
DBUG_ASSERT(!compression_method());
if (new_field->type_handler() != type_handler())
return IS_EQUAL_NO;
if (new_field->length < max_display_length())
return IS_EQUAL_NO;
if (new_field->char_length < char_length())
return IS_EQUAL_NO;
if (!csinfo_change_allows_instant_alter(new_field))
return IS_EQUAL_NO;
if (new_field->length == max_display_length())
return new_field->charset == field_charset
? IS_EQUAL_YES : IS_EQUAL_PACK_LENGTH;
return IS_EQUAL_NO;
return new_field.type_handler() == type_handler() &&
new_field.char_length == char_length() &&
new_field.charset == field_charset &&
new_field.length == max_display_length();
}
@ -7941,32 +7919,13 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root, TABLE *new_table,
return res;
}
uint Field_varstring::is_equal(Create_field *new_field)
bool Field_varstring::is_equal(const Column_definition &new_field) const
{
if (new_field->length < field_length)
return IS_EQUAL_NO;
if (new_field->char_length < char_length())
return IS_EQUAL_NO;
if (!new_field->compression_method() != !compression_method())
return IS_EQUAL_NO;
if (!csinfo_change_allows_instant_alter(new_field))
return IS_EQUAL_NO;
const Type_handler *new_type_handler= new_field->type_handler();
if (new_type_handler == type_handler())
{
if (new_field->length == field_length)
return new_field->charset == field_charset
? IS_EQUAL_YES : IS_EQUAL_PACK_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
}
return IS_EQUAL_NO;
return new_field.type_handler() == type_handler() &&
new_field.length == field_length &&
new_field.char_length == char_length() &&
!new_field.compression_method() == !compression_method() &&
new_field.charset == field_charset;
}
@ -8730,30 +8689,12 @@ uint Field_blob::max_packed_col_length(uint max_length)
again an already compressed field just because compression method changes.
*/
uint Field_blob::is_equal(Create_field *new_field)
bool Field_blob::is_equal(const Column_definition &new_field) const
{
if (new_field->type_handler() != type_handler())
{
return IS_EQUAL_NO;
}
if (!new_field->compression_method() != !compression_method())
{
return IS_EQUAL_NO;
}
if (new_field->pack_length != pack_length())
{
return IS_EQUAL_NO;
}
if (!csinfo_change_allows_instant_alter(new_field))
return IS_EQUAL_NO;
if (field_charset != new_field->charset)
{
return IS_EQUAL_PACK_LENGTH;
}
return IS_EQUAL_YES;
return new_field.type_handler() == type_handler() &&
!new_field.compression_method() == !compression_method() &&
new_field.pack_length == pack_length() &&
new_field.charset == field_charset;
}
@ -9062,16 +9003,16 @@ Field::geometry_type Field_geom::geometry_type_merge(geometry_type a,
}
uint Field_geom::is_equal(Create_field *new_field)
bool Field_geom::is_equal(const Column_definition &new_field) const
{
return new_field->type_handler() == type_handler() &&
return new_field.type_handler() == type_handler() &&
/*
- Allow ALTER..INPLACE to supertype (GEOMETRY),
e.g. POINT to GEOMETRY or POLYGON to GEOMETRY.
- Allow ALTER..INPLACE to the same geometry type: POINT -> POINT
*/
(new_field->geom_type == geom_type ||
new_field->geom_type == GEOM_GEOMETRY);
(new_field.geom_type == geom_type ||
new_field.geom_type == GEOM_GEOMETRY);
}
@ -9502,22 +9443,22 @@ bool Field_enum::eq_def(const Field *field) const
alteration purposes. Fields are equal if they retain the same
pack length and if new members are added to the end of the list.
@return IS_EQUAL_YES if fields are compatible.
IS_EQUAL_NO otherwise.
@return true if fields are compatible.
false otherwise.
*/
uint Field_enum::is_equal(Create_field *new_field)
bool Field_enum::is_equal(const Column_definition &new_field) const
{
const TYPELIB *values= new_field->interval;
const TYPELIB *values= new_field.interval;
/*
The fields are compatible if they have the same flags,
type, charset and have the same underlying length.
*/
if (new_field->type_handler() != type_handler() ||
new_field->charset != field_charset ||
new_field->pack_length != pack_length())
return IS_EQUAL_NO;
if (new_field.type_handler() != type_handler() ||
new_field.charset != field_charset ||
new_field.pack_length != pack_length())
return false;
/*
Changing the definition of an ENUM or SET column by adding a new
@ -9525,13 +9466,13 @@ uint Field_enum::is_equal(Create_field *new_field)
values only alters table metadata and not table data.
*/
if (typelib->count > values->count)
return IS_EQUAL_NO;
return false;
/* Check whether there are modification before the end. */
if (! compare_type_names(field_charset, typelib, new_field->interval))
return IS_EQUAL_NO;
if (! compare_type_names(field_charset, typelib, new_field.interval))
return false;
return IS_EQUAL_YES;
return true;
}
@ -9577,17 +9518,17 @@ bool Field_num::eq_def(const Field *field) const
and retain the same pack length.
*/
uint Field_num::is_equal(Create_field *new_field)
bool Field_num::is_equal(const Column_definition &new_field) const
{
if (((new_field->flags & UNSIGNED_FLAG) != (flags & UNSIGNED_FLAG)) ||
((new_field->flags & AUTO_INCREMENT_FLAG) > (flags & AUTO_INCREMENT_FLAG)))
return IS_EQUAL_NO;
if (((new_field.flags & UNSIGNED_FLAG) != (flags & UNSIGNED_FLAG)) ||
((new_field.flags & AUTO_INCREMENT_FLAG) > (flags & AUTO_INCREMENT_FLAG)))
return false;
const Type_handler *th= type_handler(), *new_th = new_field->type_handler();
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;
/* FIXME: Test and consider returning IS_EQUAL_YES for the following:
if (th == new_th && new_field.pack_length == pack_length())
return true;
/* FIXME: Test and consider returning true for the following:
TINYINT UNSIGNED to BIT(8)
SMALLINT UNSIGNED to BIT(16)
MEDIUMINT UNSIGNED to BIT(24)
@ -9602,10 +9543,10 @@ uint Field_num::is_equal(Create_field *new_field)
Note: InnoDB stores integers in big-endian format, and BIT appears
to use big-endian format. For storage engines that use little-endian
format for integers, we can only return IS_EQUAL_YES for the TINYINT
format for integers, we can only return true for the TINYINT
conversion. */
return IS_EQUAL_NO;
return false;
}
@ -9752,10 +9693,10 @@ Field *Field_bit::new_key_field(MEM_ROOT *root, TABLE *new_table,
}
uint Field_bit::is_equal(Create_field *new_field)
bool Field_bit::is_equal(const Column_definition &new_field) const
{
return new_field->type_handler() == type_handler() &&
new_field->length == max_display_length();
return new_field.type_handler() == type_handler() &&
new_field.length == max_display_length();
}
@ -11330,4 +11271,4 @@ void Field_blob::print_key_value(String *out, uint32 length)
void Field::print_key_value_binary(String *out, const uchar* key, uint32 length)
{
out->append_semi_hex((const char*)key, length, charset());
}
}

View file

@ -1562,13 +1562,16 @@ public:
/* maximum possible display length */
virtual uint32 max_display_length() const= 0;
/**
Whether a field being created is compatible with a existing one.
Used by the ALTER TABLE code to evaluate whether the new definition
of a table is compatible with the old definition so that it can
determine if data needs to be copied over (table data change).
Whether a field being created has the samle type.
Used by the ALTER TABLE
*/
virtual uint is_equal(Create_field *new_field)= 0;
virtual bool is_equal(const Column_definition &new_field) const= 0;
// Used as double dispatch pattern: calls virtual method of handler
virtual bool
can_be_converted_by_engine(const Column_definition &new_type) const
{
return false;
}
/* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
int *err);
@ -1587,7 +1590,7 @@ public:
{
return field_length / charset()->mbmaxlen;
}
virtual geometry_type get_geometry_type()
virtual geometry_type get_geometry_type() const
{
/* shouldn't get here. */
DBUG_ASSERT(0);
@ -1868,7 +1871,7 @@ public:
!((flags & UNSIGNED_FLAG) && !(from->flags & UNSIGNED_FLAG)) &&
decimals() == from->decimals();
}
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
uint row_pack_length() const { return pack_length(); }
uint32 pack_length_from_metadata(uint field_metadata) const
{
@ -1934,7 +1937,7 @@ public:
bool val_bool() { return val_real() != 0e0; }
virtual bool str_needs_quotes() { return TRUE; }
bool eq_cmp_as_binary() { return MY_TEST(flags & BINARY_FLAG); }
virtual uint length_size() { return 0; }
virtual uint length_size() const { return 0; }
double pos_in_interval(Field *min, Field *max)
{
return pos_in_interval_val_str(min, max, length_size());
@ -1988,7 +1991,6 @@ protected:
CHARSET_INFO *cs, size_t nchars);
String *uncompress(String *val_buffer, String *val_ptr,
const uchar *from, uint from_length);
bool csinfo_change_allows_instant_alter(const Create_field *to) const;
public:
Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
@ -2209,7 +2211,7 @@ public:
uint row_pack_length() const { return pack_length(); }
bool compatible_field_size(uint field_metadata, const Relay_log_info *rli,
uint16 mflags, int *order_var) const;
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
virtual const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data);
Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item);
};
@ -2719,7 +2721,7 @@ public:
my_decimal *val_decimal(my_decimal *) { return 0; }
String *val_str(String *value,String *value2)
{ value2->length(0); return value2;}
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
int cmp(const uchar *a, const uchar *b) { return 0;}
void sort_string(uchar *buff, uint length) {}
uint32 pack_length() const { return 0; }
@ -2802,7 +2804,7 @@ public:
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
bool binary() const { return true; }
bool val_bool() { return val_real() != 0e0; }
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
bool eq_def(const Field *field) const
{
return (Field::eq_def(field) && decimals() == field->decimals());
@ -3676,7 +3678,11 @@ public:
st->m_fixed_string_total_length+= pack_length();
}
void sql_type(String &str) const;
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_string(this, new_type);
}
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length);
virtual const uchar *unpack(uchar* to, const uchar *from,
@ -3815,9 +3821,13 @@ public:
Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
uchar *new_ptr, uint32 length,
uchar *new_null_ptr, uint new_null_bit);
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_varstring(this, new_type);
}
void hash(ulong *nr, ulong *nr2);
uint length_size() { return length_bytes; }
uint length_size() const { return length_bytes; }
void print_key_value(String *out, uint32 length);
private:
int save_field_metadata(uchar *first_byte);
@ -4166,7 +4176,11 @@ public:
uint32 max_display_length() const;
uint32 char_length() const;
uint32 character_octet_length() const;
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_blob(this, new_type);
}
void print_key_value(String *out, uint32 length);
friend void TABLE::remember_blob_values(String *blob_storage);
@ -4269,7 +4283,27 @@ public:
const Item *item,
bool is_eq_func) const;
void sql_type(String &str) const;
uint is_equal(Create_field *new_field);
Copy_func *get_copy_func(const Field *from) const
{
if (type_handler() == from->type_handler() &&
(geom_type == GEOM_GEOMETRY ||
geom_type == static_cast<const Field_geom*>(from)->geom_type))
return get_identical_copy_func();
return do_conv_blob;
}
bool memcpy_field_possible(const Field *from) const
{
return type_handler() == from->type_handler() &&
(geom_type == GEOM_GEOMETRY ||
geom_type == static_cast<const Field_geom*>(from)->geom_type) &&
!table->copy_blobs;
}
bool is_equal(const Column_definition &new_field) const;
bool can_be_converted_by_engine(const Column_definition &new_type) const
{
return table->file->can_convert_geom(this, new_type);
}
int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
@ -4292,7 +4326,7 @@ public:
bool load_data_set_null(THD *thd);
bool load_data_set_no_data(THD *thd, bool fixed_format);
geometry_type get_geometry_type() { return geom_type; };
geometry_type get_geometry_type() const { return geom_type; };
static geometry_type geometry_type_merge(geometry_type, geometry_type);
uint get_srid() { return srid; }
void print_key_value(String *out, uint32 length)
@ -4416,7 +4450,7 @@ public:
bool is_eq_func) const;
private:
int save_field_metadata(uchar *first_byte);
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
};
@ -4603,7 +4637,7 @@ public:
bit_ptr == ((Field_bit *)field)->bit_ptr &&
bit_ofs == ((Field_bit *)field)->bit_ofs);
}
uint is_equal(Create_field *new_field);
bool is_equal(const Column_definition &new_field) const;
void move_field_offset(my_ptrdiff_t ptr_diff)
{
Field::move_field_offset(ptr_diff);

View file

@ -4553,7 +4553,7 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table,
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
alter_table_operations inplace_offline_operations=
ALTER_COLUMN_EQUAL_PACK_LENGTH |
ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE |
ALTER_COLUMN_NAME |
ALTER_RENAME_COLUMN |
ALTER_CHANGE_COLUMN_DEFAULT |
@ -4589,7 +4589,7 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table,
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
uint table_changes= (ha_alter_info->handler_flags &
ALTER_COLUMN_EQUAL_PACK_LENGTH) ?
ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE) ?
IS_EQUAL_PACK_LENGTH : IS_EQUAL_YES;
if (table->file->check_if_incompatible_data(create_info, table_changes)
== COMPATIBLE_DATA_YES)

View file

@ -49,6 +49,11 @@ class Alter_info;
class Virtual_column_info;
class sequence_definition;
class Rowid_filter;
class Field_string;
class Field_varstring;
class Field_blob;
class Field_geom;
class Column_definition;
// the following is for checking tables
@ -324,10 +329,6 @@ 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)
/* Support native hash index */
#define HA_CAN_HASH_KEYS (1ULL << 58)
#define HA_LAST_TABLE_FLAG HA_CAN_HASH_KEYS
@ -710,13 +711,9 @@ typedef ulonglong alter_table_operations;
#define ALTER_VIRTUAL_COLUMN_TYPE (1ULL << 47)
#define ALTER_STORED_COLUMN_TYPE (1ULL << 48)
/**
Change column datatype in such way that new type 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 ALTER_COLUMN_EQUAL_PACK_LENGTH (1ULL << 49)
// Engine can handle type change by itself in ALGORITHM=INPLACE
#define ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE (1ULL << 49)
// Reorder column
#define ALTER_STORED_COLUMN_ORDER (1ULL << 50)
@ -4805,6 +4802,32 @@ public:
virtual bool is_clustering_key(uint index) { return false; }
/**
Some engines can perform column type conversion with ALGORITHM=INPLACE.
These functions check for such possibility.
Implementation could be based on Field_xxx::is_equal()
*/
virtual bool can_convert_string(const Field_string *field,
const Column_definition &new_type) const
{
return false;
}
virtual bool can_convert_varstring(const Field_varstring *field,
const Column_definition &new_type) const
{
return false;
}
virtual bool can_convert_blob(const Field_blob *field,
const Column_definition &new_type) const
{
return false;
}
virtual bool can_convert_geom(const Field_geom *field,
const Column_definition &new_type) const
{
return false;
}
protected:
Handler_share *get_ha_share_ptr();
void set_ha_share_ptr(Handler_share *arg_ha_share);

View file

@ -5632,17 +5632,11 @@ int mysqld_main(int argc, char **argv)
init_ssl();
network_init();
#ifdef __WIN__
#ifdef _WIN32
if (!opt_console)
{
FreeConsole(); // Remove window
}
if (fileno(stdin) >= 0)
{
/* Disable CRLF translation (MDEV-9409). */
_setmode(fileno(stdin), O_BINARY);
}
#endif
#ifdef WITH_WSREP

View file

@ -504,6 +504,43 @@ static my_bool tc_collect_used_shares(TDC_element *element,
}
/*
Ignore errors from opening read only tables
*/
class flush_tables_error_handler : public Internal_error_handler
{
public:
int handled_errors;
int unhandled_errors;
flush_tables_error_handler() : handled_errors(0), unhandled_errors(0)
{}
bool handle_condition(THD *thd,
uint sql_errno,
const char* sqlstate,
Sql_condition::enum_warning_level *level,
const char* msg,
Sql_condition ** cond_hdl)
{
*cond_hdl= NULL;
if (sql_errno == ER_OPEN_AS_READONLY)
{
handled_errors++;
return TRUE;
}
if (*level == Sql_condition::WARN_LEVEL_ERROR)
unhandled_errors++;
return FALSE;
}
bool got_fatal_error()
{
return unhandled_errors > 0;
}
};
/**
Flush cached table as part of global read lock
@ -520,9 +557,9 @@ static my_bool tc_collect_used_shares(TDC_element *element,
bool flush_tables(THD *thd, flush_tables_type flag)
{
bool result= TRUE;
uint open_errors= 0;
tc_collect_arg collect_arg;
TABLE *tmp_table;
flush_tables_error_handler error_handler;
DBUG_ENTER("flush_tables");
purge_tables(false); /* Flush unused tables and shares */
@ -555,6 +592,8 @@ bool flush_tables(THD *thd, flush_tables_type flag)
}
/* Call HA_EXTRA_FLUSH on all found shares */
thd->push_internal_handler(&error_handler);
for (uint i= 0 ; i < collect_arg.shares.elements ; i++)
{
TABLE_SHARE *share= *dynamic_element(&collect_arg.shares, i,
@ -584,14 +623,14 @@ bool flush_tables(THD *thd, flush_tables_type flag)
*/
closefrm(tmp_table);
}
else
open_errors++;
}
tdc_release_share(share);
}
result= open_errors ? TRUE : FALSE;
DBUG_PRINT("note", ("open_errors: %u", open_errors));
thd->pop_internal_handler();
result= error_handler.got_fatal_error();
DBUG_PRINT("note", ("open_errors: %u %u",
error_handler.handled_errors,
error_handler.unhandled_errors));
err:
my_free(tmp_table);
delete_dynamic(&collect_arg.shares);

View file

@ -5382,7 +5382,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
impossible_range= records == 0 && s->table->reginfo.impossible_range;
if (join->thd->lex->sql_command == SQLCOM_SELECT &&
optimizer_flag(join->thd, OPTIMIZER_SWITCH_USE_ROWID_FILTER))
s->table->init_cost_info_for_usable_range_rowid_filters(join->thd);
s->table->init_cost_info_for_usable_range_rowid_filters(join->thd);
}
if (!impossible_range)
{

View file

@ -1197,10 +1197,14 @@ uint convert_to_printable(char *to, size_t to_len,
return (uint) (t - to);
}
size_t convert_to_printable_required_length(uint len)
{
return static_cast<size_t>(len) * 4 + 3/*dots*/ + 1/*trailing \0 */;
}
bool String::append_semi_hex(const char *s, uint len, CHARSET_INFO *cs)
{
size_t dst_len= len * 4 + 1; //extra length for the '\0' character
size_t dst_len= convert_to_printable_required_length(len);
if (reserve(dst_len))
return true;
uint nbytes= convert_to_printable(Ptr + str_length, dst_len, s, len, cs);

View file

@ -126,6 +126,7 @@ size_t my_copy_with_hex_escaping(CHARSET_INFO *cs,
uint convert_to_printable(char *to, size_t to_len,
const char *from, size_t from_len,
CHARSET_INFO *from_cs, size_t nbytes= 0);
size_t convert_to_printable_required_length(uint len);
class Charset
@ -171,7 +172,7 @@ public:
*/
LEX_CSTRING collation_specific_name() const;
bool encoding_allows_reinterpret_as(CHARSET_INFO *cs) const;
bool encoding_and_order_allow_reinterpret_as(CHARSET_INFO *cs) const;
bool eq_collation_specific_names(CHARSET_INFO *cs) const;
};

View file

@ -2776,6 +2776,7 @@ bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db,
- UNIQUE keys where all column are NOT NULL
- UNIQUE keys that don't contain partial segments
- Other UNIQUE keys
- LONG UNIQUE keys
- Normal keys
- Fulltext keys
@ -2799,6 +2800,14 @@ static int sort_keys(KEY *a, KEY *b)
{
if (!(b_flags & HA_NOSAME))
return -1;
/*
Long Unique keys should always be last unique key.
Before this patch they used to change order wrt to partial keys (MDEV-19049)
*/
if (a->algorithm == HA_KEY_ALG_LONG_HASH)
return 1;
if (b->algorithm == HA_KEY_ALG_LONG_HASH)
return -1;
if ((a_flags ^ b_flags) & HA_NULL_PART_KEY)
{
/* Sort NOT NULL keys before other keys */
@ -6592,23 +6601,28 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key,
if the user key part length is different.
*/
const Field *old_field= table->field[key_part->fieldnr - 1];
auto old_field_len= old_field->pack_length();
if (old_field->type() == MYSQL_TYPE_VARCHAR)
bool is_equal= key_part->field->is_equal(*new_field);
/* TODO: below is an InnoDB specific code which should be moved to InnoDB */
if (!is_equal)
{
old_field_len= (old_field->pack_length() -
((Field_varstring *) old_field)->length_bytes);
if (!key_part->field->can_be_converted_by_engine(*new_field))
return Compare_keys::NotEqual;
if (!Charset(old_field->charset())
.eq_collation_specific_names(new_field->charset))
return Compare_keys::NotEqual;
}
if (key_part->length == old_field_len &&
key_part->length < new_part->length &&
(key_part->field->is_equal((Create_field *) new_field) ==
IS_EQUAL_PACK_LENGTH))
if (key_part->length != new_part->length)
{
if (key_part->length != old_field->field_length ||
key_part->length >= new_part->length || is_equal)
{
return Compare_keys::NotEqual;
}
result= Compare_keys::EqualButKeyPartLength;
}
else if (key_part->length != new_part->length)
return Compare_keys::NotEqual;
}
/*
@ -6764,61 +6778,50 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar,
/* Field is not dropped. Evaluate changes bitmap for it. */
/*
Check if type of column has changed to some incompatible type.
Check if type of column has changed.
*/
uint is_equal= field->is_equal(new_field);
switch (is_equal)
bool is_equal= field->is_equal(*new_field);
if (!is_equal)
{
case IS_EQUAL_NO:
/* New column type is incompatible with old one. */
if (field->stored_in_db())
ha_alter_info->handler_flags|= ALTER_STORED_COLUMN_TYPE;
else
ha_alter_info->handler_flags|= ALTER_VIRTUAL_COLUMN_TYPE;
if (table->s->tmp_table == NO_TMP_TABLE)
if (field->can_be_converted_by_engine(*new_field))
{
delete_statistics_for_column(thd, table, field);
KEY *key_info= table->key_info;
for (uint i=0; i < table->s->keys; i++, key_info++)
/*
New column type differs from the old one, but storage engine can
change it by itself.
(for example, VARCHAR(300) is changed to VARCHAR(400)).
*/
ha_alter_info->handler_flags|= ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE;
}
else
{
/* New column type is incompatible with old one. */
ha_alter_info->handler_flags|= field->stored_in_db()
? ALTER_STORED_COLUMN_TYPE
: ALTER_VIRTUAL_COLUMN_TYPE;
if (table->s->tmp_table == NO_TMP_TABLE)
{
if (field->part_of_key.is_set(i))
delete_statistics_for_column(thd, table, field);
KEY *key_info= table->key_info;
for (uint i= 0; i < table->s->keys; i++, key_info++)
{
if (!field->part_of_key.is_set(i))
continue;
uint key_parts= table->actual_n_key_parts(key_info);
for (uint j= 0; j < key_parts; j++)
{
if (key_info->key_part[j].fieldnr-1 == field->field_index)
if (key_info->key_part[j].fieldnr - 1 == field->field_index)
{
delete_statistics_for_index(thd, table, key_info,
j >= key_info->user_defined_key_parts);
delete_statistics_for_index(
thd, table, key_info,
j >= key_info->user_defined_key_parts);
break;
}
}
}
}
}
}
}
break;
case IS_EQUAL_YES:
/*
New column is the same as the old one or the fully compatible with
it (for example, ENUM('a','b') was changed to ENUM('a','b','c')).
Such a change if any can ALWAYS be carried out by simply updating
data-dictionary without even informing storage engine.
No flag is set in this case.
*/
break;
case IS_EQUAL_PACK_LENGTH:
/*
New column type differs from the old one, but has compatible packed
data representation. Depending on storage engine, such a change can
be carried out by simply updating data dictionary without changing
actual data (for example, VARCHAR(300) is changed to VARCHAR(400)).
*/
ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH;
break;
default:
DBUG_ASSERT(0);
/* Safety. */
ha_alter_info->handler_flags|= ALTER_STORED_COLUMN_TYPE;
}
if (field->vcol_info || new_field->vcol_info)
@ -6829,7 +6832,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar,
ALTER_VIRTUAL_COLUMN_TYPE);
if (field->vcol_info && new_field->vcol_info)
{
bool value_changes= is_equal == IS_EQUAL_NO;
bool value_changes= !is_equal;
alter_table_operations alter_expr;
if (field->stored_in_db())
alter_expr= ALTER_STORED_GCOL_EXPR;
@ -6923,7 +6926,6 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar,
ha_alter_info->create_info->fields_option_struct[f_ptr - table->field]=
new_field->option_struct;
}
}
else
{
@ -7288,7 +7290,7 @@ bool mysql_compare_tables(TABLE *table,
DBUG_RETURN(false);
/* Evaluate changes bitmap and send to check_if_incompatible_data() */
uint field_changes= field->is_equal(tmp_new_field);
uint field_changes= field->is_equal(*tmp_new_field);
if (field_changes != IS_EQUAL_YES)
DBUG_RETURN(false);
@ -8790,7 +8792,7 @@ fk_check_column_changes(THD *thd, Alter_info *alter_info,
return FK_COLUMN_RENAMED;
}
if ((old_field->is_equal(new_field) == IS_EQUAL_NO) ||
if ((old_field->is_equal(*new_field) == IS_EQUAL_NO) ||
((new_field->flags & NOT_NULL_FLAG) &&
!(old_field->flags & NOT_NULL_FLAG)))
{

View file

@ -8639,19 +8639,8 @@ Charset::encoding_allows_reinterpret_as(const CHARSET_INFO *cs) const
bool
Charset::encoding_and_order_allow_reinterpret_as(CHARSET_INFO *cs) const
Charset::eq_collation_specific_names(CHARSET_INFO *cs) const
{
/*
Test quickly if we have two exactly equal CHARSET_INFO pointers.
This also handles a special case with my_charset_bin:
it does not have a collation name specific part in CHARSET_INFO::name,
which is just "binary" (without a character set name prefix),
so the code with collation_specific_name() below won't work for it.
*/
if (m_charset == cs)
return true;
if (!encoding_allows_reinterpret_as(cs))
return false;
LEX_CSTRING name0= collation_specific_name();
LEX_CSTRING name1= Charset(cs).collation_specific_name();
return name0.length && !cmp(&name0, &name1);

View file

@ -738,7 +738,7 @@ static bool pack_header(THD *thd, uchar *forminfo,
(const char **) thd->alloc(sizeof(char*) *
(field->interval->count+1));
tmpint->type_lengths=
(uint *) thd->alloc(sizeof(uint) * field->interval->count);
(uint *) thd->alloc(sizeof(uint) * field->interval->count+1);
tmpint->type_names[field->interval->count]= 0;
tmpint->type_lengths[field->interval->count]= 0;

View file

@ -7017,7 +7017,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
ALTER_DROP_PK_INDEX;
alter_table_operations inplace_offline_operations=
ALTER_COLUMN_EQUAL_PACK_LENGTH |
ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE |
ALTER_COLUMN_NAME |
ALTER_COLUMN_DEFAULT |
ALTER_CHANGE_CREATE_OPTION |
@ -7116,7 +7116,7 @@ ha_connect::check_if_supported_inplace_alter(TABLE *altered_table,
#if 0
uint table_changes= (ha_alter_info->handler_flags &
ALTER_COLUMN_EQUAL_PACK_LENGTH) ?
ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE) ?
IS_EQUAL_PACK_LENGTH : IS_EQUAL_YES;
if (table->file->check_if_incompatible_data(create_info, table_changes)

View file

@ -74,6 +74,8 @@ Warnings:
Warning 1105 Truncated author content
# increase author size
ALTER TABLE bookstore MODIFY `author` VARCHAR(128) NOT NULL;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00

View file

@ -72,6 +72,8 @@ Warnings:
Warning 1105 Truncated author content
# increase author size
ALTER TABLE bookstore MODIFY `author` VARCHAR(128) NOT NULL;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00

View file

@ -65,7 +65,6 @@ ib_warn_row_too_big(const dict_table_t* table);
#include "lock0lock.h"
#include "mach0data.h"
#include "mem0mem.h"
#include "os0once.h"
#include "page0page.h"
#include "page0zip.h"
#include "pars0pars.h"
@ -226,145 +225,6 @@ dict_get_db_name_len(
return ulint(s - name);
}
/** Allocate and init a dict_table_t's stats latch.
This function must not be called concurrently on the same table object.
@param[in,out] table_void table whose stats latch to create */
static
void
dict_table_stats_latch_alloc(
void* table_void)
{
dict_table_t* table = static_cast<dict_table_t*>(table_void);
/* Note: rw_lock_create() will call the constructor */
table->stats_latch = static_cast<rw_lock_t*>(
ut_malloc_nokey(sizeof(rw_lock_t)));
ut_a(table->stats_latch != NULL);
rw_lock_create(dict_table_stats_key, table->stats_latch,
SYNC_INDEX_TREE);
}
/** Deinit and free a dict_table_t's stats latch.
This function must not be called concurrently on the same table object.
@param[in,out] table table whose stats latch to free */
static
void
dict_table_stats_latch_free(
dict_table_t* table)
{
rw_lock_free(table->stats_latch);
ut_free(table->stats_latch);
}
/** Create a dict_table_t's stats latch or delay for lazy creation.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to create
@param[in] enabled if false then the latch is disabled
and dict_table_stats_lock()/unlock() become noop on this table. */
void
dict_table_stats_latch_create(
dict_table_t* table,
bool enabled)
{
if (!enabled) {
table->stats_latch = NULL;
table->stats_latch_created = os_once::DONE;
return;
}
/* We create this lazily the first time it is used. */
table->stats_latch = NULL;
table->stats_latch_created = os_once::NEVER_DONE;
}
/** Destroy a dict_table_t's stats latch.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to destroy */
void
dict_table_stats_latch_destroy(
dict_table_t* table)
{
if (table->stats_latch_created == os_once::DONE
&& table->stats_latch != NULL) {
dict_table_stats_latch_free(table);
}
}
/** Lock the appropriate latch to protect a given table's statistics.
@param[in] table table whose stats to lock
@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
void
dict_table_stats_lock(
dict_table_t* table,
ulint latch_mode)
{
ut_ad(table != NULL);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
os_once::do_or_wait_for_done(
&table->stats_latch_created,
dict_table_stats_latch_alloc, table);
if (table->stats_latch == NULL) {
/* This is a dummy table object that is private in the current
thread and is not shared between multiple threads, thus we
skip any locking. */
return;
}
switch (latch_mode) {
case RW_S_LATCH:
rw_lock_s_lock(table->stats_latch);
break;
case RW_X_LATCH:
rw_lock_x_lock(table->stats_latch);
break;
case RW_NO_LATCH:
/* fall through */
default:
ut_error;
}
}
/** Unlock the latch that has been locked by dict_table_stats_lock().
@param[in] table table whose stats to unlock
@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
void
dict_table_stats_unlock(
dict_table_t* table,
ulint latch_mode)
{
ut_ad(table != NULL);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
if (table->stats_latch == NULL) {
/* This is a dummy table object that is private in the current
thread and is not shared between multiple threads, thus we
skip any locking. */
return;
}
switch (latch_mode) {
case RW_S_LATCH:
rw_lock_s_unlock(table->stats_latch);
break;
case RW_X_LATCH:
rw_lock_x_unlock(table->stats_latch);
break;
case RW_NO_LATCH:
/* fall through */
default:
ut_error;
}
}
/** Open a persistent table.
@param[in] table_id persistent table identifier
@param[in] ignore_err errors to ignore
@ -707,61 +567,6 @@ dict_table_get_nth_v_col_mysql(
return(dict_table_get_nth_v_col(table, i));
}
/** Allocate and init the autoinc latch of a given table.
This function must not be called concurrently on the same table object.
@param[in,out] table_void table whose autoinc latch to create */
static
void
dict_table_autoinc_alloc(
void* table_void)
{
dict_table_t* table = static_cast<dict_table_t*>(table_void);
table->autoinc_mutex = UT_NEW_NOKEY(ib_mutex_t());
ut_a(table->autoinc_mutex != NULL);
mutex_create(LATCH_ID_AUTOINC, table->autoinc_mutex);
}
/** Allocate and init the zip_pad_mutex of a given index.
This function must not be called concurrently on the same index object.
@param[in,out] index_void index whose zip_pad_mutex to create */
static
void
dict_index_zip_pad_alloc(
void* index_void)
{
dict_index_t* index = static_cast<dict_index_t*>(index_void);
index->zip_pad.mutex = UT_NEW_NOKEY(SysMutex());
ut_a(index->zip_pad.mutex != NULL);
mutex_create(LATCH_ID_ZIP_PAD_MUTEX, index->zip_pad.mutex);
}
/********************************************************************//**
Acquire the autoinc lock. */
void
dict_table_autoinc_lock(
/*====================*/
dict_table_t* table) /*!< in/out: table */
{
os_once::do_or_wait_for_done(
&table->autoinc_mutex_created,
dict_table_autoinc_alloc, table);
mutex_enter(table->autoinc_mutex);
}
/** Acquire the zip_pad_mutex latch.
@param[in,out] index the index whose zip_pad_mutex to acquire.*/
static
void
dict_index_zip_pad_lock(
dict_index_t* index)
{
os_once::do_or_wait_for_done(
&index->zip_pad.mutex_created,
dict_index_zip_pad_alloc, index);
mutex_enter(index->zip_pad.mutex);
}
/** Get all the FTS indexes on a table.
@param[in] table table
@ -788,16 +593,6 @@ dict_table_get_all_fts_indexes(
return(ib_vector_size(indexes));
}
/********************************************************************//**
Release the autoinc lock. */
void
dict_table_autoinc_unlock(
/*======================*/
dict_table_t* table) /*!< in/out: table */
{
mutex_exit(table->autoinc_mutex);
}
/** Looks for column n in an index.
@param[in] index index
@param[in] n column number
@ -1192,6 +987,8 @@ inline void dict_sys_t::add(dict_table_t* table)
ulint fold = ut_fold_string(table->name.m_name);
mutex_create(LATCH_ID_AUTOINC, &table->autoinc_mutex);
/* Look for a table with the same name: error if such exists */
{
dict_table_t* table2;
@ -1939,6 +1736,8 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
UT_DELETE(table->vc_templ);
}
mutex_free(&table->autoinc_mutex);
if (!keep) {
dict_mem_table_free(table);
}
@ -6626,10 +6425,10 @@ dict_index_zip_success(
return;
}
dict_index_zip_pad_lock(index);
mutex_enter(&index->zip_pad.mutex);
++index->zip_pad.success;
dict_index_zip_pad_update(&index->zip_pad, zip_threshold);
dict_index_zip_pad_unlock(index);
mutex_exit(&index->zip_pad.mutex);
}
/*********************************************************************//**
@ -6646,10 +6445,10 @@ dict_index_zip_failure(
return;
}
dict_index_zip_pad_lock(index);
mutex_enter(&index->zip_pad.mutex);
++index->zip_pad.failure;
dict_index_zip_pad_update(&index->zip_pad, zip_threshold);
dict_index_zip_pad_unlock(index);
mutex_exit(&index->zip_pad.mutex);
}
/*********************************************************************//**

View file

@ -171,16 +171,9 @@ dict_mem_table_create(
new (&table->v_cols[i]) dict_v_col_t();
}
/* true means that the stats latch will be enabled -
dict_table_stats_lock() will not be noop. */
dict_table_stats_latch_create(table, true);
table->autoinc_lock = static_cast<ib_lock_t*>(
mem_heap_alloc(heap, lock_get_size()));
/* lazy creation of table autoinc latch */
dict_table_autoinc_create_lazy(table);
/* If the table has an FTS index or we are in the process
of building one, create the table->fts */
if (dict_table_has_fts_index(table)
@ -193,6 +186,9 @@ dict_mem_table_create(
new(&table->foreign_set) dict_foreign_set();
new(&table->referenced_set) dict_foreign_set();
rw_lock_create(dict_table_stats_key, &table->stats_latch,
SYNC_INDEX_TREE);
return(table);
}
@ -217,9 +213,7 @@ dict_mem_table_free(
}
}
dict_table_autoinc_destroy(table);
dict_mem_table_free_foreign_vcol_set(table);
dict_table_stats_latch_destroy(table);
table->foreign_set.~dict_foreign_set();
table->referenced_set.~dict_foreign_set();
@ -235,6 +229,8 @@ dict_mem_table_free(
UT_DELETE(table->s_cols);
rw_lock_free(&table->stats_latch);
mem_heap_free(table->heap);
}
@ -744,7 +740,7 @@ dict_mem_index_create(
dict_mem_fill_index_struct(index, heap, index_name, type, n_fields);
dict_index_zip_pad_mutex_create_lazy(index);
mutex_create(LATCH_ID_ZIP_PAD_MUTEX, &index->zip_pad.mutex);
if (type & DICT_SPATIAL) {
mutex_create(LATCH_ID_RTR_SSN_MUTEX, &index->rtr_ssn.mutex);
@ -1054,7 +1050,7 @@ dict_mem_index_free(
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
dict_index_zip_pad_mutex_destroy(index);
mutex_free(&index->zip_pad.mutex);
if (dict_index_is_spatial(index)) {
for (auto& rtr_info : index->rtr_track->rtr_active) {

View file

@ -33,6 +33,7 @@ Created Jan 06, 2010 Vasil Dimov
#include "pars0pars.h"
#include <mysql_com.h>
#include "btr0btr.h"
#include "sync0sync.h"
#include <algorithm>
#include <map>
@ -417,11 +418,6 @@ dict_stats_table_clone_create(
t->corrupted = table->corrupted;
/* This private object "t" is not shared with other threads, so
we do not need the stats_latch (thus we pass false below). The
dict_table_stats_lock()/unlock() routines will do nothing. */
dict_table_stats_latch_create(t, false);
UT_LIST_INIT(t->indexes, &dict_index_t::indexes);
for (index = dict_table_get_first_index(table);
@ -484,6 +480,8 @@ dict_stats_table_clone_create(
ut_d(t->magic_n = DICT_TABLE_MAGIC_N);
rw_lock_create(dict_table_stats_key, &t->stats_latch, SYNC_INDEX_TREE);
return(t);
}
@ -496,15 +494,13 @@ dict_stats_table_clone_free(
/*========================*/
dict_table_t* t) /*!< in: dummy table object to free */
{
dict_table_stats_latch_destroy(t);
rw_lock_free(&t->stats_latch);
mem_heap_free(t->heap);
}
/*********************************************************************//**
Write all zeros (or 1 where it makes sense) into an index
statistics members. The resulting stats correspond to an empty index.
The caller must own index's table stats latch in X mode
(dict_table_stats_lock(table, RW_X_LATCH)) */
statistics members. The resulting stats correspond to an empty index. */
static
void
dict_stats_empty_index(
@ -515,6 +511,7 @@ dict_stats_empty_index(
{
ut_ad(!(index->type & DICT_FTS));
ut_ad(!dict_index_is_ibuf(index));
ut_ad(rw_lock_own(&index->table->stats_latch, RW_LOCK_X));
ulint n_uniq = index->n_uniq;
@ -546,7 +543,7 @@ dict_stats_empty_table(
{
/* Zero the stats members */
dict_table_stats_lock(table, RW_X_LATCH);
rw_lock_x_lock(&table->stats_latch);
table->stat_n_rows = 0;
table->stat_clustered_index_size = 1;
@ -572,7 +569,7 @@ dict_stats_empty_table(
table->stat_initialized = TRUE;
dict_table_stats_unlock(table, RW_X_LATCH);
rw_lock_x_unlock(&table->stats_latch);
}
/*********************************************************************//**
@ -788,7 +785,7 @@ dict_stats_snapshot_create(
{
mutex_enter(&dict_sys.mutex);
dict_table_stats_lock(table, RW_S_LATCH);
rw_lock_s_lock(&table->stats_latch);
dict_stats_assert_initialized(table);
@ -803,7 +800,7 @@ dict_stats_snapshot_create(
t->stats_sample_pages = table->stats_sample_pages;
t->stats_bg_flag = table->stats_bg_flag;
dict_table_stats_unlock(table, RW_S_LATCH);
rw_lock_s_unlock(&table->stats_latch);
mutex_exit(&dict_sys.mutex);
@ -2215,7 +2212,7 @@ dict_stats_update_persistent(
DEBUG_PRINTF("%s(table=%s)\n", __func__, table->name);
dict_table_stats_lock(table, RW_X_LATCH);
rw_lock_x_lock(&table->stats_latch);
/* analyze the clustered index first */
@ -2226,7 +2223,7 @@ dict_stats_update_persistent(
|| (index->type | DICT_UNIQUE) != (DICT_CLUSTERED | DICT_UNIQUE)) {
/* Table definition is corrupt */
dict_table_stats_unlock(table, RW_X_LATCH);
rw_lock_x_unlock(&table->stats_latch);
dict_stats_empty_table(table, true);
return(DB_CORRUPTION);
@ -2278,7 +2275,7 @@ dict_stats_update_persistent(
dict_stats_assert_initialized(table);
dict_table_stats_unlock(table, RW_X_LATCH);
rw_lock_x_unlock(&table->stats_latch);
return(DB_SUCCESS);
}
@ -3097,11 +3094,11 @@ dict_stats_update_for_index(
if (dict_stats_is_persistent_enabled(index->table)) {
if (dict_stats_persistent_storage_check(false)) {
dict_table_stats_lock(index->table, RW_X_LATCH);
rw_lock_x_lock(&index->table->stats_latch);
dict_stats_analyze_index(index);
index->table->stat_sum_of_other_index_sizes
+= index->stat_index_size;
dict_table_stats_unlock(index->table, RW_X_LATCH);
rw_lock_x_unlock(&index->table->stats_latch);
dict_stats_save(index->table, &index->id);
DBUG_VOID_RETURN;
}
@ -3122,9 +3119,9 @@ dict_stats_update_for_index(
}
}
dict_table_stats_lock(index->table, RW_X_LATCH);
rw_lock_x_lock(&index->table->stats_latch);
dict_stats_update_transient_for_index(index);
dict_table_stats_unlock(index->table, RW_X_LATCH);
rw_lock_x_unlock(&index->table->stats_latch);
DBUG_VOID_RETURN;
}
@ -3278,7 +3275,7 @@ dict_stats_update(
switch (err) {
case DB_SUCCESS:
dict_table_stats_lock(table, RW_X_LATCH);
rw_lock_x_lock(&table->stats_latch);
/* Pass reset_ignored_indexes=true as parameter
to dict_stats_copy. This will cause statictics
@ -3287,7 +3284,7 @@ dict_stats_update(
dict_stats_assert_initialized(table);
dict_table_stats_unlock(table, RW_X_LATCH);
rw_lock_x_unlock(&table->stats_latch);
dict_stats_table_clone_free(t);
@ -3342,11 +3339,11 @@ dict_stats_update(
transient:
dict_table_stats_lock(table, RW_X_LATCH);
rw_lock_x_lock(&table->stats_latch);
dict_stats_update_transient(table);
dict_table_stats_unlock(table, RW_X_LATCH);
rw_lock_x_unlock(&table->stats_latch);
return(DB_SUCCESS);
}

View file

@ -54,6 +54,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <my_bitmap.h>
#include <mysql/service_thd_alloc.h>
#include <mysql/service_thd_wait.h>
#include "field.h"
// MYSQL_PLUGIN_IMPORT extern my_bool lower_case_file_system;
// MYSQL_PLUGIN_IMPORT extern char mysql_unpacked_real_data_home[];
@ -2532,8 +2533,7 @@ ha_innobase::innobase_reset_autoinc(
if (error == DB_SUCCESS) {
dict_table_autoinc_initialize(m_prebuilt->table, autoinc);
dict_table_autoinc_unlock(m_prebuilt->table);
mutex_exit(&m_prebuilt->table->autoinc_mutex);
}
return(error);
@ -5924,7 +5924,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
const unsigned col_no = innodb_col_no(field);
dict_table_autoinc_lock(table);
mutex_enter(&table->autoinc_mutex);
table->persistent_autoinc = 1
+ dict_table_get_nth_col_pos(table, col_no, NULL);
@ -5932,7 +5932,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
if (table->autoinc) {
/* Already initialized. Our caller checked
table->persistent_autoinc without
dict_table_autoinc_lock(), and there might be multiple
autoinc_mutex protection, and there might be multiple
ha_innobase::open() executing concurrently. */
} else if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
/* If the recovery level is set so high that writes
@ -5954,7 +5954,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
innobase_get_int_col_max_value(field));
}
dict_table_autoinc_unlock(table);
mutex_exit(&table->autoinc_mutex);
}
/** Open an InnoDB table
@ -6010,11 +6010,6 @@ 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)
@ -7795,7 +7790,7 @@ ha_innobase::innobase_lock_autoinc(void)
switch (innobase_autoinc_lock_mode) {
case AUTOINC_NO_LOCKING:
/* Acquire only the AUTOINC mutex. */
dict_table_autoinc_lock(m_prebuilt->table);
mutex_enter(&m_prebuilt->table->autoinc_mutex);
break;
case AUTOINC_NEW_STYLE_LOCKING:
@ -7810,14 +7805,14 @@ ha_innobase::innobase_lock_autoinc(void)
) {
/* Acquire the AUTOINC mutex. */
dict_table_autoinc_lock(m_prebuilt->table);
mutex_enter(&m_prebuilt->table->autoinc_mutex);
/* We need to check that another transaction isn't
already holding the AUTOINC lock on the table. */
if (m_prebuilt->table->n_waiting_or_granted_auto_inc_locks) {
/* Release the mutex to avoid deadlocks and
fall back to old style locking. */
dict_table_autoinc_unlock(m_prebuilt->table);
mutex_exit(&m_prebuilt->table->autoinc_mutex);
} else {
/* Do not fall back to old style locking. */
break;
@ -7833,7 +7828,7 @@ ha_innobase::innobase_lock_autoinc(void)
if (error == DB_SUCCESS) {
/* Acquire the AUTOINC mutex. */
dict_table_autoinc_lock(m_prebuilt->table);
mutex_enter(&m_prebuilt->table->autoinc_mutex);
}
break;
@ -7861,8 +7856,7 @@ ha_innobase::innobase_set_max_autoinc(
if (error == DB_SUCCESS) {
dict_table_autoinc_update_if_greater(m_prebuilt->table, auto_inc);
dict_table_autoinc_unlock(m_prebuilt->table);
mutex_exit(&m_prebuilt->table->autoinc_mutex);
}
return(error);
@ -12446,7 +12440,7 @@ create_table_info_t::create_table_update_dict()
autoinc = 1;
}
dict_table_autoinc_lock(innobase_table);
mutex_enter(&innobase_table->autoinc_mutex);
dict_table_autoinc_initialize(innobase_table, autoinc);
if (innobase_table->is_temporary()) {
@ -12471,7 +12465,7 @@ create_table_info_t::create_table_update_dict()
}
}
dict_table_autoinc_unlock(innobase_table);
mutex_exit(&innobase_table->autoinc_mutex);
}
innobase_parse_hint_from_comment(m_thd, innobase_table, m_form->s);
@ -13860,7 +13854,7 @@ ha_innobase::info_low(
ulint stat_sum_of_other_index_sizes;
if (!(flag & HA_STATUS_NO_LOCK)) {
dict_table_stats_lock(ib_table, RW_S_LATCH);
rw_lock_s_lock(&ib_table->stats_latch);
}
ut_a(ib_table->stat_initialized);
@ -13874,7 +13868,7 @@ ha_innobase::info_low(
= ib_table->stat_sum_of_other_index_sizes;
if (!(flag & HA_STATUS_NO_LOCK)) {
dict_table_stats_unlock(ib_table, RW_S_LATCH);
rw_lock_s_unlock(&ib_table->stats_latch);
}
/*
@ -13978,7 +13972,7 @@ ha_innobase::info_low(
}
if (!(flag & HA_STATUS_NO_LOCK)) {
dict_table_stats_lock(ib_table, RW_S_LATCH);
rw_lock_s_lock(&ib_table->stats_latch);
}
ut_a(ib_table->stat_initialized);
@ -14060,7 +14054,7 @@ ha_innobase::info_low(
}
if (!(flag & HA_STATUS_NO_LOCK)) {
dict_table_stats_unlock(ib_table, RW_S_LATCH);
rw_lock_s_unlock(&ib_table->stats_latch);
}
snprintf(path, sizeof(path), "%s/%s%s",
@ -16314,7 +16308,7 @@ ha_innobase::innobase_get_autoinc(
/* It should have been initialized during open. */
if (*value == 0) {
m_prebuilt->autoinc_error = DB_UNSUPPORTED;
dict_table_autoinc_unlock(m_prebuilt->table);
mutex_exit(&m_prebuilt->table->autoinc_mutex);
}
}
@ -16338,7 +16332,7 @@ ha_innobase::innobase_peek_autoinc(void)
innodb_table = m_prebuilt->table;
dict_table_autoinc_lock(innodb_table);
mutex_enter(&innodb_table->autoinc_mutex);
auto_inc = dict_table_autoinc_read(innodb_table);
@ -16347,7 +16341,7 @@ ha_innobase::innobase_peek_autoinc(void)
" '" << innodb_table->name << "'";
}
dict_table_autoinc_unlock(innodb_table);
mutex_exit(&innodb_table->autoinc_mutex);
return(auto_inc);
}
@ -16454,7 +16448,7 @@ ha_innobase::get_auto_increment(
/* Out of range number. Let handler::update_auto_increment()
take care of this */
m_prebuilt->autoinc_last_value = 0;
dict_table_autoinc_unlock(m_prebuilt->table);
mutex_exit(&m_prebuilt->table->autoinc_mutex);
*nb_reserved_values= 0;
return;
}
@ -16518,7 +16512,7 @@ ha_innobase::get_auto_increment(
m_prebuilt->autoinc_offset = offset;
m_prebuilt->autoinc_increment = increment;
dict_table_autoinc_unlock(m_prebuilt->table);
mutex_exit(&m_prebuilt->table->autoinc_mutex);
}
/*******************************************************************//**
@ -20673,6 +20667,146 @@ bool ha_innobase::rowid_filter_push(Rowid_filter* pk_filter)
DBUG_RETURN(false);
}
static bool
is_part_of_a_primary_key(const Field* field)
{
const TABLE_SHARE* s = field->table->s;
return s->primary_key != MAX_KEY
&& field->part_of_key.is_set(s->primary_key);
}
bool
ha_innobase::can_convert_string(const Field_string* field,
const Column_definition& new_type) const
{
DBUG_ASSERT(!field->compression_method());
if (new_type.type_handler() != field->type_handler()) {
return false;
}
if (new_type.char_length < field->char_length()) {
return false;
}
if (new_type.charset != field->charset()) {
if (new_type.length != field->max_display_length()
&& !m_prebuilt->table->not_redundant()) {
return IS_EQUAL_NO;
}
Charset field_cs(field->charset());
if (!field_cs.encoding_allows_reinterpret_as(
new_type.charset)) {
return false;
}
if (!field_cs.eq_collation_specific_names(new_type.charset)) {
return !is_part_of_a_primary_key(field);
}
return true;
}
if (new_type.length != field->max_display_length()) {
return false;
}
return true;
}
static bool
supports_enlarging(const dict_table_t* table, const Field_varstring* field,
const Column_definition& new_type)
{
return field->field_length <= 127 || new_type.length <= 255
|| field->field_length > 255 || !table->not_redundant();
}
bool
ha_innobase::can_convert_varstring(const Field_varstring* field,
const Column_definition& new_type) const
{
if (new_type.length < field->field_length) {
return false;
}
if (new_type.char_length < field->char_length()) {
return false;
}
if (!new_type.compression_method() != !field->compression_method()) {
return false;
}
if (new_type.type_handler() != field->type_handler()) {
return false;
}
if (new_type.charset != field->charset()) {
if (!supports_enlarging(m_prebuilt->table, field, new_type)) {
return false;
}
Charset field_cs(field->charset());
if (!field_cs.encoding_allows_reinterpret_as(
new_type.charset)) {
return false;
}
if (!field_cs.eq_collation_specific_names(new_type.charset)) {
return !is_part_of_a_primary_key(field);
}
return true;
}
if (new_type.length != field->field_length) {
if (!supports_enlarging(m_prebuilt->table, field, new_type)) {
return false;
}
return true;
}
return true;
}
bool
ha_innobase::can_convert_blob(const Field_blob* field,
const Column_definition& new_type) const
{
if (new_type.type_handler() != field->type_handler()) {
return false;
}
if (!new_type.compression_method() != !field->compression_method()) {
return false;
}
if (new_type.pack_length != field->pack_length()) {
return false;
}
if (new_type.charset != field->charset()) {
Charset field_cs(field->charset());
if (!field_cs.encoding_allows_reinterpret_as(
new_type.charset)) {
return false;
}
if (!field_cs.eq_collation_specific_names(new_type.charset)) {
bool is_part_of_a_key
= !field->part_of_key.is_clear_all();
return !is_part_of_a_key;
}
return true;
}
return true;
}
/******************************************************************//**
Use this when the args are passed to the format string from
errmsg-utf8.txt directly as is.

View file

@ -437,6 +437,13 @@ public:
@retval false if pushed (always) */
bool rowid_filter_push(Rowid_filter *rowid_filter);
bool can_convert_string(const Field_string* field,
const Column_definition& new_field) const;
bool can_convert_varstring(const Field_varstring* field,
const Column_definition& new_field) const;
bool can_convert_blob(const Field_blob* field,
const Column_definition& new_field) const;
protected:
/**
MySQL calls this method at the end of each statement. This method

View file

@ -131,7 +131,7 @@ static const alter_table_operations INNOBASE_ALTER_INSTANT
| ALTER_COLUMN_NAME
| ALTER_ADD_VIRTUAL_COLUMN
| INNOBASE_FOREIGN_OPERATIONS
| ALTER_COLUMN_EQUAL_PACK_LENGTH
| ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE
| ALTER_COLUMN_UNVERSIONED
| ALTER_RENAME_INDEX
| ALTER_DROP_VIRTUAL_COLUMN;
@ -8332,7 +8332,7 @@ ok_exit:
rebuild_templ
= ctx->need_rebuild()
|| ((ha_alter_info->handler_flags
& ALTER_COLUMN_EQUAL_PACK_LENGTH)
& ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE)
&& alter_templ_needs_rebuild(
altered_table, ha_alter_info, ctx->new_table));
@ -9120,14 +9120,20 @@ innobase_rename_or_enlarge_column_try(
DBUG_ASSERT(col->len <= len);
#ifdef UNIV_DEBUG
ut_ad(col->mbminlen <= col->mbmaxlen);
switch (mtype) {
case DATA_MYSQL:
if (!(prtype & DATA_BINARY_TYPE) || user_table->not_redundant()
|| col->mbminlen != col->mbmaxlen) {
/* 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. */
break;
}
/* fall through */
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_ad(col->len == len);
break;
case DATA_BINARY:
@ -9188,7 +9194,7 @@ innobase_rename_or_enlarge_columns_try(
DBUG_ENTER("innobase_rename_or_enlarge_columns_try");
if (!(ha_alter_info->handler_flags
& (ALTER_COLUMN_EQUAL_PACK_LENGTH
& (ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE
| ALTER_COLUMN_NAME))) {
DBUG_RETURN(false);
}
@ -9236,7 +9242,7 @@ innobase_rename_or_enlarge_columns_cache(
dict_table_t* user_table)
{
if (!(ha_alter_info->handler_flags
& (ALTER_COLUMN_EQUAL_PACK_LENGTH
& (ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE
| ALTER_COLUMN_NAME))) {
return;
}

View file

@ -5274,7 +5274,7 @@ i_s_dict_fill_sys_tablestats(
OK(field_store_string(fields[SYS_TABLESTATS_NAME],
table->name.m_name));
dict_table_stats_lock(table, RW_S_LATCH);
rw_lock_s_lock(&table->stats_latch);
if (table->stat_initialized) {
OK(field_store_string(fields[SYS_TABLESTATS_INIT],
@ -5304,7 +5304,7 @@ i_s_dict_fill_sys_tablestats(
OK(fields[SYS_TABLESTATS_MODIFIED]->store(0, true));
}
dict_table_stats_unlock(table, RW_S_LATCH);
rw_lock_s_unlock(&table->stats_latch);
OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, true));

View file

@ -288,13 +288,6 @@ dict_col_name_is_reserved(
/*======================*/
const char* name) /*!< in: column name */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/********************************************************************//**
Acquire the autoinc lock. */
void
dict_table_autoinc_lock(
/*====================*/
dict_table_t* table) /*!< in/out: table */
MY_ATTRIBUTE((nonnull));
/** Unconditionally set the AUTO_INCREMENT counter.
@param[in,out] table table or partition
@param[in] value next available AUTO_INCREMENT value */
@ -303,7 +296,7 @@ UNIV_INLINE
void
dict_table_autoinc_initialize(dict_table_t* table, ib_uint64_t value)
{
ut_ad(dict_table_autoinc_own(table));
ut_ad(mutex_own(&table->autoinc_mutex));
table->autoinc = value;
}
@ -316,7 +309,7 @@ UNIV_INLINE
ib_uint64_t
dict_table_autoinc_read(const dict_table_t* table)
{
ut_ad(dict_table_autoinc_own(table));
ut_ad(mutex_own(&table->autoinc_mutex));
return(table->autoinc);
}
@ -330,7 +323,7 @@ UNIV_INLINE
bool
dict_table_autoinc_update_if_greater(dict_table_t* table, ib_uint64_t value)
{
ut_ad(dict_table_autoinc_own(table));
ut_ad(mutex_own(&table->autoinc_mutex));
if (value > table->autoinc) {
@ -341,13 +334,6 @@ dict_table_autoinc_update_if_greater(dict_table_t* table, ib_uint64_t value)
return(false);
}
/********************************************************************//**
Release the autoinc lock. */
void
dict_table_autoinc_unlock(
/*======================*/
dict_table_t* table) /*!< in/out: table */
MY_ATTRIBUTE((nonnull));
/**********************************************************************//**
Adds system columns to a table object. */
void
@ -1355,41 +1341,6 @@ dict_index_calc_min_rec_len(
#define dict_mutex_enter_for_mysql() mutex_enter(&dict_sys.mutex)
#define dict_mutex_exit_for_mysql() mutex_exit(&dict_sys.mutex)
/** Create a dict_table_t's stats latch or delay for lazy creation.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to create
@param[in] enabled if false then the latch is disabled
and dict_table_stats_lock()/unlock() become noop on this table. */
void
dict_table_stats_latch_create(
dict_table_t* table,
bool enabled);
/** Destroy a dict_table_t's stats latch.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to destroy */
void
dict_table_stats_latch_destroy(
dict_table_t* table);
/** Lock the appropriate latch to protect a given table's statistics.
@param[in] table table whose stats to lock
@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
void
dict_table_stats_lock(
dict_table_t* table,
ulint latch_mode);
/** Unlock the latch that has been locked by dict_table_stats_lock().
@param[in] table table whose stats to unlock
@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
void
dict_table_stats_unlock(
dict_table_t* table,
ulint latch_mode);
/********************************************************************//**
Checks if the database name in two table names is the same.
@return TRUE if same db name */

View file

@ -44,7 +44,6 @@ Created 1/8/1996 Heikki Tuuri
#include "fts0fts.h"
#include "buf0buf.h"
#include "gis0type.h"
#include "os0once.h"
#include "fil0fil.h"
#include "fil0crypt.h"
#include <sql_const.h>
@ -883,7 +882,7 @@ extern ulong zip_pad_max;
an uncompressed page should be left as padding to avoid compression
failures. This estimate is based on a self-adapting heuristic. */
struct zip_pad_info_t {
SysMutex* mutex; /*!< mutex protecting the info */
SysMutex mutex; /*!< mutex protecting the info */
Atomic_counter<ulint>
pad; /*!< number of bytes used as pad */
ulint success;/*!< successful compression ops during
@ -892,9 +891,6 @@ struct zip_pad_info_t {
current round */
ulint n_rounds;/*!< number of currently successful
rounds */
volatile os_once::state_t
mutex_created;
/*!< Creation state of mutex member */
};
/** Number of samples of data size kept when page compression fails for
@ -1965,9 +1961,6 @@ public:
/** Statistics for query optimization. @{ */
/** Creation state of 'stats_latch'. */
volatile os_once::state_t stats_latch_created;
/** This latch protects:
dict_table_t::stat_initialized,
dict_table_t::stat_n_rows (*),
@ -1979,7 +1972,7 @@ public:
dict_table_t::indexes*::stat_n_leaf_pages.
(*) Those are not always protected for
performance reasons. */
rw_lock_t* stats_latch;
rw_lock_t stats_latch;
/** TRUE if statistics have been calculated the first time after
database startup or table creation. */
@ -2103,11 +2096,8 @@ public:
from a select. */
lock_t* autoinc_lock;
/** Creation state of autoinc_mutex member */
volatile os_once::state_t autoinc_mutex_created;
/** Mutex protecting the autoincrement counter. */
ib_mutex_t* autoinc_mutex;
ib_mutex_t autoinc_mutex;
/** Autoinc counter value to give to the next inserted row. */
ib_uint64_t autoinc;
@ -2292,87 +2282,6 @@ struct dict_foreign_add_to_referenced_table {
}
};
/** Destroy the autoinc latch of the given table.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to destroy */
inline
void
dict_table_autoinc_destroy(
dict_table_t* table)
{
if (table->autoinc_mutex_created == os_once::DONE
&& table->autoinc_mutex != NULL) {
mutex_free(table->autoinc_mutex);
UT_DELETE(table->autoinc_mutex);
}
}
/** Request for lazy creation of the autoinc latch of a given table.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose autoinc latch is to be created. */
inline
void
dict_table_autoinc_create_lazy(
dict_table_t* table)
{
table->autoinc_mutex = NULL;
table->autoinc_mutex_created = os_once::NEVER_DONE;
}
/** Request a lazy creation of dict_index_t::zip_pad::mutex.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] index index whose zip_pad mutex is to be created */
inline
void
dict_index_zip_pad_mutex_create_lazy(
dict_index_t* index)
{
index->zip_pad.mutex = NULL;
index->zip_pad.mutex_created = os_once::NEVER_DONE;
}
/** Destroy the zip_pad_mutex of the given index.
This function is only called from either single threaded environment
or from a thread that has not shared the table object with other threads.
@param[in,out] table table whose stats latch to destroy */
inline
void
dict_index_zip_pad_mutex_destroy(
dict_index_t* index)
{
if (index->zip_pad.mutex_created == os_once::DONE
&& index->zip_pad.mutex != NULL) {
mutex_free(index->zip_pad.mutex);
UT_DELETE(index->zip_pad.mutex);
}
}
/** Release the zip_pad_mutex of a given index.
@param[in,out] index index whose zip_pad_mutex is to be released */
inline
void
dict_index_zip_pad_unlock(
dict_index_t* index)
{
mutex_exit(index->zip_pad.mutex);
}
#ifdef UNIV_DEBUG
/** Check if the current thread owns the autoinc_mutex of a given table.
@param[in] table the autoinc_mutex belongs to this table
@return true, if the current thread owns the autoinc_mutex, false otherwise.*/
inline
bool
dict_table_autoinc_own(
const dict_table_t* table)
{
return(mutex_own(table->autoinc_mutex));
}
#endif /* UNIV_DEBUG */
/** Check whether the col is used in spatial index or regular index.
@param[in] col column to check
@return spatial status */

View file

@ -75,7 +75,7 @@ dict_stats_is_persistent_enabled(const dict_table_t* table)
+ dict_stats_update(DICT_STATS_RECALC_TRANSIENT) on a table that has
just been PS-enabled.
This is acceptable. Avoiding this would mean that we would have to
protect the ::stat_persistent with dict_table_stats_lock() like the
protect the ::stat_persistent with dict_table_t::stats_latch like the
other ::stat_ members which would be too big performance penalty,
especially when this function is called from
dict_stats_update_if_needed(). */
@ -178,10 +178,10 @@ dict_stats_deinit(
ut_a(table->get_ref_count() == 0);
dict_table_stats_lock(table, RW_X_LATCH);
rw_lock_x_lock(&table->stats_latch);
if (!table->stat_initialized) {
dict_table_stats_unlock(table, RW_X_LATCH);
rw_lock_x_unlock(&table->stats_latch);
return;
}
@ -223,5 +223,5 @@ dict_stats_deinit(
}
#endif /* UNIV_DEBUG_VALGRIND */
dict_table_stats_unlock(table, RW_X_LATCH);
rw_lock_x_unlock(&table->stats_latch);
}

View file

@ -1,120 +0,0 @@
/*****************************************************************************
Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved.
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
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/os0once.h
A class that aids executing a given function exactly once in a multi-threaded
environment.
Created Feb 20, 2014 Vasil Dimov
*******************************************************/
#ifndef os0once_h
#define os0once_h
#include "univ.i"
#include "ut0ut.h"
#include "my_cpu.h"
/** Execute a given function exactly once in a multi-threaded environment
or wait for the function to be executed by another thread.
Example usage:
First the user must create a control variable of type os_once::state_t and
assign it os_once::NEVER_DONE.
Then the user must pass this variable, together with a function to be
executed to os_once::do_or_wait_for_done().
Multiple threads can call os_once::do_or_wait_for_done() simultaneously with
the same (os_once::state_t) control variable. The provided function will be
called exactly once and when os_once::do_or_wait_for_done() returns then this
function has completed execution, by this or another thread. In other words
os_once::do_or_wait_for_done() will either execute the provided function or
will wait for its execution to complete if it is already called by another
thread or will do nothing if the function has already completed its execution
earlier.
This mimics pthread_once(3), but unfortunatelly pthread_once(3) does not
support passing arguments to the init_routine() function. We should use
std::call_once() when we start compiling with C++11 enabled. */
class os_once {
public:
/** Control variables' state type */
typedef ib_uint32_t state_t;
/** Not yet executed. */
static const state_t NEVER_DONE = 0;
/** Currently being executed by this or another thread. */
static const state_t IN_PROGRESS = 1;
/** Finished execution. */
static const state_t DONE = 2;
/** Call a given function or wait its execution to complete if it is
already called by another thread.
@param[in,out] state control variable
@param[in] do_func function to call
@param[in,out] do_func_arg an argument to pass to do_func(). */
static
void
do_or_wait_for_done(
volatile state_t* state,
void (*do_func)(void*),
void* do_func_arg)
{
int32 oldval = NEVER_DONE;
/* Avoid calling my_atomic_cas32() in the most common case. */
if (*state == DONE) {
return;
}
if (my_atomic_cas32((int32*) state, &oldval, IN_PROGRESS)) {
/* We are the first. Call the function. */
do_func(do_func_arg);
my_atomic_store32((int32*) state, DONE);
} else {
/* The state is not NEVER_DONE, so either it is
IN_PROGRESS (somebody is calling the function right
now or DONE (it has already been called and completed).
Wait for it to become DONE. */
for (;;) {
const state_t s = *state;
switch (s) {
case DONE:
return;
case IN_PROGRESS:
break;
case NEVER_DONE:
/* fall through */
default:
ut_error;
}
MY_RELAX_CPU();
}
}
}
};
#endif /* os0once_h */

View file

@ -30,6 +30,7 @@ Created 12/15/2009 Jimmy Yang
#define srv0mon_h
#include "univ.i"
#include "my_atomic.h"
#ifndef __STDC_LIMIT_MACROS
/* Required for FreeBSD so that INT64_MAX is defined. */

View file

@ -28,7 +28,6 @@ Created 9/5/1995 Heikki Tuuri
#define sync0types_h
#include <vector>
#include <my_atomic.h>
#include "ut0new.h"

View file

@ -1602,7 +1602,7 @@ page_zip_fields_free(
{
if (index) {
dict_table_t* table = index->table;
dict_index_zip_pad_mutex_destroy(index);
mutex_free(&index->zip_pad.mutex);
mem_heap_free(index->heap);
dict_mem_table_free(table);

View file

@ -3893,10 +3893,24 @@ row_search_idx_cond_check(
switch (result) {
case ICP_MATCH:
if (handler_rowid_filter_is_active(prebuilt->pk_filter)
&& !handler_rowid_filter_check(prebuilt->pk_filter)) {
MONITOR_INC(MONITOR_ICP_MATCH);
return(ICP_NO_MATCH);
if (handler_rowid_filter_is_active(prebuilt->pk_filter)) {
ut_ad(!prebuilt->index->is_primary());
if (prebuilt->clust_index_was_generated) {
ulint len;
dict_index_t* index = prebuilt->index;
const byte* data = rec_get_nth_field(
rec, offsets, index->n_fields - 1,
&len);
ut_ad(dict_index_get_nth_col(index,
index->n_fields - 1)
->prtype == (DATA_ROW_ID | DATA_NOT_NULL));
ut_ad(len == DATA_ROW_ID_LEN);
memcpy(prebuilt->row_id, data, DATA_ROW_ID_LEN);
}
if (!handler_rowid_filter_check(prebuilt->pk_filter)) {
MONITOR_INC(MONITOR_ICP_MATCH);
return(ICP_NO_MATCH);
}
}
/* Convert the remaining fields to MySQL format.
If this is a secondary index record, we must defer

View file

@ -152,10 +152,11 @@ static void update_log_file_size(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save);
/* The 4096 is there because of MariaDB privilege tables */
static MYSQL_SYSVAR_ULONG(block_size, maria_block_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Block size to be used for Aria index pages.", 0, 0,
MARIA_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH,
MARIA_KEY_BLOCK_LENGTH, 4096,
MARIA_MAX_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH);
static MYSQL_SYSVAR_ULONG(checkpoint_interval, checkpoint_interval,

View file

@ -916,6 +916,9 @@ public:
Item* idx_cond_push(uint keyno, class Item* idx_cond);
void cancel_pushed_idx_cond();
bool can_convert_varstring(const Field_varstring* field,
const Column_definition&new_type) const;
#if defined(TOKU_INCLUDE_ALTER_56) && TOKU_INCLUDE_ALTER_56
public:
enum_alter_inplace_result check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info *ha_alter_info);

View file

@ -465,10 +465,10 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(
result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK;
}
} else if ((ctx->handler_flags &
ALTER_COLUMN_EQUAL_PACK_LENGTH) &&
ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE) &&
only_flags(
ctx->handler_flags,
ALTER_COLUMN_EQUAL_PACK_LENGTH |
ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE |
ALTER_COLUMN_DEFAULT) &&
table->s->fields == altered_table->s->fields &&
find_changed_fields(
@ -1180,6 +1180,18 @@ static bool change_varchar_length_is_supported(Field* old_field,
return true;
}
bool ha_tokudb::can_convert_varstring(const Field_varstring* field,
const Column_definition& new_type) const {
if (new_type.length < field->field_length ||
new_type.char_length < field->char_length() ||
!new_type.compression_method() != !field->compression_method() ||
new_type.type_handler() != field->type_handler()) {
return false;
}
return true;
}
// Return true if all changed field lengths can be changed inplace, otherwise
// return false
static bool change_length_is_supported(TABLE* table,