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

Merge branch '10.5' into 10.6

This commit is contained in:
Oleksandr Byelkin
2023-08-02 20:20:50 +02:00
42 changed files with 639 additions and 404 deletions

View File

@@ -270,17 +270,15 @@ enum ha_base_keytype {
#define HA_NOSAME 1U /* Set if not dupplicated records */ #define HA_NOSAME 1U /* Set if not dupplicated records */
#define HA_PACK_KEY 2U /* Pack string key to previous key */ #define HA_PACK_KEY 2U /* Pack string key to previous key */
#define HA_AUTO_KEY 16U #define HA_AUTO_KEY 16U /* MEMORY/MyISAM/Aria internal */
#define HA_BINARY_PACK_KEY 32U /* Packing of all keys to prev key */ #define HA_BINARY_PACK_KEY 32U /* Packing of all keys to prev key */
#define HA_FULLTEXT 128U /* For full-text search */ #define HA_FULLTEXT 128U /* For full-text search */
#define HA_UNIQUE_CHECK 256U /* Check the key for uniqueness */
#define HA_SPATIAL 1024U /* For spatial search */ #define HA_SPATIAL 1024U /* For spatial search */
#define HA_NULL_ARE_EQUAL 2048U /* NULL in key are cmp as equal */ #define HA_NULL_ARE_EQUAL 2048U /* NULL in key are cmp as equal */
#define HA_GENERATED_KEY 8192U /* Automatically generated key */ #define HA_GENERATED_KEY 8192U /* Automatically generated key */
/* The combination of the above can be used for key type comparison. */ /* The combination of the above can be used for key type comparison. */
#define HA_KEYFLAG_MASK (HA_NOSAME | HA_AUTO_KEY | \ #define HA_KEYFLAG_MASK (HA_NOSAME | HA_AUTO_KEY | HA_FULLTEXT | \
HA_FULLTEXT | HA_UNIQUE_CHECK | \
HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY) HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY)
/* /*

View File

@@ -1221,7 +1221,7 @@ drop table if exists t1,t2,t3;
# Fix modified for MariaDB: we support this syntax # Fix modified for MariaDB: we support this syntax
create table t1 (a int) transactional=0; create table t1 (a int) transactional=0;
Warnings: Warnings:
Warning 1478 Table storage engine 'MyISAM' does not support the create option 'TRANSACTIONAL=0' Warning 1911 Unknown option 'transactional'
create table t2 (a int) page_checksum=1; create table t2 (a int) page_checksum=1;
create table t3 (a int) row_format=page; create table t3 (a int) row_format=page;
drop table t1,t2,t3; drop table t1,t2,t3;
@@ -2019,7 +2019,7 @@ drop table t1;
# MDEV-18428 Memory: If transactional=0 is specified in CREATE TABLE, it is not possible to ALTER TABLE # MDEV-18428 Memory: If transactional=0 is specified in CREATE TABLE, it is not possible to ALTER TABLE
# #
create table t1 (c int(10) unsigned) engine=memory transactional=0; create table t1 (c int(10) unsigned) engine=memory transactional=0;
ERROR HY000: Table storage engine 'MEMORY' does not support the create option 'TRANSACTIONAL=0' ERROR HY000: Unknown option 'transactional'
# #
# End of 10.2 tests # End of 10.2 tests
# #

View File

@@ -1879,7 +1879,7 @@ drop table t1;
--echo # --echo #
--echo # MDEV-18428 Memory: If transactional=0 is specified in CREATE TABLE, it is not possible to ALTER TABLE --echo # MDEV-18428 Memory: If transactional=0 is specified in CREATE TABLE, it is not possible to ALTER TABLE
--echo # --echo #
--error ER_ILLEGAL_HA_CREATE_OPTION --error ER_UNKNOWN_OPTION
create table t1 (c int(10) unsigned) engine=memory transactional=0; create table t1 (c int(10) unsigned) engine=memory transactional=0;
--echo # --echo #

View File

@@ -2415,13 +2415,13 @@ DROP TABLE t1;
set statement sql_mode='' for set statement sql_mode='' for
create table t1 (n int not null, c char(1)) transactional=1; create table t1 (n int not null, c char(1)) transactional=1;
Warnings: Warnings:
Warning 1478 Table storage engine 'MyISAM' does not support the create option 'TRANSACTIONAL=1' Warning 1911 Unknown option 'transactional'
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`n` int(11) NOT NULL, `n` int(11) NOT NULL,
`c` char(1) DEFAULT NULL `c` char(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci TRANSACTIONAL=1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci /* TRANSACTIONAL=1 */
drop table t1; drop table t1;
CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam; CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam;
INSERT INTO t1 VALUES (GeomFromText("LINESTRING(0 0)")); INSERT INTO t1 VALUES (GeomFromText("LINESTRING(0 0)"));

View File

@@ -85,7 +85,7 @@ t2id id
use test; use test;
drop database `#mysql50#-`; drop database `#mysql50#-`;
SET NAMES default; SET NAMES default;
FOUND 8 /\[ERROR\] Invalid \(old\?\) table or database name/ in mysqld.1.err FOUND 10 /\[ERROR\] Invalid \(old\?\) table or database name/ in mysqld.1.err
set global query_cache_type=DEFAULT; set global query_cache_type=DEFAULT;
set global query_cache_size=@save_query_cache_size; set global query_cache_size=@save_query_cache_size;
End of 10.2 tests End of 10.2 tests

View File

@@ -1,4 +1,3 @@
drop table if exists t1;
SET @OLD_SQL_MODE=@@SQL_MODE; SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1='1v1'; create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1='1v1';
@@ -180,3 +179,103 @@ SET SQL_MODE='';
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1; create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
ERROR HY000: Unknown option 'fkey' ERROR HY000: Unknown option 'fkey'
SET @@SQL_MODE=@OLD_SQL_MODE; SET @@SQL_MODE=@OLD_SQL_MODE;
#
# End of 5.5 tests
#
#
# MDEV-31822 ALTER TABLE ENGINE=x started failing instead of producing warning on unsupported TRANSACTIONAL=1
#
create table t0 (a int) transactional=0 engine=aria;
create table t1 (a int) transactional=1 engine=aria;
create table t2 (a int) transactional=default engine=aria;
show create table t0;
Table Create Table
t0 CREATE TABLE `t0` (
`a` int(11) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 TRANSACTIONAL=0
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 TRANSACTIONAL=1
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
alter table t0 engine=myisam;
alter table t1 engine=myisam;
alter table t2 engine=myisam;
show create table t0;
Table Create Table
t0 CREATE TABLE `t0` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 /* TRANSACTIONAL=0 */
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 /* TRANSACTIONAL=1 */
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1
alter table t0 engine=myisam transactional=0;
ERROR HY000: Unknown option 'transactional'
alter table t1 engine=myisam transactional=1;
ERROR HY000: Unknown option 'transactional'
alter table t2 engine=myisam transactional=default;
ERROR HY000: Unknown option 'transactional'
set sql_mode=IGNORE_BAD_TABLE_OPTIONS;
alter table t0 engine=myisam transactional=0;
Warnings:
Warning 1911 Unknown option 'transactional'
alter table t1 engine=myisam transactional=1;
Warnings:
Warning 1911 Unknown option 'transactional'
alter table t2 engine=myisam transactional=default;
Warnings:
Warning 1911 Unknown option 'transactional'
show create table t0;
Table Create Table
t0 CREATE TABLE `t0` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci TRANSACTIONAL=0
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci TRANSACTIONAL=1
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t0,t1,t2;
create table t1 (a int) foo=bar;
Warnings:
Warning 1911 Unknown option 'foo'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `foo`=bar
set sql_mode=default;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci /* `foo`=bar */
alter table t1 engine=aria bar=foo;
ERROR HY000: Unknown option 'bar'
alter table t1 engine=aria;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 /* `foo`=bar */
drop table t1;
#
# End of 10.5 tests
#

View File

@@ -1,7 +1,3 @@
--disable_warnings
drop table if exists t1;
--enable_warnings
SET @OLD_SQL_MODE=@@SQL_MODE; SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
@@ -66,3 +62,52 @@ SET SQL_MODE='';
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1; create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
SET @@SQL_MODE=@OLD_SQL_MODE; SET @@SQL_MODE=@OLD_SQL_MODE;
--echo #
--echo # End of 5.5 tests
--echo #
--echo #
--echo # MDEV-31822 ALTER TABLE ENGINE=x started failing instead of producing warning on unsupported TRANSACTIONAL=1
--echo #
create table t0 (a int) transactional=0 engine=aria;
create table t1 (a int) transactional=1 engine=aria;
create table t2 (a int) transactional=default engine=aria;
show create table t0;
show create table t1;
show create table t2;
alter table t0 engine=myisam;
alter table t1 engine=myisam;
alter table t2 engine=myisam;
show create table t0;
show create table t1;
show create table t2;
--error ER_UNKNOWN_OPTION
alter table t0 engine=myisam transactional=0;
--error ER_UNKNOWN_OPTION
alter table t1 engine=myisam transactional=1;
--error ER_UNKNOWN_OPTION
alter table t2 engine=myisam transactional=default;
set sql_mode=IGNORE_BAD_TABLE_OPTIONS;
alter table t0 engine=myisam transactional=0;
alter table t1 engine=myisam transactional=1;
alter table t2 engine=myisam transactional=default;
show create table t0;
show create table t1;
show create table t2;
drop table t0,t1,t2;
# same behavior for other unknown options:
create table t1 (a int) foo=bar;
show create table t1;
set sql_mode=default;
show create table t1;
--error ER_UNKNOWN_OPTION
alter table t1 engine=aria bar=foo;
alter table t1 engine=aria;
show create table t1;
drop table t1;
--echo #
--echo # End of 10.5 tests
--echo #

4
mysql-test/suite/galera/r/mariadb_tzinfo_to_sql.result Normal file → Executable file
View File

@@ -11,8 +11,8 @@ CREATE TABLE time_zone_name LIKE mysql.time_zone_name;
CREATE TABLE time_zone_transition LIKE mysql.time_zone_transition; CREATE TABLE time_zone_transition LIKE mysql.time_zone_transition;
CREATE TABLE time_zone_transition_type LIKE mysql.time_zone_transition_type; CREATE TABLE time_zone_transition_type LIKE mysql.time_zone_transition_type;
CREATE TABLE time_zone_leap_second LIKE mysql.time_zone_leap_second; CREATE TABLE time_zone_leap_second LIKE mysql.time_zone_leap_second;
ALTER TABLE time_zone_name ENGINE=MyISAM TRANSACTIONAL=default; ALTER TABLE time_zone_name ENGINE=MyISAM;
ALTER TABLE time_zone_transition_type ENGINE=MyISAM TRANSACTIONAL=default; ALTER TABLE time_zone_transition_type ENGINE=MyISAM;
SET @save_wsrep_mode=@@WSREP_MODE; SET @save_wsrep_mode=@@WSREP_MODE;
# #
# Run on zoneinfo directory --skip-write-binlog # Run on zoneinfo directory --skip-write-binlog

4
mysql-test/suite/galera/t/mariadb_tzinfo_to_sql.test Normal file → Executable file
View File

@@ -20,8 +20,8 @@ CREATE TABLE time_zone_name LIKE mysql.time_zone_name;
CREATE TABLE time_zone_transition LIKE mysql.time_zone_transition; CREATE TABLE time_zone_transition LIKE mysql.time_zone_transition;
CREATE TABLE time_zone_transition_type LIKE mysql.time_zone_transition_type; CREATE TABLE time_zone_transition_type LIKE mysql.time_zone_transition_type;
CREATE TABLE time_zone_leap_second LIKE mysql.time_zone_leap_second; CREATE TABLE time_zone_leap_second LIKE mysql.time_zone_leap_second;
ALTER TABLE time_zone_name ENGINE=MyISAM TRANSACTIONAL=default; ALTER TABLE time_zone_name ENGINE=MyISAM;
ALTER TABLE time_zone_transition_type ENGINE=MyISAM TRANSACTIONAL=default; ALTER TABLE time_zone_transition_type ENGINE=MyISAM;
SET @save_wsrep_mode=@@WSREP_MODE; SET @save_wsrep_mode=@@WSREP_MODE;

0
mysql-test/suite/galera/t/mysql_tzinfo_to_sql.test Normal file → Executable file
View File

View File

@@ -1077,7 +1077,7 @@ KEY `a_2` (`a`,`vbidxcol`),
KEY `vbidxcol_2` (`vbidxcol`,`d`), KEY `vbidxcol_2` (`vbidxcol`,`d`),
CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL
) ENGINE=InnoDB; ) ENGINE=InnoDB;
DROP TABLE ibstd_16_fk; ERROR HY000: Function or expression 'a' cannot be used in the GENERATED ALWAYS AS clause of `vadcol`
CREATE TABLE `ibstd_16_fk` ( CREATE TABLE `ibstd_16_fk` (
`a` int(11) DEFAULT NULL, `a` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL, `d` int(11) DEFAULT NULL,

View File

@@ -1021,7 +1021,7 @@ CREATE TABLE `ibstd_16` (
) ENGINE=INNODB; ) ENGINE=INNODB;
# Block when FK constraint on base column of stored column. # Block when FK constraint on base column of stored column.
#--error ER_CANNOT_ADD_FOREIGN --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
CREATE TABLE `ibstd_16_fk` ( CREATE TABLE `ibstd_16_fk` (
`a` int(11) DEFAULT NULL, `a` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL, `d` int(11) DEFAULT NULL,
@@ -1040,7 +1040,6 @@ CREATE TABLE `ibstd_16_fk` (
KEY `vbidxcol_2` (`vbidxcol`,`d`), KEY `vbidxcol_2` (`vbidxcol`,`d`),
CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL
) ENGINE=InnoDB; ) ENGINE=InnoDB;
DROP TABLE ibstd_16_fk;
# Take out "KEY `a_2` (`a`,`vbidxcol`)", this should then be successful # Take out "KEY `a_2` (`a`,`vbidxcol`)", this should then be successful
CREATE TABLE `ibstd_16_fk` ( CREATE TABLE `ibstd_16_fk` (

View File

@@ -1,19 +1,21 @@
# Create statement with FK on base column of stored column
create table t1(f1 int, f2 int as(f1) stored,
foreign key(f1) references t2(f1) on delete cascade)engine=innodb;
ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed")
# adding new stored column during alter table copy operation.
create table t1(f1 int primary key) engine=innodb; create table t1(f1 int primary key) engine=innodb;
# Create statement with FK on base column of stored column
create table t2(f1 int not null, f2 int as (f1) stored,
foreign key(f1) references t1(f1) on update cascade)engine=innodb;
ERROR HY000: Function or expression 'f1' cannot be used in the GENERATED ALWAYS AS clause of `f2`
create table t2(f1 int not null, f2 int as (f1) virtual, f3 int as (f2) stored,
foreign key(f1) references t1(f1) on update cascade)engine=innodb;
ERROR HY000: Function or expression 'f2' cannot be used in the GENERATED ALWAYS AS clause of `f3`
# adding new stored column during alter table copy operation.
create table t2(f1 int not null, f2 int as (f1) virtual, create table t2(f1 int not null, f2 int as (f1) virtual,
foreign key(f1) references t1(f1) on update cascade)engine=innodb; foreign key(f1) references t1(f1) on update cascade)engine=innodb;
alter table t2 add column f3 int as (f1) stored, add column f4 int as (f1) virtual; alter table t2 add column f3 int as (f1) stored, add column f4 int as (f1) virtual;
ERROR HY000: Function or expression 'f1' cannot be used in the GENERATED ALWAYS AS clause of `f3`
show create table t2; show create table t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`f1` int(11) NOT NULL, `f1` int(11) NOT NULL,
`f2` int(11) GENERATED ALWAYS AS (`f1`) VIRTUAL, `f2` int(11) GENERATED ALWAYS AS (`f1`) VIRTUAL,
`f3` int(11) GENERATED ALWAYS AS (`f1`) STORED,
`f4` int(11) GENERATED ALWAYS AS (`f1`) VIRTUAL,
KEY `f1` (`f1`), KEY `f1` (`f1`),
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON UPDATE CASCADE CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
@@ -21,26 +23,25 @@ drop table t2;
# adding foreign key constraint for base columns during alter copy. # adding foreign key constraint for base columns during alter copy.
create table t2(f1 int not null, f2 int as (f1) stored) engine=innodb; create table t2(f1 int not null, f2 int as (f1) stored) engine=innodb;
alter table t2 add foreign key(f1) references t1(f1) on update cascade, algorithm=copy; alter table t2 add foreign key(f1) references t1(f1) on update cascade, algorithm=copy;
ERROR HY000: Function or expression 'f1' cannot be used in the GENERATED ALWAYS AS clause of `f2`
show create table t2; show create table t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`f1` int(11) NOT NULL, `f1` int(11) NOT NULL,
`f2` int(11) GENERATED ALWAYS AS (`f1`) STORED, `f2` int(11) GENERATED ALWAYS AS (`f1`) STORED
KEY `f1` (`f1`),
CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
drop table t2; drop table t2;
# adding foreign key constraint for base columns during online alter. # adding foreign key constraint for base columns during online alter.
create table t2(f1 int not null, f2 int as (f1) stored) engine=innodb; create table t2(f1 int not null, f2 int as (f1) stored) engine=innodb;
set foreign_key_checks = 0; set foreign_key_checks = 0;
alter table t2 add foreign key(f1) references t1(f1) on update cascade, algorithm=inplace; alter table t2 add foreign key(f1) references t1(f1) on update cascade, algorithm=inplace;
ERROR 0A000: Cannot add foreign key on the base column of stored column ERROR HY000: Function or expression 'f1' cannot be used in the GENERATED ALWAYS AS clause of `f2`
drop table t2; drop table t2;
# adding stored column via online alter. # adding stored column via online alter.
create table t2(f1 int not null, create table t2(f1 int not null,
foreign key(f1) references t1(f1) on update cascade)engine=innodb; foreign key(f1) references t1(f1) on update cascade)engine=innodb;
alter table t2 add column f2 int as (f1) stored, algorithm=inplace; alter table t2 add column f2 int as (f1) stored, algorithm=inplace;
ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY ERROR HY000: Function or expression 'f1' cannot be used in the GENERATED ALWAYS AS clause of `f2`
drop table t2, t1; drop table t2, t1;
# #
# BUG#26731689 FK ON TABLE WITH GENERATED COLS: ASSERTION POS < N_DEF # BUG#26731689 FK ON TABLE WITH GENERATED COLS: ASSERTION POS < N_DEF

View File

@@ -1,24 +1,28 @@
--source include/have_innodb.inc --source include/have_innodb.inc
create table t1(f1 int primary key) engine=innodb;
--echo # Create statement with FK on base column of stored column --echo # Create statement with FK on base column of stored column
--error ER_CANT_CREATE_TABLE --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1(f1 int, f2 int as(f1) stored, create table t2(f1 int not null, f2 int as (f1) stored,
foreign key(f1) references t2(f1) on delete cascade)engine=innodb; foreign key(f1) references t1(f1) on update cascade)engine=innodb;
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t2(f1 int not null, f2 int as (f1) virtual, f3 int as (f2) stored,
foreign key(f1) references t1(f1) on update cascade)engine=innodb;
--echo # adding new stored column during alter table copy operation. --echo # adding new stored column during alter table copy operation.
create table t1(f1 int primary key) engine=innodb;
create table t2(f1 int not null, f2 int as (f1) virtual, create table t2(f1 int not null, f2 int as (f1) virtual,
foreign key(f1) references t1(f1) on update cascade)engine=innodb; foreign key(f1) references t1(f1) on update cascade)engine=innodb;
# MySQL 5.7 would refuse this --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
#--error ER_ERROR_ON_RENAME
alter table t2 add column f3 int as (f1) stored, add column f4 int as (f1) virtual; alter table t2 add column f3 int as (f1) stored, add column f4 int as (f1) virtual;
show create table t2; show create table t2;
drop table t2; drop table t2;
--echo # adding foreign key constraint for base columns during alter copy. --echo # adding foreign key constraint for base columns during alter copy.
create table t2(f1 int not null, f2 int as (f1) stored) engine=innodb; create table t2(f1 int not null, f2 int as (f1) stored) engine=innodb;
# MySQL 5.7 would refuse this --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
alter table t2 add foreign key(f1) references t1(f1) on update cascade, algorithm=copy; alter table t2 add foreign key(f1) references t1(f1) on update cascade, algorithm=copy;
show create table t2; show create table t2;
drop table t2; drop table t2;
@@ -26,14 +30,14 @@ drop table t2;
--echo # adding foreign key constraint for base columns during online alter. --echo # adding foreign key constraint for base columns during online alter.
create table t2(f1 int not null, f2 int as (f1) stored) engine=innodb; create table t2(f1 int not null, f2 int as (f1) stored) engine=innodb;
set foreign_key_checks = 0; set foreign_key_checks = 0;
--error 138 --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
alter table t2 add foreign key(f1) references t1(f1) on update cascade, algorithm=inplace; alter table t2 add foreign key(f1) references t1(f1) on update cascade, algorithm=inplace;
drop table t2; drop table t2;
--echo # adding stored column via online alter. --echo # adding stored column via online alter.
create table t2(f1 int not null, create table t2(f1 int not null,
foreign key(f1) references t1(f1) on update cascade)engine=innodb; foreign key(f1) references t1(f1) on update cascade)engine=innodb;
--error ER_ALTER_OPERATION_NOT_SUPPORTED --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
alter table t2 add column f2 int as (f1) stored, algorithm=inplace; alter table t2 add column f2 int as (f1) stored, algorithm=inplace;
drop table t2, t1; drop table t2, t1;

View File

@@ -521,8 +521,6 @@ t1 CREATE TABLE `t1` (
drop table t1; drop table t1;
create table t1 (n int not null, c char(1)) engine=aria transactional=1; create table t1 (n int not null, c char(1)) engine=aria transactional=1;
alter table t1 engine=myisam; alter table t1 engine=myisam;
Warnings:
Warning 1478 Table storage engine 'MyISAM' does not support the create option 'TRANSACTIONAL=1'
alter table t1 engine=aria; alter table t1 engine=aria;
show create table t1; show create table t1;
Table Create Table Table Create Table
@@ -533,7 +531,7 @@ t1 CREATE TABLE `t1` (
drop table t1; drop table t1;
create table t1 (n int not null, c char(1)) engine=myisam transactional=1; create table t1 (n int not null, c char(1)) engine=myisam transactional=1;
Warnings: Warnings:
Warning 1478 Table storage engine 'MyISAM' does not support the create option 'TRANSACTIONAL=1' Warning 1911 Unknown option 'transactional'
alter table t1 engine=aria; alter table t1 engine=aria;
show create table t1; show create table t1;
Table Create Table Table Create Table

View File

@@ -1,9 +1,4 @@
set @old_sql_mode= @@sql_mode;
set @@sql_mode= '';
alter table mysql.plugin engine=myisam; alter table mysql.plugin engine=myisam;
Warnings:
Warning 1478 Table storage engine 'MyISAM' does not support the create option 'TRANSACTIONAL=1'
set @@sql_mode= @old_sql_mode;
set @old_dbug=@@debug_dbug; set @old_dbug=@@debug_dbug;
call mtr.add_suppression("Index for table.*mysql.plugin.MYI"); call mtr.add_suppression("Index for table.*mysql.plugin.MYI");
call mtr.add_suppression("Index for table 'plugin' is corrupt; try to repair it"); call mtr.add_suppression("Index for table 'plugin' is corrupt; try to repair it");

View File

@@ -5,10 +5,7 @@ if (!$ADT_NULL_SO) {
skip No NULL_AUDIT plugin; skip No NULL_AUDIT plugin;
} }
set @old_sql_mode= @@sql_mode;
set @@sql_mode= '';
alter table mysql.plugin engine=myisam; alter table mysql.plugin engine=myisam;
set @@sql_mode= @old_sql_mode;
set @old_dbug=@@debug_dbug; set @old_dbug=@@debug_dbug;
call mtr.add_suppression("Index for table.*mysql.plugin.MYI"); call mtr.add_suppression("Index for table.*mysql.plugin.MYI");

View File

@@ -10,3 +10,73 @@ select * from t2;
id id
drop table t2; drop table t2;
drop table t1; drop table t1;
#
# End of 10.2 tests
#
#
# MDEV-18114 Foreign Key Constraint actions don't affect Virtual Column
#
create table t1 (id int primary key);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update cascade);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on delete set null);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update set null);
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update cascade);
ERROR HY000: Function or expression 'id' cannot be used in the GENERATED ALWAYS AS clause of `id2`
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on delete set null);
ERROR HY000: Function or expression 'id' cannot be used in the GENERATED ALWAYS AS clause of `id2`
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update set null);
ERROR HY000: Function or expression 'id' cannot be used in the GENERATED ALWAYS AS clause of `id2`
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update cascade);
ERROR HY000: Function or expression 'id2' cannot be used in the GENERATED ALWAYS AS clause of `id3`
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on delete set null);
ERROR HY000: Function or expression 'id2' cannot be used in the GENERATED ALWAYS AS clause of `id3`
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update set null);
ERROR HY000: Function or expression 'id2' cannot be used in the GENERATED ALWAYS AS clause of `id3`
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update cascade);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on delete set null);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update set null);
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update cascade);
ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `id2`
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on delete set null);
ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `id2`
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update set null);
ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `id2`
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update cascade);
ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `CONSTRAINT_1`
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on delete set null);
ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `CONSTRAINT_1`
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update set null);
ERROR HY000: Function or expression 'id' cannot be used in the CHECK clause of `CONSTRAINT_1`
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update cascade);
ERROR HY000: Function or expression 'id2' cannot be used in the CHECK clause of `CONSTRAINT_1`
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on delete set null);
ERROR HY000: Function or expression 'id2' cannot be used in the CHECK clause of `CONSTRAINT_1`
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update set null);
ERROR HY000: Function or expression 'id2' cannot be used in the CHECK clause of `CONSTRAINT_1`
drop table if exists t2, t1;
Warnings:
Note 1051 Unknown table 'test.t2'
#
# End of 10.5 tests
#

View File

@@ -54,22 +54,22 @@ set session sql_mode=@OLD_SQL_MODE;
# #
create table t2 (x int); create table t2 (x int);
create table t1 (x int, y int generated always as (t2.x)); create table t1 (x int, y int generated always as (t2.x));
ERROR 42S22: Unknown column '`t2`.`x`' in 'GENERATED ALWAYS' ERROR HY000: Function or expression 't2.x' cannot be used in the GENERATED ALWAYS AS clause of `y`
create table t1 (x int, y int check (y > t2.x)); create table t1 (x int, y int check (y > t2.x));
ERROR 42S22: Unknown column '`t2`.`x`' in 'CHECK' ERROR HY000: Function or expression 't2.x' cannot be used in the CHECK clause of `y`
create table t1 (x int, y int default t2.x); create table t1 (x int, y int default t2.x);
ERROR 42S22: Unknown column '`t2`.`x`' in 'DEFAULT' ERROR HY000: Function or expression 't2.x' cannot be used in the DEFAULT clause of `y`
create table t1 (x int, check (t2.x > 0)); create table t1 (x int, check (t2.x > 0));
ERROR 42S22: Unknown column '`t2`.`x`' in 'CHECK' ERROR HY000: Function or expression 't2.x' cannot be used in the CHECK clause of `CONSTRAINT_1`
create table t1 (x int); create table t1 (x int);
alter table t1 add column y int generated always as (t2.x); alter table t1 add column y int generated always as (t2.x);
ERROR 42S22: Unknown column '`t2`.`x`' in 'GENERATED ALWAYS' ERROR HY000: Function or expression 't2.x' cannot be used in the GENERATED ALWAYS AS clause of `y`
alter table t1 add column y int check (z > t2.x); alter table t1 add column y int check (z > t2.x);
ERROR 42S22: Unknown column '`t2`.`x`' in 'CHECK' ERROR HY000: Function or expression 't2.x' cannot be used in the CHECK clause of `y`
alter table t1 add column y int default t2.x; alter table t1 add column y int default t2.x;
ERROR 42S22: Unknown column '`t2`.`x`' in 'DEFAULT' ERROR HY000: Function or expression 't2.x' cannot be used in the DEFAULT clause of `y`
alter table t1 add constraint check (t2.x > 0); alter table t1 add constraint check (t2.x > 0);
ERROR 42S22: Unknown column '`t2`.`x`' in 'CHECK' ERROR HY000: Function or expression 't2.x' cannot be used in the CHECK clause of `CONSTRAINT_1`
create or replace table t1 (x int, y int generated always as (t1.x)); create or replace table t1 (x int, y int generated always as (t1.x));
create or replace table t1 (x int, y int check (y > t1.x)); create or replace table t1 (x int, y int check (y > t1.x));
create or replace table t1 (x int, y int default t1.x); create or replace table t1 (x int, y int default t1.x);
@@ -80,13 +80,13 @@ create or replace table t1 (x int, y int default test.t1.x);
create or replace table t1 (x int, check (test.t1.x > 0)); create or replace table t1 (x int, check (test.t1.x > 0));
drop tables t1, t2; drop tables t1, t2;
create table t1 (x int, y int generated always as (test2.t1.x)); create table t1 (x int, y int generated always as (test2.t1.x));
ERROR 42S22: Unknown column '`test2`.`t1`.`x`' in 'GENERATED ALWAYS' ERROR HY000: Function or expression 'test2.t1.x' cannot be used in the GENERATED ALWAYS AS clause of `y`
create table t1 (x int, y int check (y > test2.t1.x)); create table t1 (x int, y int check (y > test2.t1.x));
ERROR 42S22: Unknown column '`test2`.`t1`.`x`' in 'CHECK' ERROR HY000: Function or expression 'test2.t1.x' cannot be used in the CHECK clause of `y`
create table t1 (x int, y int default test2.t1.x); create table t1 (x int, y int default test2.t1.x);
ERROR 42S22: Unknown column '`test2`.`t1`.`x`' in 'DEFAULT' ERROR HY000: Function or expression 'test2.t1.x' cannot be used in the DEFAULT clause of `y`
create table t1 (x int, check (test2.t1.x > 0)); create table t1 (x int, check (test2.t1.x > 0));
ERROR 42S22: Unknown column '`test2`.`t1`.`x`' in 'CHECK' ERROR HY000: Function or expression 'test2.t1.x' cannot be used in the CHECK clause of `CONSTRAINT_1`
# #
# MDEV-25672 table alias from previous statement interferes later commands # MDEV-25672 table alias from previous statement interferes later commands
# #

View File

@@ -14,3 +14,92 @@ select * from t1;
select * from t2; select * from t2;
drop table t2; drop table t2;
drop table t1; drop table t1;
--echo #
--echo # End of 10.2 tests
--echo #
--echo #
--echo # MDEV-18114 Foreign Key Constraint actions don't affect Virtual Column
--echo #
create table t1 (id int primary key);
# note that RESTRICT, NO ACTION, and DELETE CASCADE are fine
# because they don't change values of referenced columns
# virtual indexed
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update cascade);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on delete set null);
create or replace table t2 (id int, id2 int as (id) virtual, key(id2), foreign key (id) references t1 (id) on update set null);
# stored
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on delete cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on delete set null);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) stored, foreign key (id) references t1 (id) on update set null);
# stored indirect
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on delete cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on delete set null);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) virtual, id3 int as (id2) stored, foreign key (id) references t1 (id) on update set null);
# default
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on delete cascade);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update cascade);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on delete set null);
create or replace table t2 (id int, id2 int default (id), foreign key (id) references t1 (id) on update set null);
# field check
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on delete cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on delete set null);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int check (id), foreign key (id) references t1 (id) on update set null);
# table check
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on delete cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on delete set null);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int, check (id), foreign key (id) references t1 (id) on update set null);
# table check indirect
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update restrict);
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update no action);
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on delete cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update cascade);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on delete set null);
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t2 (id int, id2 int as (id) virtual, check (id2), foreign key (id) references t1 (id) on update set null);
drop table if exists t2, t1;
--echo #
--echo # End of 10.5 tests
--echo #

View File

@@ -29,23 +29,23 @@ set session sql_mode=@OLD_SQL_MODE;
--echo # --echo #
create table t2 (x int); create table t2 (x int);
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1 (x int, y int generated always as (t2.x)); create table t1 (x int, y int generated always as (t2.x));
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1 (x int, y int check (y > t2.x)); create table t1 (x int, y int check (y > t2.x));
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1 (x int, y int default t2.x); create table t1 (x int, y int default t2.x);
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1 (x int, check (t2.x > 0)); create table t1 (x int, check (t2.x > 0));
create table t1 (x int); create table t1 (x int);
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
alter table t1 add column y int generated always as (t2.x); alter table t1 add column y int generated always as (t2.x);
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
alter table t1 add column y int check (z > t2.x); alter table t1 add column y int check (z > t2.x);
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
alter table t1 add column y int default t2.x; alter table t1 add column y int default t2.x;
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
alter table t1 add constraint check (t2.x > 0); alter table t1 add constraint check (t2.x > 0);
create or replace table t1 (x int, y int generated always as (t1.x)); create or replace table t1 (x int, y int generated always as (t1.x));
@@ -60,13 +60,13 @@ create or replace table t1 (x int, check (test.t1.x > 0));
drop tables t1, t2; drop tables t1, t2;
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1 (x int, y int generated always as (test2.t1.x)); create table t1 (x int, y int generated always as (test2.t1.x));
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1 (x int, y int check (y > test2.t1.x)); create table t1 (x int, y int check (y > test2.t1.x));
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1 (x int, y int default test2.t1.x); create table t1 (x int, y int default test2.t1.x);
--error ER_BAD_FIELD_ERROR --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t1 (x int, check (test2.t1.x > 0)); create table t1 (x int, check (test2.t1.x > 0));
--echo # --echo #

View File

@@ -5235,7 +5235,7 @@ class Column_definition: public Sql_alloc,
const Type_handler *field_type() const; // Prevent using this const Type_handler *field_type() const; // Prevent using this
Compression_method *compression_method_ptr; Compression_method *compression_method_ptr;
public: public:
LEX_CSTRING field_name; Lex_ident field_name;
LEX_CSTRING comment; // Comment for field LEX_CSTRING comment; // Comment for field
enum enum_column_versioning enum enum_column_versioning
{ {

View File

@@ -110,7 +110,7 @@ static handlerton *installed_htons[128];
#define BITMAP_STACKBUF_SIZE (128/8) #define BITMAP_STACKBUF_SIZE (128/8)
KEY_CREATE_INFO default_key_create_info= KEY_CREATE_INFO default_key_create_info=
{ HA_KEY_ALG_UNDEF, 0, 0, {NullS, 0}, {NullS, 0}, true, false }; { HA_KEY_ALG_UNDEF, 0, 0, {NullS, 0}, {NullS, 0}, false };
/* number of entries in handlertons[] */ /* number of entries in handlertons[] */
ulong total_ha= 0; ulong total_ha= 0;

View File

@@ -2702,12 +2702,6 @@ typedef struct st_key_create_information
uint flags; /* HA_USE.. flags */ uint flags; /* HA_USE.. flags */
LEX_CSTRING parser_name; LEX_CSTRING parser_name;
LEX_CSTRING comment; LEX_CSTRING comment;
/**
A flag to determine if we will check for duplicate indexes.
This typically means that the key information was specified
directly by the user (set by the parser).
*/
bool check_for_duplicate_indexes;
bool is_ignored; bool is_ignored;
} KEY_CREATE_INFO; } KEY_CREATE_INFO;
@@ -3717,7 +3711,7 @@ public:
- How things are tracked in trx and in add_changed_table(). - How things are tracked in trx and in add_changed_table().
- If we can combine several statements under one commit in the binary log. - If we can combine several statements under one commit in the binary log.
*/ */
bool has_transactions() bool has_transactions() const
{ {
return ((ha_table_flags() & (HA_NO_TRANSACTIONS | HA_PERSISTENT_TABLE)) return ((ha_table_flags() & (HA_NO_TRANSACTIONS | HA_PERSISTENT_TABLE))
== 0); == 0);
@@ -3728,24 +3722,33 @@ public:
we don't have to write failed statements to the log as they can be we don't have to write failed statements to the log as they can be
rolled back. rolled back.
*/ */
bool has_transactions_and_rollback() bool has_transactions_and_rollback() const
{ {
return has_transactions() && has_rollback(); return has_transactions() && has_rollback();
} }
/* /*
True if the underlaying table support transactions and rollback True if the underlaying table support transactions and rollback
*/ */
bool has_transaction_manager() bool has_transaction_manager() const
{ {
return ((ha_table_flags() & HA_NO_TRANSACTIONS) == 0 && has_rollback()); return ((ha_table_flags() & HA_NO_TRANSACTIONS) == 0 && has_rollback());
} }
/*
True if the underlaying table support TRANSACTIONAL table option
*/
bool has_transactional_option() const
{
extern handlerton *maria_hton;
return partition_ht() == maria_hton || has_transaction_manager();
}
/* /*
True if table has rollback. Used to check if an update on the table True if table has rollback. Used to check if an update on the table
can be killed fast. can be killed fast.
*/ */
bool has_rollback() bool has_rollback() const
{ {
return ((ht->flags & HTON_NO_ROLLBACK) == 0); return ((ht->flags & HTON_NO_ROLLBACK) == 0);
} }

View File

@@ -1521,7 +1521,7 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
#ifndef DBUG_OFF #ifndef DBUG_OFF
static inline static inline
void mark_unsupported_func(const char *where, const char *processor_name) void dbug_mark_unsupported_func(const char *where, const char *processor_name)
{ {
char buff[64]; char buff[64];
my_snprintf(buff, sizeof(buff), "%s::%s", where ? where: "", processor_name); my_snprintf(buff, sizeof(buff), "%s::%s", where ? where: "", processor_name);
@@ -1531,7 +1531,7 @@ void mark_unsupported_func(const char *where, const char *processor_name)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#else #else
#define mark_unsupported_func(X,Y) {} #define dbug_mark_unsupported_func(X,Y) {}
#endif #endif
bool mark_unsupported_function(const char *where, void *store, uint result) bool mark_unsupported_function(const char *where, void *store, uint result)
@@ -1539,7 +1539,7 @@ bool mark_unsupported_function(const char *where, void *store, uint result)
Item::vcol_func_processor_result *res= Item::vcol_func_processor_result *res=
(Item::vcol_func_processor_result*) store; (Item::vcol_func_processor_result*) store;
uint old_errors= res->errors; uint old_errors= res->errors;
mark_unsupported_func(where, "check_vcol_func_processor"); dbug_mark_unsupported_func(where, "check_vcol_func_processor");
res->errors|= result; /* Store type of expression */ res->errors|= result; /* Store type of expression */
/* Store the name to the highest violation (normally VCOL_IMPOSSIBLE) */ /* Store the name to the highest violation (normally VCOL_IMPOSSIBLE) */
if (result > old_errors) if (result > old_errors)
@@ -1560,33 +1560,19 @@ bool mark_unsupported_function(const char *w1, const char *w2,
bool Item_field::check_vcol_func_processor(void *arg) bool Item_field::check_vcol_func_processor(void *arg)
{ {
uint r= VCOL_FIELD_REF;
context= 0; context= 0;
vcol_func_processor_result *res= (vcol_func_processor_result *) arg; vcol_func_processor_result *res= (vcol_func_processor_result *) arg;
if (res && res->alter_info) if (res && res->alter_info)
r|= res->alter_info->check_vcol_field(this);
else if (field)
{ {
for (Key &k: res->alter_info->key_list) if (field->unireg_check == Field::NEXT_NUMBER)
{ r|= VCOL_AUTO_INC;
if (k.type != Key::FOREIGN_KEY) if (field->vcol_info &&
continue; field->vcol_info->flags & (VCOL_NOT_STRICTLY_DETERMINISTIC | VCOL_AUTO_INC))
Foreign_key *fk= (Foreign_key*) &k; r|= VCOL_NON_DETERMINISTIC;
if (fk->update_opt != FK_OPTION_CASCADE)
continue;
for (Key_part_spec& kp: fk->columns)
{
if (!lex_string_cmp(system_charset_info, &kp.field_name, &field_name))
{
return mark_unsupported_function(field_name.str, arg, VCOL_IMPOSSIBLE);
}
}
}
} }
uint r= VCOL_FIELD_REF;
if (field && field->unireg_check == Field::NEXT_NUMBER)
r|= VCOL_AUTO_INC;
if (field && field->vcol_info &&
field->vcol_info->flags & (VCOL_NOT_STRICTLY_DETERMINISTIC | VCOL_AUTO_INC))
r|= VCOL_NON_DETERMINISTIC;
return mark_unsupported_function(field_name.str, arg, r); return mark_unsupported_function(field_name.str, arg, r);
} }

View File

@@ -2207,15 +2207,6 @@ public:
return 0; return 0;
} }
/**
Check db/table_name if they defined in item and match arg values
@param arg Pointer to Check_table_name_prm structure
@retval true Match failed
@retval false Match succeeded
*/
virtual bool check_table_name_processor(void *arg) { return false; }
/* /*
TRUE if the expression depends only on the table indicated by tab_map TRUE if the expression depends only on the table indicated by tab_map
or can be converted to such an exression using equalities. or can be converted to such an exression using equalities.
@@ -2416,15 +2407,6 @@ public:
bool collect; bool collect;
}; };
struct Check_table_name_prm
{
LEX_CSTRING db;
LEX_CSTRING table_name;
String field;
Check_table_name_prm(LEX_CSTRING _db, LEX_CSTRING _table_name) :
db(_db), table_name(_table_name) {}
};
/* /*
For SP local variable returns pointer to Item representing its For SP local variable returns pointer to Item representing its
current value and pointer to current Item otherwise. current value and pointer to current Item otherwise.
@@ -3480,17 +3462,17 @@ protected:
updated during fix_fields() to values from Field object and life-time updated during fix_fields() to values from Field object and life-time
of those is shorter than life-time of Item_field. of those is shorter than life-time of Item_field.
*/ */
LEX_CSTRING orig_db_name; Lex_table_name orig_db_name;
LEX_CSTRING orig_table_name; Lex_table_name orig_table_name;
LEX_CSTRING orig_field_name; Lex_ident orig_field_name;
void undeclared_spvar_error() const; void undeclared_spvar_error() const;
public: public:
Name_resolution_context *context; Name_resolution_context *context;
LEX_CSTRING db_name; Lex_table_name db_name;
LEX_CSTRING table_name; Lex_table_name table_name;
LEX_CSTRING field_name; Lex_ident field_name;
/* /*
Cached pointer to table which contains this field, used for the same reason Cached pointer to table which contains this field, used for the same reason
by prep. stmt. too in case then we have not-fully qualified field. by prep. stmt. too in case then we have not-fully qualified field.
@@ -3741,24 +3723,6 @@ public:
} }
return 0; return 0;
} }
bool check_table_name_processor(void *arg) override
{
Check_table_name_prm &p= *static_cast<Check_table_name_prm*>(arg);
if (!field && p.table_name.length && table_name.length)
{
DBUG_ASSERT(p.db.length);
if ((db_name.length &&
my_strcasecmp(table_alias_charset, p.db.str, db_name.str)) ||
my_strcasecmp(table_alias_charset, p.table_name.str, table_name.str))
{
print(&p.field, (enum_query_type) (QT_ITEM_ORIGINAL_FUNC_NULLIF |
QT_NO_DATA_EXPANSION |
QT_TO_SYSTEM_CHARSET));
return true;
}
}
return false;
}
void cleanup() override; void cleanup() override;
Item_equal *get_item_equal() override { return item_equal; } Item_equal *get_item_equal() override { return item_equal; }
void set_item_equal(Item_equal *item_eq) override { item_equal= item_eq; } void set_item_equal(Item_equal *item_eq) override { item_equal= item_eq; }

View File

@@ -253,6 +253,43 @@ Alter_info::algorithm(const THD *thd) const
} }
uint Alter_info::check_vcol_field(Item_field *item) const
{
if (!item->field &&
((item->db_name.length && !db.streq(item->db_name)) ||
(item->table_name.length && !table_name.streq(item->table_name))))
{
char *ptr= (char*)current_thd->alloc(item->db_name.length +
item->table_name.length +
item->field_name.length + 3);
strxmov(ptr, safe_str(item->db_name.str), item->db_name.length ? "." : "",
item->table_name.str, ".", item->field_name.str, NullS);
item->field_name.str= ptr;
return VCOL_IMPOSSIBLE;
}
for (Key &k: key_list)
{
if (k.type != Key::FOREIGN_KEY)
continue;
Foreign_key *fk= (Foreign_key*) &k;
if (fk->update_opt < FK_OPTION_CASCADE &&
fk->delete_opt < FK_OPTION_SET_NULL)
continue;
for (Key_part_spec& kp: fk->columns)
{
if (item->field_name.streq(kp.field_name))
return VCOL_NON_DETERMINISTIC;
}
}
for (Create_field &cf: create_list)
{
if (item->field_name.streq(cf.field_name))
return cf.vcol_info ? cf.vcol_info->flags : 0;
}
return 0;
}
Alter_table_ctx::Alter_table_ctx() Alter_table_ctx::Alter_table_ctx()
: db(null_clex_str), table_name(null_clex_str), alias(null_clex_str), : db(null_clex_str), table_name(null_clex_str), alias(null_clex_str),
new_db(null_clex_str), new_name(null_clex_str), new_alias(null_clex_str) new_db(null_clex_str), new_name(null_clex_str), new_alias(null_clex_str)

View File

@@ -85,6 +85,7 @@ public:
ALTER_TABLE_LOCK_EXCLUSIVE ALTER_TABLE_LOCK_EXCLUSIVE
}; };
Lex_table_name db, table_name;
// Columns and keys to be dropped. // Columns and keys to be dropped.
List<Alter_drop> drop_list; List<Alter_drop> drop_list;
@@ -234,6 +235,8 @@ public:
*/ */
enum_alter_table_algorithm algorithm(const THD *thd) const; enum_alter_table_algorithm algorithm(const THD *thd) const;
uint check_vcol_field(Item_field *f) const;
private: private:
Alter_info &operator=(const Alter_info &rhs); // not implemented Alter_info &operator=(const Alter_info &rhs); // not implemented
Alter_info(const Alter_info &rhs); // not implemented Alter_info(const Alter_info &rhs); // not implemented

View File

@@ -177,7 +177,7 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root)
name(rhs.name), name(rhs.name),
option_list(rhs.option_list), option_list(rhs.option_list),
generated(rhs.generated), invisible(false), generated(rhs.generated), invisible(false),
without_overlaps(rhs.without_overlaps), period(rhs.period) without_overlaps(rhs.without_overlaps), old(rhs.old), period(rhs.period)
{ {
list_copy_and_replace_each_value(columns, mem_root); list_copy_and_replace_each_value(columns, mem_root);
} }
@@ -213,11 +213,11 @@ Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
We only compare field names We only compare field names
RETURN RETURN
0 Generated key is a prefix of other key true Generated key is a prefix of other key
1 Not equal false Not a prefix
*/ */
bool foreign_key_prefix(Key *a, Key *b) bool is_foreign_key_prefix(Key *a, Key *b)
{ {
/* Ensure that 'a' is the generated key */ /* Ensure that 'a' is the generated key */
if (a->generated) if (a->generated)
@@ -228,13 +228,13 @@ bool foreign_key_prefix(Key *a, Key *b)
else else
{ {
if (!b->generated) if (!b->generated)
return TRUE; // No foreign key return false; // No foreign key
swap_variables(Key*, a, b); // Put generated key in 'a' swap_variables(Key*, a, b); // Put generated key in 'a'
} }
/* Test if 'a' is a prefix of 'b' */ /* Test if 'a' is a prefix of 'b' */
if (a->columns.elements > b->columns.elements) if (a->columns.elements > b->columns.elements)
return TRUE; // Can't be prefix return false; // Can't be prefix
List_iterator<Key_part_spec> col_it1(a->columns); List_iterator<Key_part_spec> col_it1(a->columns);
List_iterator<Key_part_spec> col_it2(b->columns); List_iterator<Key_part_spec> col_it2(b->columns);
@@ -254,17 +254,17 @@ bool foreign_key_prefix(Key *a, Key *b)
} }
} }
if (!found) if (!found)
return TRUE; // Error return false; // Error
} }
return FALSE; // Is prefix return true; // Is prefix
#else #else
while ((col1= col_it1++)) while ((col1= col_it1++))
{ {
col2= col_it2++; col2= col_it2++;
if (!(*col1 == *col2)) if (!(*col1 == *col2))
return TRUE; return false;
} }
return FALSE; // Is prefix return true; // Is prefix
#endif #endif
} }
@@ -285,6 +285,8 @@ bool Foreign_key::validate(List<Create_field> &table_fields)
List_iterator<Key_part_spec> cols(columns); List_iterator<Key_part_spec> cols(columns);
List_iterator<Create_field> it(table_fields); List_iterator<Create_field> it(table_fields);
DBUG_ENTER("Foreign_key::validate"); DBUG_ENTER("Foreign_key::validate");
if (old)
DBUG_RETURN(FALSE); // must be good
while ((column= cols++)) while ((column= cols++))
{ {
it.rewind(); it.rewind();

View File

@@ -318,7 +318,7 @@ typedef struct st_copy_info {
class Key_part_spec :public Sql_alloc { class Key_part_spec :public Sql_alloc {
public: public:
LEX_CSTRING field_name; Lex_ident field_name;
uint length; uint length;
bool generated; bool generated;
Key_part_spec(const LEX_CSTRING *name, uint len, bool gen= false) Key_part_spec(const LEX_CSTRING *name, uint len, bool gen= false)
@@ -453,6 +453,7 @@ public:
bool generated; bool generated;
bool invisible; bool invisible;
bool without_overlaps; bool without_overlaps;
bool old;
Lex_ident period; Lex_ident period;
Key(enum Keytype type_par, const LEX_CSTRING *name_arg, Key(enum Keytype type_par, const LEX_CSTRING *name_arg,
@@ -460,7 +461,7 @@ public:
:DDL_options(ddl_options), :DDL_options(ddl_options),
type(type_par), key_create_info(default_key_create_info), type(type_par), key_create_info(default_key_create_info),
name(*name_arg), option_list(NULL), generated(generated_arg), name(*name_arg), option_list(NULL), generated(generated_arg),
invisible(false), without_overlaps(false) invisible(false), without_overlaps(false), old(false)
{ {
key_create_info.algorithm= algorithm_arg; key_create_info.algorithm= algorithm_arg;
} }
@@ -471,12 +472,12 @@ public:
:DDL_options(ddl_options), :DDL_options(ddl_options),
type(type_par), key_create_info(*key_info_arg), columns(*cols), type(type_par), key_create_info(*key_info_arg), columns(*cols),
name(*name_arg), option_list(create_opt), generated(generated_arg), name(*name_arg), option_list(create_opt), generated(generated_arg),
invisible(false), without_overlaps(false) invisible(false), without_overlaps(false), old(false)
{} {}
Key(const Key &rhs, MEM_ROOT *mem_root); Key(const Key &rhs, MEM_ROOT *mem_root);
virtual ~Key() = default; virtual ~Key() = default;
/* Equality comparison of keys (ignoring name) */ /* Equality comparison of keys (ignoring name) */
friend bool foreign_key_prefix(Key *a, Key *b); friend bool is_foreign_key_prefix(Key *a, Key *b);
/** /**
Used to make a clone of this object for ALTER/CREATE TABLE Used to make a clone of this object for ALTER/CREATE TABLE
@sa comment for Key_part_spec::clone @sa comment for Key_part_spec::clone
@@ -509,9 +510,7 @@ public:
ref_db(*ref_db_arg), ref_table(*ref_table_arg), ref_columns(*ref_cols), ref_db(*ref_db_arg), ref_table(*ref_table_arg), ref_columns(*ref_cols),
delete_opt(delete_opt_arg), update_opt(update_opt_arg), delete_opt(delete_opt_arg), update_opt(update_opt_arg),
match_opt(match_opt_arg) match_opt(match_opt_arg)
{ {
// We don't check for duplicate FKs.
key_create_info.check_for_duplicate_indexes= false;
} }
Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root); Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root);
/** /**

View File

@@ -4537,8 +4537,6 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
*/ */
if (!mysql_create_table_no_lock(thd, &ddl_log_state_create, &ddl_log_state_rm, if (!mysql_create_table_no_lock(thd, &ddl_log_state_create, &ddl_log_state_rm,
&create_table->db,
&create_table->table_name,
create_info, alter_info, NULL, create_info, alter_info, NULL,
select_field_count, create_table)) select_field_count, create_table))
{ {

View File

@@ -6033,7 +6033,8 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
THD *thd= lpt->thd; THD *thd= lpt->thd;
DBUG_ENTER("mysql_change_partitions"); DBUG_ENTER("mysql_change_partitions");
build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str,
lpt->alter_info->table_name.str, "", 0);
if(mysql_trans_prepare_alter_copy_data(thd)) if(mysql_trans_prepare_alter_copy_data(thd))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@@ -6081,7 +6082,8 @@ static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
int error; int error;
DBUG_ENTER("mysql_rename_partitions"); DBUG_ENTER("mysql_rename_partitions");
build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str,
lpt->alter_info->table_name.str, "", 0);
if (unlikely((error= lpt->table->file->ha_rename_partitions(path)))) if (unlikely((error= lpt->table->file->ha_rename_partitions(path))))
{ {
if (error != 1) if (error != 1)
@@ -6125,7 +6127,8 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
lpt->table->s->table_name.str, lpt->table->s->table_name.str,
MDL_EXCLUSIVE)); MDL_EXCLUSIVE));
build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str,
lpt->alter_info->table_name.str, "", 0);
if ((error= lpt->table->file->ha_drop_partitions(path))) if ((error= lpt->table->file->ha_drop_partitions(path)))
{ {
lpt->table->file->print_error(error, MYF(0)); lpt->table->file->print_error(error, MYF(0));
@@ -6518,7 +6521,8 @@ static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("write_log_rename_frm"); DBUG_ENTER("write_log_rename_frm");
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str,
lpt->alter_info->table_name.str, "", 0);
build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt);
mysql_mutex_lock(&LOCK_gdl); mysql_mutex_lock(&LOCK_gdl);
if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE)) if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE))
@@ -6569,7 +6573,8 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("write_log_drop_partition"); DBUG_ENTER("write_log_drop_partition");
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str,
lpt->alter_info->table_name.str, "", 0);
build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt); build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
mysql_mutex_lock(&LOCK_gdl); mysql_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
@@ -6627,7 +6632,8 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ASSERT(old_first_log_entry); DBUG_ASSERT(old_first_log_entry);
DBUG_ENTER("write_log_add_change_partition"); DBUG_ENTER("write_log_add_change_partition");
build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str,
lpt->alter_info->table_name.str, "", 0);
build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt); build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
mysql_mutex_lock(&LOCK_gdl); mysql_mutex_lock(&LOCK_gdl);
@@ -6694,7 +6700,8 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
Replace the revert operations with forced retry operations. Replace the revert operations with forced retry operations.
*/ */
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str,
lpt->alter_info->table_name.str, "", 0);
build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt);
mysql_mutex_lock(&LOCK_gdl); mysql_mutex_lock(&LOCK_gdl);
if (write_log_changed_partitions(lpt, &next_entry, (const char*)path)) if (write_log_changed_partitions(lpt, &next_entry, (const char*)path))
@@ -6880,8 +6887,8 @@ static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
Better to do that here, than leave the cleaning up to others. Better to do that here, than leave the cleaning up to others.
Acquire EXCLUSIVE mdl lock if not already acquired. Acquire EXCLUSIVE mdl lock if not already acquired.
*/ */
if (!thd->mdl_context.is_lock_owner(MDL_key::TABLE, lpt->db.str, if (!thd->mdl_context.is_lock_owner(MDL_key::TABLE, lpt->alter_info->db.str,
lpt->table_name.str, lpt->alter_info->table_name.str,
MDL_EXCLUSIVE) && MDL_EXCLUSIVE) &&
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
{ {
@@ -7061,13 +7068,13 @@ bool log_partition_alter_to_ddl_log(ALTER_PARTITION_PARAM_TYPE *lpt)
ddl_log.query= { C_STRING_WITH_LEN("ALTER") }; ddl_log.query= { C_STRING_WITH_LEN("ALTER") };
ddl_log.org_storage_engine_name= old_engine_lex; ddl_log.org_storage_engine_name= old_engine_lex;
ddl_log.org_partitioned= true; ddl_log.org_partitioned= true;
ddl_log.org_database= lpt->db; ddl_log.org_database= lpt->alter_info->db;
ddl_log.org_table= lpt->table_name; ddl_log.org_table= lpt->alter_info->table_name;
ddl_log.org_table_id= lpt->org_tabledef_version; ddl_log.org_table_id= lpt->org_tabledef_version;
ddl_log.new_storage_engine_name= old_engine_lex; ddl_log.new_storage_engine_name= old_engine_lex;
ddl_log.new_partitioned= true; ddl_log.new_partitioned= true;
ddl_log.new_database= lpt->db; ddl_log.new_database= lpt->alter_info->db;
ddl_log.new_table= lpt->table_name; ddl_log.new_table= lpt->alter_info->table_name;
ddl_log.new_table_id= lpt->create_info->tabledef_version; ddl_log.new_table_id= lpt->create_info->tabledef_version;
backup_log_ddl(&ddl_log); // This sets backup_log_error on failure backup_log_ddl(&ddl_log); // This sets backup_log_error on failure
return 0; return 0;
@@ -7099,14 +7106,11 @@ bool log_partition_alter_to_ddl_log(ALTER_PARTITION_PARAM_TYPE *lpt)
uint fast_alter_partition_table(THD *thd, TABLE *table, uint fast_alter_partition_table(THD *thd, TABLE *table,
Alter_info *alter_info, Alter_info *alter_info,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
TABLE_LIST *table_list, TABLE_LIST *table_list)
const LEX_CSTRING *db,
const LEX_CSTRING *table_name)
{ {
/* Set-up struct used to write frm files */ /* Set-up struct used to write frm files */
partition_info *part_info; partition_info *part_info;
ALTER_PARTITION_PARAM_TYPE lpt_obj; ALTER_PARTITION_PARAM_TYPE lpt_obj, *lpt= &lpt_obj;
ALTER_PARTITION_PARAM_TYPE *lpt= &lpt_obj;
bool action_completed= FALSE; bool action_completed= FALSE;
bool frm_install= FALSE; bool frm_install= FALSE;
MDL_ticket *mdl_ticket= table->mdl_ticket; MDL_ticket *mdl_ticket= table->mdl_ticket;
@@ -7125,8 +7129,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->table= table; lpt->table= table;
lpt->key_info_buffer= 0; lpt->key_info_buffer= 0;
lpt->key_count= 0; lpt->key_count= 0;
lpt->db= *db;
lpt->table_name= *table_name;
lpt->org_tabledef_version= table->s->tabledef_version; lpt->org_tabledef_version= table->s->tabledef_version;
lpt->copied= 0; lpt->copied= 0;
lpt->deleted= 0; lpt->deleted= 0;

View File

@@ -57,8 +57,6 @@ typedef struct st_lock_param_type
Alter_info *alter_info; Alter_info *alter_info;
TABLE *table; TABLE *table;
KEY *key_info_buffer; KEY *key_info_buffer;
LEX_CSTRING db;
LEX_CSTRING table_name;
LEX_CUSTRING org_tabledef_version; LEX_CUSTRING org_tabledef_version;
uchar *pack_frm_data; uchar *pack_frm_data;
uint key_count; uint key_count;
@@ -256,9 +254,7 @@ typedef int (*get_partitions_in_range_iter)(partition_info *part_info,
uint fast_alter_partition_table(THD *thd, TABLE *table, uint fast_alter_partition_table(THD *thd, TABLE *table,
Alter_info *alter_info, Alter_info *alter_info,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
TABLE_LIST *table_list, TABLE_LIST *table_list);
const LEX_CSTRING *db,
const LEX_CSTRING *table_name);
bool set_part_state(Alter_info *alter_info, partition_info *tab_part_info, bool set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
enum partition_state part_state); enum partition_state part_state);
uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,

View File

@@ -1977,8 +1977,13 @@ static void add_table_options(THD *thd, TABLE *table,
} }
if (share->transactional != HA_CHOICE_UNDEF) if (share->transactional != HA_CHOICE_UNDEF)
{ {
bool do_comment= !table->file->has_transactional_option() && check_options;
if (do_comment)
packet->append(STRING_WITH_LEN(" /*"));
packet->append(STRING_WITH_LEN(" TRANSACTIONAL=")); packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
packet->append(ha_choice_values[(uint) share->transactional]); packet->append(ha_choice_values[(uint) share->transactional]);
if (do_comment)
packet->append(STRING_WITH_LEN(" */"));
} }
if (share->table_type == TABLE_TYPE_SEQUENCE) if (share->table_type == TABLE_TYPE_SEQUENCE)
packet->append(STRING_WITH_LEN(" SEQUENCE=1")); packet->append(STRING_WITH_LEN(" SEQUENCE=1"));

View File

@@ -82,12 +82,9 @@ static int copy_data_between_tables(THD *, TABLE *,TABLE *,
ha_rows *, ha_rows *, ha_rows *, ha_rows *,
Alter_info::enum_enable_or_disable, Alter_info::enum_enable_or_disable,
Alter_table_ctx *); Alter_table_ctx *);
static int append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info, static int append_system_key_parts(THD *, HA_CREATE_INFO *, Key *);
Key *key);
static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *, static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *,
uint *, handler *, KEY **, uint *, int, uint *, handler *, KEY **, uint *, int);
const LEX_CSTRING db,
const LEX_CSTRING table_name);
static uint blob_length_by_type(enum_field_types type); static uint blob_length_by_type(enum_field_types type);
static bool fix_constraints_names(THD *, List<Virtual_column_info> *, static bool fix_constraints_names(THD *, List<Virtual_column_info> *,
const HA_CREATE_INFO *); const HA_CREATE_INFO *);
@@ -401,8 +398,7 @@ uint filename_to_tablename(const char *from, char *to, size_t to_length,
system_charset_info, to, to_length, &errors); system_charset_info, to, to_length, &errors);
if (unlikely(errors)) // Old 5.0 name if (unlikely(errors)) // Old 5.0 name
{ {
res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) - res= strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) - to;
to);
if (!stay_quiet) if (!stay_quiet)
sql_print_error("Invalid (old?) table or database name '%s'", from); sql_print_error("Invalid (old?) table or database name '%s'", from);
} }
@@ -673,9 +669,9 @@ uint build_table_shadow_filename(char *buff, size_t bufflen,
{ {
char tmp_name[FN_REFLEN]; char tmp_name[FN_REFLEN];
my_snprintf(tmp_name, sizeof (tmp_name), "%s-shadow-%lx-%s", tmp_file_prefix, my_snprintf(tmp_name, sizeof (tmp_name), "%s-shadow-%lx-%s", tmp_file_prefix,
(ulong) current_thd->thread_id, lpt->table_name.str); (ulong) current_thd->thread_id, lpt->alter_info->table_name.str);
return build_table_filename(buff, bufflen, lpt->db.str, tmp_name, "", return build_table_filename(buff, bufflen, lpt->alter_info->db.str, tmp_name,
FN_IS_TMP); "", FN_IS_TMP);
} }
@@ -734,7 +730,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
if (mysql_prepare_create_table(lpt->thd, lpt->create_info, lpt->alter_info, if (mysql_prepare_create_table(lpt->thd, lpt->create_info, lpt->alter_info,
&lpt->db_options, lpt->table->file, &lpt->db_options, lpt->table->file,
&lpt->key_info_buffer, &lpt->key_count, &lpt->key_info_buffer, &lpt->key_count,
C_ALTER_TABLE, lpt->db, lpt->table_name)) C_ALTER_TABLE))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@@ -754,7 +750,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
#endif #endif
/* Write shadow frm file */ /* Write shadow frm file */
lpt->create_info->table_options= lpt->db_options; lpt->create_info->table_options= lpt->db_options;
LEX_CUSTRING frm= build_frm_image(lpt->thd, lpt->table_name, LEX_CUSTRING frm= build_frm_image(lpt->thd, lpt->alter_info->table_name,
lpt->create_info, lpt->create_info,
lpt->alter_info->create_list, lpt->alter_info->create_list,
lpt->key_count, lpt->key_info_buffer, lpt->key_count, lpt->key_info_buffer,
@@ -765,7 +761,8 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
goto end; goto end;
} }
int error= writefile(shadow_frm_name, lpt->db.str, lpt->table_name.str, int error= writefile(shadow_frm_name, lpt->alter_info->db.str,
lpt->alter_info->table_name.str,
lpt->create_info->tmp_table(), frm.str, frm.length); lpt->create_info->tmp_table(), frm.str, frm.length);
my_free(const_cast<uchar*>(frm.str)); my_free(const_cast<uchar*>(frm.str));
@@ -787,8 +784,8 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
/* /*
Build frm file name Build frm file name
*/ */
build_table_filename(path, sizeof(path) - 1, lpt->db.str, build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str,
lpt->table_name.str, "", 0); lpt->alter_info->table_name.str, "", 0);
strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS); strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS);
/* /*
When we are changing to use new frm file we need to ensure that we When we are changing to use new frm file we need to ensure that we
@@ -2207,7 +2204,7 @@ static void check_duplicate_key(THD *thd, const Key *key, const KEY *key_info,
Check is requested if the key was explicitly created or altered Check is requested if the key was explicitly created or altered
by the user (unless it's a foreign key). by the user (unless it's a foreign key).
*/ */
if (!key->key_create_info.check_for_duplicate_indexes || key->generated) if (key->old || key->type == Key::FOREIGN_KEY || key->generated)
return; return;
for (const Key &k : *key_list) for (const Key &k : *key_list)
@@ -2575,8 +2572,7 @@ static int
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
Alter_info *alter_info, uint *db_options, Alter_info *alter_info, uint *db_options,
handler *file, KEY **key_info_buffer, handler *file, KEY **key_info_buffer,
uint *key_count, int create_table_mode, uint *key_count, int create_table_mode)
const LEX_CSTRING db, const LEX_CSTRING table_name)
{ {
const char *key_name; const char *key_name;
Create_field *sql_field,*dup_field; Create_field *sql_field,*dup_field;
@@ -2595,6 +2591,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
const Column_derived_attributes dattr(create_info->default_table_charset); const Column_derived_attributes dattr(create_info->default_table_charset);
const Column_bulk_alter_attributes const Column_bulk_alter_attributes
battr(create_info->alter_table_convert_to_charset); battr(create_info->alter_table_convert_to_charset);
const CHARSET_INFO *scs= system_charset_info;
DBUG_ENTER("mysql_prepare_create_table"); DBUG_ENTER("mysql_prepare_create_table");
DBUG_EXECUTE_IF("test_pseudo_invisible",{ DBUG_EXECUTE_IF("test_pseudo_invisible",{
@@ -2608,23 +2605,17 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
new (thd->mem_root)Item_int(thd, 9)); new (thd->mem_root)Item_int(thd, 9));
}); });
DBUG_EXECUTE_IF("test_invisible_index",{ DBUG_EXECUTE_IF("test_invisible_index",{
LEX_CSTRING temp; LEX_CSTRING temp= { STRING_WITH_LEN("invisible") };
temp.str= "invisible"; mysql_add_invisible_index(thd, &alter_info->key_list, &temp,
temp.length= strlen("invisible"); Key::MULTIPLE);
mysql_add_invisible_index(thd, &alter_info->key_list
, &temp, Key::MULTIPLE);
}); });
LEX_CSTRING* connect_string = &create_info->connect_string; LEX_CSTRING* connstr = &create_info->connect_string;
if (connect_string->length != 0 && if (connstr->length > CONNECT_STRING_MAXLEN &&
connect_string->length > CONNECT_STRING_MAXLEN && scs->charpos(connstr->str, connstr->str + connstr->length,
(system_charset_info->charpos(connect_string->str, CONNECT_STRING_MAXLEN) < connstr->length)
(connect_string->str +
connect_string->length),
CONNECT_STRING_MAXLEN)
< connect_string->length))
{ {
my_error(ER_WRONG_STRING_LENGTH, MYF(0), my_error(ER_WRONG_STRING_LENGTH, MYF(0), connstr->str, "CONNECTION",
connect_string->str, "CONNECTION", CONNECT_STRING_MAXLEN); CONNECT_STRING_MAXLEN);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@@ -2687,9 +2678,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/* Check if we have used the same field name before */ /* Check if we have used the same field name before */
for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++) for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
{ {
if (lex_string_cmp(system_charset_info, if (lex_string_cmp(scs, &sql_field->field_name, &dup_field->field_name) == 0)
&sql_field->field_name,
&dup_field->field_name) == 0)
{ {
/* /*
If this was a CREATE ... SELECT statement, accept a field If this was a CREATE ... SELECT statement, accept a field
@@ -2861,15 +2850,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
while ((key2 = key_iterator2++) != key) while ((key2 = key_iterator2++) != key)
{ {
/* /*
foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is is_foreign_key_prefix(key, key2) returns true if key or key2, or
'generated', and a generated key is a prefix of the other key. both, is 'generated', and a generated key is a prefix of the other
Then we do not need the generated shorter key. key. Then we do not need the generated shorter key.
*/ */
if ((key2->type != Key::FOREIGN_KEY && if (key2->type != Key::FOREIGN_KEY && key2->name.str != ignore_key &&
key2->name.str != ignore_key && is_foreign_key_prefix(key, key2))
!foreign_key_prefix(key, key2)))
{ {
/* TODO: issue warning message */
/* mark that the generated key should be ignored */ /* mark that the generated key should be ignored */
if (!key2->generated || if (!key2->generated ||
(key->generated && key->columns.elements < (key->generated && key->columns.elements <
@@ -2890,14 +2877,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
else else
(*key_count)--; (*key_count)--;
if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) && if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
!my_strcasecmp(system_charset_info, key->name.str, !my_strcasecmp(scs, key->name.str, primary_key_name.str))
primary_key_name.str))
{ {
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str); my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
if (key->type == Key::PRIMARY && key->name.str && if (key->type == Key::PRIMARY && key->name.str &&
my_strcasecmp(system_charset_info, key->name.str, primary_key_name.str) != 0) my_strcasecmp(scs, key->name.str, primary_key_name.str) != 0)
{ {
bool sav_abort_on_warning= thd->abort_on_warning; bool sav_abort_on_warning= thd->abort_on_warning;
thd->abort_on_warning= FALSE; /* Don't make an error out of this. */ thd->abort_on_warning= FALSE; /* Don't make an error out of this. */
@@ -2935,9 +2921,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
auto field_name= key->columns.elem(0)->field_name; auto field_name= key->columns.elem(0)->field_name;
it.rewind(); it.rewind();
while ((sql_field=it++) && while ((sql_field=it++) &&
lex_string_cmp(system_charset_info, lex_string_cmp(scs, &field_name, &sql_field->field_name));
&field_name,
&sql_field->field_name));
if (sql_field) if (sql_field)
field_name= sql_field->field_name; field_name= sql_field->field_name;
key_name=make_unique_key_name(thd, field_name.str, key_name=make_unique_key_name(thd, field_name.str,
@@ -3110,9 +3094,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
it.rewind(); it.rewind();
field=0; field=0;
while ((sql_field=it++) && while ((sql_field=it++) &&
lex_string_cmp(system_charset_info, lex_string_cmp(scs, &column->field_name, &sql_field->field_name))
&column->field_name,
&sql_field->field_name))
field++; field++;
/* /*
Either field is not present or field visibility is > INVISIBLE_USER Either field is not present or field visibility is > INVISIBLE_USER
@@ -3132,8 +3114,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
} }
while ((dup_column= cols2++) != column) while ((dup_column= cols2++) != column)
{ {
if (!lex_string_cmp(system_charset_info, if (!lex_string_cmp(scs, &column->field_name, &dup_column->field_name))
&column->field_name, &dup_column->field_name))
{ {
my_error(ER_DUP_FIELDNAME, MYF(0), column->field_name.str); my_error(ER_DUP_FIELDNAME, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@@ -3436,8 +3417,7 @@ without_overlaps_err:
{ {
for (Key_part_spec& kp2: fk->columns) for (Key_part_spec& kp2: fk->columns)
{ {
if (!lex_string_cmp(system_charset_info, &kp.field_name, if (!lex_string_cmp(scs, &kp.field_name, &kp2.field_name))
&kp2.field_name))
{ {
goto without_overlaps_err; goto without_overlaps_err;
} }
@@ -3489,7 +3469,6 @@ without_overlaps_err:
create_info->null_bits= null_fields; create_info->null_bits= null_fields;
/* Check fields. */ /* Check fields. */
Item::Check_table_name_prm walk_prm(db, table_name);
it.rewind(); it.rewind();
while ((sql_field=it++)) while ((sql_field=it++))
{ {
@@ -3547,33 +3526,22 @@ without_overlaps_err:
if (create_simple) if (create_simple)
{ {
/*
NOTE: we cannot do this in check_vcol_func_processor() as there is already
no table name qualifier in expression.
*/
if (sql_field->vcol_info && sql_field->vcol_info->expr && if (sql_field->vcol_info && sql_field->vcol_info->expr &&
sql_field->vcol_info->expr->walk(&Item::check_table_name_processor, check_expression(sql_field->vcol_info, &sql_field->field_name,
false, (void *) &walk_prm)) sql_field->vcol_info->stored_in_db
{ ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL,
my_error(ER_BAD_FIELD_ERROR, MYF(0), walk_prm.field.c_ptr(), "GENERATED ALWAYS"); alter_info))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
if (sql_field->default_value && if (sql_field->default_value &&
sql_field->default_value->expr->walk(&Item::check_table_name_processor, check_expression(sql_field->default_value, &sql_field->field_name,
false, (void *) &walk_prm)) VCOL_DEFAULT, alter_info))
{
my_error(ER_BAD_FIELD_ERROR, MYF(0), walk_prm.field.c_ptr(), "DEFAULT");
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
if (sql_field->check_constraint && if (sql_field->check_constraint &&
sql_field->check_constraint->expr->walk(&Item::check_table_name_processor, check_expression(sql_field->check_constraint, &sql_field->field_name,
false, (void *) &walk_prm)) VCOL_CHECK_FIELD, alter_info))
{
my_error(ER_BAD_FIELD_ERROR, MYF(0), walk_prm.field.c_ptr(), "CHECK");
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
} }
} }
@@ -3581,22 +3549,9 @@ without_overlaps_err:
create_info->check_constraint_list= &alter_info->check_constraint_list; create_info->check_constraint_list= &alter_info->check_constraint_list;
{ {
List_iterator_fast<Virtual_column_info> c_it(alter_info->check_constraint_list); List_iterator_fast<Virtual_column_info> c_it(alter_info->check_constraint_list);
Virtual_column_info *check; while (Virtual_column_info *check= c_it++)
while ((check= c_it++))
{ {
if (create_simple && check->expr->walk(&Item::check_table_name_processor, false, if (check->name.length && !check->automatic_name)
(void *) &walk_prm))
{
my_error(ER_BAD_FIELD_ERROR, MYF(0), walk_prm.field.c_ptr(), "CHECK");
DBUG_RETURN(TRUE);
}
if (!check->name.length || check->automatic_name)
{
if (check_expression(check, &check->name, VCOL_CHECK_TABLE, alter_info))
DBUG_RETURN(TRUE);
continue;
}
{ {
/* Check that there's no repeating table CHECK constraint names. */ /* Check that there's no repeating table CHECK constraint names. */
List_iterator_fast<Virtual_column_info> List_iterator_fast<Virtual_column_info>
@@ -3604,57 +3559,45 @@ without_overlaps_err:
const Virtual_column_info *dup_check; const Virtual_column_info *dup_check;
while ((dup_check= dup_it++) && dup_check != check) while ((dup_check= dup_it++) && dup_check != check)
{ {
if (!lex_string_cmp(system_charset_info, if (check->name.streq(dup_check->name))
&check->name, &dup_check->name))
{ {
my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str); my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
} }
}
/* Check that there's no repeating key constraint names. */ /* Check that there's no repeating key constraint names. */
List_iterator_fast<Key> key_it(alter_info->key_list); List_iterator_fast<Key> key_it(alter_info->key_list);
while (const Key *key= key_it++) while (const Key *key= key_it++)
{
/*
Not all keys considered to be the CONSTRAINT
Noly Primary Key UNIQUE and Foreign keys.
*/
if (key->type != Key::PRIMARY && key->type != Key::UNIQUE &&
key->type != Key::FOREIGN_KEY)
continue;
if (check->name.length == key->name.length &&
my_strcasecmp(system_charset_info,
check->name.str, key->name.str) == 0)
{ {
my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str); if (key->type != Key::PRIMARY && key->type != Key::UNIQUE &&
key->type != Key::FOREIGN_KEY)
continue;
if (check->name.length == key->name.length &&
my_strcasecmp(scs, check->name.str, key->name.str) == 0)
{
my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name.str);
DBUG_RETURN(TRUE);
}
}
if (check_string_char_length(&check->name, 0, NAME_CHAR_LEN, scs, 1))
{
my_error(ER_TOO_LONG_IDENT, MYF(0), check->name.str);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
} }
if (check_string_char_length(&check->name, 0, NAME_CHAR_LEN,
system_charset_info, 1))
{
my_error(ER_TOO_LONG_IDENT, MYF(0), check->name.str);
DBUG_RETURN(TRUE);
}
if (check_expression(check, &check->name, VCOL_CHECK_TABLE, alter_info)) if (check_expression(check, &check->name, VCOL_CHECK_TABLE, alter_info))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
} }
/* Give warnings for not supported table options */ /* Give warnings for not supported table options */
extern handlerton *maria_hton; if (create_info->used_fields & HA_CREATE_USED_TRANSACTIONAL &&
if (file->partition_ht() != maria_hton && create_info->transactional && !file->has_transactional_option())
!file->has_transaction_manager()) push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_OPTION,
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_THD(thd, ER_UNKNOWN_OPTION), "transactional");
ER_ILLEGAL_HA_CREATE_OPTION,
ER_THD(thd, ER_ILLEGAL_HA_CREATE_OPTION),
file->engine_name()->str,
create_info->transactional == HA_CHOICE_YES
? "TRANSACTIONAL=1" : "TRANSACTIONAL=0");
if (parse_option_list(thd, file->partition_ht(), &create_info->option_struct, if (parse_option_list(thd, file->partition_ht(), &create_info->option_struct,
&create_info->option_list, &create_info->option_list,
@@ -3662,12 +3605,10 @@ without_overlaps_err:
thd->mem_root)) thd->mem_root))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
#ifndef DBUG_OFF
DBUG_EXECUTE_IF("key", DBUG_EXECUTE_IF("key",
Debug_key::print_keys(thd, "prep_create_table: ", Debug_key::print_keys(thd, "prep_create_table: ",
*key_info_buffer, *key_count); *key_info_buffer, *key_count);
); );
#endif
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
@@ -3909,9 +3850,7 @@ static int append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info,
return result; return result;
} }
handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db, handler *mysql_create_frm_image(THD *thd, HA_CREATE_INFO *create_info,
const LEX_CSTRING &table_name,
HA_CREATE_INFO *create_info,
Alter_info *alter_info, int create_table_mode, Alter_info *alter_info, int create_table_mode,
KEY **key_info, uint *key_count, KEY **key_info, uint *key_count,
LEX_CUSTRING *frm) LEX_CUSTRING *frm)
@@ -3926,7 +3865,7 @@ handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
set_table_default_charset(thd, create_info, db); set_table_default_charset(thd, create_info, alter_info->db);
db_options= create_info->table_options_with_row_type(); db_options= create_info->table_options_with_row_type();
@@ -4047,7 +3986,7 @@ handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
if (part_info->vers_info && !create_info->versioned()) if (part_info->vers_info && !create_info->versioned())
{ {
my_error(ER_VERS_NOT_VERSIONED, MYF(0), table_name.str); my_error(ER_VERS_NOT_VERSIONED, MYF(0), alter_info->table_name.str);
goto err; goto err;
} }
@@ -4145,14 +4084,12 @@ handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
#endif #endif
if (mysql_prepare_create_table(thd, create_info, alter_info, &db_options, if (mysql_prepare_create_table(thd, create_info, alter_info, &db_options,
file, key_info, key_count, file, key_info, key_count, create_table_mode))
create_table_mode, db, table_name))
goto err; goto err;
create_info->table_options=db_options; create_info->table_options=db_options;
*frm= build_frm_image(thd, table_name, create_info, *frm= build_frm_image(thd, alter_info->table_name, create_info,
alter_info->create_list, *key_count, alter_info->create_list, *key_count, *key_info, file);
*key_info, file);
if (frm->str) if (frm->str)
DBUG_RETURN(file); DBUG_RETURN(file);
@@ -4457,9 +4394,10 @@ int create_table_impl(THD *thd,
&path, &db, &table_name, frm_only); &path, &db, &table_name, frm_only);
debug_crash_here("ddl_log_create_before_create_frm"); debug_crash_here("ddl_log_create_before_create_frm");
file= mysql_create_frm_image(thd, orig_db, orig_table_name, create_info, alter_info->db= orig_db;
alter_info, create_table_mode, key_info, alter_info->table_name= orig_table_name;
key_count, frm); file= mysql_create_frm_image(thd, create_info, alter_info,
create_table_mode, key_info, key_count, frm);
/* /*
TODO: remove this check of thd->is_error() (now it intercept TODO: remove this check of thd->is_error() (now it intercept
errors in some val_*() methods and bring some single place to errors in some val_*() methods and bring some single place to
@@ -4548,8 +4486,6 @@ warn:
int mysql_create_table_no_lock(THD *thd, int mysql_create_table_no_lock(THD *thd,
DDL_LOG_STATE *ddl_log_state_create, DDL_LOG_STATE *ddl_log_state_create,
DDL_LOG_STATE *ddl_log_state_rm, DDL_LOG_STATE *ddl_log_state_rm,
const LEX_CSTRING *db,
const LEX_CSTRING *table_name,
Table_specification_st *create_info, Table_specification_st *create_info,
Alter_info *alter_info, bool *is_trans, Alter_info *alter_info, bool *is_trans,
int create_table_mode, TABLE_LIST *table_list) int create_table_mode, TABLE_LIST *table_list)
@@ -4560,6 +4496,8 @@ int mysql_create_table_no_lock(THD *thd,
uint path_length; uint path_length;
char path[FN_REFLEN + 1]; char path[FN_REFLEN + 1];
LEX_CSTRING cpath; LEX_CSTRING cpath;
const LEX_CSTRING *db= &table_list->db;
const LEX_CSTRING *table_name= &table_list->table_name;
LEX_CUSTRING frm= {0,0}; LEX_CUSTRING frm= {0,0};
if (create_info->tmp_table()) if (create_info->tmp_table())
@@ -4747,8 +4685,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
thd->abort_on_warning= thd->is_strict_mode(); thd->abort_on_warning= thd->is_strict_mode();
if (mysql_create_table_no_lock(thd, &ddl_log_state_create, &ddl_log_state_rm, if (mysql_create_table_no_lock(thd, &ddl_log_state_create, &ddl_log_state_rm,
&create_table->db, create_info,
&create_table->table_name, create_info,
alter_info, alter_info,
&is_trans, create_table_mode, &is_trans, create_table_mode,
create_table) > 0) create_table) > 0)
@@ -5260,7 +5197,6 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
res= ((create_res= res= ((create_res=
mysql_create_table_no_lock(thd, mysql_create_table_no_lock(thd,
&ddl_log_state_create, &ddl_log_state_rm, &ddl_log_state_create, &ddl_log_state_rm,
&table->db, &table->table_name,
&local_create_info, &local_alter_info, &local_create_info, &local_alter_info,
&is_trans, C_ORDINARY_CREATE, &is_trans, C_ORDINARY_CREATE,
table)) > 0); table)) > 0);
@@ -6948,10 +6884,8 @@ static void update_altered_table(const Alter_inplace_info &ha_alter_info,
@retval false success @retval false success
*/ */
bool mysql_compare_tables(TABLE *table, bool mysql_compare_tables(TABLE *table, Alter_info *alter_info,
Alter_info *alter_info, HA_CREATE_INFO *create_info, bool *metadata_equal)
HA_CREATE_INFO *create_info,
bool *metadata_equal)
{ {
DBUG_ENTER("mysql_compare_tables"); DBUG_ENTER("mysql_compare_tables");
@@ -6976,15 +6910,16 @@ bool mysql_compare_tables(TABLE *table,
Alter_info tmp_alter_info(*alter_info, thd->mem_root); Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */ uint db_options= 0; /* not used */
KEY *key_info_buffer= NULL; KEY *key_info_buffer= NULL;
LEX_CSTRING db= { table->s->db.str, table->s->db.length };
LEX_CSTRING table_name= { table->s->db.str, table->s->table_name.length }; tmp_alter_info.db= table->s->db;
tmp_alter_info.table_name= table->s->table_name;
/* Create the prepared information. */ /* Create the prepared information. */
int create_table_mode= table->s->tmp_table == NO_TMP_TABLE ? int create_table_mode= table->s->tmp_table == NO_TMP_TABLE ?
C_ORDINARY_CREATE : C_ALTER_TABLE; C_ORDINARY_CREATE : C_ALTER_TABLE;
if (mysql_prepare_create_table(thd, create_info, &tmp_alter_info, if (mysql_prepare_create_table(thd, create_info, &tmp_alter_info,
&db_options, table->file, &key_info_buffer, &db_options, table->file, &key_info_buffer,
&key_count, create_table_mode, db, table_name)) &key_count, create_table_mode))
DBUG_RETURN(1); DBUG_RETURN(1);
/* Some very basic checks. */ /* Some very basic checks. */
@@ -7760,6 +7695,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
List<Create_field> new_create_tail; List<Create_field> new_create_tail;
/* New key definitions are added here */ /* New key definitions are added here */
List<Key> new_key_list; List<Key> new_key_list;
List<FOREIGN_KEY_INFO> fk_list;
List<Alter_rename_key> rename_key_list(alter_info->alter_rename_key_list); List<Alter_rename_key> rename_key_list(alter_info->alter_rename_key_list);
/* /*
@@ -7793,12 +7729,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
bool drop_period= false; bool drop_period= false;
LEX_CSTRING period_start_name= {nullptr, 0}; LEX_CSTRING period_start_name= {nullptr, 0};
LEX_CSTRING period_end_name= {nullptr, 0}; LEX_CSTRING period_end_name= {nullptr, 0};
DBUG_ENTER("mysql_prepare_alter_table");
if (table->s->period.name) if (table->s->period.name)
{ {
period_start_name= table->s->period_start_field()->field_name; period_start_name= table->s->period_start_field()->field_name;
period_end_name= table->s->period_end_field()->field_name; period_end_name= table->s->period_end_field()->field_name;
} }
DBUG_ENTER("mysql_prepare_alter_table");
/* /*
Merge incompatible changes flag in case of upgrade of a table from an Merge incompatible changes flag in case of upgrade of a table from an
@@ -7859,6 +7796,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
create_info->option_list= merge_engine_table_options(table->s->option_list, create_info->option_list= merge_engine_table_options(table->s->option_list,
create_info->option_list, thd->mem_root); create_info->option_list, thd->mem_root);
table->file->get_foreign_key_list(thd, &fk_list);
/* /*
First collect all fields from table which isn't in drop_list First collect all fields from table which isn't in drop_list
*/ */
@@ -8473,12 +8412,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
key_create_info.comment= key_info->comment; key_create_info.comment= key_info->comment;
key_create_info.is_ignored= key_info->is_ignored; key_create_info.is_ignored= key_info->is_ignored;
/*
We're refreshing an already existing index. Since the index is not
modified, there is no need to check for duplicate indexes again.
*/
key_create_info.check_for_duplicate_indexes= false;
if (key_info->flags & HA_SPATIAL) if (key_info->flags & HA_SPATIAL)
key_type= Key::SPATIAL; key_type= Key::SPATIAL;
else if (key_info->flags & HA_NOSAME) else if (key_info->flags & HA_NOSAME)
@@ -8525,10 +8458,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
tmp_name.length= strlen(key_name); tmp_name.length= strlen(key_name);
/* We dont need LONG_UNIQUE_HASH_FIELD flag because it will be autogenerated */ /* We dont need LONG_UNIQUE_HASH_FIELD flag because it will be autogenerated */
key= new (thd->mem_root) Key(key_type, &tmp_name, &key_create_info, key= new (thd->mem_root) Key(key_type, &tmp_name, &key_create_info,
MY_TEST(key_info->flags & HA_GENERATED_KEY), key_info->flags & HA_GENERATED_KEY,
&key_parts, key_info->option_list, DDL_options()); &key_parts, key_info->option_list, DDL_options());
key->without_overlaps= key_info->without_overlaps; key->without_overlaps= key_info->without_overlaps;
key->period= table->s->period.name; key->period= table->s->period.name;
key->old= true;
new_key_list.push_back(key, thd->mem_root); new_key_list.push_back(key, thd->mem_root);
} }
if (long_hash_key) if (long_hash_key)
@@ -8537,6 +8471,30 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
re_setup_keyinfo_hash(key_info); re_setup_keyinfo_hash(key_info);
} }
} }
{
// add existing foreign keys
for (auto &fk : fk_list)
{
Alter_drop *drop;
for(drop_it.rewind(); (drop=drop_it++); )
if (drop->type == Alter_drop::FOREIGN_KEY &&
!my_strcasecmp(system_charset_info, fk.foreign_id->str, drop->name))
break;
if (drop)
continue;
List<Key_part_spec> cols, ref_cols;
for (LEX_CSTRING &c : fk.foreign_fields)
cols.push_back(new (thd->mem_root) Key_part_spec(&c, 0));
for (LEX_CSTRING &c : fk.referenced_fields)
ref_cols.push_back(new (thd->mem_root) Key_part_spec(&c, 0));
auto key= new (thd->mem_root)
Foreign_key(fk.foreign_id, &cols, fk.foreign_id, fk.referenced_db,
fk.referenced_table, &ref_cols, fk.delete_method, fk.update_method,
Foreign_key::FK_MATCH_UNDEF, DDL_options());
key->old= true;
new_key_list.push_back(key, thd->mem_root);
}
}
{ {
Key *key; Key *key;
while ((key=key_it++)) // Add new keys while ((key=key_it++)) // Add new keys
@@ -8661,10 +8619,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (!alter_info->check_constraint_list.is_empty()) if (!alter_info->check_constraint_list.is_empty())
{ {
/* Check the table FOREIGN KEYs for name duplications. */ /* Check the table FOREIGN KEYs for name duplications. */
List <FOREIGN_KEY_INFO> fk_child_key_list;
FOREIGN_KEY_INFO *f_key; FOREIGN_KEY_INFO *f_key;
table->file->get_foreign_key_list(thd, &fk_child_key_list); List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_list);
List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list);
while ((f_key= fk_key_it++)) while ((f_key= fk_key_it++))
{ {
List_iterator_fast<Virtual_column_info> List_iterator_fast<Virtual_column_info>
@@ -9089,7 +9045,7 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
while (Key *key= fk_list_it++) while (Key *key= fk_list_it++)
{ {
if (key->type != Key::FOREIGN_KEY) if (key->type != Key::FOREIGN_KEY || key->old)
continue; continue;
Foreign_key *fk= static_cast<Foreign_key*>(key); Foreign_key *fk= static_cast<Foreign_key*>(key);
@@ -10099,10 +10055,10 @@ do_continue:;
} }
// In-place execution of ALTER TABLE for partitioning. // In-place execution of ALTER TABLE for partitioning.
alter_info->db= alter_ctx.db;
alter_info->table_name= alter_ctx.table_name;
DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info, DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
create_info, table_list, create_info, table_list));
&alter_ctx.db,
&alter_ctx.table_name));
} }
#endif #endif
@@ -10255,9 +10211,9 @@ do_continue:;
alter_ctx.db, alter_ctx.table_name, alter_ctx.db, alter_ctx.table_name,
alter_ctx.new_db, alter_ctx.tmp_name, alter_ctx.new_db, alter_ctx.tmp_name,
alter_ctx.get_tmp_cstring_path(), alter_ctx.get_tmp_cstring_path(),
thd->lex->create_info, create_info, alter_info, thd->lex->create_info,
C_ALTER_TABLE_FRM_ONLY, NULL, create_info, alter_info, C_ALTER_TABLE_FRM_ONLY,
&key_info, &key_count, &frm); NULL, &key_info, &key_count, &frm);
thd->abort_on_warning= false; thd->abort_on_warning= false;
reenable_binlog(thd); reenable_binlog(thd);

View File

@@ -128,24 +128,16 @@ bool add_keyword_to_query(THD *thd, String *result, const LEX_CSTRING *keyword,
int mysql_create_table_no_lock(THD *thd, int mysql_create_table_no_lock(THD *thd,
DDL_LOG_STATE *ddl_log_state, DDL_LOG_STATE *ddl_log_state,
DDL_LOG_STATE *ddl_log_state_rm, DDL_LOG_STATE *ddl_log_state_rm,
const LEX_CSTRING *db,
const LEX_CSTRING *table_name,
Table_specification_st *create_info, Table_specification_st *create_info,
Alter_info *alter_info, bool *is_trans, Alter_info *alter_info, bool *is_trans,
int create_table_mode, TABLE_LIST *table); int create_table_mode, TABLE_LIST *table);
handler *mysql_create_frm_image(THD *thd, handler *mysql_create_frm_image(THD *thd, HA_CREATE_INFO *create_info,
const LEX_CSTRING &db, Alter_info *alter_info, int create_table_mode,
const LEX_CSTRING &table_name, KEY **key_info, uint *key_count,
HA_CREATE_INFO *create_info,
Alter_info *alter_info,
int create_table_mode,
KEY **key_info,
uint *key_count,
LEX_CUSTRING *frm); LEX_CUSTRING *frm);
int mysql_discard_or_import_tablespace(THD *thd, int mysql_discard_or_import_tablespace(THD *thd, TABLE_LIST *table_list,
TABLE_LIST *table_list,
bool discard); bool discard);
bool mysql_prepare_alter_table(THD *thd, TABLE *table, bool mysql_prepare_alter_table(THD *thd, TABLE *table,

View File

@@ -3532,17 +3532,18 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
sql_unusable_for_discovery(thd, hton, sql_copy)))) sql_unusable_for_discovery(thd, hton, sql_copy))))
goto ret; goto ret;
thd->lex->create_info.db_type= hton; tmp_lex.create_info.db_type= hton;
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
thd->work_part_info= 0; // For partitioning thd->work_part_info= 0; // For partitioning
#endif #endif
if (tabledef_version.str) if (tabledef_version.str)
thd->lex->create_info.tabledef_version= tabledef_version; tmp_lex.create_info.tabledef_version= tabledef_version;
promote_first_timestamp_column(&thd->lex->alter_info.create_list); tmp_lex.alter_info.db= db;
file= mysql_create_frm_image(thd, db, table_name, tmp_lex.alter_info.table_name= table_name;
&thd->lex->create_info, &thd->lex->alter_info, promote_first_timestamp_column(&tmp_lex.alter_info.create_list);
file= mysql_create_frm_image(thd, &tmp_lex.create_info, &tmp_lex.alter_info,
C_ORDINARY_CREATE, &unused1, &unused2, &frm); C_ORDINARY_CREATE, &unused1, &unused2, &frm);
error|= file == 0; error|= file == 0;
delete file; delete file;
@@ -3556,7 +3557,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write,
ret: ret:
my_free(const_cast<uchar*>(frm.str)); my_free(const_cast<uchar*>(frm.str));
lex_end(thd->lex); lex_end(&tmp_lex);
thd->reset_db(&db_backup); thd->reset_db(&db_backup);
thd->lex= old_lex; thd->lex= old_lex;
reenable_binlog(thd); reenable_binlog(thd);
@@ -9927,20 +9928,14 @@ LEX_CSTRING *fk_option_name(enum_fk_option opt)
{ {
{ STRING_WITH_LEN("???") }, { STRING_WITH_LEN("???") },
{ STRING_WITH_LEN("RESTRICT") }, { STRING_WITH_LEN("RESTRICT") },
{ STRING_WITH_LEN("NO ACTION") },
{ STRING_WITH_LEN("CASCADE") }, { STRING_WITH_LEN("CASCADE") },
{ STRING_WITH_LEN("SET NULL") }, { STRING_WITH_LEN("SET NULL") },
{ STRING_WITH_LEN("NO ACTION") },
{ STRING_WITH_LEN("SET DEFAULT") } { STRING_WITH_LEN("SET DEFAULT") }
}; };
return names + opt; return names + opt;
} }
bool fk_modifies_child(enum_fk_option opt)
{
static bool can_write[]= { false, false, true, true, false, true };
return can_write[opt];
}
enum TR_table::enabled TR_table::use_transaction_registry= TR_table::MAYBE; enum TR_table::enabled TR_table::use_transaction_registry= TR_table::MAYBE;
TR_table::TR_table(THD* _thd, bool rw) : TR_table::TR_table(THD* _thd, bool rw) :

View File

@@ -1871,8 +1871,8 @@ enum enum_schema_table_state
PROCESSED_BY_JOIN_EXEC PROCESSED_BY_JOIN_EXEC
}; };
enum enum_fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_CASCADE, enum enum_fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_NO_ACTION,
FK_OPTION_SET_NULL, FK_OPTION_NO_ACTION, FK_OPTION_SET_DEFAULT}; FK_OPTION_CASCADE, FK_OPTION_SET_NULL, FK_OPTION_SET_DEFAULT };
typedef struct st_foreign_key_info typedef struct st_foreign_key_info
{ {
@@ -1889,7 +1889,11 @@ typedef struct st_foreign_key_info
} FOREIGN_KEY_INFO; } FOREIGN_KEY_INFO;
LEX_CSTRING *fk_option_name(enum_fk_option opt); LEX_CSTRING *fk_option_name(enum_fk_option opt);
bool fk_modifies_child(enum_fk_option opt); static inline bool fk_modifies_child(enum_fk_option opt)
{
return opt >= FK_OPTION_CASCADE;
}
class IS_table_read_plan; class IS_table_read_plan;

View File

@@ -12427,7 +12427,7 @@ create_table_info_t::create_foreign_keys()
} }
while (Key* key = key_it++) { while (Key* key = key_it++) {
if (key->type != Key::FOREIGN_KEY) if (key->type != Key::FOREIGN_KEY || key->old)
continue; continue;
if (tmp_table) { if (tmp_table) {

View File

@@ -3208,7 +3208,7 @@ innobase_get_foreign_key_info(
*n_add_fk = 0; *n_add_fk = 0;
for (Key& key : alter_info->key_list) { for (Key& key : alter_info->key_list) {
if (key.type != Key::FOREIGN_KEY) { if (key.type != Key::FOREIGN_KEY || key.old) {
continue; continue;
} }

View File

@@ -978,7 +978,6 @@ int maria_create(const char *name, enum data_file_type datafile_type,
for (i=0; i < uniques ; i++) for (i=0; i < uniques ; i++)
{ {
tmp_keydef.keysegs=1; tmp_keydef.keysegs=1;
tmp_keydef.flag= HA_UNIQUE_CHECK;
tmp_keydef.block_length= (uint16) maria_block_size; tmp_keydef.block_length= (uint16) maria_block_size;
tmp_keydef.keylength= MARIA_UNIQUE_HASH_LENGTH + pointer; tmp_keydef.keylength= MARIA_UNIQUE_HASH_LENGTH + pointer;
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength; tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;

View File

@@ -754,7 +754,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
for (i=0; i < uniques ; i++) for (i=0; i < uniques ; i++)
{ {
tmp_keydef.keysegs=1; tmp_keydef.keysegs=1;
tmp_keydef.flag= HA_UNIQUE_CHECK;
tmp_keydef.block_length= (uint16)myisam_block_size; tmp_keydef.block_length= (uint16)myisam_block_size;
tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer; tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer;
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength; tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;