mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge remote-tracking branch 'origin/10.4' into 10.5
This commit is contained in:
commit
1a41fc77dd
54 changed files with 1739 additions and 2891 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
179
sql/field.cc
179
sql/field.cc
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
76
sql/field.h
76
sql/field.h
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
114
sql/sql_table.cc
114
sql/sql_table.cc
|
@ -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)))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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. */
|
||||
|
|
|
@ -28,7 +28,6 @@ Created 9/5/1995 Heikki Tuuri
|
|||
#define sync0types_h
|
||||
|
||||
#include <vector>
|
||||
#include <my_atomic.h>
|
||||
|
||||
#include "ut0new.h"
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue