From a96367bc670a0cdf876a3662df6e1cff98cbb467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 8 May 2025 11:58:31 +0300 Subject: [PATCH 01/15] MDEV-36620 post-fix: galera_toi_ddl_nonconflicting test failure Add wait_condition to wait until all inserted rows are replicated so that show create table is deterministic. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test b/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test index 9836aaa57ef..cc65e6bda9d 100644 --- a/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test +++ b/mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test @@ -61,6 +61,8 @@ SET SESSION wsrep_sync_wait=0; --source include/wait_condition.inc --let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1001 FROM t1; +--source include/wait_condition.inc SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; @@ -72,6 +74,8 @@ SELECT COUNT(*) AS EXPECT_1001 FROM t1; --source include/wait_condition.inc --let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; --source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1001 FROM t1; +--source include/wait_condition.inc SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'; From d38558f99b2c140d1d02590774595350bebd6c29 Mon Sep 17 00:00:00 2001 From: Hemant Dangi Date: Tue, 29 Apr 2025 18:31:13 +0530 Subject: [PATCH 02/15] MDEV-36117: MDL BF-BF conflict on ALTER and UPDATE with multi-level foreign key parents Issue: Mariadb acquires additional MDL locks on UPDATE/INSERT/DELETE statements on table with foreign keys. For example, table t1 references t2, an UPDATE to t1 will MDL lock t2 in addition to t1. A replica may deliver an ALTER t1 and UPDATE t2 concurrently for applying. Then the UPDATE may acquire MDL lock for t1, followed by a conflict when the ALTER attempts to MDL lock on t1. Causing a BF-BF conflict. Solution: Additional keys for the referenced/foreign table needs to be added to avoid potential MDL conflicts with concurrent update and DDLs. Signed-off-by: Julius Goryavsky --- .../r/galera_multi_level_fk_ddl_delete.result | 362 ++++++++++++++ .../r/galera_multi_level_fk_ddl_update.result | 358 ++++++++++++++ .../t/galera_multi_level_fk_ddl_delete.test | 452 ++++++++++++++++++ .../t/galera_multi_level_fk_ddl_update.test | 451 +++++++++++++++++ .../t/galera_multi_level_foreign_key.inc | 60 +++ sql/sql_base.cc | 17 +- sql/sql_prepare.cc | 28 +- sql/wsrep_mysqld.cc | 33 ++ sql/wsrep_mysqld.h | 10 + 9 files changed, 1758 insertions(+), 13 deletions(-) create mode 100644 mysql-test/suite/galera/r/galera_multi_level_fk_ddl_delete.result create mode 100644 mysql-test/suite/galera/r/galera_multi_level_fk_ddl_update.result create mode 100644 mysql-test/suite/galera/t/galera_multi_level_fk_ddl_delete.test create mode 100644 mysql-test/suite/galera/t/galera_multi_level_fk_ddl_update.test create mode 100644 mysql-test/suite/galera/t/galera_multi_level_foreign_key.inc diff --git a/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_delete.result b/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_delete.result new file mode 100644 index 00000000000..4199fdcd011 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_delete.result @@ -0,0 +1,362 @@ +connection node_2; +connection node_1; +# +# 1. BF-BF conflict on MDL locks between: DROP TABLE t6 and DELETE on t1 +# with foreign key references as below: +# - t1<-t2<-t3<-t4 +# - t3<-t5 +# - t2<-t6 +# +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +t5_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE, +KEY key_t5_id(t5_id) +); +CREATE TABLE t3 ( +id INT PRIMARY KEY, +t2_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t2_id(t2_id), +CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +CREATE TABLE t4 ( +id INT PRIMARY KEY, +t3_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t3_id(t3_id), +CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +CREATE TABLE t5 ( +id INT PRIMARY KEY, +t3_id_1 INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t3_id_1(t3_id_1), +CONSTRAINT key_t3_id_1 FOREIGN KEY (t3_id_1) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +CREATE TABLE t6 ( +id INT PRIMARY KEY, +t2_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t2_id_1(t2_id), +CONSTRAINT key_t2_id_1 FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t1 VALUES (3,0); +INSERT INTO t2 VALUES (1,1,1,1234); +INSERT INTO t2 VALUES (2,2,2,1234); +INSERT INTO t3 VALUES (1,1,1234); +INSERT INTO t3 VALUES (2,2,1234); +INSERT INTO t4 VALUES (1,1,1234); +INSERT INTO t4 VALUES (2,2,1234); +INSERT INTO t5 VALUES (1,1,1234); +INSERT INTO t5 VALUES (2,2,1234); +ALTER TABLE t2 ADD CONSTRAINT key_t5_id FOREIGN KEY (t5_id) +REFERENCES t5 (id) ON UPDATE CASCADE ON DELETE CASCADE; +connection node_1; +connection node_2; +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; +connection node_1; +DROP TABLE t6; +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +DELETE FROM t1 WHERE id = 3; +COMMIT; +connection node_2; +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +include/assert_grep.inc [Foreign key referenced table found: 4 tables] +include/assert_grep.inc [Foreign key referenced table found: test.t2] +include/assert_grep.inc [Foreign key referenced table found: test.t3] +include/assert_grep.inc [Foreign key referenced table found: test.t4] +include/assert_grep.inc [Foreign key referenced table found: test.t5] +connection node_2; +select * from t1; +id f2 +1 0 +2 0 +select * from t2; +id t1_id t5_id f2 +1 1 1 1234 +2 2 2 1234 +select * from t3; +id t2_id f2 +1 1 1234 +2 2 1234 +select * from t4; +id t3_id f2 +1 1 1234 +2 2 1234 +select * from t5; +id t3_id_1 f2 +1 1 1234 +2 2 1234 +select * from t6; +ERROR 42S02: Table 'test.t6' doesn't exist +connection node_1; +select * from t1; +id f2 +1 0 +2 0 +select * from t2; +id t1_id t5_id f2 +1 1 1 1234 +2 2 2 1234 +select * from t3; +id t2_id f2 +1 1 1234 +2 2 1234 +select * from t4; +id t3_id f2 +1 1 1234 +2 2 1234 +select * from t5; +id t3_id_1 f2 +1 1 1234 +2 2 1234 +select * from t6; +ERROR 42S02: Table 'test.t6' doesn't exist +ALTER TABLE t2 DROP FOREIGN KEY key_t5_id; +DROP TABLE t5, t4, t3, t2, t1; +# +# 2. BF-BF conflict on MDL locks between: +# ALTER TABLE t3 (whose parent table are t3 -> t2 -> t1), and +# DELETE on t1 with t2 referencing t1, and t3 referencing t2. +# +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +CREATE TABLE t3 ( +id INT PRIMARY KEY, +t2_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t2_id(t2_id) +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t1 VALUES (3,0); +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); +connection node_2; +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; +connection node_1; +ALTER TABLE t3 ADD CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE; +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +DELETE FROM t1 WHERE id = 3; +COMMIT; +connection node_2; +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +include/assert_grep.inc [Foreign key referenced table found: 2 tables] +include/assert_grep.inc [Foreign key referenced table found: test.t2] +include/assert_grep.inc [Foreign key referenced table found: test.t3] +connection node_2; +select * from t1; +id f2 +1 0 +2 0 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +select * from t3; +id t2_id f2 +connection node_1; +select * from t1; +id f2 +1 0 +2 0 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +select * from t3; +id t2_id f2 +DROP TABLE t3, t2, t1; +# +# 3. BF-BF conflict on MDL locks between: +# CREATE TABLE t3 (whose parent table are t3 -> t2 -> t1), and +# DELETE on t1 with t2 referencing t1, and t3 referencing t2. +# +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t1 VALUES (3,0); +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); +connection node_2; +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; +connection node_1; +CREATE TABLE t3 (id INT PRIMARY KEY, t2_id INT NOT NULL, f2 INTEGER NOT NULL, KEY key_t2_id(t2_id), CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE); +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +DELETE FROM t1 WHERE id = 3; +COMMIT; +connection node_2; +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +include/assert_grep.inc [Foreign key referenced table found: 2 tables] +include/assert_grep.inc [Foreign key referenced table found: test.t2] +include/assert_grep.inc [Foreign key referenced table found: test.t3] +connection node_2; +select * from t1; +id f2 +1 0 +2 0 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +select * from t3; +id t2_id f2 +connection node_1; +select * from t1; +id f2 +1 0 +2 0 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +select * from t3; +id t2_id f2 +DROP TABLE t3, t2, t1; +# +# 4. BF-BF conflict on MDL locks between: +# OPTIMIZE TABLE t2 (whose parent table are t2 -> t1), and +# DELETE on t1. +# +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t1 VALUES (3,0); +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); +connection node_2; +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; +connection node_1; +OPTIMIZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 optimize note Table does not support optimize, doing recreate + analyze instead +test.t2 optimize status OK +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +DELETE FROM t1 WHERE id = 3; +COMMIT; +connection node_2; +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +include/assert_grep.inc [Foreign key referenced table found: 1 tables] +include/assert_grep.inc [Foreign key referenced table found: test.t2] +connection node_2; +select * from t1; +id f2 +1 0 +2 0 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +connection node_1; +select * from t1; +id f2 +1 0 +2 0 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +DROP TABLE t2, t1; diff --git a/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_update.result b/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_update.result new file mode 100644 index 00000000000..9c8a34e7dd7 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_multi_level_fk_ddl_update.result @@ -0,0 +1,358 @@ +connection node_2; +connection node_1; +# +# 1. BF-BF conflict on MDL locks between: DROP TABLE t6 and UPDATE on t1 +# with foreign key references as below: +# - t1<-t2<-t3<-t4 +# - t3<-t5 +# - t2<-t6 +# +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +t5_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE, +KEY key_t5_id(t5_id) +); +CREATE TABLE t3 ( +id INT PRIMARY KEY, +t2_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t2_id(t2_id), +CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +CREATE TABLE t4 ( +id INT PRIMARY KEY, +t3_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t3_id(t3_id), +CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +CREATE TABLE t5 ( +id INT PRIMARY KEY, +t3_id_1 INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t3_id_1(t3_id_1), +CONSTRAINT key_t3_id_1 FOREIGN KEY (t3_id_1) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +CREATE TABLE t6 ( +id INT PRIMARY KEY, +t2_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t2_id_1(t2_id), +CONSTRAINT key_t2_id_1 FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1,1234); +INSERT INTO t2 VALUES (2,2,2,1234); +INSERT INTO t3 VALUES (1,1,1234); +INSERT INTO t3 VALUES (2,2,1234); +INSERT INTO t4 VALUES (1,1,1234); +INSERT INTO t4 VALUES (2,2,1234); +INSERT INTO t5 VALUES (1,1,1234); +INSERT INTO t5 VALUES (2,2,1234); +ALTER TABLE t2 ADD CONSTRAINT key_t5_id FOREIGN KEY (t5_id) +REFERENCES t5 (id) ON UPDATE CASCADE ON DELETE CASCADE; +connection node_1; +connection node_2; +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; +connection node_1; +DROP TABLE t6; +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +UPDATE t1 SET f2 = 1 WHERE id=2; +COMMIT; +connection node_2; +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +include/assert_grep.inc [Foreign key referenced table found: 4 tables] +include/assert_grep.inc [Foreign key referenced table found: test.t2] +include/assert_grep.inc [Foreign key referenced table found: test.t3] +include/assert_grep.inc [Foreign key referenced table found: test.t4] +include/assert_grep.inc [Foreign key referenced table found: test.t5] +connection node_2; +select * from t1; +id f2 +1 0 +2 1 +select * from t2; +id t1_id t5_id f2 +1 1 1 1234 +2 2 2 1234 +select * from t3; +id t2_id f2 +1 1 1234 +2 2 1234 +select * from t4; +id t3_id f2 +1 1 1234 +2 2 1234 +select * from t5; +id t3_id_1 f2 +1 1 1234 +2 2 1234 +select * from t6; +ERROR 42S02: Table 'test.t6' doesn't exist +connection node_1; +select * from t1; +id f2 +1 0 +2 1 +select * from t2; +id t1_id t5_id f2 +1 1 1 1234 +2 2 2 1234 +select * from t3; +id t2_id f2 +1 1 1234 +2 2 1234 +select * from t4; +id t3_id f2 +1 1 1234 +2 2 1234 +select * from t5; +id t3_id_1 f2 +1 1 1234 +2 2 1234 +select * from t6; +ERROR 42S02: Table 'test.t6' doesn't exist +ALTER TABLE t2 DROP FOREIGN KEY key_t5_id; +DROP TABLE t5, t4, t3, t2, t1; +# +# 2. BF-BF conflict on MDL locks between: +# ALTER TABLE t3 (whose parent table are t3 -> t2 -> t1), and +# UPDATE on t1 with t2 referencing t1, and t3 referencing t2. +# +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +CREATE TABLE t3 ( +id INT PRIMARY KEY, +t2_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t2_id(t2_id) +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); +connection node_2; +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; +connection node_1; +ALTER TABLE t3 ADD CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE; +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +UPDATE t1 SET f2 = 1 WHERE id=2; +COMMIT; +connection node_2; +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +include/assert_grep.inc [Foreign key referenced table found: 2 tables] +include/assert_grep.inc [Foreign key referenced table found: test.t2] +include/assert_grep.inc [Foreign key referenced table found: test.t3] +connection node_2; +select * from t1; +id f2 +1 0 +2 1 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +select * from t3; +id t2_id f2 +connection node_1; +select * from t1; +id f2 +1 0 +2 1 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +select * from t3; +id t2_id f2 +DROP TABLE t3, t2, t1; +# +# 3. BF-BF conflict on MDL locks between: +# CREATE TABLE t3 (whose parent table are t3 -> t2 -> t1), and +# UPDATE on t1 with t2 referencing t1, and t3 referencing t2. +# +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); +connection node_2; +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; +connection node_1; +CREATE TABLE t3 (id INT PRIMARY KEY, t2_id INT NOT NULL, f2 INTEGER NOT NULL, KEY key_t2_id(t2_id), CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE); +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +UPDATE t1 SET f2 = 1 WHERE id=2; +COMMIT; +connection node_2; +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +include/assert_grep.inc [Foreign key referenced table found: 2 tables] +include/assert_grep.inc [Foreign key referenced table found: test.t2] +include/assert_grep.inc [Foreign key referenced table found: test.t3] +connection node_2; +select * from t1; +id f2 +1 0 +2 1 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +select * from t3; +id t2_id f2 +connection node_1; +select * from t1; +id f2 +1 0 +2 1 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +select * from t3; +id t2_id f2 +DROP TABLE t3, t2, t1; +# +# 4. BF-BF conflict on MDL locks between: +# OPTIMIZE TABLE t2 (whose parent table are t2 -> t1), and +# UPDATE on t1. +# +connection node_2; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE t1 ( +id INTEGER PRIMARY KEY, +f2 INTEGER +); +CREATE TABLE t2 ( +id INT PRIMARY KEY, +t1_id INT NOT NULL, +f2 INTEGER NOT NULL, +KEY key_t1_id(t1_id), +CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); +connection node_2; +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; +connection node_1; +OPTIMIZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 optimize note Table does not support optimize, doing recreate + analyze instead +test.t2 optimize status OK +connection node_2; +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +UPDATE t1 SET f2 = 1 WHERE id=2; +COMMIT; +connection node_2; +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_1; +include/assert_grep.inc [Foreign key referenced table found: 1 tables] +include/assert_grep.inc [Foreign key referenced table found: test.t2] +connection node_2; +select * from t1; +id f2 +1 0 +2 1 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +connection node_1; +select * from t1; +id f2 +1 0 +2 1 +select * from t2; +id t1_id f2 +1 1 1234 +2 2 1234 +DROP TABLE t2, t1; diff --git a/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_delete.test b/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_delete.test new file mode 100644 index 00000000000..b1c3e6d5352 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_delete.test @@ -0,0 +1,452 @@ +# +# BF-BF conflict on MDL locks between DDL and delete query +# when multi-level foreign key like t3 -> t2 -> t1 +# are present. +# +# If bug is present, expect the wait condition +# to timeout and when the DELETE applies, it +# will be granted a MDL lock of type SHARED_READ +# for table t1. When resumed, the DROP TABLE will +# also try to MDL lock t1, causing a BF-BF conflict +# on that MDL lock. + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +--echo # +--echo # 1. BF-BF conflict on MDL locks between: DROP TABLE t6 and DELETE on t1 +--echo # with foreign key references as below: +--echo # - t1<-t2<-t3<-t4 +--echo # - t3<-t5 +--echo # - t2<-t6 +--echo # + + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + t5_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE, + KEY key_t5_id(t5_id) +); + +CREATE TABLE t3 ( + id INT PRIMARY KEY, + t2_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t2_id(t2_id), + CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE t4 ( + id INT PRIMARY KEY, + t3_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t3_id(t3_id), + CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE t5 ( + id INT PRIMARY KEY, + t3_id_1 INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t3_id_1(t3_id_1), + CONSTRAINT key_t3_id_1 FOREIGN KEY (t3_id_1) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE t6 ( + id INT PRIMARY KEY, + t2_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t2_id_1(t2_id), + CONSTRAINT key_t2_id_1 FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t1 VALUES (3,0); + +INSERT INTO t2 VALUES (1,1,1,1234); +INSERT INTO t2 VALUES (2,2,2,1234); + +INSERT INTO t3 VALUES (1,1,1234); +INSERT INTO t3 VALUES (2,2,1234); + +INSERT INTO t4 VALUES (1,1,1234); +INSERT INTO t4 VALUES (2,2,1234); + +INSERT INTO t5 VALUES (1,1,1234); +INSERT INTO t5 VALUES (2,2,1234); + +ALTER TABLE t2 ADD CONSTRAINT key_t5_id FOREIGN KEY (t5_id) +REFERENCES t5 (id) ON UPDATE CASCADE ON DELETE CASCADE; + +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = "t2" AND CONSTRAINT_TYPE = "FOREIGN KEY" AND CONSTRAINT_NAME="key_t5_id" +--source include/wait_condition.inc + + +--let $fk_parent_query = DROP TABLE t6 +--let $fk_child_query = DELETE FROM t1 WHERE id = 3 +--let $fk_mdl_lock_num = 5 +--source galera_multi_level_foreign_key.inc + + +# +# Verify Foreign key for referenced table added. +# +--connection node_1 +--let assert_text= Foreign key referenced table found: 4 tables +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 4 +--let assert_select= Foreign key referenced table found: +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t2 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 1 +--let assert_select= Foreign key referenced table found: test.t2 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t3 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 1 +--let assert_select= Foreign key referenced table found: test.t3 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t4 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 1 +--let assert_select= Foreign key referenced table found: test.t4 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t5 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 1 +--let assert_select= Foreign key referenced table found: test.t5 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + + +# +# Verify delete and drop table has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM test.t1 +--source include/wait_condition.inc + +select * from t1; +select * from t2; +select * from t3; +select * from t4; +select * from t5; +--error ER_NO_SUCH_TABLE +select * from t6; + +--connection node_1 +select * from t1; +select * from t2; +select * from t3; +select * from t4; +select * from t5; +--error ER_NO_SUCH_TABLE +select * from t6; + + +# +# Cleanup +# +ALTER TABLE t2 DROP FOREIGN KEY key_t5_id; +DROP TABLE t5, t4, t3, t2, t1; + + +--echo # +--echo # 2. BF-BF conflict on MDL locks between: +--echo # ALTER TABLE t3 (whose parent table are t3 -> t2 -> t1), and +--echo # DELETE on t1 with t2 referencing t1, and t3 referencing t2. +--echo # + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE t3 ( + id INT PRIMARY KEY, + t2_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t2_id(t2_id) +); + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t1 VALUES (3,0); + +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); + + +# +# ALTER TABLE t3 and wait for it to reach node_2 +# +--let $fk_parent_query = ALTER TABLE t3 ADD CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +# +# Issue a DELETE to table that references t1 +# +--let $fk_child_query = DELETE FROM t1 WHERE id = 3 +--let $fk_mdl_lock_num = 3 +--source galera_multi_level_foreign_key.inc + + +# +# Verify Foreign key for referenced table added. +# +--connection node_1 +--let assert_text= Foreign key referenced table found: 2 tables +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 6 +--let assert_select= Foreign key referenced table found: +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t2 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 2 +--let assert_select= Foreign key referenced table found: test.t2 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t3 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 2 +--let assert_select= Foreign key referenced table found: test.t3 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + + +# +# Verify delete and alter table has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM test.t1 +--source include/wait_condition.inc + +select * from t1; +select * from t2; +select * from t3; + +--connection node_1 +select * from t1; +select * from t2; +select * from t3; + + +# +# Cleanup +# +DROP TABLE t3, t2, t1; + + +--echo # +--echo # 3. BF-BF conflict on MDL locks between: +--echo # CREATE TABLE t3 (whose parent table are t3 -> t2 -> t1), and +--echo # DELETE on t1 with t2 referencing t1, and t3 referencing t2. +--echo # + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t1 VALUES (3,0); + +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); + + +--let $fk_parent_query = CREATE TABLE t3 (id INT PRIMARY KEY, t2_id INT NOT NULL, f2 INTEGER NOT NULL, KEY key_t2_id(t2_id), CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE) +--let $fk_child_query = DELETE FROM t1 WHERE id = 3 +--let $fk_mdl_lock_num = 3 +--source galera_multi_level_foreign_key.inc + + +# +# Verify Foreign key for referenced table added. +# +--connection node_1 +--let assert_text= Foreign key referenced table found: 2 tables +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 8 +--let assert_select= Foreign key referenced table found: +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t2 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 3 +--let assert_select= Foreign key referenced table found: test.t2 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t3 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 3 +--let assert_select= Foreign key referenced table found: test.t3 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + + +# +# Verify delete and create table has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM test.t1 +--source include/wait_condition.inc + +select * from t1; +select * from t2; +select * from t3; + +--connection node_1 +select * from t1; +select * from t2; +select * from t3; + + +# +# Cleanup +# +DROP TABLE t3, t2, t1; + + +--echo # +--echo # 4. BF-BF conflict on MDL locks between: +--echo # OPTIMIZE TABLE t2 (whose parent table are t2 -> t1), and +--echo # DELETE on t1. +--echo # + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); +INSERT INTO t1 VALUES (3,0); + +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); + + +--let $fk_parent_query = OPTIMIZE TABLE t2 +--let $fk_child_query = DELETE FROM t1 WHERE id = 3 +--let $fk_mdl_lock_num = 2 +--source galera_multi_level_foreign_key.inc + + +# +# Verify Foreign key for referenced table added. +# +--connection node_1 +--let assert_text= Foreign key referenced table found: 1 tables +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 9 +--let assert_select= Foreign key referenced table found: +--let $assert_only_after = CURRENT_TEST: +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t2 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 4 +--let assert_select= Foreign key referenced table found: test.t2 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_delete +--source include/assert_grep.inc + + +# +# Verify delete and create table has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM test.t1 +--source include/wait_condition.inc + + +select * from t1; +select * from t2; + +--connection node_1 +select * from t1; +select * from t2; + + +# +# Cleanup +# +DROP TABLE t2, t1; diff --git a/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_update.test b/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_update.test new file mode 100644 index 00000000000..1dea0021901 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_multi_level_fk_ddl_update.test @@ -0,0 +1,451 @@ +# +# BF-BF conflict on MDL locks between DDL and update query +# when multi-level foreign key like t3 -> t2 -> t1 +# are present. +# +# If bug is present, expect the wait condition +# to timeout and when the UPDATE applies, it +# will be granted a MDL lock of type SHARED_READ +# for table t1. When resumed, the DROP TABLE will +# also try to MDL lock t1, causing a BF-BF conflict +# on that MDL lock. + +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +--echo # +--echo # 1. BF-BF conflict on MDL locks between: DROP TABLE t6 and UPDATE on t1 +--echo # with foreign key references as below: +--echo # - t1<-t2<-t3<-t4 +--echo # - t3<-t5 +--echo # - t2<-t6 +--echo # + + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + t5_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE, + KEY key_t5_id(t5_id) +); + +CREATE TABLE t3 ( + id INT PRIMARY KEY, + t2_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t2_id(t2_id), + CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE t4 ( + id INT PRIMARY KEY, + t3_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t3_id(t3_id), + CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE t5 ( + id INT PRIMARY KEY, + t3_id_1 INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t3_id_1(t3_id_1), + CONSTRAINT key_t3_id_1 FOREIGN KEY (t3_id_1) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE t6 ( + id INT PRIMARY KEY, + t2_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t2_id_1(t2_id), + CONSTRAINT key_t2_id_1 FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); + +INSERT INTO t2 VALUES (1,1,1,1234); +INSERT INTO t2 VALUES (2,2,2,1234); + +INSERT INTO t3 VALUES (1,1,1234); +INSERT INTO t3 VALUES (2,2,1234); + +INSERT INTO t4 VALUES (1,1,1234); +INSERT INTO t4 VALUES (2,2,1234); + +INSERT INTO t5 VALUES (1,1,1234); +INSERT INTO t5 VALUES (2,2,1234); + +ALTER TABLE t2 ADD CONSTRAINT key_t5_id FOREIGN KEY (t5_id) +REFERENCES t5 (id) ON UPDATE CASCADE ON DELETE CASCADE; + +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = "t2" AND CONSTRAINT_TYPE = "FOREIGN KEY" AND CONSTRAINT_NAME="key_t5_id" +--source include/wait_condition.inc + + +--let $fk_parent_query = DROP TABLE t6 +--let $fk_child_query = UPDATE t1 SET f2 = 1 WHERE id=2 +--let $fk_mdl_lock_num = 5 +--source galera_multi_level_foreign_key.inc + + +# +# Verify Foreign key for referenced table added. +# +--connection node_1 +--let assert_text= Foreign key referenced table found: 4 tables +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 4 +--let assert_select= Foreign key referenced table found: +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t2 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 1 +--let assert_select= Foreign key referenced table found: test.t2 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t3 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 1 +--let assert_select= Foreign key referenced table found: test.t3 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t4 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 1 +--let assert_select= Foreign key referenced table found: test.t4 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t5 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 1 +--let assert_select= Foreign key referenced table found: test.t5 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + + +# +# Verify update and drop table has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM test.t1 where id=2 and f2=1; +--source include/wait_condition.inc + +select * from t1; +select * from t2; +select * from t3; +select * from t4; +select * from t5; +--error ER_NO_SUCH_TABLE +select * from t6; + +--connection node_1 +select * from t1; +select * from t2; +select * from t3; +select * from t4; +select * from t5; +--error ER_NO_SUCH_TABLE +select * from t6; + + +# +# Cleanup +# +ALTER TABLE t2 DROP FOREIGN KEY key_t5_id; +DROP TABLE t5, t4, t3, t2, t1; + + +--echo # +--echo # 2. BF-BF conflict on MDL locks between: +--echo # ALTER TABLE t3 (whose parent table are t3 -> t2 -> t1), and +--echo # UPDATE on t1 with t2 referencing t1, and t3 referencing t2. +--echo # + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + +CREATE TABLE t3 ( + id INT PRIMARY KEY, + t2_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t2_id(t2_id) +); + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); + +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); + + +# +# ALTER TABLE t3 and wait for it to reach node_2 +# +--let $fk_parent_query = ALTER TABLE t3 ADD CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE +# +# Issue a UPDATE to table that references t1 +# Notice that we update field f2, not the primary key, +# and not foreign key. Bug does not manifest if we update +# one of those fields (because FK keys appended in those cases). +# +--let $fk_child_query = UPDATE t1 SET f2 = 1 WHERE id=2 +--let $fk_mdl_lock_num = 3 +--source galera_multi_level_foreign_key.inc + + +# +# Verify Foreign key for referenced table added. +# +--connection node_1 +--let assert_text= Foreign key referenced table found: 2 tables +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 6 +--let assert_select= Foreign key referenced table found: +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t2 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 2 +--let assert_select= Foreign key referenced table found: test.t2 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t3 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 2 +--let assert_select= Foreign key referenced table found: test.t3 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + + +# +# Verify update and drop table has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM test.t1 where id=2 and f2=1; +--source include/wait_condition.inc + +select * from t1; +select * from t2; +select * from t3; + +--connection node_1 +select * from t1; +select * from t2; +select * from t3; + + +# +# Cleanup +# +DROP TABLE t3, t2, t1; + + +--echo # +--echo # 3. BF-BF conflict on MDL locks between: +--echo # CREATE TABLE t3 (whose parent table are t3 -> t2 -> t1), and +--echo # UPDATE on t1 with t2 referencing t1, and t3 referencing t2. +--echo # + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); + +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); + + +--let $fk_parent_query = CREATE TABLE t3 (id INT PRIMARY KEY, t2_id INT NOT NULL, f2 INTEGER NOT NULL, KEY key_t2_id(t2_id), CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE) +--let $fk_child_query = UPDATE t1 SET f2 = 1 WHERE id=2 +--let $fk_mdl_lock_num = 3 +--source galera_multi_level_foreign_key.inc + + +# +# Verify Foreign key for referenced table added. +# +--connection node_1 +--let assert_text= Foreign key referenced table found: 2 tables +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 8 +--let assert_select= Foreign key referenced table found: +--let $assert_only_after = CURRENT_TEST: +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t2 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 3 +--let assert_select= Foreign key referenced table found: test.t2 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t3 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 3 +--let assert_select= Foreign key referenced table found: test.t3 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + + +# +# Verify update and drop table has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM test.t1 where id=2 and f2=1; +--source include/wait_condition.inc + +select * from t1; +select * from t2; +select * from t3; + +--connection node_1 +select * from t1; +select * from t2; +select * from t3; + + +# +# Cleanup +# +DROP TABLE t3, t2, t1; + + +--echo # +--echo # 4. BF-BF conflict on MDL locks between: +--echo # OPTIMIZE TABLE t2 (whose parent table are t2 -> t1), and +--echo # UPDATE on t1. +--echo # + +# +# Setup +# +--connection node_2 +SET GLOBAL wsrep_slave_threads=2; + +CREATE TABLE t1 ( + id INTEGER PRIMARY KEY, + f2 INTEGER +); + +CREATE TABLE t2 ( + id INT PRIMARY KEY, + t1_id INT NOT NULL, + f2 INTEGER NOT NULL, + KEY key_t1_id(t1_id), + CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE +); + + +INSERT INTO t1 VALUES (1,0); +INSERT INTO t1 VALUES (2,0); + +INSERT INTO t2 VALUES (1,1,1234); +INSERT INTO t2 VALUES (2,2,1234); + + +--let $fk_parent_query = OPTIMIZE TABLE t2 +--let $fk_child_query = UPDATE t1 SET f2 = 1 WHERE id=2 +--let $fk_mdl_lock_num = 2 +--source galera_multi_level_foreign_key.inc + + +# +# Verify Foreign key for referenced table added. +# +--connection node_1 +--let assert_text= Foreign key referenced table found: 1 tables +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 9 +--let assert_select= Foreign key referenced table found: +--let $assert_only_after = CURRENT_TEST: +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + +--let assert_text= Foreign key referenced table found: test.t2 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let assert_count= 4 +--let assert_select= Foreign key referenced table found: test.t2 +--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_update +--source include/assert_grep.inc + + +# +# Verify update has succeded. +# +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM test.t1 where id=2 and f2=1; +--source include/wait_condition.inc + +select * from t1; +select * from t2; + +--connection node_1 +select * from t1; +select * from t2; + + +# +# Cleanup +# +DROP TABLE t2, t1; diff --git a/mysql-test/suite/galera/t/galera_multi_level_foreign_key.inc b/mysql-test/suite/galera/t/galera_multi_level_foreign_key.inc new file mode 100644 index 00000000000..598019b0a43 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_multi_level_foreign_key.inc @@ -0,0 +1,60 @@ +# +# Execute parent query on node_1 and wait for it to reach node_2 +# +--connection node_2 +SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi'; + +--connection node_1 +--eval $fk_parent_query + +--connection node_2 +SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; + +SET SESSION wsrep_sync_wait = 0; +--let $expected_apply_waits = query_get_value("SHOW STATUS LIKE 'wsrep_apply_waits'", Value, 1) +--let $expected_apply_waits = `select $expected_apply_waits + 1` + + +# +# Execute child query on node_1. +# If bug is present, expect the wait condition +# to timeout and when the child query applies, it +# will be granted a MDL lock on parent table. +# When resumed, the parent query will +# also try to acquire MDL lock on parent table, +# causing a BF-BF conflict on that MDL lock. +# +--connection node_1 +SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table'; +START TRANSACTION; +--eval $fk_child_query +--let $wait_condition = SELECT COUNT(*) = $fk_mdl_lock_num FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA='test' AND LOCK_STATUS="GRANTED" +--source include/wait_condition.inc +COMMIT; + + +# +# Expect the child query to depend on the parent query, +# therefore it should wait for the parent query to +# finish before it can be applied. +# +--connection node_2 +--let $status_var = wsrep_apply_waits +--let $status_var_value = $expected_apply_waits +--source include/wait_for_status_var.inc + +SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi'; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; + + +# +# Cleanup +# +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; + +--connection node_1 +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL DEBUG_DBUG = ""; +SET GLOBAL wsrep_slave_threads=DEFAULT; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 713a0b455e9..1a4fa315c3c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4804,6 +4804,7 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx, FOREIGN_KEY_INFO *fk; Query_arena *arena, backup; TABLE *table= table_list->table; + bool error= FALSE; if (!table->file->referenced_by_foreign_key()) DBUG_RETURN(FALSE); @@ -4844,10 +4845,24 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx, table_list->belong_to_view, op, &prelocking_ctx->query_tables_last, table_list->for_insert_data); + +#ifdef WITH_WSREP + /* + Append table level shared key for the referenced/foreign table for: + - statement that updates existing rows (UPDATE, multi-update) + - statement that deletes existing rows (DELETE, DELETE_MULTI) + This is done to avoid potential MDL conflicts with concurrent DDLs. + */ + if (wsrep_foreign_key_append(thd, fk)) + { + error= TRUE; + break; + } +#endif // WITH_WSREP } if (arena) thd->restore_active_arena(arena, &backup); - DBUG_RETURN(FALSE); + DBUG_RETURN(error); } /** diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index f39b0e23e58..059e3d7c510 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2475,18 +2475,8 @@ static bool check_prepared_statement(Prepared_statement *stmt) } #ifdef WITH_WSREP - if (wsrep_sync_wait(thd, sql_command)) - goto error; - if (!stmt->is_sql_prepare()) - { - wsrep_after_command_before_result(thd); - if (wsrep_current_error(thd)) - { - wsrep_override_error(thd, wsrep_current_error(thd), - wsrep_current_error_status(thd)); - goto error; - } - } + if (wsrep_sync_wait(thd, sql_command)) + goto error; #endif switch (sql_command) { case SQLCOM_REPLACE: @@ -2710,6 +2700,20 @@ static bool check_prepared_statement(Prepared_statement *stmt) default: break; } + +#ifdef WITH_WSREP + if (!stmt->is_sql_prepare()) + { + wsrep_after_command_before_result(thd); + if (wsrep_current_error(thd)) + { + wsrep_override_error(thd, wsrep_current_error(thd), + wsrep_current_error_status(thd)); + goto error; + } + } +#endif + if (res == 0) { if (!stmt->is_sql_prepare()) diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index e2d61325847..469cbc9da2d 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -4052,3 +4052,36 @@ bool wsrep_table_list_has_non_temp_tables(THD *thd, TABLE_LIST *tables) } return false; } + +bool wsrep_foreign_key_append(THD *thd, FOREIGN_KEY_INFO *fk) +{ + if (WSREP(thd) && !thd->wsrep_applier && + wsrep_is_active(thd) && + (sql_command_flags[thd->lex->sql_command] & + (CF_UPDATES_DATA | CF_DELETES_DATA))) + { + wsrep::key key(wsrep::key::shared); + key.append_key_part(fk->foreign_db->str, fk->foreign_db->length); + key.append_key_part(fk->foreign_table->str, fk->foreign_table->length); + + if (thd->wsrep_cs().append_key(key)) + { + WSREP_ERROR("Appending table key failed: %s", + wsrep_thd_query(thd)); + sql_print_information("Failed Foreign key referenced table found: " + "%s.%s", + fk->foreign_db->str, + fk->foreign_table->str); + return true; + } + + DBUG_EXECUTE_IF( + "wsrep_print_foreign_keys_table", + sql_print_information("Foreign key referenced table found: %s.%s", + fk->foreign_db->str, + fk->foreign_table->str); + ); + } + + return false; +} diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 02df7bf5ed5..389bedda30a 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -599,6 +599,16 @@ void wsrep_ready_set(bool ready_value); */ bool wsrep_table_list_has_non_temp_tables(THD *thd, TABLE_LIST *tables); +/** + * Append foreign key to wsrep. + * + * @param thd Thread object + * @param fk Foreign Key Info + * + * @return true if error, otherwise false. + */ +bool wsrep_foreign_key_append(THD *thd, FOREIGN_KEY_INFO *fk); + #else /* !WITH_WSREP */ /* These macros are needed to compile MariaDB without WSREP support From 7fd5957d55697cdafda9df3298ed36f899469c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 6 May 2025 08:15:36 +0300 Subject: [PATCH 03/15] MDEV-36622 : Hang during galera_evs_suspect_timeout test Test changes only. Add wait_condition so that all nodes are in the expected state and add debug output if issue does reproduce. Signed-off-by: Julius Goryavsky --- .../r/galera_evs_suspect_timeout.result | 5 ++++- .../galera_3nodes/t/galera_evs_suspect_timeout.cnf | 4 ++++ .../t/galera_evs_suspect_timeout.test | 14 ++++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.cnf diff --git a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result index 2ecd5edfa99..5faa862ddb6 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result +++ b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result @@ -12,10 +12,12 @@ connection node_3; Suspending node ... connection node_1; SET SESSION wsrep_sync_wait=0; +connection node_2; +SET SESSION wsrep_sync_wait=0; +connection node_1; CREATE TABLE t1 (f1 INTEGER) engine=InnoDB; INSERT INTO t1 VALUES (1); connection node_2; -SET SESSION wsrep_sync_wait=0; SET SESSION wsrep_sync_wait = 15; SELECT COUNT(*) FROM t1; COUNT(*) @@ -29,4 +31,5 @@ SELECT COUNT(*) FROM t1; COUNT(*) 1 connection node_1; +connection node_2; DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.cnf b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.cnf new file mode 100644 index 00000000000..bc8942624d2 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.cnf @@ -0,0 +1,4 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-debug=1 diff --git a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test index c36cce61f23..0b270385d24 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test +++ b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test @@ -43,6 +43,12 @@ SET SESSION wsrep_sync_wait=0; --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc +--connection node_2 +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +--connection node_1 --disable_query_log --eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_node1'; --enable_query_log @@ -52,10 +58,6 @@ CREATE TABLE t1 (f1 INTEGER) engine=InnoDB; INSERT INTO t1 VALUES (1); --connection node_2 -SET SESSION wsrep_sync_wait=0; ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' ---source include/wait_condition.inc - --disable_query_log --eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_node2'; --enable_query_log @@ -86,6 +88,10 @@ SELECT COUNT(*) FROM t1; --let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc +--connection node_2 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + DROP TABLE t1; # Restore original auto_increment_offset values. From 7aed06887bc901afd84647cd8c3530b2e0a2ac80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 28 Apr 2025 10:27:19 +0300 Subject: [PATCH 04/15] MDEV-36512 : galera_3nodes.GCF-354: certification position less than last committed Test changes only. Both warnings are expected and should be suppressed because we intentionally inject different inconsistencies on two nodes and then join them back with membership change. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera_3nodes/r/GCF-354.result | 4 ++++ mysql-test/suite/galera_3nodes/t/GCF-354.test | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/mysql-test/suite/galera_3nodes/r/GCF-354.result b/mysql-test/suite/galera_3nodes/r/GCF-354.result index 3fdd44fe9d3..cbf4e8fb147 100644 --- a/mysql-test/suite/galera_3nodes/r/GCF-354.result +++ b/mysql-test/suite/galera_3nodes/r/GCF-354.result @@ -47,9 +47,13 @@ CALL mtr.add_suppression("Slave SQL: Error 'Unknown database 'test'' on query\\. CALL mtr.add_suppression("Query apply failed"); CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on "); CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); +CALL mtr.add_suppression("WSREP: Cert position .* less than last committed"); +CALL mtr.add_suppression("WSREP: Sending JOIN failed: "); connection node_3; Node 3 synced CALL mtr.add_suppression("Slave SQL: Error 'Table 't1' already exists' on query\\. Default database: 'test'\\. Query: 'CREATE TABLE test\\.t1 \\(f1 INTEGER\\)', Error_code: 1050"); CALL mtr.add_suppression("Query apply failed"); CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on "); CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); +CALL mtr.add_suppression("WSREP: Cert position .* less than last committed"); +CALL mtr.add_suppression("WSREP: Sending JOIN failed: "); diff --git a/mysql-test/suite/galera_3nodes/t/GCF-354.test b/mysql-test/suite/galera_3nodes/t/GCF-354.test index 44dfa3deeb7..db4f32fccf9 100644 --- a/mysql-test/suite/galera_3nodes/t/GCF-354.test +++ b/mysql-test/suite/galera_3nodes/t/GCF-354.test @@ -92,6 +92,8 @@ CALL mtr.add_suppression("Slave SQL: Error 'Unknown database 'test'' on query\\. CALL mtr.add_suppression("Query apply failed"); CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on "); CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); +CALL mtr.add_suppression("WSREP: Cert position .* less than last committed"); +CALL mtr.add_suppression("WSREP: Sending JOIN failed: "); --connection node_3 --let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' @@ -101,5 +103,7 @@ CALL mtr.add_suppression("Slave SQL: Error 'Table 't1' already exists' on query\ CALL mtr.add_suppression("Query apply failed"); CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on "); CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); +CALL mtr.add_suppression("WSREP: Cert position .* less than last committed"); +CALL mtr.add_suppression("WSREP: Sending JOIN failed: "); --source ../galera/include/auto_increment_offset_restore.inc From 497d6324bc5592c211cd5f2f995e12044c3ce772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 28 Apr 2025 07:35:06 +0300 Subject: [PATCH 05/15] MDEV-36627 : galera.MDEV-29142: certification position less than last commited After the membership change on a newly synced node, then this is just a warning and safe to suppress. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/r/MDEV-29142.result | 4 ++++ mysql-test/suite/galera/t/MDEV-29142.test | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/mysql-test/suite/galera/r/MDEV-29142.result b/mysql-test/suite/galera/r/MDEV-29142.result index 370cbf5b074..ce214492b29 100644 --- a/mysql-test/suite/galera/r/MDEV-29142.result +++ b/mysql-test/suite/galera/r/MDEV-29142.result @@ -42,4 +42,8 @@ connection node_2; call mtr.add_suppression("WSREP: Failed to open table mysql\\.wsrep_streaming_log for writing"); call mtr.add_suppression("WSREP: Failed to open SR table for write"); call mtr.add_suppression("WSREP: Failed to recover SR transactions from schema: wsrep_on : 0"); +connection node_1; +call mtr.add_suppression("WSREP: Cert position .* less than last committed"); +connection node_2; +call mtr.add_suppression("WSREP: Cert position .* less than last committed"); DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/galera/t/MDEV-29142.test b/mysql-test/suite/galera/t/MDEV-29142.test index 2dc48a74a9d..d0d886ff490 100644 --- a/mysql-test/suite/galera/t/MDEV-29142.test +++ b/mysql-test/suite/galera/t/MDEV-29142.test @@ -53,16 +53,26 @@ SET SESSION wsrep_sync_wait = 0; --let $start_mysqld_params =--wsrep-new-cluster --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/start_mysqld.inc +--source include/wait_until_ready.inc --connection node_2 --let $start_mysqld_params = --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --source include/start_mysqld.inc +--source include/wait_until_ready.inc call mtr.add_suppression("WSREP: Failed to open table mysql\\.wsrep_streaming_log for writing"); call mtr.add_suppression("WSREP: Failed to open SR table for write"); call mtr.add_suppression("WSREP: Failed to recover SR transactions from schema: wsrep_on : 0"); +--connection node_1 +# +# after the membership change on a newly synced node, then this is just a warning +# +call mtr.add_suppression("WSREP: Cert position .* less than last committed"); +--connection node_2 +call mtr.add_suppression("WSREP: Cert position .* less than last committed"); + # # Cleanup # From c91c2e74ffb1bf1e4a542c435c8774548c57cff8 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 20 Mar 2025 18:31:25 +1100 Subject: [PATCH 06/15] MDEV-36337: udf_example UDF pointers need unsigned is_null/error This is required to match the sql/sql_udf.h --- sql/udf_example.c | 99 ++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/sql/udf_example.c b/sql/udf_example.c index 14c793ee98a..d87abdc9f1b 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -156,33 +156,33 @@ static pthread_mutex_t LOCK_hostname; my_bool metaphon_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void metaphon_deinit(UDF_INIT *initid); char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *length, char *is_null, char *error); + unsigned long *length, uchar *is_null, uchar *error); my_bool myfunc_double_init(UDF_INIT *, UDF_ARGS *args, char *message); -double myfunc_double(UDF_INIT *initid, UDF_ARGS *args, char *is_null, - char *error); +double myfunc_double(UDF_INIT *initid, UDF_ARGS *args, uchar *is_null, + uchar *error); my_bool myfunc_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message); -longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, - char *error); +longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, uchar *is_null, + uchar *error); my_bool udf_sequence_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void udf_sequence_deinit(UDF_INIT *initid); -longlong udf_sequence(UDF_INIT *initid, UDF_ARGS *args, char *is_null, - char *error); +longlong udf_sequence(UDF_INIT *initid, UDF_ARGS *args, uchar *is_null, + uchar *error); my_bool avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message ); void avgcost_deinit( UDF_INIT* initid ); -void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -void avgcost_clear( UDF_INIT* initid, char* is_null, char *error ); -void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -double avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); +void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, uchar* is_null, uchar *error ); +void avgcost_clear( UDF_INIT* initid, uchar* is_null, uchar *error ); +void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, uchar* is_null, uchar *error ); +double avgcost( UDF_INIT* initid, UDF_ARGS* args, uchar* is_null, uchar *error ); my_bool avg2_init( UDF_INIT* initid, UDF_ARGS* args, char* message ); void avg2_deinit( UDF_INIT* initid ); -void avg2_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -void avg2_clear( UDF_INIT* initid, char* is_null, char *error ); -void avg2_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -void avg2_remove( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -double avg2( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); +void avg2_reset( UDF_INIT* initid, UDF_ARGS* args, uchar *is_null, uchar *error ); +void avg2_clear( UDF_INIT* initid, uchar* is_null, uchar *error ); +void avg2_add( UDF_INIT* initid, UDF_ARGS* args, uchar *is_null, uchar *error ); +void avg2_remove( UDF_INIT* initid, UDF_ARGS* args, uchar* is_null, uchar *error ); +double avg2( UDF_INIT* initid, UDF_ARGS* args, uchar* is_null, uchar *error ); my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message); char *is_const(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long - *length, char *is_null, char *error); + *length, uchar *is_null, uchar *error); /************************************************************************* @@ -292,7 +292,7 @@ static char codes[26] = { char *metaphon(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, char *result, unsigned long *length, - char *is_null, char *error __attribute__((unused))) + uchar *is_null, uchar *error __attribute__((unused))) { const char *word=args->args[0]; const char *w_end; @@ -568,7 +568,7 @@ my_bool myfunc_double_init(UDF_INIT *initid, UDF_ARGS *args, char *message) double myfunc_double(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, - char *is_null, char *error __attribute__((unused))) + uchar *is_null, uchar *error __attribute__((unused))) { unsigned long val = 0; unsigned long v = 0; @@ -607,8 +607,8 @@ double myfunc_double(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, /* This function returns the sum of all arguments */ longlong myfunc_int(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, - char *is_null __attribute__((unused)), - char *error __attribute__((unused))) + uchar *is_null __attribute__((unused)), + uchar *error __attribute__((unused))) { longlong val = 0; uint i; @@ -681,8 +681,8 @@ void udf_sequence_deinit(UDF_INIT *initid) } longlong udf_sequence(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, - char *is_null __attribute__((unused)), - char *error __attribute__((unused))) + uchar *is_null __attribute__((unused)), + uchar *error __attribute__((unused))) { ulonglong val=0; if (args->arg_count) @@ -712,11 +712,11 @@ longlong udf_sequence(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, my_bool lookup_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void lookup_deinit(UDF_INIT *initid); char *lookup(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *length, char *null_value, char *error); + unsigned long *length, uchar *null_value, uchar *error); my_bool reverse_lookup_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void reverse_lookup_deinit(UDF_INIT *initid); char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *length, char *null_value, char *error); + unsigned long *length, uchar *null_value, uchar *error); /**************************************************************************** @@ -750,8 +750,8 @@ void lookup_deinit(UDF_INIT *initid __attribute__((unused))) } char *lookup(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, - char *result, unsigned long *res_length, char *null_value, - char *error __attribute__((unused))) + char *result, unsigned long *res_length, uchar *null_value, + uchar *error __attribute__((unused))) { uint length; char name_buff[256]; @@ -831,7 +831,7 @@ void reverse_lookup_deinit(UDF_INIT *initid __attribute__((unused))) char *reverse_lookup(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, char *result, unsigned long *res_length, - char *null_value, char *error __attribute__((unused))) + uchar *null_value, uchar *error __attribute__((unused))) { #if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) char name_buff[256]; @@ -974,7 +974,7 @@ avgcost_deinit( UDF_INIT* initid ) /* This is only for MySQL 4.0 compatibility */ void -avgcost_reset(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message) +avgcost_reset(UDF_INIT* initid, UDF_ARGS* args, uchar* is_null, uchar* message) { avgcost_clear(initid, is_null, message); avgcost_add(initid, args, is_null, message); @@ -983,8 +983,8 @@ avgcost_reset(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message) /* This is needed to get things to work in MySQL 4.1.1 and above */ void -avgcost_clear(UDF_INIT* initid, char* is_null __attribute__((unused)), - char* message __attribute__((unused))) +avgcost_clear(UDF_INIT* initid, uchar* is_null __attribute__((unused)), + uchar* message __attribute__((unused))) { struct avgcost_data* data = (struct avgcost_data*)initid->ptr; data->totalprice= 0.0; @@ -995,8 +995,8 @@ avgcost_clear(UDF_INIT* initid, char* is_null __attribute__((unused)), void avgcost_add(UDF_INIT* initid, UDF_ARGS* args, - char* is_null __attribute__((unused)), - char* message __attribute__((unused))) + uchar* is_null __attribute__((unused)), + uchar* message __attribute__((unused))) { if (args->args[0] && args->args[1]) { @@ -1043,7 +1043,7 @@ avgcost_add(UDF_INIT* initid, UDF_ARGS* args, double avgcost( UDF_INIT* initid, UDF_ARGS* args __attribute__((unused)), - char* is_null, char* error __attribute__((unused))) + uchar* is_null, uchar* error __attribute__((unused))) { struct avgcost_data* data = (struct avgcost_data*)initid->ptr; if (!data->count || !data->totalquantity) @@ -1121,7 +1121,8 @@ avg2_deinit( UDF_INIT* initid ) /* This is only for MySQL 4.0 compatibility */ void -avg2_reset(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message) +avg2_reset(UDF_INIT* initid, UDF_ARGS* args, uchar* is_null, + uchar* message) { avgcost_clear(initid, is_null, message); avgcost_add(initid, args, is_null, message); @@ -1130,8 +1131,8 @@ avg2_reset(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message) /* This is needed to get things to work in MySQL 4.1.1 and above */ void -avg2_clear(UDF_INIT* initid, char* is_null __attribute__((unused)), - char* message __attribute__((unused))) +avg2_clear(UDF_INIT* initid, uchar* is_null __attribute__((unused)), + uchar* message __attribute__((unused))) { struct avg2_data* data = (struct avg2_data*)initid->ptr; data->sum= 0.0; @@ -1141,8 +1142,8 @@ avg2_clear(UDF_INIT* initid, char* is_null __attribute__((unused)), void avg2_add(UDF_INIT* initid, UDF_ARGS* args, - char* is_null __attribute__((unused)), - char* message __attribute__((unused))) + uchar* is_null __attribute__((unused)), + uchar* message __attribute__((unused))) { if (args->args[0] && args->args[1]) { @@ -1158,8 +1159,8 @@ avg2_add(UDF_INIT* initid, UDF_ARGS* args, void avg2_remove(UDF_INIT* initid, UDF_ARGS* args, - char* is_null __attribute__((unused)), - char* message __attribute__((unused))) + uchar* is_null __attribute__((unused)), + uchar* message __attribute__((unused))) { if (args->args[0] && args->args[1]) { @@ -1174,8 +1175,8 @@ avg2_remove(UDF_INIT* initid, UDF_ARGS* args, double -avg2( UDF_INIT* initid, UDF_ARGS* args __attribute__((unused)), - char* is_null, char* error __attribute__((unused))) +avg2(UDF_INIT* initid, UDF_ARGS* args __attribute__((unused)), + uchar* is_null, uchar* error __attribute__((unused))) { struct avg2_data* data = (struct avg2_data*)initid->ptr; if (!data->count) @@ -1191,8 +1192,8 @@ avg2( UDF_INIT* initid, UDF_ARGS* args __attribute__((unused)), my_bool myfunc_argument_name_init(UDF_INIT *initid, UDF_ARGS *args, char *message); char *myfunc_argument_name(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *length, char *null_value, - char *error); + unsigned long *length, uchar *null_value, + uchar *error); my_bool myfunc_argument_name_init(UDF_INIT *initid, UDF_ARGS *args, char *message) @@ -1210,8 +1211,8 @@ my_bool myfunc_argument_name_init(UDF_INIT *initid, UDF_ARGS *args, char *myfunc_argument_name(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, char *result, - unsigned long *length, char *null_value, - char *error __attribute__((unused))) + unsigned long *length, uchar *null_value, + uchar *error __attribute__((unused))) { if (!args->attributes[0]) { @@ -1241,7 +1242,7 @@ my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message) char * is_const(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)), char *result, unsigned long *length, - char *is_null, char *error __attribute__((unused))) + uchar *is_null,uchar *error __attribute__((unused))) { if (initid->ptr != 0) { sprintf(result, "const"); @@ -1280,7 +1281,7 @@ my_bool check_const_len_init(UDF_INIT *initid, UDF_ARGS *args, char *message) char * check_const_len(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)), char *result, unsigned long *length, - char *is_null, char *error __attribute__((unused))) + uchar *is_null,uchar *error __attribute__((unused))) { strmov(result, initid->ptr); *length= (uint) strlen(result); From 0b5a084e27fb1abe5a1d1d57d56763477165ac0b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 20 Mar 2025 19:21:56 +1100 Subject: [PATCH 07/15] MDEV-36337: connect UDF pointers need unsigned char* for is_null/error This is required to match the sql/sql_udf.h --- storage/connect/bsonudf.cpp | 139 ++++++++++++++++++------------------ storage/connect/bsonudf.h | 35 +++++---- storage/connect/jsonudf.cpp | 130 ++++++++++++++++----------------- storage/connect/jsonudf.h | 30 ++++---- 4 files changed, 167 insertions(+), 167 deletions(-) diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp index 68d08bdd085..33a462944b5 100644 --- a/storage/connect/bsonudf.cpp +++ b/storage/connect/bsonudf.cpp @@ -1972,7 +1972,7 @@ my_bool bsonvalue_init(UDF_INIT* initid, UDF_ARGS* args, char* message) } // end of bsonvalue_init char* bsonvalue(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long* res_length, char*, char*) + unsigned long* res_length, uchar *, uchar *) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2014,7 +2014,7 @@ my_bool bson_make_array_init(UDF_INIT* initid, UDF_ARGS* args, char* message) } // end of bson_make_array_init char* bson_make_array(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long* res_length, char*, char*) + unsigned long* res_length, uchar *, uchar *) { char* str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2081,7 +2081,7 @@ my_bool bson_array_add_values_init(UDF_INIT* initid, UDF_ARGS* args, char* messa } // end of bson_array_add_values_init char* bson_array_add_values(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long* res_length, char* is_null, char*) { + unsigned long* res_length, uchar * is_null, uchar *) { char* str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2159,7 +2159,7 @@ my_bool bson_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_array_add_init char *bson_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2263,7 +2263,7 @@ my_bool bson_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_array_delete_init char *bson_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2332,7 +2332,7 @@ my_bool bson_make_object_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_make_object_init char *bson_make_object(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2381,7 +2381,7 @@ my_bool bson_object_nonull_init(UDF_INIT *initid, UDF_ARGS *args, } // end of bson_object_nonull_init char *bson_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2435,7 +2435,7 @@ my_bool bson_object_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_object_key_init char *bson_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2504,7 +2504,7 @@ my_bool bson_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_object_add_init char *bson_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PSZ key; char *str = NULL; @@ -2599,7 +2599,7 @@ my_bool bson_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_object_delete_init char *bson_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2678,7 +2678,7 @@ my_bool bson_object_list_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_object_list_init char *bson_object_list(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2745,7 +2745,7 @@ my_bool bson_object_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_object_values_init char *bson_object_values(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2815,7 +2815,7 @@ my_bool bsonset_def_prec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bsonset_def_prec_init -long long bsonset_def_prec(UDF_INIT *initid, UDF_ARGS *args, char *, char *) +long long bsonset_def_prec(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { long long n = *(long long*)args->args[0]; @@ -2836,7 +2836,7 @@ my_bool bsonget_def_prec_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bsonget_def_prec_init -long long bsonget_def_prec(UDF_INIT *initid, UDF_ARGS *args, char *, char *) +long long bsonget_def_prec(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { return (long long)GetJsonDefPrec(); } // end of bsonget_def_prec @@ -2854,7 +2854,7 @@ my_bool bsonset_grp_size_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bsonset_grp_size_init -long long bsonset_grp_size(UDF_INIT *initid, UDF_ARGS *args, char *, char *) +long long bsonset_grp_size(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { long long n = *(long long*)args->args[0]; @@ -2875,7 +2875,7 @@ my_bool bsonget_grp_size_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bsonget_grp_size_init -long long bsonget_grp_size(UDF_INIT *initid, UDF_ARGS *args, char *, char *) +long long bsonget_grp_size(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { return (long long)GetJsonGroupSize(); } // end of bsonget_grp_size @@ -2909,7 +2909,7 @@ my_bool bson_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return false; } // end of bson_array_grp_init -void bson_array_grp_clear(UDF_INIT *initid, char*, char*) +void bson_array_grp_clear(UDF_INIT *initid, uchar *, uchar *) { PGLOBAL g = (PGLOBAL)initid->ptr; PBJNX bxp = (PBJNX)((char*)g->Sarea + sizeof(POOLHEADER)); @@ -2919,7 +2919,7 @@ void bson_array_grp_clear(UDF_INIT *initid, char*, char*) g->N = GetJsonGroupSize(); } // end of bson_array_grp_clear -void bson_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) +void bson_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { PGLOBAL g = (PGLOBAL)initid->ptr; PBJNX bxp = (PBJNX)((char*)g->Sarea + sizeof(POOLHEADER)); @@ -2931,7 +2931,7 @@ void bson_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) } // end of bson_array_grp_add char *bson_array_grp(UDF_INIT *initid, UDF_ARGS *, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2982,7 +2982,7 @@ my_bool bson_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return false; } // end of bson_object_grp_init -void bson_object_grp_clear(UDF_INIT *initid, char*, char*) +void bson_object_grp_clear(UDF_INIT *initid, uchar *, uchar *) { PGLOBAL g = (PGLOBAL)initid->ptr; PBJNX bxp = (PBJNX)((char*)g->Sarea + sizeof(POOLHEADER)); @@ -2992,7 +2992,7 @@ void bson_object_grp_clear(UDF_INIT *initid, char*, char*) g->N = GetJsonGroupSize(); } // end of bson_object_grp_clear -void bson_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) +void bson_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { PGLOBAL g = (PGLOBAL)initid->ptr; PBJNX bxp = (PBJNX)((char*)g->Sarea + sizeof(POOLHEADER)); @@ -3004,7 +3004,7 @@ void bson_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) } // end of bson_object_grp_add char *bson_object_grp(UDF_INIT *initid, UDF_ARGS *, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3045,7 +3045,7 @@ my_bool bson_test_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { } // end of bson_test_init char* bson_test(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long* res_length, char* is_null, char* error) { + unsigned long* res_length, uchar * is_null, uchar * error) { char* str = NULL, *fn = NULL; int pretty = 1; PBVAL bvp; @@ -3149,7 +3149,7 @@ my_bool bsonlocate_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { } // end of bsonlocate_init char* bsonlocate(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long* res_length, char* is_null, char* error) { + unsigned long* res_length, uchar * is_null, uchar * error) { char *path = NULL; int k; PBVAL bvp, bvp2; @@ -3270,7 +3270,7 @@ my_bool bson_locate_all_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { } // end of bson_locate_all_init char* bson_locate_all(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long* res_length, char* is_null, char* error) { + unsigned long* res_length, uchar * is_null, uchar * error) { char* path = NULL; int mx = 10; PBVAL bvp, bvp2; @@ -3395,9 +3395,10 @@ my_bool bson_contains_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return JsonInit(initid, args, message, false, reslen, memlen, more); } // end of bson contains_init -long long bson_contains(UDF_INIT *initid, UDF_ARGS *args, char *, char *error) +long long bson_contains(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *error) { - char isn, res[256]; + unsigned char isn; + char res[256]; unsigned long reslen; isn = 0; @@ -3444,7 +3445,7 @@ my_bool bsoncontains_path_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of bsoncontains_path_init -long long bsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *, char *error) +long long bsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *error) { char *p, *path; long long n; @@ -3559,7 +3560,7 @@ my_bool bson_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_item_merge_init char *bson_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3669,7 +3670,7 @@ my_bool bson_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_get_item_init char *bson_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *path, *str = NULL; PBVAL jvp; @@ -3775,7 +3776,7 @@ my_bool bsonget_string_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bsonget_string_init char *bsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *p, *path, *str = NULL; PBVAL jsp, jvp; @@ -3886,7 +3887,7 @@ my_bool bsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bsonget_int_init long long bsonget_int(UDF_INIT *initid, UDF_ARGS *args, - char *is_null, char *error) + uchar *is_null, uchar *error) { char *p, *path; long long n; @@ -4008,7 +4009,7 @@ my_bool bsonget_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bsonget_real_init double bsonget_real(UDF_INIT *initid, UDF_ARGS *args, - char *is_null, char *error) + uchar *is_null, uchar *error) { char *p, *path; double d; @@ -4130,7 +4131,7 @@ my_bool bson_delete_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_delete_item_init char *bson_delete_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *path, *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -4213,7 +4214,7 @@ void bson_delete_item_deinit(UDF_INIT* initid) /* This function is used by the json_set/insert/update_item functions. */ /*********************************************************************************/ static char *bson_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *path, *str = NULL; int w; @@ -4360,7 +4361,7 @@ my_bool bson_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_set_item_init char *bson_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$set"); return bson_handle_item(initid, args, result, res_length, is_null, p); @@ -4380,7 +4381,7 @@ my_bool bson_insert_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_insert_item_init char *bson_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$insert"); return bson_handle_item(initid, args, result, res_length, is_null, p); @@ -4400,7 +4401,7 @@ my_bool bson_update_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_update_item_init char *bson_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$update"); return bson_handle_item(initid, args, result, res_length, is_null, p); @@ -4459,7 +4460,7 @@ my_bool bson_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_file_init char *bson_file(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *fn, *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -4552,7 +4553,7 @@ my_bool bfile_make_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bfile_make_init char *bfile_make(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *p, *str = NULL, *fn = NULL; int n, pretty = 2; @@ -4673,7 +4674,7 @@ my_bool bfile_convert_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { } // end of bfile_convert_init char *bfile_convert(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long *res_length, char *is_null, char *error) { + unsigned long *res_length, uchar *is_null, uchar *error) { char *str, *fn, *ofn; int lrecl = (int)*(longlong*)args->args[2]; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -4732,7 +4733,7 @@ my_bool bfile_bjson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { } // end of bfile_bjson_init char *bfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char*, char *error) { + unsigned long *res_length, uchar *, uchar *error) { char *buf, *str = NULL, fn[_MAX_PATH], ofn[_MAX_PATH]; bool loop; ssize_t len, newloc; @@ -4846,7 +4847,7 @@ my_bool bson_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bson_serialize_init char *bson_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *error) + unsigned long *res_length, uchar *, uchar *error) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -4893,7 +4894,7 @@ my_bool bbin_make_array_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_make_array_init char *bbin_make_array(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = NULL; @@ -4966,7 +4967,7 @@ my_bool bbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_array_add_init char *bbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = NULL; @@ -5035,7 +5036,7 @@ my_bool bbin_array_add_values_init(UDF_INIT* initid, UDF_ARGS* args, char* messa } // end of bbin_array_add_values_init char* bbin_array_add_values(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long* res_length, char* is_null, char* error) + unsigned long* res_length, uchar * is_null, uchar * error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = NULL; @@ -5087,18 +5088,18 @@ my_bool bbin_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return bson_array_grp_init(initid, args, message); } // end of bbin_array_grp_init -void bbin_array_grp_clear(UDF_INIT *initid, char *a, char *b) +void bbin_array_grp_clear(UDF_INIT *initid, uchar *a, uchar *b) { bson_array_grp_clear(initid, a, b); } // end of bbin_array_grp_clear -void bbin_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, char *a, char *b) +void bbin_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, uchar *a, uchar *b) { bson_array_grp_add(initid, args, a, b); } // end of bbin_array_grp_add char *bbin_array_grp(UDF_INIT *initid, UDF_ARGS *, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PBSON bsp = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5135,18 +5136,18 @@ my_bool bbin_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return bson_object_grp_init(initid, args, message); } // end of bbin_object_grp_init -void bbin_object_grp_clear(UDF_INIT *initid, char *a, char *b) +void bbin_object_grp_clear(UDF_INIT *initid, uchar *a, uchar *b) { bson_object_grp_clear(initid, a, b); } // end of bbin_object_grp_clear -void bbin_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, char *a, char *b) +void bbin_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, uchar *a, uchar *b) { bson_object_grp_add(initid, args, a, b); } // end of bbin_object_grp_add char *bbin_object_grp(UDF_INIT *initid, UDF_ARGS *, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PBSON bsp = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5187,7 +5188,7 @@ my_bool bbin_make_object_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_make_object_init char *bbin_make_object(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -5241,7 +5242,7 @@ my_bool bbin_object_nonull_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_object_nonull_init char *bbin_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -5301,7 +5302,7 @@ my_bool bbin_object_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_object_key_init char *bbin_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -5363,7 +5364,7 @@ my_bool bbin_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_object_add_init char *bbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = NULL; @@ -5425,7 +5426,7 @@ my_bool bbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_array_delete_init char *bbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = NULL; @@ -5496,7 +5497,7 @@ my_bool bbin_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_object_delete_init char *bbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = NULL; @@ -5555,7 +5556,7 @@ my_bool bbin_object_list_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_object_list_init char *bbin_object_list(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -5607,7 +5608,7 @@ my_bool bbin_object_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_object_values_init char *bbin_object_values(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -5662,7 +5663,7 @@ my_bool bbin_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_get_item_init char *bbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PBSON bsp = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5712,7 +5713,7 @@ my_bool bbin_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_item_merge_init char *bbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PBSON bsp = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5785,7 +5786,7 @@ void bbin_item_merge_deinit(UDF_INIT* initid) /* This function is used by the jbin_set/insert/update_item functions. */ /*********************************************************************************/ static char *bbin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *path; int w; @@ -5891,7 +5892,7 @@ my_bool bbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_set_item_init char *bbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$set"); return bbin_handle_item(initid, args, result, res_length, is_null, p); @@ -5911,7 +5912,7 @@ my_bool bbin_insert_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_insert_item_init char *bbin_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$insert"); return bbin_handle_item(initid, args, result, res_length, is_null, p); @@ -5931,7 +5932,7 @@ my_bool bbin_update_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_update_item_init char *bbin_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$update"); return bbin_handle_item(initid, args, result, res_length, is_null, p); @@ -5951,7 +5952,7 @@ my_bool bbin_delete_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_delete_item_init char *bbin_delete_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *path; PBSON bsp = NULL; @@ -6045,7 +6046,7 @@ my_bool bbin_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of bbin_file_init char *bbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *fn; int pretty = 3; @@ -6122,7 +6123,7 @@ my_bool bbin_locate_all_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { } // end of bbin_locate_all_init char* bbin_locate_all(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long* res_length, char* is_null, char* error) { + unsigned long* res_length, uchar * is_null, uchar * error) { char *path = NULL; int mx = 10; PBVAL bvp, bvp2; diff --git a/storage/connect/bsonudf.h b/storage/connect/bsonudf.h index e355fe7b48e..90cabf72e21 100644 --- a/storage/connect/bsonudf.h +++ b/storage/connect/bsonudf.h @@ -10,9 +10,6 @@ #include "bson.h" #if 0 -#define UDF_EXEC_ARGS \ - UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char*, char* - // BSON size should be equal on Linux and Windows #define BMX 255 typedef struct BSON* PBSON; @@ -205,11 +202,11 @@ extern "C" { DllExport void bson_locate_all_deinit(UDF_INIT*); DllExport my_bool bson_contains_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long bson_contains(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long bson_contains(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void bson_contains_deinit(UDF_INIT*); DllExport my_bool bsoncontains_path_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long bsoncontains_path(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long bsoncontains_path(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void bsoncontains_path_deinit(UDF_INIT*); DllExport my_bool bson_make_object_init(UDF_INIT*, UDF_ARGS*, char*); @@ -253,34 +250,34 @@ extern "C" { DllExport void bsonget_string_deinit(UDF_INIT*); DllExport my_bool bsonget_int_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long bsonget_int(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long bsonget_int(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void bsonget_int_deinit(UDF_INIT*); DllExport my_bool bsonget_real_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport double bsonget_real(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport double bsonget_real(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void bsonget_real_deinit(UDF_INIT*); DllExport my_bool bsonset_def_prec_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long bsonset_def_prec(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long bsonset_def_prec(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport my_bool bsonget_def_prec_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long bsonget_def_prec(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long bsonget_def_prec(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport my_bool bsonset_grp_size_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long bsonset_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long bsonset_grp_size(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport my_bool bsonget_grp_size_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long bsonget_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long bsonget_grp_size(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport my_bool bson_array_grp_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport void bson_array_grp_clear(UDF_INIT *, char *, char *); - DllExport void bson_array_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); + DllExport void bson_array_grp_clear(UDF_INIT *, uchar *, uchar *); + DllExport void bson_array_grp_add(UDF_INIT *, UDF_ARGS *, uchar *, uchar *); DllExport char *bson_array_grp(UDF_EXEC_ARGS); DllExport void bson_array_grp_deinit(UDF_INIT*); DllExport my_bool bson_object_grp_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport void bson_object_grp_clear(UDF_INIT *, char *, char *); - DllExport void bson_object_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); + DllExport void bson_object_grp_clear(UDF_INIT *, uchar *, uchar *); + DllExport void bson_object_grp_add(UDF_INIT *, UDF_ARGS *, uchar *, uchar *); DllExport char *bson_object_grp(UDF_EXEC_ARGS); DllExport void bson_object_grp_deinit(UDF_INIT*); @@ -337,14 +334,14 @@ extern "C" { DllExport void bbin_array_delete_deinit(UDF_INIT*); DllExport my_bool bbin_array_grp_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport void bbin_array_grp_clear(UDF_INIT *, char *, char *); - DllExport void bbin_array_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); + DllExport void bbin_array_grp_clear(UDF_INIT *, uchar *, uchar *); + DllExport void bbin_array_grp_add(UDF_INIT *, UDF_ARGS *, uchar *, uchar *); DllExport char *bbin_array_grp(UDF_EXEC_ARGS); DllExport void bbin_array_grp_deinit(UDF_INIT*); DllExport my_bool bbin_object_grp_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport void bbin_object_grp_clear(UDF_INIT *, char *, char *); - DllExport void bbin_object_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); + DllExport void bbin_object_grp_clear(UDF_INIT *, uchar *, uchar *); + DllExport void bbin_object_grp_add(UDF_INIT *, UDF_ARGS *, uchar *, uchar *); DllExport char *bbin_object_grp(UDF_EXEC_ARGS); DllExport void bbin_object_grp_deinit(UDF_INIT*); diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 66f2e2b65b9..60870dc3618 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -28,9 +28,9 @@ #define M 9 static char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error); + unsigned long *res_length, uchar *is_null, uchar *error); static char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error); + unsigned long *res_length, uchar *is_null, uchar *error); static PJSON JsonNew(PGLOBAL g, JTYP type); static PJVAL JvalNew(PGLOBAL g, JTYP type, void *vp = NULL); static PJSNX JsnxNew(PGLOBAL g, PJSON jsp, int type, int len = 64); @@ -2065,7 +2065,7 @@ my_bool jsonvalue_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jsonvalue_init char *jsonvalue(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2106,7 +2106,7 @@ my_bool json_make_array_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_make_array_init char *json_make_array(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2173,7 +2173,7 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa } // end of json_array_add_values_init char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2255,7 +2255,7 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_array_add_init char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2363,7 +2363,7 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_array_delete_init char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2443,7 +2443,7 @@ my_bool jsonsum_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jsonsum_int_init -long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) +long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, uchar *is_null, uchar *error) { long long n = 0LL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2518,7 +2518,7 @@ my_bool jsonsum_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jsonsum_real_init -double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) +double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, uchar *is_null, uchar *error) { double n = 0.0; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2582,7 +2582,7 @@ my_bool jsonavg_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return jsonsum_real_init(initid, args, message); } // end of jsonavg_real_init -double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) +double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, uchar *is_null, uchar *error) { double n = 0.0; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2653,7 +2653,7 @@ my_bool json_make_object_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_make_object_init char *json_make_object(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2701,7 +2701,7 @@ my_bool json_object_nonull_init(UDF_INIT *initid, UDF_ARGS *args, } // end of json_object_nonull_init char *json_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2755,7 +2755,7 @@ my_bool json_object_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_object_key_init char *json_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2823,7 +2823,8 @@ my_bool json_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_object_add_init char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, + uchar *error) { PCSZ key; char *str = NULL; @@ -2919,7 +2920,7 @@ my_bool json_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_object_delete_init char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -2996,7 +2997,7 @@ my_bool json_object_list_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_object_list_init char *json_object_list(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3072,7 +3073,7 @@ my_bool json_object_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_object_list_init char *json_object_values(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3141,7 +3142,7 @@ my_bool jsonset_grp_size_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jsonset_grp_size_init -long long jsonset_grp_size(UDF_INIT *initid, UDF_ARGS *args, char *, char *) +long long jsonset_grp_size(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { long long n = *(long long*)args->args[0]; @@ -3162,7 +3163,7 @@ my_bool jsonget_grp_size_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jsonget_grp_size_init -long long jsonget_grp_size(UDF_INIT *initid, UDF_ARGS *args, char *, char *) +long long jsonget_grp_size(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { return (long long)GetJsonGroupSize(); } // end of jsonget_grp_size @@ -3197,7 +3198,7 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return false; } // end of json_array_grp_init -void json_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) +void json_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { PGLOBAL g = (PGLOBAL)initid->ptr; PJAR arp = (PJAR)g->Activityp; @@ -3208,7 +3209,7 @@ void json_array_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) } // end of json_array_grp_add char *json_array_grp(UDF_INIT *initid, UDF_ARGS *, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3230,7 +3231,7 @@ char *json_array_grp(UDF_INIT *initid, UDF_ARGS *, char *result, return str; } // end of json_array_grp -void json_array_grp_clear(UDF_INIT *initid, char*, char*) +void json_array_grp_clear(UDF_INIT *initid, uchar *, uchar *) { PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3274,7 +3275,7 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return false; } // end of json_object_grp_init -void json_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) +void json_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *) { PGLOBAL g = (PGLOBAL)initid->ptr; PJOB objp = (PJOB)g->Activityp; @@ -3285,7 +3286,7 @@ void json_object_grp_add(UDF_INIT *initid, UDF_ARGS *args, char*, char*) } // end of json_object_grp_add char *json_object_grp(UDF_INIT *initid, UDF_ARGS *, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, uchar *, uchar *) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3301,7 +3302,7 @@ char *json_object_grp(UDF_INIT *initid, UDF_ARGS *, char *result, return str; } // end of json_object_grp -void json_object_grp_clear(UDF_INIT *initid, char*, char*) +void json_object_grp_clear(UDF_INIT *initid, uchar *, uchar *) { PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3351,7 +3352,7 @@ my_bool json_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_item_merge_init char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -3450,7 +3451,7 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_get_item_init char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *path, *str = NULL; PJSON jsp; @@ -3557,7 +3558,7 @@ my_bool jsonget_string_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jsonget_string_init char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *p, *path, *str = NULL; PJSON jsp; @@ -3666,7 +3667,7 @@ my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jsonget_int_init long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args, - char *is_null, char *error) + uchar *is_null, uchar *error) { char *p, *path; long long n; @@ -3786,7 +3787,7 @@ my_bool jsonget_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jsonget_real_init double jsonget_real(UDF_INIT *initid, UDF_ARGS *args, - char *is_null, char *error) + uchar *is_null, uchar *error) { char *p, *path; double d; @@ -3907,7 +3908,7 @@ my_bool jsonlocate_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jsonlocate_init char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *path = NULL; int k; @@ -4035,7 +4036,7 @@ my_bool json_locate_all_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_locate_all_init char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *p, *path = NULL; int mx = 10; @@ -4161,9 +4162,10 @@ my_bool jsoncontains_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return JsonInit(initid, args, message, false, reslen, memlen, more); } // end of jsoncontains_init -long long jsoncontains(UDF_INIT *initid, UDF_ARGS *args, char *, char *error) +long long jsoncontains(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *error) { - char isn, res[256]; + unsigned char isn; + char res[256]; unsigned long reslen; isn = 0; @@ -4210,7 +4212,7 @@ my_bool jsoncontains_path_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jsoncontains_path_init -long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *, char *error) +long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, uchar *, uchar *error) { char *p, *path; long long n; @@ -4290,7 +4292,7 @@ void jsoncontains_path_deinit(UDF_INIT* initid) /* This function is used by the json_set/insert/update_item functions. */ /*********************************************************************************/ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *p, *path, *str = NULL; int w; @@ -4440,7 +4442,7 @@ my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_set_item_init char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$set"); return handle_item(initid, args, result, res_length, is_null, p); @@ -4460,7 +4462,7 @@ my_bool json_insert_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_insert_item_init char *json_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$insert"); return handle_item(initid, args, result, res_length, is_null, p); @@ -4480,7 +4482,7 @@ my_bool json_update_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_update_item_init char *json_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$update"); return handle_item(initid, args, result, res_length, is_null, p); @@ -4539,7 +4541,7 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_file_init char *json_file(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *str, *fn; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -4636,7 +4638,7 @@ my_bool jfile_make_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jfile_make_init char *jfile_make(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *p, *str = NULL, *fn = NULL; int n, pretty = 2; @@ -4744,7 +4746,7 @@ my_bool jbin_array_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_array_init char *jbin_array(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -4805,7 +4807,7 @@ my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa } // end of jbin_array_add_values_init char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -4879,7 +4881,7 @@ my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_array_add_init char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { int n = 2; PJSON top = NULL; @@ -4969,7 +4971,7 @@ my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_array_delete_init char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PJSON top = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5038,7 +5040,7 @@ my_bool jbin_object_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_object_init char *jbin_object(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -5093,7 +5095,7 @@ my_bool jbin_object_nonull_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_object_nonull_init char *jbin_object_nonull(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -5154,7 +5156,7 @@ my_bool jbin_object_key_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_object_key_init char *jbin_object_key(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PGLOBAL g = (PGLOBAL)initid->ptr; PBSON bsp = (PBSON)g->Xchk; @@ -5216,7 +5218,7 @@ my_bool jbin_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_object_add_init char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PJSON top = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5296,7 +5298,7 @@ my_bool jbin_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_object_delete_init char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PJSON top = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5359,7 +5361,7 @@ my_bool jbin_object_list_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_object_list_init char *jbin_object_list(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PJAR jarp = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5420,7 +5422,7 @@ my_bool jbin_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_get_item_init char *jbin_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *path; PJSON jsp; @@ -5513,7 +5515,7 @@ my_bool jbin_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_item_merge_init char *jbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { PJSON top = NULL; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5573,7 +5575,7 @@ void jbin_item_merge_deinit(UDF_INIT* initid) /* This function is used by the jbin_set/insert/update functions. */ /*********************************************************************************/ char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *p, *path; int w; @@ -5697,7 +5699,7 @@ my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_set_item_init char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$set"); return bin_handle_item(initid, args, result, res_length, is_null, p); @@ -5717,7 +5719,7 @@ my_bool jbin_insert_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_insert_item_init char *jbin_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$insert"); return bin_handle_item(initid, args, result, res_length, is_null, p); @@ -5737,7 +5739,7 @@ my_bool jbin_update_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_update_item_init char *jbin_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *p) + unsigned long *res_length, uchar *is_null, uchar *p) { strcpy(result, "$update"); return bin_handle_item(initid, args, result, res_length, is_null, p); @@ -5785,7 +5787,7 @@ my_bool jbin_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of jbin_file_init char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) + unsigned long *res_length, uchar *is_null, uchar *error) { char *fn; int pretty = 3, pty = 3; @@ -5880,7 +5882,7 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_serialize_init char *json_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *error) + unsigned long *res_length, uchar *, uchar *error) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5936,7 +5938,7 @@ my_bool jfile_convert_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { } // end of jfile_convert_init char *jfile_convert(UDF_INIT* initid, UDF_ARGS* args, char* result, - unsigned long *res_length, char *is_null, char *error) { + unsigned long *res_length, uchar *is_null, uchar *error) { char *str, *fn, *ofn; int lrecl = (int)*(longlong*)args->args[2]; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -5995,7 +5997,7 @@ my_bool jfile_bjson_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { } // end of jfile_bjson_init char *jfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char*, char *error) { + unsigned long *res_length, uchar *, uchar *error) { char *fn, *ofn, *buf, *str = NULL; bool loop; ssize_t len, newloc; @@ -6535,7 +6537,7 @@ my_bool envar_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of envar_init char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *str, name[256]; int n = MY_MIN(args->lengths[0], sizeof(name) - 1); @@ -6573,7 +6575,7 @@ my_bool uvar_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of uvar_init char *uvar(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *) + unsigned long *res_length, uchar *is_null, uchar *) { char *str, varname[256]; PGLOBAL g = (PGLOBAL)initid->ptr; @@ -6617,7 +6619,7 @@ my_bool countin_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return false; } // end of countin_init -long long countin(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *) +long long countin(UDF_INIT *initid, UDF_ARGS *args, uchar *is_null, uchar *) { PSZ str1, str2; char *s; diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h index 4378bddf9ba..782d17acb12 100644 --- a/storage/connect/jsonudf.h +++ b/storage/connect/jsonudf.h @@ -14,7 +14,7 @@ #include "json.h" #define UDF_EXEC_ARGS \ - UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char*, char* + UDF_INIT*, UDF_ARGS*, char*, unsigned long*, uchar *, uchar * // BSON size should be equal on Linux and Windows #define BMX 255 @@ -95,15 +95,15 @@ extern "C" { DllExport void json_array_delete_deinit(UDF_INIT*); DllExport my_bool jsonsum_int_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long jsonsum_int(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long jsonsum_int(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void jsonsum_int_deinit(UDF_INIT*); DllExport my_bool jsonsum_real_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport double jsonsum_real(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport double jsonsum_real(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void jsonsum_real_deinit(UDF_INIT*); DllExport my_bool jsonavg_real_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport double jsonavg_real(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport double jsonavg_real(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void jsonavg_real_deinit(UDF_INIT*); DllExport my_bool json_make_object_init(UDF_INIT*, UDF_ARGS*, char*); @@ -135,21 +135,21 @@ extern "C" { DllExport void json_object_values_deinit(UDF_INIT*); DllExport my_bool jsonset_grp_size_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long jsonset_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long jsonset_grp_size(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport my_bool jsonget_grp_size_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long jsonget_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long jsonget_grp_size(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport my_bool json_array_grp_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport void json_array_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); + DllExport void json_array_grp_add(UDF_INIT *, UDF_ARGS *, uchar *, uchar *); DllExport char *json_array_grp(UDF_EXEC_ARGS); - DllExport void json_array_grp_clear(UDF_INIT *, char *, char *); + DllExport void json_array_grp_clear(UDF_INIT *, uchar *, uchar *); DllExport void json_array_grp_deinit(UDF_INIT*); DllExport my_bool json_object_grp_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport void json_object_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); + DllExport void json_object_grp_add(UDF_INIT *, UDF_ARGS *, uchar *, uchar *); DllExport char *json_object_grp(UDF_EXEC_ARGS); - DllExport void json_object_grp_clear(UDF_INIT *, char *, char *); + DllExport void json_object_grp_clear(UDF_INIT *, uchar *, uchar *); DllExport void json_object_grp_deinit(UDF_INIT*); DllExport my_bool json_item_merge_init(UDF_INIT*, UDF_ARGS*, char*); @@ -165,15 +165,15 @@ extern "C" { DllExport void jsonget_string_deinit(UDF_INIT*); DllExport my_bool jsonget_int_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long jsonget_int(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long jsonget_int(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void jsonget_int_deinit(UDF_INIT*); DllExport my_bool jsonget_real_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport double jsonget_real(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport double jsonget_real(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void jsonget_real_deinit(UDF_INIT*); DllExport my_bool jsoncontains_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long jsoncontains(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long jsoncontains(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void jsoncontains_deinit(UDF_INIT*); DllExport my_bool jsonlocate_init(UDF_INIT*, UDF_ARGS*, char*); @@ -185,7 +185,7 @@ extern "C" { DllExport void json_locate_all_deinit(UDF_INIT*); DllExport my_bool jsoncontains_path_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long jsoncontains_path(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long jsoncontains_path(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); DllExport void jsoncontains_path_deinit(UDF_INIT*); DllExport my_bool json_set_item_init(UDF_INIT*, UDF_ARGS*, char*); @@ -293,7 +293,7 @@ extern "C" { #endif // DEVELOPMENT DllExport my_bool countin_init(UDF_INIT*, UDF_ARGS*, char*); - DllExport long long countin(UDF_INIT*, UDF_ARGS*, char*, char*); + DllExport long long countin(UDF_INIT*, UDF_ARGS*, uchar *, uchar *); } // extern "C" From b9a20752a9b80df7b5431e271ef4d677fea0fb46 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 21 Mar 2025 16:37:44 +1100 Subject: [PATCH 08/15] MDEV-36337 auth_ed25519 correct UDF pointers for is_null/error Shows up on test plugins.auth_ed25519. There isn't the import to define uchar so left as unsigned char. --- plugin/auth_ed25519/server_ed25519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/auth_ed25519/server_ed25519.c b/plugin/auth_ed25519/server_ed25519.c index b789bd34ca4..11e2fb7c03f 100644 --- a/plugin/auth_ed25519/server_ed25519.c +++ b/plugin/auth_ed25519/server_ed25519.c @@ -135,7 +135,7 @@ maria_declare_plugin_end; MYSQL_PLUGIN_EXPORT char *ed25519_password(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, char *result, unsigned long *length, - char *is_null, char *error __attribute__((unused))) + unsigned char *is_null, unsigned char *error __attribute__((unused))) { unsigned char pk[CRYPTO_PUBLICKEYBYTES]; From 2c4fe3557ace378a763869ef9c97a7cd2f69c78c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 28 Mar 2025 17:58:06 +1100 Subject: [PATCH 09/15] MDEV-36337: mroonga_* udf correct ptr types for is_null/error Shows up in mroonga UDF tests under clang with UBSAN: UndefinedBehaviorSanitizer: function-type-mismatch Accepted upstream: https://github.com/mroonga/mroonga/pull/902 --- storage/mroonga/udf/mrn_udf_command.cpp | 2 +- storage/mroonga/udf/mrn_udf_escape.cpp | 2 +- storage/mroonga/udf/mrn_udf_highlight_html.cpp | 4 ++-- storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp | 2 +- storage/mroonga/udf/mrn_udf_normalize.cpp | 2 +- storage/mroonga/udf/mrn_udf_query_expand.cpp | 4 ++-- storage/mroonga/udf/mrn_udf_snippet.cpp | 2 +- storage/mroonga/udf/mrn_udf_snippet_html.cpp | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/storage/mroonga/udf/mrn_udf_command.cpp b/storage/mroonga/udf/mrn_udf_command.cpp index 46911c56e25..44d8c9ccdd0 100644 --- a/storage/mroonga/udf/mrn_udf_command.cpp +++ b/storage/mroonga/udf/mrn_udf_command.cpp @@ -220,7 +220,7 @@ static void mroonga_command_escape_value(grn_ctx *ctx, } MRN_API char *mroonga_command(UDF_INIT *init, UDF_ARGS *args, char *result, - unsigned long *length, char *is_null, char *error) + unsigned long *length, uchar *is_null, uchar *error) { CommandInfo *info = (CommandInfo *)init->ptr; grn_ctx *ctx = info->ctx; diff --git a/storage/mroonga/udf/mrn_udf_escape.cpp b/storage/mroonga/udf/mrn_udf_escape.cpp index 55a3639565e..a03bf25cba2 100644 --- a/storage/mroonga/udf/mrn_udf_escape.cpp +++ b/storage/mroonga/udf/mrn_udf_escape.cpp @@ -214,7 +214,7 @@ static void escape(EscapeInfo *info, UDF_ARGS *args) } MRN_API char *mroonga_escape(UDF_INIT *init, UDF_ARGS *args, char *result, - unsigned long *length, char *is_null, char *error) + unsigned long *length, uchar *is_null, uchar *error) { EscapeInfo *info = reinterpret_cast(init->ptr); grn_ctx *ctx = info->ctx; diff --git a/storage/mroonga/udf/mrn_udf_highlight_html.cpp b/storage/mroonga/udf/mrn_udf_highlight_html.cpp index d986777caff..5085a885fe0 100644 --- a/storage/mroonga/udf/mrn_udf_highlight_html.cpp +++ b/storage/mroonga/udf/mrn_udf_highlight_html.cpp @@ -412,8 +412,8 @@ MRN_API char *mroonga_highlight_html(UDF_INIT *init, UDF_ARGS *args, char *result, unsigned long *length, - char *is_null, - char *error) + uchar *is_null, + uchar *error) { MRN_DBUG_ENTER_FUNCTION(); diff --git a/storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp b/storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp index f40dcf0055f..fb948a72ea9 100644 --- a/storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp +++ b/storage/mroonga/udf/mrn_udf_last_insert_grn_id.cpp @@ -45,7 +45,7 @@ MRN_API my_bool last_insert_grn_id_init(UDF_INIT *init, UDF_ARGS *args, char *me return 0; } -MRN_API longlong last_insert_grn_id(UDF_INIT *init, UDF_ARGS *args, char *is_null, char *error) +MRN_API longlong last_insert_grn_id(UDF_INIT *init, UDF_ARGS *args, uchar *is_null, uchar *error) { THD *thd = current_thd; st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, false); diff --git a/storage/mroonga/udf/mrn_udf_normalize.cpp b/storage/mroonga/udf/mrn_udf_normalize.cpp index 0ebee2ff608..5c34e9b0ec7 100644 --- a/storage/mroonga/udf/mrn_udf_normalize.cpp +++ b/storage/mroonga/udf/mrn_udf_normalize.cpp @@ -151,7 +151,7 @@ error: } MRN_API char *mroonga_normalize(UDF_INIT *init, UDF_ARGS *args, char *result, - unsigned long *length, char *is_null, char *error) + unsigned long *length, uchar *is_null, uchar *error) { st_mrn_normalize_info *info = (st_mrn_normalize_info *)init->ptr; grn_ctx *ctx = info->ctx; diff --git a/storage/mroonga/udf/mrn_udf_query_expand.cpp b/storage/mroonga/udf/mrn_udf_query_expand.cpp index 76a5dad53b4..4ecafe1812b 100644 --- a/storage/mroonga/udf/mrn_udf_query_expand.cpp +++ b/storage/mroonga/udf/mrn_udf_query_expand.cpp @@ -244,8 +244,8 @@ MRN_API char *mroonga_query_expand(UDF_INIT *init, UDF_ARGS *args, char *result, unsigned long *length, - char *is_null, - char *error) + uchar *is_null, + uchar *error) { MRN_DBUG_ENTER_FUNCTION(); diff --git a/storage/mroonga/udf/mrn_udf_snippet.cpp b/storage/mroonga/udf/mrn_udf_snippet.cpp index 1bd6cb7d722..53058bf02f5 100644 --- a/storage/mroonga/udf/mrn_udf_snippet.cpp +++ b/storage/mroonga/udf/mrn_udf_snippet.cpp @@ -248,7 +248,7 @@ error: } MRN_API char *mroonga_snippet(UDF_INIT *init, UDF_ARGS *args, char *result, - unsigned long *length, char *is_null, char *error) + unsigned long *length, uchar *is_null, uchar *error) { st_mrn_snip_info *snip_info = (st_mrn_snip_info *) init->ptr; grn_ctx *ctx = snip_info->ctx; diff --git a/storage/mroonga/udf/mrn_udf_snippet_html.cpp b/storage/mroonga/udf/mrn_udf_snippet_html.cpp index ba0cdadda99..3acdef03f54 100644 --- a/storage/mroonga/udf/mrn_udf_snippet_html.cpp +++ b/storage/mroonga/udf/mrn_udf_snippet_html.cpp @@ -323,8 +323,8 @@ MRN_API char *mroonga_snippet_html(UDF_INIT *init, UDF_ARGS *args, char *result, unsigned long *length, - char *is_null, - char *error) + uchar *is_null, + uchar *error) { MRN_DBUG_ENTER_FUNCTION(); From d5247592c53953a051596b411437fea4f6eb4676 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 21 May 2025 11:10:09 +0300 Subject: [PATCH 10/15] Test sysvars_server failure fix --- mysql-test/suite/sys_vars/inc/sysvars_server.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/sys_vars/inc/sysvars_server.inc b/mysql-test/suite/sys_vars/inc/sysvars_server.inc index 8fca98e0383..61b46f5a26a 100644 --- a/mysql-test/suite/sys_vars/inc/sysvars_server.inc +++ b/mysql-test/suite/sys_vars/inc/sysvars_server.inc @@ -1,4 +1,5 @@ --source include/have_perfschema.inc +--source include/have_profiling.inc --source include/word_size.inc --source include/platform.inc --vertical_results From fbd736c87232a6ab39b89176cdd909d4230ecd46 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 21 May 2025 11:10:09 +0300 Subject: [PATCH 11/15] mysqltest: result_format fix --result_format 2 command fails with assertion: DbugExit (why=0x7fffffff49e0 "missing DBUG_RETURN or DBUG_VOID_RETURN macro in function \"do_result_format_version\"\n") at ../src/dbug/dbug.c:2045 --- client/mysqltest.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 6262a46ad95..110f7167ac8 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -2852,6 +2852,7 @@ do_result_format_version(struct st_command *command) dynstr_append_mem(&ds_res, ds_version.str, ds_version.length); dynstr_append_mem(&ds_res, STRING_WITH_LEN("\n")); dynstr_free(&ds_version); + DBUG_VOID_RETURN; } From 1a95c2a4b2028d3808febdbd15c2ab48f0242414 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 21 May 2025 11:10:09 +0300 Subject: [PATCH 12/15] MDEV-36817 Server crashes in do_mark_index_columns instead of ER_DUP_ENTRY on partitioned table Now as c1492f3d077 (MDEV-36115) restores m_last_part table->file points to partition p0 while the error happens in p1, so error index does not match ib_table in innobase_get_mysql_key_number_for_index(). This case is handled by separate code block in innobase_get_mysql_key_number_for_index() which was wrong on using secondary index for dict_index_is_auto_gen_clust() and it was not covered by the tests. --- mysql-test/suite/versioning/r/partition.result | 9 +++++++++ mysql-test/suite/versioning/t/partition.test | 10 ++++++++++ storage/innobase/handler/ha_innodb.cc | 3 ++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index bda04f6f0f6..580ced253a8 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -1805,6 +1805,15 @@ insert into t values (1),(2); DELETE from t; drop table t; # +# MDEV-36817 Server crashes in do_mark_index_columns instead of +# ER_DUP_ENTRY on partitioned table +# +create table t (f int, unique(f)) engine=innodb partition by key (f) partitions 2; +insert into t (f) values (1), (3); +update t set f = 0; +ERROR 23000: Duplicate entry '0' for key 'f' +drop table t; +# # End of 10.5 tests # set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index d3af1d25dd3..b3eceb7184a 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -1583,6 +1583,16 @@ insert into t values (1),(2); DELETE from t; drop table t; +--echo # +--echo # MDEV-36817 Server crashes in do_mark_index_columns instead of +--echo # ER_DUP_ENTRY on partitioned table +--echo # +create table t (f int, unique(f)) engine=innodb partition by key (f) partitions 2; +insert into t (f) values (1), (3); +--error ER_DUP_ENTRY +update t set f = 0; +drop table t; + --echo # --echo # End of 10.5 tests --echo # diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 562362db16e..7e8eef467cf 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -14554,13 +14554,14 @@ innobase_get_mysql_key_number_for_index( if (index->table != ib_table) { i = 0; ind = dict_table_get_first_index(index->table); + const bool auto_gen_clust = dict_index_is_auto_gen_clust(ind); while (index != ind) { ind = dict_table_get_next_index(ind); i++; } - if (dict_index_is_auto_gen_clust(index)) { + if (auto_gen_clust) { ut_a(i > 0); i--; } From 1037f9594178deac433c026c51930619cf6ee440 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 21 May 2025 11:10:09 +0300 Subject: [PATCH 13/15] MDEV-33675 Assertion(reclength < vreclength) in setup_vcols_for_repair() When table2myisam() prepares recinfo structures BIT field was skipped because pack_length_in_rec() returns 0. Instead of BIT field DB_ROW_HASH_1 field was taken into recinfo structure and its length was added to reclength. This is wrong because not stored fields must not be prepared as record columns (MI_COLUMNDEF) in storage layer. 0-length fields are prepared in "reserve space for null bits" branch. The problem only occurs with tables where there is no data for the main record outside of the null bits. The fix updates minpos condition so we avoid fields after stored_rec_length and these are not stored by definition. share->reclength already includes not stored lengths from CREATE TABLE so we cannot use it as minpos starting point. In Aria there is no "reserve space for null bits" and it does not create column definition for BIT. Also there is no setup_vcols_for_repair() to reproduce the issue. But nonetheless it creates column definition for not stored fields redundantly, so we patch table2maria() as well. The test case for Aria tries to demonstrate BIT field works, it does not reproduce any issues (as redundant column definition for not stored field seem to not cause any problems). --- mysql-test/main/long_unique_bugs.result | 38 +++++++++++++++++++++++++ mysql-test/main/long_unique_bugs.test | 26 +++++++++++++++++ storage/maria/ha_maria.cc | 4 +-- storage/myisam/ha_myisam.cc | 4 +-- 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index a5b0f67c0aa..6bf3a7dcc44 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -770,4 +770,42 @@ alter table t1 add constraint constraint_1 unique (a); Warnings: Note 1831 Duplicate index `constraint_1`. This is deprecated and will be disallowed in a future release drop table t1; +# +# MDEV-33675 assertion(reclength < vreclength) in setup_vcols_for_repair() +# +create table t (c1 bit, unique key(c1) using hash) engine=myisam; +insert into t values (0); +check table t; +Table Op Msg_type Msg_text +test.t check status OK +insert into t values(); +select cast(c1 as unsigned) c1 from t; +c1 +0 +NULL +drop table t; +create table t1 (c1 bit, c2 long as (c1) virtual, c3 char(10), +c4 long as (c1) stored) engine=myisam; +insert into t1 (c1, c3) values (1, "a"); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +insert into t1 values(); +select hex(c1), hex(c2), c3, hex(c4) from t1; +hex(c1) hex(c2) c3 hex(c4) +1 01 a 01 +NULL NULL NULL NULL +drop table t1; +create table t1 (c1 bit, c2 long as (c1) virtual, c3 char(10), +c4 long as (c1) stored) engine=aria; +insert into t1 (c1, c3) values (1, "a"); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +insert into t1 values(); +select hex(c1), hex(c2), c3, hex(c4) from t1; +hex(c1) hex(c2) c3 hex(c4) +1 01 a 01 +NULL NULL NULL NULL +drop table t1; # End of 10.5 tests diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index ea662a832f2..b1daf97d194 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -745,4 +745,30 @@ create table t1 (a blob unique); alter table t1 add constraint constraint_1 unique (a); drop table t1; +--echo # +--echo # MDEV-33675 assertion(reclength < vreclength) in setup_vcols_for_repair() +--echo # +create table t (c1 bit, unique key(c1) using hash) engine=myisam; +insert into t values (0); +check table t; +insert into t values(); +select cast(c1 as unsigned) c1 from t; +drop table t; + +create table t1 (c1 bit, c2 long as (c1) virtual, c3 char(10), + c4 long as (c1) stored) engine=myisam; +insert into t1 (c1, c3) values (1, "a"); +check table t1; +insert into t1 values(); +select hex(c1), hex(c2), c3, hex(c4) from t1; +drop table t1; + +create table t1 (c1 bit, c2 long as (c1) virtual, c3 char(10), + c4 long as (c1) stored) engine=aria; +insert into t1 (c1, c3) values (1, "a"); +check table t1; +insert into t1 values(); +select hex(c1), hex(c2), c3, hex(c4) from t1; +drop table t1; + --echo # End of 10.5 tests diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index edc8a8b52a6..28e5fd970db 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -616,13 +616,13 @@ static int table2maria(TABLE *table_arg, data_file_type row_type, while (recpos < (uint) share->stored_rec_length) { Field **field, *found= 0; - minpos= share->reclength; + minpos= share->stored_rec_length; length= 0; for (field= table_arg->field; *field; field++) { if ((fieldpos= (*field)->offset(record)) >= recpos && - fieldpos <= minpos) + fieldpos < minpos) { /* skip null fields */ if (!(temp_length= (*field)->pack_length_in_rec())) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index d564daf656f..ed35783d394 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -367,13 +367,13 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, while (recpos < (uint) share->stored_rec_length) { Field **field, *found= 0; - minpos= share->reclength; + minpos= share->stored_rec_length; length= 0; for (field= table_arg->field; *field; field++) { if ((fieldpos= (*field)->offset(record)) >= recpos && - fieldpos <= minpos) + fieldpos < minpos) { /* skip null fields */ if (!(temp_length= (*field)->pack_length_in_rec())) From 4c8143b4510eac64869cefe258f1399ab7874780 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 23 May 2025 14:18:07 +0200 Subject: [PATCH 14/15] Make it compiling with last gcc --- strings/json_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/json_lib.c b/strings/json_lib.c index 29aa010761b..a04cee573c6 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -1612,7 +1612,7 @@ static enum json_esc_char_classes json_escape_chr_map[0x60] = { }; -static const char hexconv[16] = "0123456789ABCDEF"; +static const char hexconv[17] = "0123456789ABCDEF"; int json_escape(CHARSET_INFO *str_cs, From 8a4d3a044f9de992eabe725522bceea49fdd0e61 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Sun, 25 May 2025 09:11:41 +0530 Subject: [PATCH 15/15] MDEV-36017 Alter table aborts when temporary directory is full Problem: ======= - During inplace algorithm, concurrent DML fails to write the log operation into the temporary file. InnoDB fail to mark the error for the online log. - ddl_log_write() releases the global ddl lock prematurely before release the log memory entry Fix: === row_log_online_op(): Mark the error in online log when InnoDB ran out of temporary space fil_space_extend_must_retry(): Mark the os_has_said_disk_full as true if os_file_set_size() fails btr_cur_pessimistic_update(): Return error code when btr_cur_pessimistic_insert() fails ddl_log_write(): Release the global ddl lock after releasing the log memory entry when error was encountered btr_cur_optimistic_update(): Relax the assertion that blob pointer can be null during rollback because InnoDB can ran out of space while allocating the external page row_undo_mod_upd_exist_sec(): Remove the assertion which says that InnoDB should fail to build index entry when rollbacking an incomplete transaction after crash recovery. This scenario can happen when InnoDB ran out of space. row_upd_changes_ord_field_binary_func(): Relax the assertion to make that externally stored field can be null when InnoDB ran out of space. --- .../suite/innodb/r/alter_temp_fail.result | 25 ++++++++++++++++ mysql-test/suite/innodb/t/alter_temp_fail.opt | 1 + .../suite/innodb/t/alter_temp_fail.test | 30 +++++++++++++++++++ sql/ddl_log.cc | 4 ++- storage/innobase/btr/btr0cur.cc | 11 +++++-- storage/innobase/fil/fil0fil.cc | 2 +- storage/innobase/row/row0log.cc | 5 ++++ storage/innobase/row/row0umod.cc | 18 ++--------- storage/innobase/row/row0upd.cc | 15 ++++------ 9 files changed, 81 insertions(+), 30 deletions(-) create mode 100644 mysql-test/suite/innodb/r/alter_temp_fail.result create mode 100644 mysql-test/suite/innodb/t/alter_temp_fail.opt create mode 100644 mysql-test/suite/innodb/t/alter_temp_fail.test diff --git a/mysql-test/suite/innodb/r/alter_temp_fail.result b/mysql-test/suite/innodb/r/alter_temp_fail.result new file mode 100644 index 00000000000..f6e62328bbe --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_temp_fail.result @@ -0,0 +1,25 @@ +# +# MDEV-36017 Alter table aborts when temporary +# directory is full +# +CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100), +f3 CHAR(100))ENGINE=InnoDB; +INSERT INTO t1 SELECT seq, 'a', 'b' FROM seq_1_to_4096; +SET DEBUG_SYNC="inplace_after_index_build SIGNAL dml_start WAIT_FOR dml_commit"; +ALTER TABLE t1 ADD KEY(f1), ADD INDEX(f3(10)); +connect con1,localhost,root,,,; +SET DEBUG_SYNC="now WAIT_FOR dml_start"; +BEGIN; +INSERT INTO t1 SELECT * FROM t1; +SET STATEMENT DEBUG_DBUG="+d,os_file_write_fail" FOR COMMIT; +SET DEBUG_SYNC="now SIGNAL dml_commit"; +connection default; +ERROR HY000: Temporary file write failure +disconnect con1; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +SET STATEMENT DEBUG_DBUG="+d,ddl_log_write_fail" FOR +CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/alter_temp_fail.opt b/mysql-test/suite/innodb/t/alter_temp_fail.opt new file mode 100644 index 00000000000..c3f4a891cca --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_temp_fail.opt @@ -0,0 +1 @@ +--innodb_sort_buffer_size=64k diff --git a/mysql-test/suite/innodb/t/alter_temp_fail.test b/mysql-test/suite/innodb/t/alter_temp_fail.test new file mode 100644 index 00000000000..938a3165aaa --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_temp_fail.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/have_debug.inc +--echo # +--echo # MDEV-36017 Alter table aborts when temporary +--echo # directory is full +--echo # +CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100), + f3 CHAR(100))ENGINE=InnoDB; +INSERT INTO t1 SELECT seq, 'a', 'b' FROM seq_1_to_4096; +SET DEBUG_SYNC="inplace_after_index_build SIGNAL dml_start WAIT_FOR dml_commit"; +SEND ALTER TABLE t1 ADD KEY(f1), ADD INDEX(f3(10)); + +connect(con1,localhost,root,,,); +SET DEBUG_SYNC="now WAIT_FOR dml_start"; +BEGIN; +INSERT INTO t1 SELECT * FROM t1; +SET STATEMENT DEBUG_DBUG="+d,os_file_write_fail" FOR COMMIT; +SET DEBUG_SYNC="now SIGNAL dml_commit"; + +connection default; +--error ER_TEMP_FILE_WRITE_FAILURE +reap; +disconnect con1; +CHECK TABLE t1; +DROP TABLE t1; + +SET STATEMENT DEBUG_DBUG="+d,ddl_log_write_fail" FOR +CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +DROP TABLE t1; diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc index b210f68a203..b50456755eb 100644 --- a/sql/ddl_log.cc +++ b/sql/ddl_log.cc @@ -3029,13 +3029,15 @@ static bool ddl_log_write(DDL_LOG_STATE *ddl_state, error= ((ddl_log_write_entry(ddl_log_entry, &log_entry)) || ddl_log_write_execute_entry(log_entry->entry_pos, &ddl_state->execute_entry)); - mysql_mutex_unlock(&LOCK_gdl); + DBUG_EXECUTE_IF("ddl_log_write_fail", error= true;); if (error) { if (log_entry) ddl_log_release_memory_entry(log_entry); + mysql_mutex_unlock(&LOCK_gdl); DBUG_RETURN(1); } + mysql_mutex_unlock(&LOCK_gdl); add_log_entry(ddl_state, log_entry); ddl_state->flags|= ddl_log_entry->flags; // Update cache DBUG_RETURN(0); diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 6a57f2dc307..9a97651eb36 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -3696,8 +3696,10 @@ btr_cur_optimistic_update( *offsets = rec_get_offsets(rec, index, *offsets, index->n_core_fields, ULINT_UNDEFINED, heap); #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG + /* Blob pointer can be null if InnoDB was killed or + ran out of space while allocating a page. */ ut_a(!rec_offs_any_null_extern(rec, *offsets) - || thr_get_trx(thr) == trx_roll_crash_recv_trx); + || thr_get_trx(thr)->in_rollback); #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ if (UNIV_LIKELY(!update->is_metadata()) @@ -4370,7 +4372,12 @@ btr_cur_pessimistic_update( cursor, offsets, offsets_heap, new_entry, &rec, &dummy_big_rec, n_ext, NULL, mtr); - ut_a(err == DB_SUCCESS); + if (err) { + /* This should happen when InnoDB tries to extend the + tablespace */ + ut_ad(err == DB_OUT_OF_FILE_SPACE); + return err; + } ut_a(rec); ut_a(dummy_big_rec == NULL); ut_ad(rec_offs_validate(rec, cursor->index(), *offsets)); diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 37bc74233de..63b0c3414c5 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -591,7 +591,7 @@ fil_space_extend_must_retry( *success = os_file_set_size(node->name, node->handle, new_size, node->punch_hole == 1); - os_has_said_disk_full = *success; + os_has_said_disk_full = !*success; if (*success) { os_file_flush(node->handle); last_page_no = size; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 702e7098839..ab049a11018 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -398,12 +398,17 @@ start_log: } log->tail.blocks++; + DBUG_EXECUTE_IF("os_file_write_fail", + log->error = DB_TEMP_FILE_WRITE_FAIL; + goto write_failed;); + if (os_file_write( IORequestWrite, "(modification log)", log->fd, buf, byte_offset, srv_sort_buf_size) != DB_SUCCESS) { + log->error = DB_TEMP_FILE_WRITE_FAIL; write_failed: index->type |= DICT_CORRUPT; } diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index fe766b8313e..7f677d1c2f7 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1128,9 +1128,8 @@ row_undo_mod_upd_exist_sec( dtuple_t* entry = row_build_index_entry( node->row, node->ext, index, heap); if (UNIV_UNLIKELY(!entry)) { - /* The server must have crashed in - row_upd_clust_rec_by_insert() before - the updated externally stored columns (BLOBs) + /* InnoDB must have run of space or been killed + before the updated externally stored columns (BLOBs) of the new clustered index entry were written. */ /* The table must be in DYNAMIC or COMPRESSED @@ -1138,19 +1137,6 @@ row_undo_mod_upd_exist_sec( store a local 768-byte prefix of each externally stored column. */ ut_a(dict_table_has_atomic_blobs(index->table)); - - /* This is only legitimate when - rolling back an incomplete transaction - after crash recovery. */ - ut_a(thr_get_trx(thr)->is_recovered); - - /* The server must have crashed before - completing the insert of the new - clustered index entry and before - inserting to the secondary indexes. - Because node->row was not yet written - to this index, we can ignore it. But - we must restore node->undo_row. */ } else { /* NOTE that if we updated the fields of a delete-marked secondary index record so that diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 03118fb25f2..e7fa4aa71a4 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1414,16 +1414,11 @@ row_upd_changes_ord_field_binary_func( if (UNIV_LIKELY_NULL(buf)) { if (UNIV_UNLIKELY(buf == field_ref_zero)) { /* The externally stored field - was not written yet. This - record should only be seen by - trx_rollback_recovered() - when the server had crashed before - storing the field. */ - ut_ad(!thr - || thr->graph->trx->is_recovered); - ut_ad(!thr - || thr->graph->trx - == trx_roll_crash_recv_trx); + was not written yet. InnoDB must + have ran out of space or been killed + before storing the page */ + ut_ad(thr); + ut_ad(thr->graph->trx->in_rollback); return(TRUE); }