Merge commit '96badb16afcf' into 10.0

Conflicts:
	client/mysql_upgrade.c
	mysql-test/r/func_misc.result
	mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
	mysql-test/suite/innodb/r/innodb-fk.result
	mysql-test/t/subselect_sj_mat.test
	sql/item.cc
	sql/item_func.cc
	sql/log.cc
	sql/log_event.cc
	sql/rpl_utility.cc
	sql/slave.cc
	sql/sql_class.cc
	sql/sql_class.h
	sql/sql_select.cc
	storage/innobase/dict/dict0crea.c
	storage/innobase/dict/dict0dict.c
	storage/innobase/handler/ha_innodb.cc
	storage/xtradb/dict/dict0crea.c
	storage/xtradb/dict/dict0dict.c
	storage/xtradb/handler/ha_innodb.cc
	vio/viosslfactories.c
This commit is contained in:
Jan Lindström 2015-08-03 23:09:43 +03:00
commit 9a5787db51
64 changed files with 2520 additions and 305 deletions

View File

@ -1095,7 +1095,7 @@ int main(int argc, char **argv)
printf("This installation of MySQL is already upgraded to %s, "
"use --force if you still need to run mysql_upgrade\n",
MYSQL_SERVER_VERSION);
die(NULL);
goto end;
}
if (opt_version_check && check_version_match())
@ -1124,6 +1124,7 @@ int main(int argc, char **argv)
DBUG_ASSERT(phase == phases_total);
end:
free_used_memory();
my_end(my_end_arg);
exit(0);

View File

@ -228,7 +228,7 @@ rollback;
create table t0 (n int);
insert t0 select * from t1;
set autocommit=1;
insert into t0 select GET_LOCK("lock1",null);
insert into t0 select GET_LOCK("lock1",0);
set autocommit=0;
create table t2 (n int) engine=innodb;
insert into t2 values (3);

View File

@ -4862,6 +4862,7 @@ sub extract_warning_lines ($$) {
qr|InnoDB: Setting thread \d+ nice to \d+ failed, current nice \d+, errno 13|, # setpriority() fails under valgrind
qr|Failed to setup SSL|,
qr|SSL error: Failed to set ciphers to use|,
qr/Plugin 'InnoDB' will be forced to shutdown/,
);
my $matched_lines= [];

View File

@ -1103,3 +1103,19 @@ ORDER BY field;
field
c,c
drop table t3, t2, t1;
#
# MDEV-7821 - Server crashes in Item_func_group_concat::fix_fields on 2nd
# execution of PS
#
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1),(2);
PREPARE stmt FROM "SELECT GROUP_CONCAT(t1a.a ORDER BY 1, t1a.a=0) FROM t1 AS t1a, t1 AS t1b GROUP BY t1a.a";
EXECUTE stmt;
GROUP_CONCAT(t1a.a ORDER BY 1, t1a.a=0)
1,1
2,2
EXECUTE stmt;
GROUP_CONCAT(t1a.a ORDER BY 1, t1a.a=0)
1,1
2,2
DROP TABLE t1;

View File

@ -361,7 +361,18 @@ set optimizer_switch=@optimizer_switch_save;
drop view v_merge, vm;
drop table t1,tv;
#
# GET_LOCK, RELEASE_LOCK, IS_USED_LOCK functions test
# MDEV-4017 - GET_LOCK() with negative timeouts has strange behavior
#
SELECT GET_LOCK('ul1', NULL);
GET_LOCK('ul1', NULL)
NULL
Warnings:
Warning 1411 Incorrect timeout value: 'NULL' for function get_lock
SELECT GET_LOCK('ul1', -1);
GET_LOCK('ul1', -1)
NULL
Warnings:
Warning 1411 Incorrect timeout value: '-1' for function get_lock
#
# IS_USED_LOCK, IS_FREE_LOCK: the lock is not acquired
# Note: IS_USED_LOCK returns NULL if the lock is unused

View File

@ -19,3 +19,5 @@ mysqld-bin.000001 # Query # # use `test`; insert t1 values (2)
mysqld-bin.000001 # Query # # COMMIT
drop table t1;
uninstall plugin innodb;
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown

View File

@ -0,0 +1,156 @@
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'
drop view if exists view_t1;
Warnings:
Note 1051 Unknown table 'test.view_t1'
SET sql_mode=ONLY_FULL_GROUP_BY;
CREATE TABLE t1 (
pk INT,
f0 INT, f1 INT, f2 INT, f3 INT, f4 INT,
f5 INT, f6 INT, f7 INT, f8 INT, f9 INT,
PRIMARY KEY (pk)
);
CREATE VIEW view_t1 AS SELECT * FROM t1;
CREATE PROCEDURE s1()
SELECT * FROM (
INFORMATION_SCHEMA.`INNODB_BUFFER_PAGE_LRU` AS table1
LEFT JOIN test.view_t1 AS table2
ON ( table2.`f6` = table1.FREE_PAGE_CLOCK)
)
ORDER BY table1.NUMBER_RECORDS
LIMIT 0
;
CALL s1;
POOL_ID LRU_POSITION SPACE PAGE_NUMBER PAGE_TYPE FLUSH_TYPE FIX_COUNT IS_HASHED NEWEST_MODIFICATION OLDEST_MODIFICATION ACCESS_TIME TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE COMPRESSED_SIZE COMPRESSED IO_FIX IS_OLD FREE_PAGE_CLOCK pk f0 f1 f2 f3 f4 f5 f6 f7 f8 f9
CALL s1;
POOL_ID LRU_POSITION SPACE PAGE_NUMBER PAGE_TYPE FLUSH_TYPE FIX_COUNT IS_HASHED NEWEST_MODIFICATION OLDEST_MODIFICATION ACCESS_TIME TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE COMPRESSED_SIZE COMPRESSED IO_FIX IS_OLD FREE_PAGE_CLOCK pk f0 f1 f2 f3 f4 f5 f6 f7 f8 f9
drop table t1;
drop view view_t1;
drop procedure s1;
CREATE TABLE A (
pk INTEGER AUTO_INCREMENT,
col_int_key INTEGER,
col_varchar_key VARCHAR(1),
PRIMARY KEY (pk)
) ENGINE=MyISAM;
CREATE VIEW view_A AS SELECT * FROM A;
CREATE TABLE C (
pk INTEGER AUTO_INCREMENT,
col_int_nokey INTEGER,
col_int_key INTEGER,
col_date_key DATE,
col_date_nokey DATE,
col_time_key TIME,
col_time_nokey TIME,
col_datetime_key DATETIME,
col_datetime_nokey DATETIME,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk)
) ENGINE=MyISAM;
CREATE VIEW view_C AS SELECT * FROM C;
CREATE TABLE AA (
pk INTEGER AUTO_INCREMENT,
col_int_nokey INTEGER,
col_int_key INTEGER,
col_date_key DATE,
col_date_nokey DATE,
col_time_key TIME,
col_time_nokey TIME,
col_datetime_key DATETIME,
col_datetime_nokey DATETIME,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_varchar_key, col_int_key)
) ENGINE=MyISAM;
CREATE VIEW view_AA AS SELECT * FROM AA;
CREATE TABLE BB (
pk INTEGER AUTO_INCREMENT,
col_int_key INTEGER,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_varchar_key, col_int_key)
) ENGINE=MyISAM;
CREATE VIEW view_BB AS SELECT * FROM BB;
CREATE TABLE DD (
pk INTEGER AUTO_INCREMENT,
col_int_key INTEGER,
col_date_key DATE,
col_time_key TIME,
col_datetime_key DATETIME,
col_varchar_key VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_varchar_key, col_int_key)
) ENGINE=MyISAM;
CREATE VIEW view_DD AS SELECT * FROM DD;
CREATE TRIGGER k BEFORE INSERT ON `DD` FOR EACH ROW INSERT INTO `view_BB` SELECT * FROM `view_A` LIMIT 0 ;
CREATE TRIGGER r BEFORE INSERT ON `A` FOR EACH ROW INSERT INTO `view_AA` SELECT * FROM `view_C` LIMIT 0 ;
ALTER TABLE `DD` DROP PRIMARY KEY;
ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key
INSERT INTO `view_A` ( `pk` ) VALUES (NULL);
INSERT INTO `DD` ( `pk` ) VALUES (NULL);
INSERT INTO `A` ( `pk` ) VALUES (NULL);
INSERT INTO `view_DD` ( `pk` ) VALUES (NULL);
drop trigger r;
drop trigger k;
drop view view_A,view_AA,view_C,view_BB,view_DD;
drop table A,C,AA,BB,DD;
CREATE TABLE A (
i INT,
i1 INT,
i2 INT,
d1 DATE,
d2 DATE,
col_time_nokey1 TIME,
col_time_nokey2 TIME,
col_datetime_nokey1 DATETIME,
col_datetime_nokey2 DATETIME,
col_varchar_nokey1 VARCHAR(1),
col_varchar_nokey2 VARCHAR(1)
) ENGINE=MyISAM;
CREATE VIEW view_A AS SELECT * FROM A;
CREATE TABLE B (
col_varchar_nokey VARCHAR(1)
) ENGINE=MyISAM;
CREATE TABLE AA (
i INT,
i1 INT,
i2 INT,
d1 DATE,
d2 DATE,
col_time_nokey1 TIME,
col_time_nokey2 TIME,
col_datetime_nokey1 DATETIME,
col_datetime_nokey2 DATETIME,
col_varchar_nokey1 VARCHAR(1),
col_varchar_nokey2 VARCHAR(1)
) ENGINE=MyISAM;
CREATE VIEW view_AA AS SELECT * FROM AA;
CREATE TABLE DD (
i INT,
i1 INT,
i2 INT,
d1 DATE,
d2 DATE,
col_time_nokey1 TIME,
col_time_nokey2 TIME,
col_datetime_nokey1 DATETIME,
col_datetime_nokey2 DATETIME,
col_varchar_nokey1 VARCHAR(1),
col_varchar_nokey2 VARCHAR(1)
) ENGINE=MyISAM;
CREATE VIEW view_DD AS SELECT * FROM DD;
CREATE TRIGGER tr1 BEFORE INSERT ON `AA` FOR EACH ROW INSERT INTO `view_A` SELECT * FROM `view_AA` LIMIT 0 ;
CREATE TRIGGER tr2 BEFORE INSERT ON `B` FOR EACH ROW INSERT INTO `D` SELECT * FROM `A` LIMIT 0 ;
INSERT INTO `view_AA` ( `i` ) VALUES (1);
INSERT INTO `AA` ( `i` ) VALUES (2);
DELETE FROM `B`;
INSERT INTO `view_DD` ( `i` ) VALUES (1);
INSERT INTO `view_AA` ( `i` ) VALUES (3);
drop trigger tr1;
drop trigger tr2;
drop view view_A, view_AA,view_DD;
drop table A,B,AA,DD;

View File

@ -2145,6 +2145,24 @@ drop database mysqltest1;
drop database mysqltest2;
drop database mysqltest3;
drop database mysqltest4;
#
# MDEV-7810 Wrong result on execution of a query as a PS
# (both 1st and further executions)
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0),(8);
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
a
0
PREPARE stmt FROM "
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
";
execute stmt;
a
0
execute stmt;
a
0
drop table t1;
# End of 5.5 tests
#
# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT

View File

@ -2185,6 +2185,24 @@ drop database mysqltest1;
drop database mysqltest2;
drop database mysqltest3;
drop database mysqltest4;
#
# MDEV-7810 Wrong result on execution of a query as a PS
# (both 1st and further executions)
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0),(8);
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
a
0
PREPARE stmt FROM "
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
";
execute stmt;
a
0
execute stmt;
a
0
drop table t1;
# End of 5.5 tests
#
# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT

View File

@ -259,7 +259,7 @@ Warning 1196 Some non-transactional changed tables couldn't be rolled back
create table t0 (n int);
insert t0 select * from t1;
set autocommit=1;
insert into t0 select GET_LOCK("lock1",null);
insert into t0 select GET_LOCK("lock1",0);
set autocommit=0;
create table t2 (n int) engine=innodb;
insert into t2 values (3);

View File

@ -243,7 +243,7 @@ Warning 1196 Some non-transactional changed tables couldn't be rolled back
create table t0 (n int);
insert t0 select * from t1;
set autocommit=1;
insert into t0 select GET_LOCK("lock1",null);
insert into t0 select GET_LOCK("lock1",0);
Warnings:
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave.
set autocommit=0;
@ -293,7 +293,7 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; insert t0 select * from t1
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; insert into t0 select GET_LOCK("lock1",null)
master-bin.000001 # Query # # use `test`; insert into t0 select GET_LOCK("lock1",0)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t2 (n int) engine=innodb

View File

@ -0,0 +1,112 @@
CREATE TABLE t1 (
id int(11) NOT NULL PRIMARY KEY,
a int(11) NOT NULL,
b int(11) NOT NULL,
c int not null,
CONSTRAINT test FOREIGN KEY (b) REFERENCES t1 (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE t2 (
id int(11) NOT NULL PRIMARY KEY,
a int(11) NOT NULL,
b int(11) NOT NULL,
c int not null,
CONSTRAINT mytest FOREIGN KEY (c) REFERENCES t1(id),
CONSTRAINT test FOREIGN KEY (b) REFERENCES t2 (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ERROR HY000: Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update")
show warnings;
Level Code Message
Warning 121 Create or Alter table `test`.`t2` with foreign key constraint failed. Foreign key constraint `test/test` already exists on data dictionary. Foreign key constraint names need to be unique in database. Error in foreign key definition: CONSTRAINT `test` FOREIGN KEY (`b`) REFERENCES `test`.`t2` (`id`).
Error 1005 Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update")
Warning 1022 Can't write; duplicate key in table 't2'
drop table t1;
create table t1(a int) engine=innodb;
create table t2(a int, constraint a foreign key a (a) references t1(a)) engine=innodb;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key a (a) references t1(a)) engine=innodb.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
drop table t1;
create table t1(a int not null primary key, b int) engine=innodb;
create table t2(a int, b int, constraint a foreign key a (a) references t1(a),
constraint a foreign key a (a) references t1(b)) engine=innodb;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
create table t2(a int, b int, constraint a foreign key a (a) references t1(a)) engine=innodb;
alter table t2 add constraint b foreign key (b) references t2(b);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. Error close to foreign key (b) references t2(b).
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
drop table t2, t1;
create table t1 (f1 integer primary key) engine=innodb;
alter table t1 add constraint c1 foreign key (f1) references t11(f1);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t11` not found in the data dictionary close to foreign key (f1) references t11(f1).
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
drop table t1;
create temporary table t1(a int not null primary key, b int, key(b)) engine=innodb;
create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Create table `mysqld.1`.`t2` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(a) references t1(a)) engine=innodb.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
alter table t1 add foreign key(b) references t1(a);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(b) references t1(a).
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
drop table t1;
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
alter table t1 add foreign key(a,b) references t1(a);
ERROR 42000: Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match
show warnings;
Level Code Message
Error 1239 Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match
drop table t1;
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
alter table t1 add foreign key(a) references t1(a,b);
ERROR 42000: Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match
show warnings;
Level Code Message
Error 1239 Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match
drop table t1;
create table t1 (f1 integer not null primary key) engine=innodb;
alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update set null;
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Alter table `test`.`t1` with foreign key constraint failed. You have defined a SET NULL condition but column f1 is defined as NOT NULL in foreign key (f1) references t1(f1) on update set null close to on update set null.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Create table `test`.`t2` with foreign key constraint failed. You have defined a SET NULL condition but column a is defined as NOT NULL in foreign key(a) references t1(f1) on delete set null) engine=innodb close to on delete set null) engine=innodb.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
drop table t1;
create table t1 (id int not null primary key, f1 int, f2 int, key(f1)) engine=innodb;
create table t2(a char(20), key(a), foreign key(a) references t1(f1)) engine=innodb;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Create table `test`.`t2` with foreign key constraint failed. Field type or character set for column a does not mach referenced column f1 close to foreign key(a) references t1(f1)) engine=innodb
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
drop table t1;

View File

@ -50,6 +50,8 @@ CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Create table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary close to FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE
) ENGINE=InnoDB.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
CREATE TABLE t2 (
@ -63,6 +65,7 @@ ALTER TABLE t2 ADD CONSTRAINT fk3 FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Alter table `test`.`t2` with foreign key constraint failed. Referenced table `test`.`t3` not found in the data dictionary close to FOREIGN KEY (f3) REFERENCES t3 (id) ON DELETE CASCADE.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
drop table t2;

View File

@ -0,0 +1,22 @@
install plugin innodb soname 'ha_innodb';
create table t1(a int not null primary key) engine=innodb;
begin;
insert into t1 values(1);
flush tables;
uninstall plugin innodb;
select sleep(1);
sleep(1)
0
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
drop table t1;
install plugin innodb soname 'ha_innodb';
create table t2(a int not null primary key) engine=innodb;
insert into t2 values(1);
drop table t2;
uninstall plugin innodb;
select sleep(1);
sleep(1)
0
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown

View File

@ -0,0 +1,130 @@
--source include/have_innodb.inc
#
# MDEV-8524: Improve error messaging when there is duplicate key or foreign key names
#
CREATE TABLE t1 (
id int(11) NOT NULL PRIMARY KEY,
a int(11) NOT NULL,
b int(11) NOT NULL,
c int not null,
CONSTRAINT test FOREIGN KEY (b) REFERENCES t1 (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
#
# Below create table fails because constraint name test
# is reserved for above table.
#
--error 1005
CREATE TABLE t2 (
id int(11) NOT NULL PRIMARY KEY,
a int(11) NOT NULL,
b int(11) NOT NULL,
c int not null,
CONSTRAINT mytest FOREIGN KEY (c) REFERENCES t1(id),
CONSTRAINT test FOREIGN KEY (b) REFERENCES t2 (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
show warnings;
drop table t1;
#
# MDEV-6697: Improve foreign keys warnings/errors
#
#
# No index for referenced columns
#
create table t1(a int) engine=innodb;
--error 1005
create table t2(a int, constraint a foreign key a (a) references t1(a)) engine=innodb;
show warnings;
drop table t1;
create table t1(a int not null primary key, b int) engine=innodb;
--error 1005
create table t2(a int, b int, constraint a foreign key a (a) references t1(a),
constraint a foreign key a (a) references t1(b)) engine=innodb;
show warnings;
create table t2(a int, b int, constraint a foreign key a (a) references t1(a)) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
alter table t2 add constraint b foreign key (b) references t2(b);
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
drop table t2, t1;
#
# Referenced table does not exists
#
create table t1 (f1 integer primary key) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
alter table t1 add constraint c1 foreign key (f1) references t11(f1);
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
drop table t1;
#
# Foreign key on temporal tables
#
create temporary table t1(a int not null primary key, b int, key(b)) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
alter table t1 add foreign key(b) references t1(a);
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
drop table t1;
#
# Column numbers do not match
#
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1239
alter table t1 add foreign key(a,b) references t1(a);
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
drop table t1;
create table t1(a int not null primary key, b int, key(b)) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1239
alter table t1 add foreign key(a) references t1(a,b);
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
drop table t1;
#
# ON UPDATE/DELETE SET NULL on NOT NULL column
#
create table t1 (f1 integer not null primary key) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
alter table t1 add constraint c1 foreign key (f1) references t1(f1) on update set null;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
create table t2(a int not null, foreign key(a) references t1(f1) on delete set null) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
drop table t1;
#
# Incorrect types
#
create table t1 (id int not null primary key, f1 int, f2 int, key(f1)) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
create table t2(a char(20), key(a), foreign key(a) references t1(f1)) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
drop table t1;

View File

@ -0,0 +1,3 @@
--ignore-builtin-innodb
--loose-innodb

View File

@ -0,0 +1,58 @@
--source include/not_embedded.inc
--source include/not_windows.inc
if (!$HA_INNODB_SO) {
--skip Need InnoDB plugin
}
#
# MDEV-8474: InnoDB sets per-connection data unsafely
# Below test caused hang
#
install plugin innodb soname 'ha_innodb';
create table t1(a int not null primary key) engine=innodb;
connect (con1, localhost, root);
connection con1;
begin;
insert into t1 values(1);
connection default;
flush tables;
send uninstall plugin innodb;
connection con1;
select sleep(1);
disconnect con1;
connection default;
reap;
--source include/restart_mysqld.inc
drop table t1;
#
# Another test that caused hang.
#
connect (con1, localhost, root);
connection con1;
install plugin innodb soname 'ha_innodb';
create table t2(a int not null primary key) engine=innodb;
insert into t2 values(1);
drop table t2;
connection default;
send uninstall plugin innodb;
connection con1;
select sleep(1);
disconnect con1;
connection default;
reap;
--source include/restart_mysqld.inc

View File

@ -14,4 +14,109 @@ select * from mysqltest.t3;
n
45
drop database mysqltest;
use test;
#
# Test bug where ALTER TABLE MODIFY didn't replicate properly
#
create table t1 (a int unsigned primary key, b int);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(10) unsigned NOT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 (a) values (1),((1<<32)-1);
select * from t1;
a b
1 NULL
4294967295 NULL
alter table t1 modify a bigint;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(20) NOT NULL DEFAULT '0',
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t1;
a b
1 NULL
4294967295 NULL
alter table t1 modify a int unsigned;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(10) unsigned NOT NULL DEFAULT '0',
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t1;
a b
1 NULL
4294967295 NULL
alter table t1 modify a bigint unsigned;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(20) unsigned NOT NULL DEFAULT '0',
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t1;
a b
1 NULL
4294967295 NULL
use test;
select * from t1;
a b
1 NULL
4294967295 NULL
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(20) unsigned NOT NULL DEFAULT '0',
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create table t2 (a int unsigned auto_increment primary key, b int);
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(10) unsigned NOT NULL AUTO_INCREMENT,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
alter table t2 modify a bigint;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` bigint(20) NOT NULL DEFAULT '0',
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
alter table t2 modify a bigint auto_increment;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` bigint(20) NOT NULL AUTO_INCREMENT,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2;
#
# MDEV-8432: Slave cannot replicate signed integer-type values
# with high bit set to 1
# Test replication when we have int on master and bigint on slave
#
create table t1 (a int unsigned primary key, b int);
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY';
alter table t1 modify a bigint unsigned;
insert into t1 (a) values (1),((1<<32)-1);
select * from t1;
a b
1 NULL
4294967295 NULL
SET GLOBAL SLAVE_TYPE_CONVERSIONS='';
drop table t1;
include/rpl_end.inc

View File

@ -15,4 +15,57 @@ drop database mysqltest;
sync_slave_with_master;
# End of 4.1 tests
connection master;
use test;
--echo #
--echo # Test bug where ALTER TABLE MODIFY didn't replicate properly
--echo #
create table t1 (a int unsigned primary key, b int);
show create table t1;
insert into t1 (a) values (1),((1<<32)-1);
select * from t1;
alter table t1 modify a bigint;
show create table t1;
select * from t1;
alter table t1 modify a int unsigned;
show create table t1;
select * from t1;
alter table t1 modify a bigint unsigned;
show create table t1;
select * from t1;
sync_slave_with_master;
use test;
select * from t1;
show create table t1;
connection master;
#
create table t2 (a int unsigned auto_increment primary key, b int);
show create table t2;
alter table t2 modify a bigint;
show create table t2;
alter table t2 modify a bigint auto_increment;
show create table t2;
drop table t1,t2;
--echo #
--echo # MDEV-8432: Slave cannot replicate signed integer-type values
--echo # with high bit set to 1
--echo # Test replication when we have int on master and bigint on slave
--echo #
create table t1 (a int unsigned primary key, b int);
sync_slave_with_master;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY';
alter table t1 modify a bigint unsigned;
connection master;
insert into t1 (a) values (1),((1<<32)-1);
sync_slave_with_master;
select * from t1;
SET GLOBAL SLAVE_TYPE_CONVERSIONS='';
connection master;
drop table t1;
--source include/rpl_end.inc

View File

@ -821,3 +821,14 @@ FROM ( SELECT * FROM t2 ) AS sq2, t3
ORDER BY field;
drop table t3, t2, t1;
--echo #
--echo # MDEV-7821 - Server crashes in Item_func_group_concat::fix_fields on 2nd
--echo # execution of PS
--echo #
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1),(2);
PREPARE stmt FROM "SELECT GROUP_CONCAT(t1a.a ORDER BY 1, t1a.a=0) FROM t1 AS t1a, t1 AS t1b GROUP BY t1a.a";
EXECUTE stmt;
EXECUTE stmt;
DROP TABLE t1;

View File

@ -391,6 +391,11 @@ set optimizer_switch=@optimizer_switch_save;
drop view v_merge, vm;
drop table t1,tv;
--echo #
--echo # MDEV-4017 - GET_LOCK() with negative timeouts has strange behavior
--echo #
SELECT GET_LOCK('ul1', NULL);
SELECT GET_LOCK('ul1', -1);
--echo #
--echo # GET_LOCK, RELEASE_LOCK, IS_USED_LOCK functions test

View File

@ -16,3 +16,6 @@ commit;
--source include/show_binlog_events.inc
drop table t1;
uninstall plugin innodb;
--source include/restart_mysqld.inc

View File

@ -15,7 +15,6 @@ file_exists $MYSQLD_DATADIR/mysql_upgrade_info;
--echo Run it again - should say already completed
--replace_result $MYSQL_SERVER_VERSION VERSION
--error 1
--exec $MYSQL_UPGRADE 2>&1
# It should have created a file in the MySQL Servers datadir

187
mysql-test/t/sp-group.test Normal file
View File

@ -0,0 +1,187 @@
--source include/have_innodb.inc
drop table if exists t1;
drop view if exists view_t1;
#
# Test case for MDEV 7601, MDEV-7594 and MDEV-7555
# Server crashes in functions related to stored procedures
# Server crashes in different ways while executing concurrent
# flow involving views and non-empty sql_mode with ONLY_FULL_GROUP_BY
#
SET sql_mode=ONLY_FULL_GROUP_BY;
CREATE TABLE t1 (
pk INT,
f0 INT, f1 INT, f2 INT, f3 INT, f4 INT,
f5 INT, f6 INT, f7 INT, f8 INT, f9 INT,
PRIMARY KEY (pk)
);
CREATE VIEW view_t1 AS SELECT * FROM t1;
CREATE PROCEDURE s1()
SELECT * FROM (
INFORMATION_SCHEMA.`INNODB_BUFFER_PAGE_LRU` AS table1
LEFT JOIN test.view_t1 AS table2
ON ( table2.`f6` = table1.FREE_PAGE_CLOCK)
)
ORDER BY table1.NUMBER_RECORDS
LIMIT 0
;
CALL s1;
CALL s1;
drop table t1;
drop view view_t1;
drop procedure s1;
#
# MDEV-7590
# Server crashes in st_select_lex_unit::cleanup on executing a trigger
#
CREATE TABLE A (
pk INTEGER AUTO_INCREMENT,
col_int_key INTEGER,
col_varchar_key VARCHAR(1),
PRIMARY KEY (pk)
) ENGINE=MyISAM;
CREATE VIEW view_A AS SELECT * FROM A;
CREATE TABLE C (
pk INTEGER AUTO_INCREMENT,
col_int_nokey INTEGER,
col_int_key INTEGER,
col_date_key DATE,
col_date_nokey DATE,
col_time_key TIME,
col_time_nokey TIME,
col_datetime_key DATETIME,
col_datetime_nokey DATETIME,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk)
) ENGINE=MyISAM;
CREATE VIEW view_C AS SELECT * FROM C;
CREATE TABLE AA (
pk INTEGER AUTO_INCREMENT,
col_int_nokey INTEGER,
col_int_key INTEGER,
col_date_key DATE,
col_date_nokey DATE,
col_time_key TIME,
col_time_nokey TIME,
col_datetime_key DATETIME,
col_datetime_nokey DATETIME,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_varchar_key, col_int_key)
) ENGINE=MyISAM;
CREATE VIEW view_AA AS SELECT * FROM AA;
CREATE TABLE BB (
pk INTEGER AUTO_INCREMENT,
col_int_key INTEGER,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_varchar_key, col_int_key)
) ENGINE=MyISAM;
CREATE VIEW view_BB AS SELECT * FROM BB;
CREATE TABLE DD (
pk INTEGER AUTO_INCREMENT,
col_int_key INTEGER,
col_date_key DATE,
col_time_key TIME,
col_datetime_key DATETIME,
col_varchar_key VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_varchar_key, col_int_key)
) ENGINE=MyISAM;
CREATE VIEW view_DD AS SELECT * FROM DD;
CREATE TRIGGER k BEFORE INSERT ON `DD` FOR EACH ROW INSERT INTO `view_BB` SELECT * FROM `view_A` LIMIT 0 ;
CREATE TRIGGER r BEFORE INSERT ON `A` FOR EACH ROW INSERT INTO `view_AA` SELECT * FROM `view_C` LIMIT 0 ;
--error ER_WRONG_AUTO_KEY
ALTER TABLE `DD` DROP PRIMARY KEY;
INSERT INTO `view_A` ( `pk` ) VALUES (NULL);
--error 0,ER_WRONG_VALUE_COUNT_ON_ROW
INSERT INTO `DD` ( `pk` ) VALUES (NULL);
INSERT INTO `A` ( `pk` ) VALUES (NULL);
--error 0,ER_WRONG_VALUE_COUNT_ON_ROW
INSERT INTO `view_DD` ( `pk` ) VALUES (NULL);
drop trigger r;
drop trigger k;
drop view view_A,view_AA,view_C,view_BB,view_DD;
drop table A,C,AA,BB,DD;
#
# MDEV-7581
# Server crashes in st_select_lex_unit::cleanup after a sequence of statements
#
CREATE TABLE A (
i INT,
i1 INT,
i2 INT,
d1 DATE,
d2 DATE,
col_time_nokey1 TIME,
col_time_nokey2 TIME,
col_datetime_nokey1 DATETIME,
col_datetime_nokey2 DATETIME,
col_varchar_nokey1 VARCHAR(1),
col_varchar_nokey2 VARCHAR(1)
) ENGINE=MyISAM;
CREATE VIEW view_A AS SELECT * FROM A;
CREATE TABLE B (
col_varchar_nokey VARCHAR(1)
) ENGINE=MyISAM;
CREATE TABLE AA (
i INT,
i1 INT,
i2 INT,
d1 DATE,
d2 DATE,
col_time_nokey1 TIME,
col_time_nokey2 TIME,
col_datetime_nokey1 DATETIME,
col_datetime_nokey2 DATETIME,
col_varchar_nokey1 VARCHAR(1),
col_varchar_nokey2 VARCHAR(1)
) ENGINE=MyISAM;
CREATE VIEW view_AA AS SELECT * FROM AA;
CREATE TABLE DD (
i INT,
i1 INT,
i2 INT,
d1 DATE,
d2 DATE,
col_time_nokey1 TIME,
col_time_nokey2 TIME,
col_datetime_nokey1 DATETIME,
col_datetime_nokey2 DATETIME,
col_varchar_nokey1 VARCHAR(1),
col_varchar_nokey2 VARCHAR(1)
) ENGINE=MyISAM;
CREATE VIEW view_DD AS SELECT * FROM DD;
CREATE TRIGGER tr1 BEFORE INSERT ON `AA` FOR EACH ROW INSERT INTO `view_A` SELECT * FROM `view_AA` LIMIT 0 ;
CREATE TRIGGER tr2 BEFORE INSERT ON `B` FOR EACH ROW INSERT INTO `D` SELECT * FROM `A` LIMIT 0 ;
INSERT INTO `view_AA` ( `i` ) VALUES (1);
INSERT INTO `AA` ( `i` ) VALUES (2);
DELETE FROM `B`;
INSERT INTO `view_DD` ( `i` ) VALUES (1);
INSERT INTO `view_AA` ( `i` ) VALUES (3);
drop trigger tr1;
drop trigger tr2;
drop view view_A, view_AA,view_DD;
drop table A,B,AA,DD;

View File

@ -1841,8 +1841,23 @@ drop database mysqltest2;
drop database mysqltest3;
drop database mysqltest4;
--echo # End of 5.5 tests
--echo #
--echo # MDEV-7810 Wrong result on execution of a query as a PS
--echo # (both 1st and further executions)
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0),(8);
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
PREPARE stmt FROM "
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
";
execute stmt;
execute stmt;
drop table t1;
--echo # End of 5.5 tests
--echo #
--echo # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
--echo #

View File

@ -4363,18 +4363,23 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
Item_ident *resolved_item,
Item_ident *mark_item)
{
const char *db_name= (resolved_item->db_name ?
resolved_item->db_name : "");
const char *table_name= (resolved_item->table_name ?
resolved_item->table_name : "");
DBUG_ENTER("mark_as_dependent");
/* store pointer on SELECT_LEX from which item is dependent */
if (mark_item && mark_item->can_be_depended)
{
DBUG_PRINT("info", ("mark_item: %p lex: %p", mark_item, last));
mark_item->depended_from= last;
if (current->mark_as_dependent(thd, last, /** resolved_item psergey-thu
**/mark_item))
return TRUE;
}
if (current->mark_as_dependent(thd, last,
/** resolved_item psergey-thu **/ mark_item))
DBUG_RETURN(TRUE);
if (thd->lex->describe & DESCRIBE_EXTENDED)
{
const char *db_name= (resolved_item->db_name ?
resolved_item->db_name : "");
const char *table_name= (resolved_item->table_name ?
resolved_item->table_name : "");
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_WARN_FIELD_RESOLVED, ER(ER_WARN_FIELD_RESOLVED),
db_name, (db_name[0] ? "." : ""),
@ -4382,7 +4387,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
resolved_item->field_name,
current->select_number, last->select_number);
}
return FALSE;
DBUG_RETURN(FALSE);
}
@ -4831,7 +4836,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
non aggregated fields of the outer select.
*/
marker= select->cur_pos_in_select_list;
select->non_agg_fields.push_back(this);
select->join->non_agg_fields.push_back(this);
}
if (*from_field != view_ref_found)
{
@ -5247,9 +5252,10 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
fixed= 1;
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
!outer_fixed && !thd->lex->in_sum_func &&
thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS)
thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS &&
thd->lex->current_select->join)
{
thd->lex->current_select->non_agg_fields.push_back(this);
thd->lex->current_select->join->non_agg_fields.push_back(this);
marker= thd->lex->current_select->cur_pos_in_select_list;
}
mark_non_agg_field:
@ -6730,7 +6736,7 @@ Item_ref::Item_ref(Name_resolution_context *context_arg,
/*
This constructor used to create some internals references over fixed items
*/
if (ref && *ref && (*ref)->fixed)
if ((set_properties_only= (ref && *ref && (*ref)->fixed)))
set_properties();
}
@ -6774,7 +6780,7 @@ Item_ref::Item_ref(TABLE_LIST *view_arg, Item **item,
/*
This constructor is used to create some internal references over fixed items
*/
if (ref && *ref && (*ref)->fixed)
if ((set_properties_only= (ref && *ref && (*ref)->fixed)))
set_properties();
}
@ -6849,7 +6855,11 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(fixed == 0);
SELECT_LEX *current_sel= thd->lex->current_select;
if (!ref || ref == not_found_item)
if (set_properties_only)
{
/* do nothing */
}
else if (!ref || ref == not_found_item)
{
DBUG_ASSERT(reference_trough_name != 0);
if (!(ref= resolve_ref_in_select_and_group(thd, this,
@ -6867,7 +6877,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
{
/* The current reference cannot be resolved in this query. */
my_error(ER_BAD_FIELD_ERROR,MYF(0),
this->full_name(), current_thd->where);
this->full_name(), thd->where);
goto error;
}
@ -7002,7 +7012,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
goto error;
thd->change_item_tree(reference, fld);
mark_as_dependent(thd, last_checked_context->select_lex,
thd->lex->current_select, fld, fld);
current_sel, fld, fld);
/*
A reference is resolved to a nest level that's outer or the same as
the nest level of the enclosing set function : adjust the value of
@ -7019,7 +7029,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
{
/* The item was not a table field and not a reference */
my_error(ER_BAD_FIELD_ERROR, MYF(0),
this->full_name(), current_thd->where);
this->full_name(), thd->where);
goto error;
}
/* Should be checked in resolve_ref_in_select_and_group(). */

View File

@ -657,7 +657,7 @@ public:
*/
uint name_length; /* Length of name */
uint decimals;
int8 marker;
int marker;
bool maybe_null; /* If item may be null */
bool in_rollup; /* If used in GROUP BY list
of a query with ROLLUP */
@ -3356,6 +3356,7 @@ class Item_ref :public Item_ident
{
protected:
void set_properties();
bool set_properties_only; // the item doesn't need full fix_fields
public:
enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF, AGGREGATE_REF };
Field *result_field; /* Save result here */
@ -3365,7 +3366,7 @@ public:
const char *db_arg, const char *table_name_arg,
const char *field_name_arg)
:Item_ident(context_arg, db_arg, table_name_arg, field_name_arg),
result_field(0), ref(0), reference_trough_name(1) {}
set_properties_only(0), result_field(0), ref(0), reference_trough_name(1) {}
/*
This constructor is used in two scenarios:
A) *item = NULL
@ -3388,7 +3389,7 @@ public:
/* Constructor need to process subselect with temporary tables (see Item) */
Item_ref(THD *thd, Item_ref *item)
:Item_ident(thd, item), result_field(item->result_field), ref(item->ref) {}
:Item_ident(thd, item), set_properties_only(0), result_field(item->result_field), ref(item->ref) {}
enum Type type() const { return REF_ITEM; }
enum Type real_type() const { return ref ? (*ref)->type() :
REF_ITEM; }

View File

@ -4266,6 +4266,24 @@ longlong Item_func_get_lock::val_int()
it's not guaranteed to be same as on master.
*/
if (thd->slave_thread)
{
null_value= 0;
}
if (args[1]->null_value ||
(!args[1]->unsigned_flag && ((longlong) timeout < 0)))
{
char buf[22];
if (args[1]->null_value)
strmov(buf, "NULL");
else
llstr(((longlong) timeout), buf);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
"timeout", buf, "get_lock");
null_value= 1;
DBUG_RETURN(0);
}
{
null_value= 0;
DBUG_RETURN(1);

View File

@ -477,6 +477,7 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
{
List_iterator_fast<Ref_to_outside> it(upper_refs);
Ref_to_outside *upper;
DBUG_ENTER("recalc_used_tables");
used_tables_cache= 0;
while ((upper= it++))
@ -536,6 +537,8 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
he has done const table detection, and that will be our chance to update
const_tables_cache.
*/
DBUG_PRINT("exit", ("used_tables_cache: %llx", used_tables_cache));
DBUG_VOID_RETURN;
}
@ -2002,7 +2005,7 @@ bool Item_allany_subselect::is_maxmin_applicable(JOIN *join)
*/
bool
Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
Item **where_item,
Item **having_item)
{
@ -2012,7 +2015,6 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
during JOIN::optimize: this->tmp_having= this->having; this->having= 0;
*/
Item* join_having= join->having ? join->having : join->tmp_having;
DBUG_ENTER("Item_in_subselect::create_single_in_to_exists_cond");
*where_item= NULL;

View File

@ -3527,9 +3527,16 @@ bool Item_func_group_concat::setup(THD *thd)
"all_fields". The resulting field list is used as input to create
tmp table columns.
*/
if (arg_count_order &&
setup_order(thd, args, context->table_list, list, all_fields, *order))
DBUG_RETURN(TRUE);
if (arg_count_order)
{
uint n_elems= arg_count_order + all_fields.elements;
ref_pointer_array= static_cast<Item**>(thd->alloc(sizeof(Item*) * n_elems));
memcpy(ref_pointer_array, args, arg_count * sizeof(Item*));
if (!ref_pointer_array ||
setup_order(thd, ref_pointer_array, context->table_list, list,
all_fields, *order))
DBUG_RETURN(TRUE);
}
count_field_types(select_lex, tmp_table_param, all_fields, 0);
tmp_table_param->force_copy_fields= force_copy_fields;

View File

@ -1394,6 +1394,7 @@ class Item_func_group_concat : public Item_sum
String *separator;
TREE tree_base;
TREE *tree;
Item **ref_pointer_array;
/**
If DISTINCT is used with this GROUP_CONCAT, this member is used to filter

View File

@ -4129,6 +4129,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
int error;
char *to_purge_if_included= NULL;
inuse_relaylog *ir;
ulonglong log_space_reclaimed= 0;
DBUG_ENTER("purge_first_log");
DBUG_ASSERT(is_open());
@ -4200,17 +4201,13 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
mysql_mutex_lock(&rli->log_space_lock);
rli->relay_log.purge_logs(to_purge_if_included, included,
0, 0, &rli->log_space_total);
mysql_mutex_unlock(&rli->log_space_lock);
0, 0, &log_space_reclaimed);
/*
Ok to broadcast after the critical region as there is no risk of
the mutex being destroyed by this thread later - this helps save
context switches
*/
mysql_mutex_lock(&rli->log_space_lock);
rli->log_space_total-= log_space_reclaimed;
mysql_cond_broadcast(&rli->log_space_cond);
mysql_mutex_unlock(&rli->log_space_lock);
/*
* Need to update the log pos because purge logs has been called
@ -4259,8 +4256,8 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
@param need_mutex
@param need_update_threads If we want to update the log coordinates of
all threads. False for relay logs, true otherwise.
@param freed_log_space If not null, decrement this variable of
the amount of log space freed
@param reclaimeed_log_space If not null, increment this variable to
the amount of log space freed
@note
If any of the logs before the deleted one is in use,
@ -4276,10 +4273,10 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
*/
int MYSQL_BIN_LOG::purge_logs(const char *to_log,
bool included,
bool need_mutex,
bool need_update_threads,
ulonglong *decrease_log_space)
bool included,
bool need_mutex,
bool need_update_threads,
ulonglong *reclaimed_space)
{
int error= 0;
bool exit_loop= 0;
@ -4343,7 +4340,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
err:
/* Read each entry from purge_index_file and delete the file. */
if (is_inited_purge_index_file() &&
(error= purge_index_entry(thd, decrease_log_space, FALSE)))
(error= purge_index_entry(thd, reclaimed_space, FALSE)))
sql_print_error("MSYQL_BIN_LOG::purge_logs failed to process registered files"
" that would be purged.");
close_purge_index_file();
@ -4448,7 +4445,7 @@ int MYSQL_BIN_LOG::register_create_index_entry(const char *entry)
DBUG_RETURN(register_purge_index_entry(entry));
}
int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *reclaimed_space,
bool need_mutex)
{
DBUG_ENTER("MYSQL_BIN_LOG:purge_index_entry");
@ -4568,8 +4565,8 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
DBUG_PRINT("info",("purging %s",log_info.log_file_name));
if (!my_delete(log_info.log_file_name, MYF(0)))
{
if (decrease_log_space)
*decrease_log_space-= s.st_size;
if (reclaimed_space)
*reclaimed_space+= s.st_size;
}
else
{

View File

@ -2768,6 +2768,16 @@ void unlink_thd(THD *thd)
sync feature has been shut down at this point.
*/
DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5););
if (unlikely(abort_loop))
{
/*
During shutdown, we have to delete thd inside the mutex
to not refer to mutexes that may be deleted during shutdown
*/
delete thd;
thd= 0;
}
thread_count--;
mysql_mutex_unlock(&LOCK_thread_count);
delete thd;

View File

@ -39,8 +39,6 @@ typedef struct Trans_binlog_info {
char log_file[FN_REFLEN];
} Trans_binlog_info;
static pthread_key(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
int get_user_var_int(const char *name,
long long int *value, int *null_value)
{
@ -144,13 +142,6 @@ int delegates_init()
}
#endif
if (pthread_key_create(&RPL_TRANS_BINLOG_INFO, NULL))
{
sql_print_error("Error while creating pthread specific data key for replication. "
"Please report a bug.");
return 1;
}
return 0;
}
@ -196,27 +187,27 @@ void delegates_destroy()
int Trans_delegate::after_commit(THD *thd, bool all)
{
Trans_param param;
Trans_binlog_info *log_info;
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
int ret= 0;
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
Trans_binlog_info *log_info=
my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
log_info= thd->semisync_info;
param.log_file= log_info ? log_info->log_file : 0;
param.log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
param.log_pos= log_info ? log_info->log_pos : 0;
int ret= 0;
FOREACH_OBSERVER(ret, after_commit, false, (&param));
/*
This is the end of a real transaction or autocommit statement, we
can free the memory allocated for binlog file and position.
can mark the memory unused.
*/
if (is_real_trans && log_info)
{
my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, NULL);
my_free(log_info);
log_info->log_file[0]= 0;
log_info->log_pos= 0;
}
return ret;
}
@ -224,27 +215,27 @@ int Trans_delegate::after_commit(THD *thd, bool all)
int Trans_delegate::after_rollback(THD *thd, bool all)
{
Trans_param param;
Trans_binlog_info *log_info;
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
int ret= 0;
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
Trans_binlog_info *log_info=
my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
param.log_file= log_info ? log_info->log_file : 0;
log_info= thd->semisync_info;
param.log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
param.log_pos= log_info ? log_info->log_pos : 0;
int ret= 0;
FOREACH_OBSERVER(ret, after_rollback, false, (&param));
/*
This is the end of a real transaction or autocommit statement, we
can free the memory allocated for binlog file and position.
can mark the memory unused.
*/
if (is_real_trans && log_info)
{
my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, NULL);
my_free(log_info);
log_info->log_file[0]= 0;
log_info->log_pos= 0;
}
return ret;
}
@ -255,25 +246,24 @@ int Binlog_storage_delegate::after_flush(THD *thd,
bool synced)
{
Binlog_storage_param param;
Trans_binlog_info *log_info;
uint32 flags=0;
int ret= 0;
if (synced)
flags |= BINLOG_STORAGE_IS_SYNCED;
Trans_binlog_info *log_info=
my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
if (!log_info)
if (!(log_info= thd->semisync_info))
{
if(!(log_info=
(Trans_binlog_info *)my_malloc(sizeof(Trans_binlog_info), MYF(0))))
(Trans_binlog_info*) my_malloc(sizeof(Trans_binlog_info), MYF(0))))
return 1;
my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, log_info);
thd->semisync_info= log_info;
}
strcpy(log_info->log_file, log_file+dirname_length(log_file));
log_info->log_pos = log_pos;
int ret= 0;
FOREACH_OBSERVER(ret, after_flush, false,
(&param, log_info->log_file, log_info->log_pos, flags));
return ret;

View File

@ -947,6 +947,7 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
{
Create_field *field_def=
(Create_field*) alloc_root(thd->mem_root, sizeof(Create_field));
bool unsigned_flag= 0;
if (field_list.push_back(field_def))
DBUG_RETURN(NULL);
@ -956,8 +957,7 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
uint32 max_length=
max_display_length_for_field(type(col), field_metadata(col));
switch(type(col))
{
switch(type(col)) {
int precision;
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
@ -996,6 +996,18 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
pack_length= field_metadata(col) & 0x00ff;
break;
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG:
/*
As we don't know if the integer was signed or not on the master,
assume we have same sign on master and slave. This is true when not
using conversions so it should be true also when using conversions.
*/
unsigned_flag= ((Field_num*) target_table->field[col])->unsigned_flag;
break;
default:
break;
}
@ -1003,12 +1015,13 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
DBUG_PRINT("debug", ("sql_type: %d, target_field: '%s', max_length: %d, decimals: %d,"
" maybe_null: %d, unsigned_flag: %d, pack_length: %u",
binlog_type(col), target_table->field[col]->field_name,
max_length, decimals, TRUE, FALSE, pack_length));
max_length, decimals, TRUE, unsigned_flag,
pack_length));
field_def->init_for_tmp_table(type(col),
max_length,
decimals,
TRUE, // maybe_null
FALSE, // unsigned_flag
unsigned_flag,
pack_length);
field_def->charset= target_table->field[col]->charset();
field_def->interval= interval;

View File

@ -4523,9 +4523,7 @@ pthread_handler_t handle_slave_sql(void *arg)
rli->parallel.reset();
//tell the I/O thread to take relay_log_space_limit into account from now on
mysql_mutex_lock(&rli->log_space_lock);
rli->ignore_log_space_limit= 0;
mysql_mutex_unlock(&rli->log_space_lock);
serial_rgi->gtid_sub_id= 0;
serial_rgi->gtid_pending= false;
@ -6626,14 +6624,8 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size)
rli->ignore_log_space_limit= true;
}
/*
If the I/O thread is blocked, unblock it. Ok to broadcast
after unlock, because the mutex is only destroyed in
~Relay_log_info(), i.e. when rli is destroyed, and rli will
not be destroyed before we exit the present function.
*/
mysql_mutex_unlock(&rli->log_space_lock);
mysql_cond_broadcast(&rli->log_space_cond);
mysql_mutex_unlock(&rli->log_space_lock);
// Note that wait_for_update_relay_log unlocks lock_log !
rli->relay_log.wait_for_update_relay_log(rli->sql_driver_thd);
// re-acquire data lock since we released it earlier

View File

@ -6583,6 +6583,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
if (item->cached_table)
{
DBUG_PRINT("info", ("using cached table"));
/*
This shortcut is used by prepared statements. We assume that
TABLE_LIST *first_table is not changed during query execution (which

View File

@ -960,6 +960,7 @@ THD::THD()
file_id = 0;
query_id= 0;
query_name_consts= 0;
semisync_info= 0;
db_charset= global_system_variables.collation_database;
bzero(ha_data, sizeof(ha_data));
mysys_var=0;
@ -1395,6 +1396,7 @@ void THD::init(void)
bzero((char *) &org_status_var, sizeof(org_status_var));
start_bytes_received= 0;
last_commit_gtid.seq_no= 0;
status_in_global= 0;
if (variables.sql_log_bin)
variables.option_bits|= OPTION_BIN_LOG;
@ -1500,6 +1502,7 @@ void THD::change_user(void)
cleanup();
reset_killed();
cleanup_done= 0;
status_in_global= 0;
init();
stmt_map.reset();
my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
@ -1630,6 +1633,7 @@ THD::~THD()
mysql_audit_free_thd(this);
if (rgi_slave)
rgi_slave->cleanup_after_session();
my_free(semisync_info);
#endif
free_root(&main_mem_root, MYF(0));

View File

@ -64,7 +64,6 @@ class Reprepare_observer;
class Relay_log_info;
struct rpl_group_info;
class Rpl_filter;
class Query_log_event;
class Load_log_event;
class Slave_log_event;
@ -75,6 +74,7 @@ class Parser_state;
class Rows_log_event;
class Sroutine_hash_entry;
class user_var_entry;
struct Trans_binlog_info;
class rpl_io_thread_info;
class rpl_sql_thread_info;
@ -1959,6 +1959,9 @@ public:
*/
const char *where;
/* Needed by MariaDB semi sync replication */
Trans_binlog_info *semisync_info;
ulong client_capabilities; /* What the client supports */
ulong max_client_packet_length;
@ -2027,11 +2030,11 @@ public:
/* Do not set socket timeouts for wait_timeout (used with threadpool) */
bool skip_wait_timeout;
/* container for handler's private per-connection data */
Ha_data ha_data[MAX_HA];
bool prepare_derived_at_open;
/* Set to 1 if status of this THD is already in global status */
bool status_in_global;
/*
To signal that the tmp table to be created is created for materialized
derived table or a view.
@ -2040,6 +2043,9 @@ public:
bool save_prep_leaf_list;
/* container for handler's private per-connection data */
Ha_data ha_data[MAX_HA];
#ifndef MYSQL_CLIENT
binlog_cache_mngr * binlog_setup_trx_data();
@ -3687,6 +3693,8 @@ public:
{
mysql_mutex_lock(&LOCK_status);
add_to_status(&global_status_var, &status_var);
/* Mark that this THD status has already been added in global status */
status_in_global= 1;
mysql_mutex_unlock(&LOCK_status);
}

View File

@ -1910,7 +1910,6 @@ void st_select_lex::init_select()
with_sum_func= 0;
is_correlated= 0;
cur_pos_in_select_list= UNDEF_POS;
non_agg_fields.empty();
cond_value= having_value= Item::COND_UNDEF;
inner_refs_list.empty();
insert_tables= 0;
@ -1918,6 +1917,7 @@ void st_select_lex::init_select()
m_non_agg_field_used= false;
m_agg_func_used= false;
name_visibility_map= 0;
join= 0;
}
/*

View File

@ -823,8 +823,6 @@ public:
bool no_wrap_view_item;
/* exclude this select from check of unique_table() */
bool exclude_from_table_unique_test;
/* List of fields that aren't under an aggregate function */
List<Item_field> non_agg_fields;
/* index in the select list of the expression currently being fixed */
int cur_pos_in_select_list;

View File

@ -5185,6 +5185,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
KEY_FIELD *key_fields, *end, *field;
uint sz;
uint m= MY_MAX(select_lex->max_equal_elems,1);
DBUG_ENTER("update_ref_and_keys");
DBUG_PRINT("enter", ("normal_tables: %llx", normal_tables));
SELECT_LEX *sel=thd->lex->current_select;
sel->cond_count= 0;
@ -5231,7 +5233,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
sz= MY_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
((sel->cond_count*2 + sel->between_count)*m+1);
if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
return TRUE; /* purecov: inspected */
DBUG_RETURN(TRUE); /* purecov: inspected */
and_level= 0;
field= end= key_fields;
*sargables= (SARGABLE_PARAM *) key_fields +
@ -5241,7 +5243,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64,
MYF(MY_THREAD_SPECIFIC)))
return TRUE;
DBUG_RETURN(TRUE);
if (cond)
{
@ -5291,16 +5293,16 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
for ( ; field != end ; field++)
{
if (add_key_part(keyuse,field))
return TRUE;
DBUG_RETURN(TRUE);
}
if (select_lex->ftfunc_list->elements)
{
if (add_ft_keys(keyuse,join_tab,cond,normal_tables))
return TRUE;
DBUG_RETURN(TRUE);
}
return FALSE;
DBUG_RETURN(FALSE);
}
@ -21544,7 +21546,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
Item_field *field;
int cur_pos_in_select_list= 0;
List_iterator<Item> li(fields);
List_iterator<Item_field> naf_it(thd->lex->current_select->non_agg_fields);
List_iterator<Item_field> naf_it(thd->lex->current_select->join->non_agg_fields);
field= naf_it++;
while (field && (item=li++))

View File

@ -934,6 +934,9 @@ public:
Item *pre_sort_idx_pushed_cond;
void clean_pre_sort_join_tab();
/* List of fields that aren't under an aggregate function */
List<Item_field> non_agg_fields;
/*
For "Using temporary+Using filesort" queries, JOIN::join_tab can point to
either:
@ -1326,6 +1329,7 @@ public:
all_fields= fields_arg;
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
fields_list= fields_arg;
non_agg_fields.empty();
bzero((char*) &keyuse,sizeof(keyuse));
tmp_table_param.init();
tmp_table_param.end_write_records= HA_POS_ERROR;

View File

@ -3512,7 +3512,10 @@ void calc_sum_of_all_status(STATUS_VAR *to)
/* Add to this status from existing threads */
while ((tmp= it++))
add_to_status(to, &tmp->status_var);
{
if (!tmp->status_in_global)
add_to_status(to, &tmp->status_var);
}
mysql_mutex_unlock(&LOCK_thread_count);
DBUG_VOID_RETURN;

View File

@ -222,7 +222,7 @@ TEST_join(JOIN *join)
#define FT_KEYPART (MAX_FIELDS+10)
void print_keyuse(KEYUSE *keyuse)
static void print_keyuse(KEYUSE *keyuse)
{
char buff[256];
char buf2[64];
@ -240,14 +240,11 @@ void print_keyuse(KEYUSE *keyuse)
else
fieldname= key_info->key_part[keyuse->keypart].field->field_name;
ll2str(keyuse->used_tables, buf2, 16, 0);
DBUG_LOCK_FILE;
fprintf(DBUG_FILE, "KEYUSE: %s.%s=%s optimize: %u used_tables: %s "
"ref_table_rows: %lu keypart_map: %0lx\n",
keyuse->table->alias.c_ptr(), fieldname, str.ptr(),
(uint) keyuse->optimize, buf2, (ulong) keyuse->ref_table_rows,
(ulong) keyuse->keypart_map);
DBUG_UNLOCK_FILE;
//key_part_map keypart_map; --?? there can be several?
}
@ -256,9 +253,9 @@ void print_keyuse_array(DYNAMIC_ARRAY *keyuse_array)
{
DBUG_LOCK_FILE;
fprintf(DBUG_FILE, "KEYUSE array (%d elements)\n", keyuse_array->elements);
DBUG_UNLOCK_FILE;
for(uint i=0; i < keyuse_array->elements; i++)
print_keyuse((KEYUSE*)dynamic_array_ptr(keyuse_array, i));
DBUG_UNLOCK_FILE;
}

View File

@ -1029,7 +1029,6 @@ bool st_select_lex::cleanup()
{
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
}
non_agg_fields.empty();
inner_refs_list.empty();
exclude_from_table_unique_test= FALSE;
DBUG_RETURN(error);
@ -1040,6 +1039,7 @@ void st_select_lex::cleanup_all_joins(bool full)
{
SELECT_LEX_UNIT *unit;
SELECT_LEX *sl;
DBUG_ENTER("st_select_lex::cleanup_all_joins");
if (join)
join->cleanup(full);
@ -1047,6 +1047,7 @@ void st_select_lex::cleanup_all_joins(bool full)
for (unit= first_inner_unit(); unit; unit= unit->next_unit())
for (sl= unit->first_select(); sl; sl= sl->next_select())
sl->cleanup_all_joins(full);
DBUG_VOID_RETURN;
}

View File

@ -5271,7 +5271,7 @@ Item *Field_iterator_table::create_item(THD *thd)
if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
!thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
{
select->non_agg_fields.push_back(item);
select->join->non_agg_fields.push_back(item);
item->marker= select->cur_pos_in_select_list;
select->set_non_agg_field_used(true);
}

View File

@ -1561,6 +1561,104 @@ dict_create_add_foreign_field_to_dictionary(
table_name, foreign->id, trx));
}
/********************************************************************//**
Construct foreign key constraint defintion from data dictionary information.
*/
UNIV_INTERN
char*
dict_foreign_def_get(
/*=================*/
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx) /*!< in: trx */
{
char* fk_def = (char *)mem_heap_alloc(foreign->heap, 4*1024);
const char* tbname;
char tablebuf[MAX_TABLE_NAME_LEN + 1] = "";
int i;
char* bufend;
tbname = dict_remove_db_name(foreign->id);
bufend = innobase_convert_name(tablebuf, MAX_TABLE_NAME_LEN,
tbname, strlen(tbname), trx->mysql_thd, FALSE);
tablebuf[bufend - tablebuf] = '\0';
sprintf(fk_def,
(char *)"CONSTRAINT %s FOREIGN KEY (", (char *)tablebuf);
for(i = 0; i < foreign->n_fields; i++) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
foreign->foreign_col_names[i],
strlen(foreign->foreign_col_names[i]),
trx->mysql_thd, FALSE);
strcat(fk_def, buf);
if (i < foreign->n_fields-1) {
strcat(fk_def, (char *)",");
}
}
strcat(fk_def,(char *)") REFERENCES ");
bufend = innobase_convert_name(tablebuf, MAX_TABLE_NAME_LEN,
foreign->referenced_table_name,
strlen(foreign->referenced_table_name),
trx->mysql_thd, TRUE);
tablebuf[bufend - tablebuf] = '\0';
strcat(fk_def, tablebuf);
strcat(fk_def, " (");
for(i = 0; i < foreign->n_fields; i++) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
bufend = innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
foreign->referenced_col_names[i],
strlen(foreign->referenced_col_names[i]),
trx->mysql_thd, FALSE);
buf[bufend - buf] = '\0';
strcat(fk_def, buf);
if (i < foreign->n_fields-1) {
strcat(fk_def, (char *)",");
}
}
strcat(fk_def, (char *)")");
return fk_def;
}
/********************************************************************//**
Convert foreign key column names from data dictionary to SQL-layer.
*/
static
void
dict_foreign_def_get_fields(
/*========================*/
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx, /*!< in: trx */
char** field, /*!< out: foreign column */
char** field2, /*!< out: referenced column */
int col_no) /*!< in: column number */
{
char* bufend;
char* fieldbuf = (char *)mem_heap_alloc(foreign->heap, MAX_TABLE_NAME_LEN+1);
char* fieldbuf2 = (char *)mem_heap_alloc(foreign->heap, MAX_TABLE_NAME_LEN+1);
bufend = innobase_convert_name(fieldbuf, MAX_TABLE_NAME_LEN,
foreign->foreign_col_names[col_no],
strlen(foreign->foreign_col_names[col_no]),
trx->mysql_thd, FALSE);
fieldbuf[bufend - fieldbuf] = '\0';
bufend = innobase_convert_name(fieldbuf2, MAX_TABLE_NAME_LEN,
foreign->referenced_col_names[col_no],
strlen(foreign->referenced_col_names[col_no]),
trx->mysql_thd, FALSE);
fieldbuf2[bufend - fieldbuf2] = '\0';
*field = fieldbuf;
*field2 = fieldbuf2;
}
/********************************************************************//**
Add a foreign key definition to the data dictionary tables.
@return error code or DB_SUCCESS */
@ -1568,6 +1666,7 @@ UNIV_INTERN
dberr_t
dict_create_add_foreign_to_dictionary(
/*==================================*/
dict_table_t* table, /*!< in: table */
const char* name, /*!< in: table name */
const dict_foreign_t* foreign,/*!< in: foreign key */
trx_t* trx) /*!< in/out: dictionary transaction */
@ -1595,6 +1694,29 @@ dict_create_add_foreign_to_dictionary(
if (error != DB_SUCCESS) {
if (error == DB_DUPLICATE_KEY) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
char tablename[MAX_TABLE_NAME_LEN + 1] = "";
char* fk_def;
innobase_convert_name(tablename, MAX_TABLE_NAME_LEN,
table->name, strlen(table->name),
trx->mysql_thd, TRUE);
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
foreign->id, strlen(foreign->id), trx->mysql_thd, FALSE);
fk_def = dict_foreign_def_get((dict_foreign_t*)foreign, trx);
ib_push_warning(trx, error,
"Create or Alter table %s with foreign key constraint"
" failed. Foreign key constraint %s"
" already exists on data dictionary."
" Foreign key constraint names need to be unique in database."
" Error in foreign key definition: %s.",
tablename, buf, fk_def);
}
return(error);
}
@ -1603,6 +1725,26 @@ dict_create_add_foreign_to_dictionary(
i, name, foreign, trx);
if (error != DB_SUCCESS) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
char tablename[MAX_TABLE_NAME_LEN + 1] = "";
char* field=NULL;
char* field2=NULL;
char* fk_def;
innobase_convert_name(tablename, MAX_TABLE_NAME_LEN,
table->name, strlen(table->name),
trx->mysql_thd, TRUE);
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
foreign->id, strlen(foreign->id), trx->mysql_thd, FALSE);
fk_def = dict_foreign_def_get((dict_foreign_t*)foreign, trx);
dict_foreign_def_get_fields((dict_foreign_t*)foreign, trx, &field, &field2, i);
ib_push_warning(trx, error,
"Create or Alter table %s with foreign key constraint"
" failed. Error adding foreign key constraint name %s"
" fields %s or %s to the dictionary."
" Error in foreign key definition: %s.",
tablename, buf, i+1, fk_def);
return(error);
}
@ -1649,7 +1791,7 @@ dict_create_add_foreigns_to_dictionary(
foreign = *it;
ut_ad(foreign->id != NULL);
error = dict_create_add_foreign_to_dictionary(table->name,
error = dict_create_add_foreign_to_dictionary((dict_table_t*)table, table->name,
foreign, trx);
if (error != DB_SUCCESS) {

View File

@ -3259,6 +3259,11 @@ dict_index_build_internal_fts(
}
/*====================== FOREIGN KEY PROCESSING ========================*/
#define DB_FOREIGN_KEY_IS_PREFIX_INDEX 200
#define DB_FOREIGN_KEY_COL_NOT_NULL 201
#define DB_FOREIGN_KEY_COLS_NOT_EQUAL 202
#define DB_FOREIGN_KEY_INDEX_NOT_FOUND 203
/*********************************************************************//**
Checks if a table is referenced by foreign keys.
@return TRUE if table is referenced by a foreign key */
@ -3413,15 +3418,26 @@ dict_foreign_find_index(
/*!< in: whether to check
charsets. only has an effect
if types_idx != NULL */
ulint check_null)
ulint check_null,
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
ulint* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
dict_index_t** err_index)
/*!< out: index where error
happened */
{
dict_index_t* index;
ut_ad(mutex_own(&dict_sys->mutex));
if (error) {
*error = DB_FOREIGN_KEY_INDEX_NOT_FOUND;
}
index = dict_table_get_first_index(table);
while (index != NULL) {
@ -3431,7 +3447,12 @@ dict_foreign_find_index(
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, types_idx,
check_charsets, check_null)) {
check_charsets, check_null,
error, err_col_no,err_index)) {
if (error) {
*error = DB_SUCCESS;
}
return(index);
}
@ -3536,11 +3557,15 @@ dict_foreign_add_to_cache(
}
if (ref_table && !for_in_cache->referenced_table) {
ulint index_error;
ulint err_col;
dict_index_t *err_index=NULL;
index = dict_foreign_find_index(
ref_table, NULL,
for_in_cache->referenced_col_names,
for_in_cache->n_fields, for_in_cache->foreign_index,
check_charsets, false);
check_charsets, false, &index_error, &err_col, &err_index);
if (index == NULL
&& !(ignore_err & DICT_ERR_IGNORE_FK_NOKEY)) {
@ -3572,6 +3597,10 @@ dict_foreign_add_to_cache(
}
if (for_table && !for_in_cache->foreign_table) {
ulint index_error;
ulint err_col;
dict_index_t *err_index=NULL;
index = dict_foreign_find_index(
for_table, col_names,
for_in_cache->foreign_col_names,
@ -3579,7 +3608,8 @@ dict_foreign_add_to_cache(
for_in_cache->referenced_index, check_charsets,
for_in_cache->type
& (DICT_FOREIGN_ON_DELETE_SET_NULL
| DICT_FOREIGN_ON_UPDATE_SET_NULL));
| DICT_FOREIGN_ON_UPDATE_SET_NULL),
&index_error, &err_col, &err_index);
if (index == NULL
&& !(ignore_err & DICT_ERR_IGNORE_FK_NOKEY)) {
@ -4239,6 +4269,8 @@ static
void
dict_foreign_report_syntax_err(
/*===========================*/
const char* fmt, /*!< in: syntax err msg */
const char* oper, /*!< in: operation */
const char* name, /*!< in: table name */
const char* start_of_latest_foreign,
/*!< in: start of the foreign key clause
@ -4251,11 +4283,101 @@ dict_foreign_report_syntax_err(
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nSyntax error close to:\n%s\n",
start_of_latest_foreign, ptr);
fprintf(ef, fmt, oper, name, start_of_latest_foreign, ptr);
mutex_exit(&dict_foreign_err_mutex);
}
/*********************************************************************//**
Push warning message to SQL-layer based on foreign key constraint
index match error. */
static
void
dict_foreign_push_index_error(
/*==========================*/
trx_t* trx, /*!< in: trx */
const char* operation, /*!< in: operation create or alter
*/
const char* create_name, /*!< in: table name in create or
alter table */
const char* latest_foreign, /*!< in: start of latest foreign key
constraint name */
const char** columns, /*!< in: foreign key columns */
ulint index_error, /*!< in: error code */
ulint err_col, /*!< in: column where error happened
*/
dict_index_t* err_index, /*!< in: index where error happened
*/
dict_table_t* table, /*!< in: table */
FILE* ef) /*!< in: output stream */
{
switch (index_error) {
case DB_FOREIGN_KEY_INDEX_NOT_FOUND: {
fprintf(ef,
"%s table '%s' with foreign key constraint"
" failed. There is no index in the referenced"
" table where the referenced columns appear"
" as the first columns. Error close to %s.\n",
operation, create_name, latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table '%s' with foreign key constraint"
" failed. There is no index in the referenced"
" table where the referenced columns appear"
" as the first columns. Error close to %s.",
operation, create_name, latest_foreign);
break;
}
case DB_FOREIGN_KEY_IS_PREFIX_INDEX: {
fprintf(ef,
"%s table '%s' with foreign key constraint"
" failed. There is only prefix index in the referenced"
" table where the referenced columns appear"
" as the first columns. Error close to %s.\n",
operation, create_name, latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table '%s' with foreign key constraint"
" failed. There is only prefix index in the referenced"
" table where the referenced columns appear"
" as the first columns. Error close to %s.",
operation, create_name, latest_foreign);
break;
}
case DB_FOREIGN_KEY_COL_NOT_NULL: {
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but "
"field %s on index is defined as NOT NULL close to %s\n",
operation, create_name, columns[err_col], latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but "
"field %s on index is defined as NOT NULL close to %s",
operation, create_name, columns[err_col], latest_foreign);
break;
}
case DB_FOREIGN_KEY_COLS_NOT_EQUAL: {
dict_field_t* field;
const char* col_name;
field = dict_index_get_nth_field(err_index, err_col);
col_name = dict_table_get_col_name(
table, dict_col_get_no(field->col));
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Field type or character set for column %s "
"does not mach referenced column %s close to %s\n",
operation, create_name, columns[err_col], col_name, latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Field type or character set for column %s "
"does not mach referenced column %s close to %s",
operation, create_name, columns[err_col], col_name, latest_foreign);
break;
}
default:
ut_error;
}
}
/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary the foreign
key constraints declared in the string. This function should be called after
@ -4284,16 +4406,21 @@ dict_create_foreign_constraints_low(
DB_CANNOT_ADD_CONSTRAINT if any foreign
keys are found. */
{
dict_table_t* table;
dict_table_t* referenced_table;
dict_table_t* table_to_alter;
dict_table_t* table = NULL;
dict_table_t* referenced_table = NULL;
dict_table_t* table_to_alter = NULL;
dict_table_t* table_to_create = NULL;
ulint highest_id_so_far = 0;
ulint number = 1;
dict_index_t* index;
dict_foreign_t* foreign;
dict_index_t* index = NULL;
dict_foreign_t* foreign = NULL;
const char* ptr = sql_string;
const char* start_of_latest_foreign = sql_string;
const char* start_of_latest_set = NULL;
FILE* ef = dict_foreign_err_file;
ulint index_error = DB_SUCCESS;
dict_index_t* err_index = NULL;
ulint err_col;
const char* constraint_name;
ibool success;
dberr_t error;
@ -4306,37 +4433,80 @@ dict_create_foreign_constraints_low(
ulint n_on_updates;
const dict_col_t*columns[500];
const char* column_names[500];
const char* ref_column_names[500];
const char* referenced_table_name;
dict_foreign_set local_fk_set;
dict_foreign_set_free local_fk_set_free(local_fk_set);
const char* create_table_name;
const char* orig;
char create_name[MAX_TABLE_NAME_LEN + 1];
char operation[8];
ut_ad(!srv_read_only_mode);
ut_ad(mutex_own(&(dict_sys->mutex)));
table = dict_table_get_low(name);
/* First check if we are actually doing an ALTER TABLE, and in that
case look for the table being altered */
orig = ptr;
ptr = dict_accept(cs, ptr, "ALTER", &success);
strcpy((char *)operation, success ? "Alter " : "Create ");
if (!success) {
orig = ptr;
ptr = dict_scan_to(ptr, "CREATE");
ptr = dict_scan_to(ptr, "TABLE");
ptr = dict_accept(cs, ptr, "TABLE", &success);
if (success) {
ptr = dict_scan_table_name(cs, ptr, &table_to_create, name,
&success, heap, &create_table_name);
}
if (success) {
char *bufend;
bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN,
create_table_name, strlen(create_table_name),
trx->mysql_thd, TRUE);
create_name[bufend-create_name]='\0';
ptr = orig;
} else {
char *bufend;
ptr = orig;
bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN,
name, strlen(name), trx->mysql_thd, TRUE);
create_name[bufend-create_name]='\0';
}
goto loop;
}
if (table == NULL) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef,
"Cannot find the table in the internal"
" data dictionary of InnoDB.\n"
"Create table statement:\n%s\n", sql_string);
dict_foreign_error_report_low(ef, create_name);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef, "%s table %s with foreign key constraint"
" failed. Table %s not found from data dictionary."
" Error close to %s.\n",
operation, create_name, create_name, start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_ERROR,
"%s table %s with foreign key constraint"
" failed. Table %s not found from data dictionary."
" Error close to %s.",
operation, create_name, create_name, start_of_latest_foreign);
return(DB_ERROR);
}
/* First check if we are actually doing an ALTER TABLE, and in that
case look for the table being altered */
ptr = dict_accept(cs, ptr, "ALTER", &success);
/* If not alter table jump to loop */
if (!success) {
goto loop;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "TABLE", &success);
if (!success) {
@ -4346,13 +4516,40 @@ dict_create_foreign_constraints_low(
/* We are doing an ALTER TABLE: scan the table name we are altering */
orig = ptr;
ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name,
&success, heap, &referenced_table_name);
if (table_to_alter) {
char *bufend;
bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN,
table_to_alter->name, strlen(table_to_alter->name),
trx->mysql_thd, TRUE);
create_name[bufend-create_name]='\0';
} else {
char *bufend;
bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN,
referenced_table_name, strlen(referenced_table_name),
trx->mysql_thd, TRUE);
create_name[bufend-create_name]='\0';
}
if (!success) {
fprintf(stderr,
"InnoDB: Error: could not find"
" the table being ALTERED in:\n%s\n",
sql_string);
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Table %s not found from data dictionary."
" Error close to %s.\n",
operation, create_name, create_name, orig);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_ERROR,
"%s table %s with foreign key constraint"
" failed. Table %s not found from data dictionary."
" Error close to %s.",
operation, create_name, create_name, orig);
return(DB_ERROR);
}
@ -4389,6 +4586,7 @@ loop:
of the constraint to system tables. */
ptr = ptr1;
orig = ptr;
ptr = dict_accept(cs, ptr, "CONSTRAINT", &success);
ut_a(success);
@ -4419,6 +4617,19 @@ loop:
if so, immediately reject the command if the table is a
temporary one. For now, this kludge will work. */
if (reject_fks && !local_fk_set.empty()) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef, "%s table %s with foreign key constraint"
" failed. Temporary tables can't have foreign key constraints."
" Error close to %s.\n",
operation, create_name, start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Temporary tables can't have foreign key constraints."
" Error close to %s.",
operation, create_name, start_of_latest_foreign);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4444,6 +4655,7 @@ loop:
start_of_latest_foreign = ptr;
orig = ptr;
ptr = dict_accept(cs, ptr, "FOREIGN", &success);
if (!success) {
@ -4454,6 +4666,7 @@ loop:
goto loop;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "KEY", &success);
if (!success) {
@ -4479,6 +4692,7 @@ loop:
}
}
orig = ptr;
ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
@ -4488,8 +4702,17 @@ loop:
ptr = dict_skip_word(cs, ptr, &success);
if (!success) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
}
else {
@ -4516,15 +4739,26 @@ loop:
/* Scan the columns in the first list */
col_loop1:
ut_a(i < (sizeof column_names) / sizeof *column_names);
orig = ptr;
ptr = dict_scan_col(cs, ptr, &success, table, columns + i,
heap, column_names + i);
if (!success) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nCannot resolve column name close to:\n%s\n",
start_of_latest_foreign, ptr);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4536,11 +4770,22 @@ col_loop1:
goto col_loop1;
}
orig = ptr;
ptr = dict_accept(cs, ptr, ")", &success);
if (!success) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4551,27 +4796,41 @@ col_loop1:
set to 0 */
index = dict_foreign_find_index(
table, NULL, column_names, i, NULL, TRUE, FALSE);
table, NULL, column_names, i,
NULL, TRUE, FALSE, &index_error, &err_col, &err_index);
if (!index) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
dict_foreign_error_report_low(ef, create_name);
fputs("There is no index in table ", ef);
ut_print_name(ef, NULL, TRUE, name);
ut_print_name(ef, NULL, TRUE, create_name);
fprintf(ef, " where the columns appear\n"
"as the first columns. Constraint:\n%s\n"
"See " REFMAN "innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
dict_foreign_push_index_error(trx, operation, create_name, start_of_latest_foreign,
column_names, index_error, err_col, err_index, table, ef);
return(DB_CHILD_NO_INDEX);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
}
orig = ptr;
ptr = dict_accept(cs, ptr, "REFERENCES", &success);
if (!success || !my_isspace(cs, *ptr)) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4640,21 +4899,46 @@ col_loop1:
checking of foreign key constraints! */
if (!success || (!referenced_table && trx->check_foreigns)) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
char* bufend;
bufend = innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
referenced_table_name, strlen(referenced_table_name),
trx->mysql_thd, TRUE);
buf[bufend - buf] = '\0';
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary "
"close to %s.",
operation, create_name, buf, start_of_latest_foreign);
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nCannot resolve table name close to:\n"
"%s\n",
start_of_latest_foreign, ptr);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary "
"close to %s.\n",
operation, create_name, buf, start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
}
orig = ptr;
ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
dict_foreign_report_syntax_err(
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4662,34 +4946,54 @@ col_loop1:
i = 0;
col_loop2:
orig = ptr;
ptr = dict_scan_col(cs, ptr, &success, referenced_table, columns + i,
heap, column_names + i);
heap, ref_column_names + i);
i++;
if (!success) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nCannot resolve column name close to:\n"
"%s\n",
start_of_latest_foreign, ptr);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
orig = ptr;
ptr = dict_accept(cs, ptr, ",", &success);
if (success) {
goto col_loop2;
}
orig = ptr;
ptr = dict_accept(cs, ptr, ")", &success);
if (!success || foreign->n_fields != i) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
dict_foreign_report_syntax_err(
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s. Too few referenced columns.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s. Too few referenced columns, you have %d when you should have %d.",
operation, create_name, start_of_latest_foreign, orig, i, foreign->n_fields);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4699,6 +5003,7 @@ col_loop2:
scan_on_conditions:
/* Loop here as long as we can find ON ... conditions */
start_of_latest_set = ptr;
ptr = dict_accept(cs, ptr, "ON", &success);
if (!success) {
@ -4706,15 +5011,27 @@ scan_on_conditions:
goto try_find_index;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "DELETE", &success);
if (!success) {
orig = ptr;
ptr = dict_accept(cs, ptr, "UPDATE", &success);
if (!success) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4725,12 +5042,14 @@ scan_on_conditions:
n_on_deletes++;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "RESTRICT", &success);
if (success) {
goto scan_on_conditions;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "CASCADE", &success);
if (success) {
@ -4743,14 +5062,25 @@ scan_on_conditions:
goto scan_on_conditions;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "NO", &success);
if (success) {
orig = ptr;
ptr = dict_accept(cs, ptr, "ACTION", &success);
if (!success) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4764,38 +5094,69 @@ scan_on_conditions:
goto scan_on_conditions;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "SET", &success);
if (!success) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
dict_foreign_report_syntax_err(
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
orig = ptr;
ptr = dict_accept(cs, ptr, "NULL", &success);
if (!success) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
dict_foreign_report_syntax_err(
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
for (j = 0; j < foreign->n_fields; j++) {
if ((dict_index_get_nth_col(foreign->foreign_index, j)->prtype)
& DATA_NOT_NULL) {
const dict_col_t* col
= dict_index_get_nth_col(foreign->foreign_index, j);
const char* col_name = dict_table_get_col_name(foreign->foreign_index->table,
dict_col_get_no(col));
/* It is not sensible to define SET NULL
if the column is not allowed to be NULL! */
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\n"
"You have defined a SET NULL condition"
" though some of the\n"
"columns are defined as NOT NULL.\n",
start_of_latest_foreign);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but column %s is defined as NOT NULL"
" in %s close to %s.\n",
operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but column %s is defined as NOT NULL"
" in %s close to %s.",
operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
}
@ -4813,11 +5174,20 @@ try_find_index:
/* It is an error to define more than 1 action */
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\n"
"You have twice an ON DELETE clause"
" or twice an ON UPDATE clause.\n",
start_of_latest_foreign);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. You have more than one on delete or on update clause"
" in %s close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. You have more than one on delete or on update clause"
" in %s close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
dict_foreign_free(foreign);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
@ -4829,12 +5199,12 @@ try_find_index:
if (referenced_table) {
index = dict_foreign_find_index(referenced_table, NULL,
column_names, i,
ref_column_names, i,
foreign->foreign_index,
TRUE, FALSE);
TRUE, FALSE, &index_error, &err_col, &err_index);
if (!index) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef, "%s:\n"
"Cannot find an index in the"
" referenced table where the\n"
@ -4852,9 +5222,13 @@ try_find_index:
"innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);
dict_foreign_push_index_error(trx, operation, create_name, start_of_latest_foreign,
column_names, index_error, err_col, err_index, referenced_table, ef);
mutex_exit(&dict_foreign_err_mutex);
return(DB_PARENT_NO_INDEX);
return(DB_CANNOT_ADD_CONSTRAINT);
}
} else {
ut_a(trx->check_foreigns == FALSE);
@ -4873,11 +5247,12 @@ try_find_index:
for (i = 0; i < foreign->n_fields; i++) {
foreign->referenced_col_names[i]
= mem_heap_strdup(foreign->heap, column_names[i]);
= mem_heap_strdup(foreign->heap, ref_column_names[i]);
}
goto loop;
}
/**************************************************************************
Determines whether a string starts with the specified keyword.
@return TRUE if str starts with keyword */
@ -6029,7 +6404,8 @@ dict_foreign_replace_index(
foreign->foreign_table, col_names,
foreign->foreign_col_names,
foreign->n_fields, index,
/*check_charsets=*/TRUE, /*check_null=*/FALSE);
/*check_charsets=*/TRUE, /*check_null=*/FALSE,
NULL, NULL, NULL);
if (new_index) {
ut_ad(new_index->table == index->table);
ut_ad(!new_index->to_be_dropped);
@ -6053,7 +6429,8 @@ dict_foreign_replace_index(
foreign->referenced_table, NULL,
foreign->referenced_col_names,
foreign->n_fields, index,
/*check_charsets=*/TRUE, /*check_null=*/FALSE);
/*check_charsets=*/TRUE, /*check_null=*/FALSE,
NULL, NULL, NULL);
/* There must exist an alternative index,
since this must have been checked earlier. */
if (new_index) {
@ -6622,10 +6999,17 @@ dict_foreign_qualify_index(
/*!< in: whether to check
charsets. only has an effect
if types_idx != NULL */
ulint check_null)
ulint check_null,
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
ulint* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
dict_index_t** err_index)
/*!< out: index where error
happened */
{
if (dict_index_get_n_fields(index) < n_cols) {
return(false);
@ -6642,11 +7026,21 @@ dict_foreign_qualify_index(
if (field->prefix_len != 0) {
/* We do not accept column prefix
indexes here */
if (error && err_col_no && err_index) {
*error = DB_FOREIGN_KEY_IS_PREFIX_INDEX;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
return(false);
}
if (check_null
&& (field->col->prtype & DATA_NOT_NULL)) {
if (error && err_col_no && err_index) {
*error = DB_FOREIGN_KEY_COL_NOT_NULL;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
return(false);
}
@ -6662,6 +7056,12 @@ dict_foreign_qualify_index(
dict_index_get_nth_col(index, i),
dict_index_get_nth_col(types_idx, i),
check_charsets)) {
if (error && err_col_no && err_index) {
*error = DB_FOREIGN_KEY_COLS_NOT_EQUAL;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
return(false);
}
}

View File

@ -417,7 +417,8 @@ dict_mem_table_col_rename_low(
dict_index_t* new_index = dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields, NULL, true, false);
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL);
/* There must be an equivalent index in this case. */
ut_ad(new_index != NULL);

View File

@ -2125,6 +2125,7 @@ check_trx_exists(
if (trx == NULL) {
trx = innobase_trx_allocate(thd);
thd_set_ha_data(thd, innodb_hton_ptr, trx);
} else if (UNIV_UNLIKELY(trx->magic_n != TRX_MAGIC_N)) {
mem_analyze_corruption(trx);
ut_error;
@ -17633,3 +17634,29 @@ ib_warn_row_too_big(const dict_table_t* table)
" ROW_FORMAT=COMPRESSED ": ""
, prefix ? DICT_MAX_FIXED_COL_LEN : 0);
}
/********************************************************************//**
Helper function to push warnings from InnoDB internals to SQL-layer. */
UNIV_INTERN
void
ib_push_warning(
trx_t* trx, /*!< in: trx */
ulint error, /*!< in: error code to push as warning */
const char *format,/*!< in: warning message */
...)
{
va_list args;
THD *thd = (THD *)trx->mysql_thd;
char *buf;
#define MAX_BUF_SIZE 4*1024
va_start(args, format);
buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME));
vsprintf(buf,format, args);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
convert_error_code_to_mysql((dberr_t)error, 0, thd),
buf);
my_free(buf);
va_end(args);
}

View File

@ -824,7 +824,8 @@ innobase_find_fk_index(
if (!(index->type & DICT_FTS)
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, NULL, true, 0)) {
index, NULL, true, 0,
NULL, NULL, NULL)) {
for (ulint i = 0; i < n_drop_index; i++) {
if (index == drop_index[i]) {
/* Skip to-be-dropped indexes. */
@ -1014,7 +1015,8 @@ innobase_get_foreign_key_info(
referenced_table, 0,
referenced_column_names,
i, index,
TRUE, FALSE);
TRUE, FALSE,
NULL, NULL, NULL);
DBUG_EXECUTE_IF(
"innodb_test_no_reference_idx",
@ -3317,7 +3319,8 @@ innobase_check_foreign_key_index(
foreign->referenced_col_names,
foreign->n_fields, index,
/*check_charsets=*/TRUE,
/*check_null=*/FALSE)
/*check_null=*/FALSE,
NULL, NULL, NULL)
&& !innobase_find_equiv_index(
foreign->referenced_col_names,
foreign->n_fields,
@ -3345,7 +3348,8 @@ innobase_check_foreign_key_index(
foreign->foreign_col_names,
foreign->n_fields, index,
/*check_charsets=*/TRUE,
/*check_null=*/FALSE)
/*check_null=*/FALSE,
NULL, NULL, NULL)
&& !innobase_find_equiv_index(
foreign->foreign_col_names,
foreign->n_fields,
@ -4789,7 +4793,8 @@ innobase_update_foreign_try(
fk->n_fields, fk->referenced_index, TRUE,
fk->type
& (DICT_FOREIGN_ON_DELETE_SET_NULL
| DICT_FOREIGN_ON_UPDATE_SET_NULL));
| DICT_FOREIGN_ON_UPDATE_SET_NULL),
NULL, NULL, NULL);
if (!fk->foreign_index) {
my_error(ER_FK_INCORRECT_OPTION,
MYF(0), table_name, fk->id);
@ -4801,7 +4806,7 @@ innobase_update_foreign_try(
names, while the columns in ctx->old_table have not
been renamed yet. */
error = dict_create_add_foreign_to_dictionary(
ctx->old_table->name, fk, trx);
(dict_table_t*)ctx->old_table,ctx->old_table->name, fk, trx);
DBUG_EXECUTE_IF(
"innodb_test_cannot_add_fk_system",

View File

@ -110,6 +110,17 @@ UNIV_INTERN
dberr_t
dict_create_or_check_foreign_constraint_tables(void);
/*================================================*/
/********************************************************************//**
Construct foreign key constraint defintion from data dictionary information.
*/
UNIV_INTERN
char*
dict_foreign_def_get(
/*=================*/
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx); /*!< in: trx */
/********************************************************************//**
Generate a foreign key constraint name when it was not named by the user.
A generated constraint has a name of the format dbname/tablename_ibfk_NUMBER,
@ -174,11 +185,22 @@ UNIV_INTERN
dberr_t
dict_create_add_foreign_to_dictionary(
/*==================================*/
dict_table_t* table, /*!< in: table */
const char* name, /*!< in: table name */
const dict_foreign_t* foreign,/*!< in: foreign key */
trx_t* trx) /*!< in/out: dictionary transaction */
__attribute__((nonnull, warn_unused_result));
/********************************************************************//**
Construct foreign key constraint defintion from data dictionary information.
*/
UNIV_INTERN
char*
dict_foreign_def_get(
/*=================*/
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx); /*!< in: trx */
/* Table create node structure */
struct tab_node_t{
que_common_t common; /*!< node type: QUE_NODE_TABLE_CREATE */

View File

@ -580,10 +580,18 @@ dict_foreign_find_index(
/*!< in: whether to check
charsets. only has an effect
if types_idx != NULL */
ulint check_null)
ulint check_null,
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
ulint* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
dict_index_t** err_index)
/*!< out: index where error
happened */
__attribute__((nonnull(1,3), warn_unused_result));
/**********************************************************************//**
Returns a column's name.
@ -675,10 +683,17 @@ dict_foreign_qualify_index(
/*!< in: whether to check
charsets. only has an effect
if types_idx != NULL */
ulint check_null)
ulint check_null,
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
ulint* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
dict_index_t** err_index)
/*!< out: index where error
happened */
__attribute__((nonnull(1,3), warn_unused_result));
#ifdef UNIV_DEBUG
/********************************************************************//**

View File

@ -615,5 +615,14 @@ innobase_convert_to_filename_charset(
const char* from, /* in: identifier to convert */
ulint len); /* in: length of 'to', in bytes */
/********************************************************************//**
Helper function to push warnings from InnoDB internals to SQL-layer. */
UNIV_INTERN
void
ib_push_warning(
trx_t* trx, /*!< in: trx */
ulint error, /*!< in: error code to push as warning */
const char *format,/*!< in: warning message */
...);
#endif /* HA_INNODB_PROTOTYPES_H */

View File

@ -1561,6 +1561,104 @@ dict_create_add_foreign_field_to_dictionary(
table_name, foreign->id, trx));
}
/********************************************************************//**
Construct foreign key constraint defintion from data dictionary information.
*/
UNIV_INTERN
char*
dict_foreign_def_get(
/*=================*/
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx) /*!< in: trx */
{
char* fk_def = (char *)mem_heap_alloc(foreign->heap, 4*1024);
const char* tbname;
char tablebuf[MAX_TABLE_NAME_LEN + 1] = "";
int i;
char* bufend;
tbname = dict_remove_db_name(foreign->id);
bufend = innobase_convert_name(tablebuf, MAX_TABLE_NAME_LEN,
tbname, strlen(tbname), trx->mysql_thd, FALSE);
tablebuf[bufend - tablebuf] = '\0';
sprintf(fk_def,
(char *)"CONSTRAINT %s FOREIGN KEY (", (char *)tablebuf);
for(i = 0; i < foreign->n_fields; i++) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
foreign->foreign_col_names[i],
strlen(foreign->foreign_col_names[i]),
trx->mysql_thd, FALSE);
strcat(fk_def, buf);
if (i < foreign->n_fields-1) {
strcat(fk_def, (char *)",");
}
}
strcat(fk_def,(char *)") REFERENCES ");
bufend = innobase_convert_name(tablebuf, MAX_TABLE_NAME_LEN,
foreign->referenced_table_name,
strlen(foreign->referenced_table_name),
trx->mysql_thd, TRUE);
tablebuf[bufend - tablebuf] = '\0';
strcat(fk_def, tablebuf);
strcat(fk_def, " (");
for(i = 0; i < foreign->n_fields; i++) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
bufend = innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
foreign->referenced_col_names[i],
strlen(foreign->referenced_col_names[i]),
trx->mysql_thd, FALSE);
buf[bufend - buf] = '\0';
strcat(fk_def, buf);
if (i < foreign->n_fields-1) {
strcat(fk_def, (char *)",");
}
}
strcat(fk_def, (char *)")");
return fk_def;
}
/********************************************************************//**
Convert foreign key column names from data dictionary to SQL-layer.
*/
static
void
dict_foreign_def_get_fields(
/*========================*/
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx, /*!< in: trx */
char** field, /*!< out: foreign column */
char** field2, /*!< out: referenced column */
int col_no) /*!< in: column number */
{
char* bufend;
char* fieldbuf = (char *)mem_heap_alloc(foreign->heap, MAX_TABLE_NAME_LEN+1);
char* fieldbuf2 = (char *)mem_heap_alloc(foreign->heap, MAX_TABLE_NAME_LEN+1);
bufend = innobase_convert_name(fieldbuf, MAX_TABLE_NAME_LEN,
foreign->foreign_col_names[col_no],
strlen(foreign->foreign_col_names[col_no]),
trx->mysql_thd, FALSE);
fieldbuf[bufend - fieldbuf] = '\0';
bufend = innobase_convert_name(fieldbuf2, MAX_TABLE_NAME_LEN,
foreign->referenced_col_names[col_no],
strlen(foreign->referenced_col_names[col_no]),
trx->mysql_thd, FALSE);
fieldbuf2[bufend - fieldbuf2] = '\0';
*field = fieldbuf;
*field2 = fieldbuf2;
}
/********************************************************************//**
Add a foreign key definition to the data dictionary tables.
@return error code or DB_SUCCESS */
@ -1568,6 +1666,7 @@ UNIV_INTERN
dberr_t
dict_create_add_foreign_to_dictionary(
/*==================================*/
dict_table_t* table,
const char* name, /*!< in: table name */
const dict_foreign_t* foreign,/*!< in: foreign key */
trx_t* trx) /*!< in/out: dictionary transaction */
@ -1594,6 +1693,28 @@ dict_create_add_foreign_to_dictionary(
, name, foreign->id, trx);
if (error != DB_SUCCESS) {
if (error == DB_DUPLICATE_KEY) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
char tablename[MAX_TABLE_NAME_LEN + 1] = "";
char* fk_def;
innobase_convert_name(tablename, MAX_TABLE_NAME_LEN,
table->name, strlen(table->name),
trx->mysql_thd, TRUE);
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
foreign->id, strlen(foreign->id), trx->mysql_thd, FALSE);
fk_def = dict_foreign_def_get((dict_foreign_t*)foreign, trx);
ib_push_warning(trx, error,
"Create or Alter table %s with foreign key constraint"
" failed. Foreign key constraint %s"
" already exists on data dictionary."
" Foreign key constraint names need to be unique in database."
" Error in foreign key definition: %s.",
tablename, buf, fk_def);
}
return(error);
}
@ -1603,6 +1724,26 @@ dict_create_add_foreign_to_dictionary(
i, name, foreign, trx);
if (error != DB_SUCCESS) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
char tablename[MAX_TABLE_NAME_LEN + 1] = "";
char* field=NULL;
char* field2=NULL;
char* fk_def;
innobase_convert_name(tablename, MAX_TABLE_NAME_LEN,
table->name, strlen(table->name),
trx->mysql_thd, TRUE);
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
foreign->id, strlen(foreign->id), trx->mysql_thd, FALSE);
fk_def = dict_foreign_def_get((dict_foreign_t*)foreign, trx);
dict_foreign_def_get_fields((dict_foreign_t*)foreign, trx, &field, &field2, i);
ib_push_warning(trx, error,
"Create or Alter table %s with foreign key constraint"
" failed. Error adding foreign key constraint name %s"
" fields %s or %s to the dictionary."
" Error in foreign key definition: %s.",
tablename, buf, i+1, fk_def);
return(error);
}
@ -1649,7 +1790,7 @@ dict_create_add_foreigns_to_dictionary(
foreign = *it;
ut_ad(foreign->id != NULL);
error = dict_create_add_foreign_to_dictionary(table->name,
error = dict_create_add_foreign_to_dictionary((dict_table_t*)table, table->name,
foreign, trx);
if (error != DB_SUCCESS) {

View File

@ -3263,6 +3263,11 @@ dict_index_build_internal_fts(
}
/*====================== FOREIGN KEY PROCESSING ========================*/
#define DB_FOREIGN_KEY_IS_PREFIX_INDEX 200
#define DB_FOREIGN_KEY_COL_NOT_NULL 201
#define DB_FOREIGN_KEY_COLS_NOT_EQUAL 202
#define DB_FOREIGN_KEY_INDEX_NOT_FOUND 203
/*********************************************************************//**
Checks if a table is referenced by foreign keys.
@return TRUE if table is referenced by a foreign key */
@ -3417,15 +3422,26 @@ dict_foreign_find_index(
/*!< in: whether to check
charsets. only has an effect
if types_idx != NULL */
ulint check_null)
ulint check_null,
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
ulint* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
dict_index_t** err_index)
/*!< out: index where error
happened */
{
dict_index_t* index;
ut_ad(mutex_own(&dict_sys->mutex));
if (error) {
*error = DB_FOREIGN_KEY_INDEX_NOT_FOUND;
}
index = dict_table_get_first_index(table);
while (index != NULL) {
@ -3435,7 +3451,8 @@ dict_foreign_find_index(
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, types_idx,
check_charsets, check_null)) {
check_charsets, check_null,
error, err_col_no,err_index)) {
return(index);
}
@ -3544,7 +3561,7 @@ dict_foreign_add_to_cache(
ref_table, NULL,
for_in_cache->referenced_col_names,
for_in_cache->n_fields, for_in_cache->foreign_index,
check_charsets, false);
check_charsets, false, NULL, NULL, NULL);
if (index == NULL
&& !(ignore_err & DICT_ERR_IGNORE_FK_NOKEY)) {
@ -3576,6 +3593,10 @@ dict_foreign_add_to_cache(
}
if (for_table && !for_in_cache->foreign_table) {
ulint index_error;
ulint err_col;
dict_index_t *err_index=NULL;
index = dict_foreign_find_index(
for_table, col_names,
for_in_cache->foreign_col_names,
@ -3583,7 +3604,8 @@ dict_foreign_add_to_cache(
for_in_cache->referenced_index, check_charsets,
for_in_cache->type
& (DICT_FOREIGN_ON_DELETE_SET_NULL
| DICT_FOREIGN_ON_UPDATE_SET_NULL));
| DICT_FOREIGN_ON_UPDATE_SET_NULL),
&index_error, &err_col, &err_index);
if (index == NULL
&& !(ignore_err & DICT_ERR_IGNORE_FK_NOKEY)) {
@ -4243,6 +4265,8 @@ static
void
dict_foreign_report_syntax_err(
/*===========================*/
const char* fmt, /*!< in: syntax err msg */
const char* oper, /*!< in: operation */
const char* name, /*!< in: table name */
const char* start_of_latest_foreign,
/*!< in: start of the foreign key clause
@ -4255,11 +4279,101 @@ dict_foreign_report_syntax_err(
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nSyntax error close to:\n%s\n",
start_of_latest_foreign, ptr);
fprintf(ef, fmt, oper, name, start_of_latest_foreign, ptr);
mutex_exit(&dict_foreign_err_mutex);
}
/*********************************************************************//**
Push warning message to SQL-layer based on foreign key constraint
index match error. */
static
void
dict_foreign_push_index_error(
/*==========================*/
trx_t* trx, /*!< in: trx */
const char* operation, /*!< in: operation create or alter
*/
const char* create_name, /*!< in: table name in create or
alter table */
const char* latest_foreign, /*!< in: start of latest foreign key
constraint name */
const char** columns, /*!< in: foreign key columns */
ulint index_error, /*!< in: error code */
ulint err_col, /*!< in: column where error happened
*/
dict_index_t* err_index, /*!< in: index where error happened
*/
dict_table_t* table, /*!< in: table */
FILE* ef) /*!< in: output stream */
{
switch (index_error) {
case DB_FOREIGN_KEY_INDEX_NOT_FOUND: {
fprintf(ef,
"%s table '%s' with foreign key constraint"
" failed. There is no index in the referenced"
" table where the referenced columns appear"
" as the first columns. Error close to %s.\n",
operation, create_name, latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table '%s' with foreign key constraint"
" failed. There is no index in the referenced"
" table where the referenced columns appear"
" as the first columns. Error close to %s.",
operation, create_name, latest_foreign);
break;
}
case DB_FOREIGN_KEY_IS_PREFIX_INDEX: {
fprintf(ef,
"%s table '%s' with foreign key constraint"
" failed. There is only prefix index in the referenced"
" table where the referenced columns appear"
" as the first columns. Error close to %s.\n",
operation, create_name, latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table '%s' with foreign key constraint"
" failed. There is only prefix index in the referenced"
" table where the referenced columns appear"
" as the first columns. Error close to %s.",
operation, create_name, latest_foreign);
break;
}
case DB_FOREIGN_KEY_COL_NOT_NULL: {
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but "
"field %s on index is defined as NOT NULL close to %s\n",
operation, create_name, columns[err_col], latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but "
"field %s on index is defined as NOT NULL close to %s",
operation, create_name, columns[err_col], latest_foreign);
break;
}
case DB_FOREIGN_KEY_COLS_NOT_EQUAL: {
dict_field_t* field;
const char* col_name;
field = dict_index_get_nth_field(err_index, err_col);
col_name = dict_table_get_col_name(
table, dict_col_get_no(field->col));
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Field type or character set for column %s "
"does not mach referenced column %s close to %s\n",
operation, create_name, columns[err_col], col_name, latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Field type or character set for column %s "
"does not mach referenced column %s close to %s",
operation, create_name, columns[err_col], col_name, latest_foreign);
break;
}
default:
ut_error;
}
}
/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary the foreign
key constraints declared in the string. This function should be called after
@ -4288,16 +4402,21 @@ dict_create_foreign_constraints_low(
DB_CANNOT_ADD_CONSTRAINT if any foreign
keys are found. */
{
dict_table_t* table;
dict_table_t* referenced_table;
dict_table_t* table_to_alter;
dict_table_t* table = NULL;
dict_table_t* referenced_table = NULL;
dict_table_t* table_to_alter = NULL;
dict_table_t* table_to_create = NULL;
ulint highest_id_so_far = 0;
ulint number = 1;
dict_index_t* index;
dict_foreign_t* foreign;
dict_index_t* index = NULL;
dict_foreign_t* foreign = NULL;
const char* ptr = sql_string;
const char* start_of_latest_foreign = sql_string;
const char* start_of_latest_set = NULL;
FILE* ef = dict_foreign_err_file;
ulint index_error = DB_SUCCESS;
dict_index_t* err_index = NULL;
ulint err_col;
const char* constraint_name;
ibool success;
dberr_t error;
@ -4310,37 +4429,80 @@ dict_create_foreign_constraints_low(
ulint n_on_updates;
const dict_col_t*columns[500];
const char* column_names[500];
const char* ref_column_names[500];
const char* referenced_table_name;
dict_foreign_set local_fk_set;
dict_foreign_set_free local_fk_set_free(local_fk_set);
const char* create_table_name;
const char* orig;
char create_name[MAX_TABLE_NAME_LEN + 1];
char operation[8];
ut_ad(!srv_read_only_mode);
ut_ad(mutex_own(&(dict_sys->mutex)));
table = dict_table_get_low(name);
/* First check if we are actually doing an ALTER TABLE, and in that
case look for the table being altered */
orig = ptr;
ptr = dict_accept(cs, ptr, "ALTER", &success);
strcpy((char *)operation, success ? "Alter " : "Create ");
if (!success) {
orig = ptr;
ptr = dict_scan_to(ptr, "CREATE");
ptr = dict_scan_to(ptr, "TABLE");
ptr = dict_accept(cs, ptr, "TABLE", &success);
if (success) {
ptr = dict_scan_table_name(cs, ptr, &table_to_create, name,
&success, heap, &create_table_name);
}
if (success) {
char *bufend;
bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN,
create_table_name, strlen(create_table_name),
trx->mysql_thd, TRUE);
create_name[bufend-create_name]='\0';
ptr = orig;
} else {
char *bufend;
ptr = orig;
bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN,
name, strlen(name), trx->mysql_thd, TRUE);
create_name[bufend-create_name]='\0';
}
goto loop;
}
if (table == NULL) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef,
"Cannot find the table in the internal"
" data dictionary of InnoDB.\n"
"Create table statement:\n%s\n", sql_string);
dict_foreign_error_report_low(ef, create_name);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef, "%s table %s with foreign key constraint"
" failed. Table %s not found from data dictionary."
" Error close to %s.\n",
operation, create_name, create_name, start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_ERROR,
"%s table %s with foreign key constraint"
" failed. Table %s not found from data dictionary."
" Error close to %s.",
operation, create_name, create_name, start_of_latest_foreign);
return(DB_ERROR);
}
/* First check if we are actually doing an ALTER TABLE, and in that
case look for the table being altered */
ptr = dict_accept(cs, ptr, "ALTER", &success);
/* If not alter table jump to loop */
if (!success) {
goto loop;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "TABLE", &success);
if (!success) {
@ -4350,13 +4512,40 @@ dict_create_foreign_constraints_low(
/* We are doing an ALTER TABLE: scan the table name we are altering */
orig = ptr;
ptr = dict_scan_table_name(cs, ptr, &table_to_alter, name,
&success, heap, &referenced_table_name);
if (table_to_alter) {
char *bufend;
bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN,
table_to_alter->name, strlen(table_to_alter->name),
trx->mysql_thd, TRUE);
create_name[bufend-create_name]='\0';
} else {
char *bufend;
bufend = innobase_convert_name((char *)create_name, MAX_TABLE_NAME_LEN,
referenced_table_name, strlen(referenced_table_name),
trx->mysql_thd, TRUE);
create_name[bufend-create_name]='\0';
}
if (!success) {
fprintf(stderr,
"InnoDB: Error: could not find"
" the table being ALTERED in:\n%s\n",
sql_string);
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Table %s not found from data dictionary."
" Error close to %s.\n",
operation, create_name, create_name, orig);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_ERROR,
"%s table %s with foreign key constraint"
" failed. Table %s not found from data dictionary."
" Error close to %s.",
operation, create_name, create_name, orig);
return(DB_ERROR);
}
@ -4393,6 +4582,7 @@ loop:
of the constraint to system tables. */
ptr = ptr1;
orig = ptr;
ptr = dict_accept(cs, ptr, "CONSTRAINT", &success);
ut_a(success);
@ -4423,6 +4613,19 @@ loop:
if so, immediately reject the command if the table is a
temporary one. For now, this kludge will work. */
if (reject_fks && !local_fk_set.empty()) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef, "%s table %s with foreign key constraint"
" failed. Temporary tables can't have foreign key constraints."
" Error close to %s.\n",
operation, create_name, start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Temporary tables can't have foreign key constraints."
" Error close to %s.",
operation, create_name, start_of_latest_foreign);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4448,6 +4651,7 @@ loop:
start_of_latest_foreign = ptr;
orig = ptr;
ptr = dict_accept(cs, ptr, "FOREIGN", &success);
if (!success) {
@ -4458,6 +4662,7 @@ loop:
goto loop;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "KEY", &success);
if (!success) {
@ -4483,6 +4688,7 @@ loop:
}
}
orig = ptr;
ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
@ -4492,8 +4698,17 @@ loop:
ptr = dict_skip_word(cs, ptr, &success);
if (!success) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
return(DB_CANNOT_ADD_CONSTRAINT);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
}
else {
@ -4520,15 +4735,26 @@ loop:
/* Scan the columns in the first list */
col_loop1:
ut_a(i < (sizeof column_names) / sizeof *column_names);
orig = ptr;
ptr = dict_scan_col(cs, ptr, &success, table, columns + i,
heap, column_names + i);
if (!success) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nCannot resolve column name close to:\n%s\n",
start_of_latest_foreign, ptr);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4540,11 +4766,22 @@ col_loop1:
goto col_loop1;
}
orig = ptr;
ptr = dict_accept(cs, ptr, ")", &success);
if (!success) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4555,27 +4792,41 @@ col_loop1:
set to 0 */
index = dict_foreign_find_index(
table, NULL, column_names, i, NULL, TRUE, FALSE);
table, NULL, column_names, i,
NULL, TRUE, FALSE, &index_error, &err_col, &err_index);
if (!index) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
dict_foreign_error_report_low(ef, create_name);
fputs("There is no index in table ", ef);
ut_print_name(ef, NULL, TRUE, name);
ut_print_name(ef, NULL, TRUE, create_name);
fprintf(ef, " where the columns appear\n"
"as the first columns. Constraint:\n%s\n"
"See " REFMAN "innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
dict_foreign_push_index_error(trx, operation, create_name, start_of_latest_foreign,
column_names, index_error, err_col, err_index, table, ef);
return(DB_CHILD_NO_INDEX);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
}
orig = ptr;
ptr = dict_accept(cs, ptr, "REFERENCES", &success);
if (!success || !my_isspace(cs, *ptr)) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4644,21 +4895,46 @@ col_loop1:
checking of foreign key constraints! */
if (!success || (!referenced_table && trx->check_foreigns)) {
char buf[MAX_TABLE_NAME_LEN + 1] = "";
char* bufend;
bufend = innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
referenced_table_name, strlen(referenced_table_name),
trx->mysql_thd, TRUE);
buf[bufend - buf] = '\0';
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary "
"close to %s.",
operation, create_name, buf, start_of_latest_foreign);
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nCannot resolve table name close to:\n"
"%s\n",
start_of_latest_foreign, ptr);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint failed. Referenced table %s not found in the data dictionary "
"close to %s.\n",
operation, create_name, buf, start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
}
orig = ptr;
ptr = dict_accept(cs, ptr, "(", &success);
if (!success) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
dict_foreign_report_syntax_err(
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4666,34 +4942,54 @@ col_loop1:
i = 0;
col_loop2:
orig = ptr;
ptr = dict_scan_col(cs, ptr, &success, referenced_table, columns + i,
heap, column_names + i);
heap, ref_column_names + i);
i++;
if (!success) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\nCannot resolve column name close to:\n"
"%s\n",
start_of_latest_foreign, ptr);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, orig);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, orig);
return(DB_CANNOT_ADD_CONSTRAINT);
}
orig = ptr;
ptr = dict_accept(cs, ptr, ",", &success);
if (success) {
goto col_loop2;
}
orig = ptr;
ptr = dict_accept(cs, ptr, ")", &success);
if (!success || foreign->n_fields != i) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
dict_foreign_report_syntax_err(
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s. Too few referenced columns.\n",
operation, create_name, start_of_latest_foreign, orig);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s. Too few referenced columns, you have %d when you should have %d.",
operation, create_name, start_of_latest_foreign, orig, i, foreign->n_fields);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4703,6 +4999,7 @@ col_loop2:
scan_on_conditions:
/* Loop here as long as we can find ON ... conditions */
start_of_latest_set = ptr;
ptr = dict_accept(cs, ptr, "ON", &success);
if (!success) {
@ -4710,15 +5007,27 @@ scan_on_conditions:
goto try_find_index;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "DELETE", &success);
if (!success) {
orig = ptr;
ptr = dict_accept(cs, ptr, "UPDATE", &success);
if (!success) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4729,12 +5038,14 @@ scan_on_conditions:
n_on_deletes++;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "RESTRICT", &success);
if (success) {
goto scan_on_conditions;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "CASCADE", &success);
if (success) {
@ -4747,14 +5058,25 @@ scan_on_conditions:
goto scan_on_conditions;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "NO", &success);
if (success) {
orig = ptr;
ptr = dict_accept(cs, ptr, "ACTION", &success);
if (!success) {
dict_foreign_report_syntax_err(
name, start_of_latest_foreign, ptr);
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
@ -4768,38 +5090,69 @@ scan_on_conditions:
goto scan_on_conditions;
}
orig = ptr;
ptr = dict_accept(cs, ptr, "SET", &success);
if (!success) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
dict_foreign_report_syntax_err(
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
orig = ptr;
ptr = dict_accept(cs, ptr, "NULL", &success);
if (!success) {
dict_foreign_report_syntax_err(name, start_of_latest_foreign,
ptr);
dict_foreign_report_syntax_err(
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. Foreign key constraint parse error in %s"
" close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
for (j = 0; j < foreign->n_fields; j++) {
if ((dict_index_get_nth_col(foreign->foreign_index, j)->prtype)
& DATA_NOT_NULL) {
const dict_col_t* col
= dict_index_get_nth_col(foreign->foreign_index, j);
const char* col_name = dict_table_get_col_name(foreign->foreign_index->table,
dict_col_get_no(col));
/* It is not sensible to define SET NULL
if the column is not allowed to be NULL! */
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\n"
"You have defined a SET NULL condition"
" though some of the\n"
"columns are defined as NOT NULL.\n",
start_of_latest_foreign);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but column %s is defined as NOT NULL"
" in %s close to %s.\n",
operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set);
mutex_exit(&dict_foreign_err_mutex);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but column %s is defined as NOT NULL"
" in %s close to %s.",
operation, create_name, col_name, start_of_latest_foreign, start_of_latest_set);
return(DB_CANNOT_ADD_CONSTRAINT);
}
}
@ -4817,11 +5170,20 @@ try_find_index:
/* It is an error to define more than 1 action */
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fprintf(ef, "%s:\n"
"You have twice an ON DELETE clause"
" or twice an ON UPDATE clause.\n",
start_of_latest_foreign);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. You have more than one on delete or on update clause"
" in %s close to %s.\n",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
"%s table %s with foreign key constraint"
" failed. You have more than one on delete or on update clause"
" in %s close to %s.",
operation, create_name, start_of_latest_foreign, start_of_latest_set);
dict_foreign_free(foreign);
mutex_exit(&dict_foreign_err_mutex);
return(DB_CANNOT_ADD_CONSTRAINT);
@ -4833,12 +5195,12 @@ try_find_index:
if (referenced_table) {
index = dict_foreign_find_index(referenced_table, NULL,
column_names, i,
ref_column_names, i,
foreign->foreign_index,
TRUE, FALSE);
TRUE, FALSE, &index_error, &err_col, &err_index);
if (!index) {
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
dict_foreign_error_report_low(ef, create_name);
fprintf(ef, "%s:\n"
"Cannot find an index in the"
" referenced table where the\n"
@ -4856,9 +5218,13 @@ try_find_index:
"innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);
dict_foreign_push_index_error(trx, operation, create_name, start_of_latest_foreign,
column_names, index_error, err_col, err_index, referenced_table, ef);
mutex_exit(&dict_foreign_err_mutex);
return(DB_PARENT_NO_INDEX);
return(DB_CANNOT_ADD_CONSTRAINT);
}
} else {
ut_a(trx->check_foreigns == FALSE);
@ -4877,11 +5243,12 @@ try_find_index:
for (i = 0; i < foreign->n_fields; i++) {
foreign->referenced_col_names[i]
= mem_heap_strdup(foreign->heap, column_names[i]);
= mem_heap_strdup(foreign->heap, ref_column_names[i]);
}
goto loop;
}
/**************************************************************************
Determines whether a string starts with the specified keyword.
@return TRUE if str starts with keyword */
@ -6071,7 +6438,8 @@ dict_foreign_replace_index(
foreign->foreign_table, col_names,
foreign->foreign_col_names,
foreign->n_fields, index,
/*check_charsets=*/TRUE, /*check_null=*/FALSE);
/*check_charsets=*/TRUE, /*check_null=*/FALSE,
NULL, NULL, NULL);
if (new_index) {
ut_ad(new_index->table == index->table);
ut_ad(!new_index->to_be_dropped);
@ -6095,7 +6463,8 @@ dict_foreign_replace_index(
foreign->referenced_table, NULL,
foreign->referenced_col_names,
foreign->n_fields, index,
/*check_charsets=*/TRUE, /*check_null=*/FALSE);
/*check_charsets=*/TRUE, /*check_null=*/FALSE,
NULL, NULL, NULL);
/* There must exist an alternative index,
since this must have been checked earlier. */
if (new_index) {
@ -6656,10 +7025,15 @@ dict_foreign_qualify_index(
/*!< in: whether to check
charsets. only has an effect
if types_idx != NULL */
ulint check_null)
ulint check_null,
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
ulint* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where error happened */
dict_index_t** err_index)
/*!< out: index where error happened */
{
if (dict_index_get_n_fields(index) < n_cols) {
return(false);
@ -6676,11 +7050,21 @@ dict_foreign_qualify_index(
if (field->prefix_len != 0) {
/* We do not accept column prefix
indexes here */
if (error && err_col_no && err_index) {
*error = DB_FOREIGN_KEY_IS_PREFIX_INDEX;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
return(false);
}
if (check_null
&& (field->col->prtype & DATA_NOT_NULL)) {
if (error && err_col_no && err_index) {
*error = DB_FOREIGN_KEY_COL_NOT_NULL;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
return(false);
}
@ -6696,6 +7080,12 @@ dict_foreign_qualify_index(
dict_index_get_nth_col(index, i),
dict_index_get_nth_col(types_idx, i),
check_charsets)) {
if (error && err_col_no && err_index) {
*error = DB_FOREIGN_KEY_COLS_NOT_EQUAL;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
return(false);
}
}

View File

@ -420,7 +420,8 @@ dict_mem_table_col_rename_low(
dict_index_t* new_index = dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields, NULL, true, false);
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL);
/* There must be an equivalent index in this case. */
ut_ad(new_index != NULL);

View File

@ -2413,6 +2413,7 @@ check_trx_exists(
if (trx == NULL) {
trx = innobase_trx_allocate(thd);
thd_set_ha_data(thd, innodb_hton_ptr, trx);
} else if (UNIV_UNLIKELY(trx->magic_n != TRX_MAGIC_N)) {
mem_analyze_corruption(trx);
ut_error;
@ -18958,3 +18959,28 @@ ib_warn_row_too_big(const dict_table_t* table)
" ROW_FORMAT=COMPRESSED ": ""
, prefix ? DICT_MAX_FIXED_COL_LEN : 0);
}
/********************************************************************//**
Helper function to push warnings from InnoDB internals to SQL-layer. */
UNIV_INTERN
void
ib_push_warning(
trx_t* trx, /*!< in: trx */
ulint error, /*!< in: error code to push as warning */
const char *format,/*!< in: warning message */
...)
{
va_list args;
THD *thd = (THD *)trx->mysql_thd;
char *buf;
#define MAX_BUF_SIZE 4*1024
va_start(args, format);
buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME));
vsprintf(buf,format, args);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
convert_error_code_to_mysql((dberr_t)error, 0, thd),
buf);
my_free(buf);
va_end(args);
}

View File

@ -825,7 +825,7 @@ innobase_find_fk_index(
if (!(index->type & DICT_FTS)
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, NULL, true, 0)) {
index, NULL, true, 0, NULL, NULL, NULL)) {
for (ulint i = 0; i < n_drop_index; i++) {
if (index == drop_index[i]) {
/* Skip to-be-dropped indexes. */
@ -1015,7 +1015,7 @@ innobase_get_foreign_key_info(
referenced_table, 0,
referenced_column_names,
i, index,
TRUE, FALSE);
TRUE, FALSE, NULL, NULL, NULL);
DBUG_EXECUTE_IF(
"innodb_test_no_reference_idx",
@ -3330,7 +3330,7 @@ innobase_check_foreign_key_index(
foreign->referenced_col_names,
foreign->n_fields, index,
/*check_charsets=*/TRUE,
/*check_null=*/FALSE)
/*check_null=*/FALSE, NULL, NULL, NULL)
&& !innobase_find_equiv_index(
foreign->referenced_col_names,
foreign->n_fields,
@ -3358,7 +3358,7 @@ innobase_check_foreign_key_index(
foreign->foreign_col_names,
foreign->n_fields, index,
/*check_charsets=*/TRUE,
/*check_null=*/FALSE)
/*check_null=*/FALSE, NULL,NULL, NULL)
&& !innobase_find_equiv_index(
foreign->foreign_col_names,
foreign->n_fields,
@ -4806,7 +4806,8 @@ innobase_update_foreign_try(
fk->n_fields, fk->referenced_index, TRUE,
fk->type
& (DICT_FOREIGN_ON_DELETE_SET_NULL
| DICT_FOREIGN_ON_UPDATE_SET_NULL));
| DICT_FOREIGN_ON_UPDATE_SET_NULL),
NULL, NULL, NULL);
if (!fk->foreign_index) {
my_error(ER_FK_INCORRECT_OPTION,
MYF(0), table_name, fk->id);
@ -4818,7 +4819,7 @@ innobase_update_foreign_try(
names, while the columns in ctx->old_table have not
been renamed yet. */
error = dict_create_add_foreign_to_dictionary(
ctx->old_table->name, fk, trx);
(dict_table_t*)ctx->old_table, ctx->old_table->name, fk, trx);
DBUG_EXECUTE_IF(
"innodb_test_cannot_add_fk_system",

View File

@ -110,6 +110,17 @@ UNIV_INTERN
dberr_t
dict_create_or_check_foreign_constraint_tables(void);
/*================================================*/
/********************************************************************//**
Construct foreign key constraint defintion from data dictionary information.
*/
UNIV_INTERN
char*
dict_foreign_def_get(
/*=================*/
dict_foreign_t* foreign,/*!< in: foreign */
trx_t* trx); /*!< in: trx */
/********************************************************************//**
Generate a foreign key constraint name when it was not named by the user.
A generated constraint has a name of the format dbname/tablename_ibfk_NUMBER,
@ -174,6 +185,7 @@ UNIV_INTERN
dberr_t
dict_create_add_foreign_to_dictionary(
/*==================================*/
dict_table_t* table, /*!< in: table */
const char* name, /*!< in: table name */
const dict_foreign_t* foreign,/*!< in: foreign key */
trx_t* trx) /*!< in/out: dictionary transaction */

View File

@ -580,10 +580,17 @@ dict_foreign_find_index(
/*!< in: whether to check
charsets. only has an effect
if types_idx != NULL */
ulint check_null)
ulint check_null,
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
ulint* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
dict_index_t** err_index)
/*!< out: index where error
happened */
__attribute__((nonnull(1,3), warn_unused_result));
/**********************************************************************//**
Returns a column's name.
@ -675,10 +682,18 @@ dict_foreign_qualify_index(
/*!< in: whether to check
charsets. only has an effect
if types_idx != NULL */
ulint check_null)
ulint check_null,
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
ulint* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
dict_index_t** err_index)
/*!< out: index where error
happened */
__attribute__((nonnull(1,3), warn_unused_result));
#ifdef UNIV_DEBUG
/********************************************************************//**

View File

@ -611,5 +611,14 @@ innobase_convert_to_filename_charset(
const char* from, /* in: identifier to convert */
ulint len); /* in: length of 'to', in bytes */
/********************************************************************//**
Helper function to push warnings from InnoDB internals to SQL-layer. */
UNIV_INTERN
void
ib_push_warning(
trx_t* trx, /*!< in: trx */
ulint error, /*!< in: error code to push as warning */
const char *format,/*!< in: warning message */
...);
#endif /* HA_INNODB_PROTOTYPES_H */

View File

@ -21,31 +21,42 @@
static my_bool ssl_algorithms_added = FALSE;
static my_bool ssl_error_strings_loaded= FALSE;
/* the function below was generated with "openssl dhparam -2 -C 1024" */
/* the function below was generated with "openssl dhparam -2 -C 2048" */
static
DH *get_dh1024()
DH *get_dh2048()
{
static unsigned char dh1024_p[]={
0xEC,0x46,0x7E,0xF9,0x4E,0x10,0x29,0xDC,0x44,0x97,0x71,0xFD,
0x71,0xC6,0x9F,0x0D,0xD1,0x09,0xF6,0x58,0x6F,0xAD,0xCA,0xF4,
0x37,0xD5,0xC3,0xBD,0xC3,0x9A,0x51,0x66,0x2C,0x58,0xBD,0x02,
0xBD,0xBA,0xBA,0xFC,0xE7,0x0E,0x5A,0xE5,0x97,0x81,0xC3,0xF3,
0x28,0x2D,0xAD,0x00,0x91,0xEF,0xF8,0xF0,0x5D,0xE9,0xE7,0x18,
0xE2,0xAD,0xC4,0x70,0xC5,0x3C,0x12,0x8A,0x80,0x6A,0x9F,0x3B,
0x00,0xA2,0x8F,0xA9,0x26,0xB0,0x0E,0x7F,0xED,0xF6,0xC2,0x03,
0x81,0xB5,0xC5,0x41,0xD0,0x00,0x2B,0x21,0xD4,0x4B,0x74,0xA6,
0xD7,0x1A,0x0E,0x82,0xC8,0xEE,0xD4,0xB1,0x6F,0xB4,0x79,0x01,
0x8A,0xF1,0x12,0xD7,0x3C,0xFD,0xCB,0x9B,0xAE,0x1C,0xA9,0x0F,
0x3D,0x0F,0xF8,0xD6,0x7D,0xDE,0xD6,0x0B,
static unsigned char dh2048_p[]={
0xA1,0xBB,0x7C,0x20,0xC5,0x5B,0xC0,0x7B,0x21,0x8B,0xD6,0xA8,
0x15,0xFC,0x3B,0xBA,0xAB,0x9F,0xDF,0x68,0xC4,0x79,0x78,0x0D,
0xC1,0x12,0x64,0xE4,0x15,0xC9,0x66,0xDB,0xF6,0xCB,0xB3,0x39,
0x02,0x5B,0x78,0x62,0xFB,0x09,0xAE,0x09,0x6B,0xDD,0xD4,0x5D,
0x97,0xBC,0xDC,0x7F,0xE6,0xD6,0xF1,0xCB,0xF5,0xEB,0xDA,0xA7,
0x2E,0x5A,0x43,0x2B,0xE9,0x40,0xE2,0x85,0x00,0x1C,0xC0,0x0A,
0x98,0x77,0xA9,0x31,0xDE,0x0B,0x75,0x4D,0x1E,0x1F,0x16,0x83,
0xCA,0xDE,0xBD,0x21,0xFC,0xC1,0x82,0x37,0x36,0x33,0x0B,0x66,
0x06,0x3C,0xF3,0xAF,0x21,0x57,0x57,0x80,0xF6,0x94,0x1B,0xA9,
0xD4,0xF6,0x8F,0x18,0x62,0x0E,0xC4,0x22,0xF9,0x5B,0x62,0xCC,
0x3F,0x19,0x95,0xCF,0x4B,0x00,0xA6,0x6C,0x0B,0xAF,0x9F,0xD5,
0xFA,0x3D,0x6D,0xDA,0x30,0x83,0x07,0x91,0xAC,0x15,0xFF,0x8F,
0x59,0x54,0xEA,0x25,0xBC,0x4E,0xEB,0x6A,0x54,0xDF,0x75,0x09,
0x72,0x0F,0xEF,0x23,0x70,0xE0,0xA8,0x04,0xEA,0xFF,0x90,0x54,
0xCD,0x84,0x18,0xC0,0x75,0x91,0x99,0x0F,0xA1,0x78,0x0C,0x07,
0xB7,0xC5,0xDE,0x55,0x06,0x7B,0x95,0x68,0x2C,0x33,0x39,0xBC,
0x2C,0xD0,0x6D,0xDD,0xFA,0xDC,0xB5,0x8F,0x82,0x39,0xF8,0x67,
0x44,0xF1,0xD8,0xF7,0x78,0x11,0x9A,0x77,0x9B,0x53,0x47,0xD6,
0x2B,0x5D,0x67,0xB8,0xB7,0xBC,0xC1,0xD7,0x79,0x62,0x15,0xC2,
0xC5,0x83,0x97,0xA7,0xF8,0xB4,0x9C,0xF6,0x8F,0x9A,0xC7,0xDA,
0x1B,0xBB,0x87,0x07,0xA7,0x71,0xAD,0xB2,0x8A,0x50,0xF8,0x26,
0x12,0xB7,0x3E,0x0B,
};
static unsigned char dh1024_g[]={
static unsigned char dh2048_g[]={
0x02,
};
DH *dh;
if ((dh=DH_new()) == NULL) return(NULL);
dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
if ((dh->p == NULL) || (dh->g == NULL))
{ DH_free(dh); return(NULL); }
return(dh);
@ -248,7 +259,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
}
/* DH stuff */
dh=get_dh1024();
dh=get_dh2048();
if (!SSL_CTX_set_tmp_dh(ssl_fd->ssl_context, dh))
{
*error= SSL_INITERR_DH;