Merge branch '10.2' into 10.3
This commit is contained in:
commit
6f741eb6e4
5
debian/mariadb-server-10.3.postrm
vendored
5
debian/mariadb-server-10.3.postrm
vendored
@ -11,6 +11,11 @@ MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
|
||||
# do it himself. No database directories should be removed while the server
|
||||
# is running!
|
||||
stop_server() {
|
||||
# Return immediately if there are no mysql processes running
|
||||
# as there is no point in trying to shutdown in that case.
|
||||
# Compatibility with versions that ran 'mariadbd'
|
||||
if ! pgrep -x --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null; then return; fi
|
||||
|
||||
set +e
|
||||
if [ -x /usr/sbin/invoke-rc.d ]; then
|
||||
invoke-rc.d mysql stop
|
||||
|
7
debian/mariadb-server-10.3.preinst
vendored
7
debian/mariadb-server-10.3.preinst
vendored
@ -22,10 +22,11 @@ mysql_upgradedir=/var/lib/mysql-upgrade
|
||||
# is running! Another mysqld in e.g. a different chroot is fine for us.
|
||||
stop_server() {
|
||||
if [ ! -x /etc/init.d/mysql ]; then return; fi
|
||||
|
||||
# Return immediately if there are no mysql processes running
|
||||
# Return immediately if there are no mysql processes running on a host
|
||||
# (leave containerized processes with the same name in other namespaces)
|
||||
# as there is no point in trying to shutdown in that case.
|
||||
if ! pgrep --ns $$ mysqld > /dev/null; then return; fi
|
||||
# Compatibility with versions that ran 'mariadbd'
|
||||
if ! pgrep -x --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null; then return; fi
|
||||
|
||||
set +e
|
||||
if [ -x /usr/sbin/invoke-rc.d ]; then
|
||||
|
@ -3406,6 +3406,24 @@ SELECT 1 FROM t1 GROUP BY DEFAULT(pk);
|
||||
1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-28402: ASAN heap-use-after-free in create_tmp_table,
|
||||
# Assertion `l_offset >= 0 && table->s->rec_buff_length - l_offset > 0'
|
||||
#
|
||||
CREATE TABLE t (a INT, KEY (a));
|
||||
INSERT INTO t VALUES (1),(2);
|
||||
SELECT DISTINCT DEFAULT(a), CASE a WHEN 0 THEN 1 ELSE 2 END FROM t GROUP BY a WITH ROLLUP;
|
||||
DEFAULT(a) CASE a WHEN 0 THEN 1 ELSE 2 END
|
||||
NULL 2
|
||||
DROP TABLE t;
|
||||
CREATE TABLE t (a INT, KEY (a));
|
||||
INSERT INTO t VALUES (1),(2);
|
||||
CREATE ALGORITHM=TEMPTABLE VIEW v AS SELECT * FROM t;
|
||||
SELECT DISTINCT DEFAULT(a), CASE a WHEN 0 THEN 1 ELSE 2 END FROM v GROUP BY a WITH ROLLUP;
|
||||
DEFAULT(a) CASE a WHEN 0 THEN 1 ELSE 2 END
|
||||
NULL 2
|
||||
DROP TABLE t;
|
||||
DROP VIEW v;
|
||||
# end of 10.2 test
|
||||
#
|
||||
# MDEV-22703 DEFAULT() on a BLOB column can overwrite the default
|
||||
|
@ -2125,6 +2125,23 @@ CREATE TABLE t1 (pk varchar(36) DEFAULT uuid());
|
||||
INSERT INTO t1 VALUES (),();
|
||||
SELECT 1 FROM t1 GROUP BY DEFAULT(pk);
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-28402: ASAN heap-use-after-free in create_tmp_table,
|
||||
--echo # Assertion `l_offset >= 0 && table->s->rec_buff_length - l_offset > 0'
|
||||
--echo #
|
||||
CREATE TABLE t (a INT, KEY (a));
|
||||
INSERT INTO t VALUES (1),(2);
|
||||
SELECT DISTINCT DEFAULT(a), CASE a WHEN 0 THEN 1 ELSE 2 END FROM t GROUP BY a WITH ROLLUP;
|
||||
DROP TABLE t;
|
||||
|
||||
CREATE TABLE t (a INT, KEY (a));
|
||||
INSERT INTO t VALUES (1),(2);
|
||||
CREATE ALGORITHM=TEMPTABLE VIEW v AS SELECT * FROM t;
|
||||
SELECT DISTINCT DEFAULT(a), CASE a WHEN 0 THEN 1 ELSE 2 END FROM v GROUP BY a WITH ROLLUP;
|
||||
DROP TABLE t;
|
||||
DROP VIEW v;
|
||||
--echo # end of 10.2 test
|
||||
|
||||
--echo #
|
||||
|
@ -661,3 +661,14 @@ group by (select a),(select 1)
|
||||
);
|
||||
1
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-28437: Assertion `!eliminated' failed in Item_subselect::exec
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (3),(4);
|
||||
SELECT 1 IN (SELECT a FROM t1 LEFT JOIN t2 ON (a = b AND EXISTS (SELECT * FROM t1)));
|
||||
1 IN (SELECT a FROM t1 LEFT JOIN t2 ON (a = b AND EXISTS (SELECT * FROM t1)))
|
||||
1
|
||||
drop table t1,t2;
|
||||
|
@ -655,3 +655,17 @@ select 1 from t1 where not exists
|
||||
--enable_warnings
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-28437: Assertion `!eliminated' failed in Item_subselect::exec
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (3),(4);
|
||||
|
||||
SELECT 1 IN (SELECT a FROM t1 LEFT JOIN t2 ON (a = b AND EXISTS (SELECT * FROM t1)));
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
# End of 10.2 tests
|
||||
|
||||
|
@ -4238,6 +4238,48 @@ SELECT 1 UNION SELECT a FROM t1 ORDER BY (row_number() over ());
|
||||
ERROR HY000: Expression #1 of ORDER BY contains aggregate function and applies to a UNION
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-19398: Assertion `item1->type() == Item::FIELD_ITEM &&
|
||||
# item2->type() == Item::FIELD_ITEM' failed in compare_order_elements
|
||||
#
|
||||
CREATE TABLE t1 ( id varchar(10));
|
||||
INSERT INTO t1 values (1),(2),(3);
|
||||
SELECT
|
||||
dense_rank() over (ORDER BY avg(1)+3),
|
||||
rank() over (ORDER BY avg(1))
|
||||
FROM t1
|
||||
GROUP BY nullif(id, 15532);
|
||||
dense_rank() over (ORDER BY avg(1)+3) rank() over (ORDER BY avg(1))
|
||||
1 1
|
||||
1 1
|
||||
1 1
|
||||
SELECT
|
||||
dense_rank() over (ORDER BY avg(1)),
|
||||
rank() over (ORDER BY avg(1))
|
||||
FROM t1
|
||||
GROUP BY nullif(id, 15532);
|
||||
dense_rank() over (ORDER BY avg(1)) rank() over (ORDER BY avg(1))
|
||||
1 1
|
||||
1 1
|
||||
1 1
|
||||
drop table t1;
|
||||
CREATE TABLE t1 ( a char(25), b text);
|
||||
INSERT INTO t1 VALUES ('foo','bar');
|
||||
SELECT
|
||||
SUM(b) OVER (PARTITION BY a),
|
||||
ROW_NUMBER() OVER (PARTITION BY b)
|
||||
FROM t1
|
||||
GROUP BY
|
||||
LEFT((SYSDATE()), 'foo')
|
||||
WITH ROLLUP;
|
||||
SUM(b) OVER (PARTITION BY a) ROW_NUMBER() OVER (PARTITION BY b)
|
||||
NULL 1
|
||||
NULL 1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect INTEGER value: 'foo'
|
||||
Warning 1292 Truncated incorrect INTEGER value: 'foo'
|
||||
drop table t1;
|
||||
#
|
||||
#
|
||||
# End of 10.2 tests
|
||||
#
|
||||
#
|
||||
|
@ -2740,6 +2740,39 @@ INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(2),(2),(2),(2),(2);
|
||||
SELECT 1 UNION SELECT a FROM t1 ORDER BY (row_number() over ());
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-19398: Assertion `item1->type() == Item::FIELD_ITEM &&
|
||||
--echo # item2->type() == Item::FIELD_ITEM' failed in compare_order_elements
|
||||
--echo #
|
||||
CREATE TABLE t1 ( id varchar(10));
|
||||
INSERT INTO t1 values (1),(2),(3);
|
||||
|
||||
SELECT
|
||||
dense_rank() over (ORDER BY avg(1)+3),
|
||||
rank() over (ORDER BY avg(1))
|
||||
FROM t1
|
||||
GROUP BY nullif(id, 15532);
|
||||
|
||||
SELECT
|
||||
dense_rank() over (ORDER BY avg(1)),
|
||||
rank() over (ORDER BY avg(1))
|
||||
FROM t1
|
||||
GROUP BY nullif(id, 15532);
|
||||
drop table t1;
|
||||
|
||||
CREATE TABLE t1 ( a char(25), b text);
|
||||
INSERT INTO t1 VALUES ('foo','bar');
|
||||
|
||||
SELECT
|
||||
SUM(b) OVER (PARTITION BY a),
|
||||
ROW_NUMBER() OVER (PARTITION BY b)
|
||||
FROM t1
|
||||
GROUP BY
|
||||
LEFT((SYSDATE()), 'foo')
|
||||
WITH ROLLUP;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo #
|
||||
--echo # End of 10.2 tests
|
||||
--echo #
|
||||
|
@ -4244,6 +4244,48 @@ SELECT 1 UNION SELECT a FROM t1 ORDER BY (row_number() over ());
|
||||
ERROR HY000: Expression #1 of ORDER BY contains aggregate function and applies to a UNION
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-19398: Assertion `item1->type() == Item::FIELD_ITEM &&
|
||||
# item2->type() == Item::FIELD_ITEM' failed in compare_order_elements
|
||||
#
|
||||
CREATE TABLE t1 ( id varchar(10));
|
||||
INSERT INTO t1 values (1),(2),(3);
|
||||
SELECT
|
||||
dense_rank() over (ORDER BY avg(1)+3),
|
||||
rank() over (ORDER BY avg(1))
|
||||
FROM t1
|
||||
GROUP BY nullif(id, 15532);
|
||||
dense_rank() over (ORDER BY avg(1)+3) rank() over (ORDER BY avg(1))
|
||||
1 1
|
||||
1 1
|
||||
1 1
|
||||
SELECT
|
||||
dense_rank() over (ORDER BY avg(1)),
|
||||
rank() over (ORDER BY avg(1))
|
||||
FROM t1
|
||||
GROUP BY nullif(id, 15532);
|
||||
dense_rank() over (ORDER BY avg(1)) rank() over (ORDER BY avg(1))
|
||||
1 1
|
||||
1 1
|
||||
1 1
|
||||
drop table t1;
|
||||
CREATE TABLE t1 ( a char(25), b text);
|
||||
INSERT INTO t1 VALUES ('foo','bar');
|
||||
SELECT
|
||||
SUM(b) OVER (PARTITION BY a),
|
||||
ROW_NUMBER() OVER (PARTITION BY b)
|
||||
FROM t1
|
||||
GROUP BY
|
||||
LEFT((SYSDATE()), 'foo')
|
||||
WITH ROLLUP;
|
||||
SUM(b) OVER (PARTITION BY a) ROW_NUMBER() OVER (PARTITION BY b)
|
||||
NULL 1
|
||||
NULL 1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect INTEGER value: 'foo'
|
||||
Warning 1292 Truncated incorrect INTEGER value: 'foo'
|
||||
drop table t1;
|
||||
#
|
||||
#
|
||||
# End of 10.2 tests
|
||||
#
|
||||
#
|
||||
|
@ -61,10 +61,3 @@ select count(*) from t1 where MBRWithin(t1.c2, @g1);
|
||||
count(*)
|
||||
57344
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-27417 Spatial index tries to update
|
||||
# change buffer bookkeeping page
|
||||
#
|
||||
CREATE TEMPORARY TABLE t1 (c POINT NOT NULL, SPATIAL(c)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 SELECT PointFromText('POINT(0 0)') FROM seq_1_to_366;
|
||||
DROP TABLE t1;
|
||||
|
14
mysql-test/suite/innodb_gis/r/rtree_temporary.result
Normal file
14
mysql-test/suite/innodb_gis/r/rtree_temporary.result
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
# MDEV-27417 Spatial index tries to update
|
||||
# change buffer bookkeeping page
|
||||
#
|
||||
CREATE TEMPORARY TABLE t1 (c POINT NOT NULL, SPATIAL(c)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 SELECT PointFromText('POINT(0 0)') FROM seq_1_to_366;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-28478 Assertion mtr->get_log_mode() == MTR_LOG_NO_REDO
|
||||
#
|
||||
CREATE TEMPORARY TABLE t1 (c POINT NOT NULL,SPATIAL (c)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 SELECT POINT(0,0) FROM seq_1_to_366;
|
||||
INSERT INTO t1 VALUES (POINT(1e-270,1e-130));
|
||||
DROP TABLE t1;
|
@ -72,11 +72,3 @@ select count(*) from t1 where MBRWithin(t1.c2, @g1);
|
||||
|
||||
# Clean up.
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-27417 Spatial index tries to update
|
||||
--echo # change buffer bookkeeping page
|
||||
--echo #
|
||||
CREATE TEMPORARY TABLE t1 (c POINT NOT NULL, SPATIAL(c)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 SELECT PointFromText('POINT(0 0)') FROM seq_1_to_366;
|
||||
DROP TABLE t1;
|
||||
|
18
mysql-test/suite/innodb_gis/t/rtree_temporary.test
Normal file
18
mysql-test/suite/innodb_gis/t/rtree_temporary.test
Normal file
@ -0,0 +1,18 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_sequence.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-27417 Spatial index tries to update
|
||||
--echo # change buffer bookkeeping page
|
||||
--echo #
|
||||
CREATE TEMPORARY TABLE t1 (c POINT NOT NULL, SPATIAL(c)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 SELECT PointFromText('POINT(0 0)') FROM seq_1_to_366;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-28478 Assertion mtr->get_log_mode() == MTR_LOG_NO_REDO
|
||||
--echo #
|
||||
CREATE TEMPORARY TABLE t1 (c POINT NOT NULL,SPATIAL (c)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 SELECT POINT(0,0) FROM seq_1_to_366;
|
||||
INSERT INTO t1 VALUES (POINT(1e-270,1e-130));
|
||||
DROP TABLE t1;
|
27
mysql-test/suite/rpl/r/rpl_iodku,stmt.rdiff
Normal file
27
mysql-test/suite/rpl/r/rpl_iodku,stmt.rdiff
Normal file
@ -0,0 +1,27 @@
|
||||
--- r/rpl_iodku.result 2022-05-04 18:51:24.956414404 +0300
|
||||
+++ r/rpl_iodku,stmt.reject 2022-05-04 18:51:49.520106231 +0300
|
||||
@@ -1,10 +1,15 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
+call mtr.add_suppression("Unsafe statement written to the binary log using statement");
|
||||
CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, a INT, b INT, c INT,
|
||||
UNIQUE (a), UNIQUE (b)) ENGINE=innodb;
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (1,1), (2,1) ON DUPLICATE KEY UPDATE c = 1;
|
||||
+Warnings:
|
||||
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
# UNSAFE
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (3, 1),(2,1), (1,1) ON DUPLICATE KEY UPDATE c = a * 10 + VALUES(c);
|
||||
+Warnings:
|
||||
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
SELECT * from t1;
|
||||
id a b c
|
||||
1 1 NULL 11
|
||||
@@ -17,6 +22,8 @@
|
||||
INSERT INTO t1 VALUES (1,10,1);
|
||||
# eligable for the statement format run unsafe warning
|
||||
INSERT INTO t1 VALUES (2,20,2) ON DUPLICATE KEY UPDATE c = 100;
|
||||
+Warnings:
|
||||
+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
# not eligable: no warning in the statement format run
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (3, 1) ON DUPLICATE KEY UPDATE c = 99;
|
||||
SELECT * from t1;
|
32
mysql-test/suite/rpl/r/rpl_iodku.result
Normal file
32
mysql-test/suite/rpl/r/rpl_iodku.result
Normal file
@ -0,0 +1,32 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, a INT, b INT, c INT,
|
||||
UNIQUE (a), UNIQUE (b)) ENGINE=innodb;
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (1,1), (2,1) ON DUPLICATE KEY UPDATE c = 1;
|
||||
# UNSAFE
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (3, 1),(2,1), (1,1) ON DUPLICATE KEY UPDATE c = a * 10 + VALUES(c);
|
||||
SELECT * from t1;
|
||||
id a b c
|
||||
1 1 NULL 11
|
||||
2 2 NULL 21
|
||||
3 3 NULL 1
|
||||
connection slave;
|
||||
include/diff_tables.inc [master:t1,slave:t1]
|
||||
connection master;
|
||||
CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, UNIQUE (a), UNIQUE (b)) ENGINE=innodb;
|
||||
INSERT INTO t1 VALUES (1,10,1);
|
||||
# eligable for the statement format run unsafe warning
|
||||
INSERT INTO t1 VALUES (2,20,2) ON DUPLICATE KEY UPDATE c = 100;
|
||||
# not eligable: no warning in the statement format run
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (3, 1) ON DUPLICATE KEY UPDATE c = 99;
|
||||
SELECT * from t1;
|
||||
a b c
|
||||
1 10 1
|
||||
2 20 2
|
||||
3 NULL 1
|
||||
connection slave;
|
||||
include/diff_tables.inc [master:t1,slave:t1]
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
connection slave;
|
||||
include/rpl_end.inc
|
@ -1,5 +1,6 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
# Case 1: UNSAFE
|
||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT,
|
||||
UNIQUE(b), c int) engine=innodb;
|
||||
@ -37,6 +38,7 @@ drop table t1;
|
||||
connection slave;
|
||||
start slave;
|
||||
include/wait_for_slave_to_start.inc
|
||||
# Case 2: UNSAFE
|
||||
connection master;
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||
UNIQUE(b), c int) engine=innodb;
|
||||
@ -45,8 +47,12 @@ connection master;
|
||||
INSERT INTO t1 VALUES (default, 1, 1);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (default, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
connection master1;
|
||||
INSERT INTO t1 VALUES(default, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
connection master;
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
@ -62,6 +68,7 @@ a b c
|
||||
connection master;
|
||||
drop table t1;
|
||||
connection slave;
|
||||
# Case 3A: UNSAFE
|
||||
connection master;
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||
UNIQUE(b), c int, d int ) engine=innodb;
|
||||
@ -93,6 +100,67 @@ a b c d
|
||||
connection master;
|
||||
drop table t1;
|
||||
connection slave;
|
||||
# Case 3B: UNSAFE - all column specified.
|
||||
connection master;
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||
UNIQUE(b), c int, d int ) engine=innodb;
|
||||
connection slave;
|
||||
connection master;
|
||||
INSERT INTO t1 VALUES (1, 1, 1, 1);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (2, NULL, 2, 2) ON DUPLICATE KEY UPDATE c=VALUES(c);
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
connection master1;
|
||||
INSERT INTO t1 VALUES(3, NULL, 2, 3) ON DUPLICATE KEY UPDATE c=VALUES(c);
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
connection master;
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
a b c d
|
||||
1 1 1 1
|
||||
2 NULL 2 2
|
||||
3 NULL 2 3
|
||||
connection slave;
|
||||
#same data as master
|
||||
SELECT * FROM t1;
|
||||
a b c d
|
||||
1 1 1 1
|
||||
2 NULL 2 2
|
||||
3 NULL 2 3
|
||||
connection master;
|
||||
drop table t1;
|
||||
connection slave;
|
||||
# Case 3C: SAFE - only one unique key (PK) specified.
|
||||
connection master;
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||
UNIQUE(b), c int, d int ) engine=innodb;
|
||||
connection slave;
|
||||
connection master;
|
||||
INSERT INTO t1 VALUES (1, 1, 1, 1);
|
||||
BEGIN;
|
||||
INSERT INTO t1 (`a`, `c`, `d`) VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE c=99;
|
||||
connection master1;
|
||||
INSERT INTO t1 (`a`, `c`, `d`) VALUES(3, 2, 3) ON DUPLICATE KEY UPDATE c=100;
|
||||
connection master;
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
a b c d
|
||||
1 1 1 1
|
||||
2 NULL 2 2
|
||||
3 NULL 2 3
|
||||
connection slave;
|
||||
#same data as master
|
||||
SELECT * FROM t1;
|
||||
a b c d
|
||||
1 1 1 1
|
||||
2 NULL 2 2
|
||||
3 NULL 2 3
|
||||
connection master;
|
||||
drop table t1;
|
||||
connection slave;
|
||||
# Case 4: UNSAFE
|
||||
connection master;
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||
UNIQUE(b), c int) engine=innodb;
|
||||
@ -101,8 +169,12 @@ connection master;
|
||||
INSERT INTO t1 VALUES (1, 1, 1);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
connection master1;
|
||||
INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
connection master;
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
|
@ -1,6 +1,5 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
||||
CREATE TABLE t1(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB;
|
||||
CREATE TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB;
|
||||
CREATE TRIGGER trig1 AFTER INSERT ON t1
|
||||
@ -50,13 +49,9 @@ connection master;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(i INT, j INT, UNIQUE KEY(i), UNIQUE KEY(j)) ENGINE=INNODB;
|
||||
INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1;
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
START TRANSACTION;
|
||||
LOCK TABLES t1 WRITE;
|
||||
INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1;
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe
|
||||
UNLOCK TABLES;
|
||||
COMMIT;
|
||||
connection slave;
|
||||
|
50
mysql-test/suite/rpl/t/rpl_iodku.test
Normal file
50
mysql-test/suite/rpl/t/rpl_iodku.test
Normal file
@ -0,0 +1,50 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
if (`select @@binlog_format = "statement"`)
|
||||
{
|
||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement");
|
||||
}
|
||||
|
||||
## MDEV-28310 loss of binlog event for multi-record IODKU
|
||||
# Check that the duplicate key error does not cause
|
||||
# loss of replication event for IODKU that specifies values
|
||||
# for at least two unique columns per record.
|
||||
# "Implicit" NULL value of the auto-increment column also counts.
|
||||
|
||||
CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, a INT, b INT, c INT,
|
||||
UNIQUE (a), UNIQUE (b)) ENGINE=innodb;
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (1,1), (2,1) ON DUPLICATE KEY UPDATE c = 1;
|
||||
--echo # UNSAFE
|
||||
# because of two keys involved: a UK and PK even though implicitly via auto-inc
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (3, 1),(2,1), (1,1) ON DUPLICATE KEY UPDATE c = a * 10 + VALUES(c);
|
||||
SELECT * from t1;
|
||||
|
||||
--sync_slave_with_master
|
||||
--let $diff_tables = master:t1,slave:t1
|
||||
--source include/diff_tables.inc
|
||||
|
||||
## MDEV-21810 MBR: Unexpected "Unsafe statement" warning for unsafe IODKU
|
||||
# Unnecessary unsafe statement warning is not error-logged anymore.
|
||||
|
||||
|
||||
--connection master
|
||||
CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, UNIQUE (a), UNIQUE (b)) ENGINE=innodb;
|
||||
INSERT INTO t1 VALUES (1,10,1);
|
||||
--echo # eligable for the statement format run unsafe warning
|
||||
INSERT INTO t1 VALUES (2,20,2) ON DUPLICATE KEY UPDATE c = 100;
|
||||
--echo # not eligable: no warning in the statement format run
|
||||
INSERT INTO t1 (`a`,`c`) VALUES (3, 1) ON DUPLICATE KEY UPDATE c = 99;
|
||||
SELECT * from t1;
|
||||
|
||||
--sync_slave_with_master
|
||||
--let $diff_tables = master:t1,slave:t1
|
||||
--source include/diff_tables.inc
|
||||
|
||||
# Cleanup
|
||||
--connection master
|
||||
DROP TABLE t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
|
||||
--source include/rpl_end.inc
|
@ -2,15 +2,22 @@ source include/have_debug.inc;
|
||||
source include/have_innodb.inc;
|
||||
-- source include/have_binlog_format_statement.inc
|
||||
source include/master-slave.inc;
|
||||
# MDEV-17614
|
||||
# INSERT on dup key update is replication unsafe
|
||||
# There can be three case
|
||||
# 1. 2 unique key, Replication is unsafe.
|
||||
# 2. 2 unique key , with one auto increment key, Safe to replicate because Innodb will acquire gap lock
|
||||
# 3. n no of unique keys (n>1) but insert is only in 1 unique key
|
||||
# 4. 2 unique key , with one auto increment key(but user gives auto inc value), unsafe to replicate
|
||||
# MDEV-17614 INSERT on dup key update is replication unsafe
|
||||
#
|
||||
# The following cases are tested below:
|
||||
# 1. 2 unique key, replication is UNSAFE
|
||||
# 2. 2 unique key, with one auto increment key and implicit value to it.
|
||||
# It is UNSAFE because autoinc column values of being inserted records
|
||||
# are revealed dynamically, so unknown at the binlog-format decision time
|
||||
# and hence this pessimistic expectation
|
||||
# 3. 2 unique keys
|
||||
# A. insert is only in 1 unique key, still all colums are specified => UNSAFE
|
||||
# B. both unique keys are specified => UNSAFE
|
||||
# C. only one unique key is specified => SAFE (motivated by MDEV-28310)
|
||||
# 4. 2 unique key, with one auto increment key(but user gives auto inc value) =>
|
||||
# UNSAFE to replicate
|
||||
|
||||
# Case 1
|
||||
--echo # Case 1: UNSAFE
|
||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT,
|
||||
UNIQUE(b), c int) engine=innodb;
|
||||
@ -42,7 +49,8 @@ drop table t1;
|
||||
connection slave;
|
||||
start slave;
|
||||
--source include/wait_for_slave_to_start.inc
|
||||
# Case 2
|
||||
|
||||
--echo # Case 2: UNSAFE
|
||||
--connection master
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||
UNIQUE(b), c int) engine=innodb;
|
||||
@ -64,7 +72,7 @@ connection master;
|
||||
drop table t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
# Case 3
|
||||
--echo # Case 3A: UNSAFE
|
||||
--connection master
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||
UNIQUE(b), c int, d int ) engine=innodb;
|
||||
@ -85,7 +93,50 @@ connection master;
|
||||
drop table t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
# Case 4
|
||||
--echo # Case 3B: UNSAFE - all column specified.
|
||||
--connection master
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||
UNIQUE(b), c int, d int ) engine=innodb;
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
INSERT INTO t1 VALUES (1, 1, 1, 1);
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (2, NULL, 2, 2) ON DUPLICATE KEY UPDATE c=VALUES(c);
|
||||
--connection master1
|
||||
INSERT INTO t1 VALUES(3, NULL, 2, 3) ON DUPLICATE KEY UPDATE c=VALUES(c);
|
||||
--connection master
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
--sync_slave_with_master
|
||||
--echo #same data as master
|
||||
SELECT * FROM t1;
|
||||
connection master;
|
||||
drop table t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
|
||||
--echo # Case 3C: SAFE - only one unique key (PK) specified.
|
||||
--connection master
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||
UNIQUE(b), c int, d int ) engine=innodb;
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
INSERT INTO t1 VALUES (1, 1, 1, 1);
|
||||
BEGIN;
|
||||
INSERT INTO t1 (`a`, `c`, `d`) VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE c=99;
|
||||
--connection master1
|
||||
INSERT INTO t1 (`a`, `c`, `d`) VALUES(3, 2, 3) ON DUPLICATE KEY UPDATE c=100;
|
||||
--connection master
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
--sync_slave_with_master
|
||||
--echo #same data as master
|
||||
SELECT * FROM t1;
|
||||
connection master;
|
||||
drop table t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
--echo # Case 4: UNSAFE
|
||||
--connection master
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||
UNIQUE(b), c int) engine=innodb;
|
||||
|
@ -24,7 +24,7 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_binlog_format_mixed.inc
|
||||
--source include/master-slave.inc
|
||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
||||
|
||||
# Case-1: BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS
|
||||
# Statement is unsafe because it invokes a trigger or a
|
||||
# stored function that inserts into an AUTO_INCREMENT column.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2008, 2022, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -6558,47 +6558,84 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
int THD::decide_logging_format_low(TABLE *table)
|
||||
|
||||
/*
|
||||
Reconsider logging format in case of INSERT...ON DUPLICATE KEY UPDATE
|
||||
for tables with more than one unique keys in case of MIXED binlog format.
|
||||
|
||||
Unsafe means that a master could execute the statement differently than
|
||||
the slave.
|
||||
This could can happen in the following cases:
|
||||
- The unique check are done in different order on master or slave
|
||||
(different engine or different key order).
|
||||
- There is a conflict on another key than the first and before the
|
||||
statement is committed, another connection commits a row that conflicts
|
||||
on an earlier unique key. Example follows:
|
||||
|
||||
Below a and b are unique keys, the table has a row (1,1,0)
|
||||
connection 1:
|
||||
INSERT INTO t1 set a=2,b=1,c=0 ON DUPLICATE KEY UPDATE c=1;
|
||||
connection 2:
|
||||
INSERT INTO t1 set a=2,b=2,c=0;
|
||||
|
||||
If 2 commits after 1 has been executed but before 1 has committed
|
||||
(and are thus put before the other in the binary log), one will
|
||||
get different data on the slave:
|
||||
(1,1,1),(2,2,1) instead of (1,1,1),(2,2,0)
|
||||
*/
|
||||
|
||||
void THD::reconsider_logging_format_for_iodup(TABLE *table)
|
||||
{
|
||||
/*
|
||||
INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys
|
||||
can be unsafe.
|
||||
*/
|
||||
if(wsrep_binlog_format() <= BINLOG_FORMAT_STMT &&
|
||||
!is_current_stmt_binlog_format_row() &&
|
||||
!lex->is_stmt_unsafe() &&
|
||||
lex->sql_command == SQLCOM_INSERT &&
|
||||
lex->duplicates == DUP_UPDATE)
|
||||
DBUG_ENTER("reconsider_logging_format_for_iodup");
|
||||
enum_binlog_format bf= (enum_binlog_format) wsrep_binlog_format();
|
||||
|
||||
DBUG_ASSERT(lex->duplicates == DUP_UPDATE);
|
||||
|
||||
if (bf <= BINLOG_FORMAT_STMT &&
|
||||
!is_current_stmt_binlog_format_row())
|
||||
{
|
||||
KEY *end= table->s->key_info + table->s->keys;
|
||||
uint unique_keys= 0;
|
||||
uint keys= table->s->keys, i= 0;
|
||||
Field *field;
|
||||
for (KEY* keyinfo= table->s->key_info;
|
||||
i < keys && unique_keys <= 1; i++, keyinfo++)
|
||||
if (keyinfo->flags & HA_NOSAME &&
|
||||
!(keyinfo->key_part->field->flags & AUTO_INCREMENT_FLAG &&
|
||||
//User given auto inc can be unsafe
|
||||
!keyinfo->key_part->field->val_int()))
|
||||
|
||||
for (KEY *keyinfo= table->s->key_info; keyinfo < end ; keyinfo++)
|
||||
{
|
||||
if (keyinfo->flags & HA_NOSAME)
|
||||
{
|
||||
/*
|
||||
We assume that the following cases will guarantee that the
|
||||
key is unique if a key part is not set:
|
||||
- The key part is an autoincrement (autogenerated)
|
||||
- The key part has a default value that is null and it not
|
||||
a virtual field that will be calculated later.
|
||||
*/
|
||||
for (uint j= 0; j < keyinfo->user_defined_key_parts; j++)
|
||||
{
|
||||
field= keyinfo->key_part[j].field;
|
||||
if(!bitmap_is_set(table->write_set,field->field_index))
|
||||
goto exit;
|
||||
Field *field= keyinfo->key_part[j].field;
|
||||
if (!bitmap_is_set(table->write_set, field->field_index))
|
||||
{
|
||||
/* Check auto_increment */
|
||||
if (field == table->next_number_field)
|
||||
goto exit;
|
||||
if (field->is_real_null() && !field->default_value)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
unique_keys++;
|
||||
if (unique_keys++)
|
||||
break;
|
||||
exit:;
|
||||
}
|
||||
|
||||
}
|
||||
if (unique_keys > 1)
|
||||
{
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
|
||||
binlog_unsafe_warning_flags|= lex->get_stmt_unsafe_flags();
|
||||
if (bf == BINLOG_FORMAT_STMT && !lex->is_stmt_unsafe())
|
||||
{
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
|
||||
binlog_unsafe_warning_flags|= lex->get_stmt_unsafe_flags();
|
||||
}
|
||||
set_current_stmt_binlog_format_row_if_mixed();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2009, 2022, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -4514,18 +4514,18 @@ public:
|
||||
mdl_context.release_transactional_locks();
|
||||
}
|
||||
int decide_logging_format(TABLE_LIST *tables);
|
||||
/*
|
||||
In Some cases when decide_logging_format is called it does not have all
|
||||
information to decide the logging format. So that cases we call decide_logging_format_2
|
||||
at later stages in execution.
|
||||
One example would be binlog format for IODKU but column with unique key is not inserted.
|
||||
We dont have inserted columns info when we call decide_logging_format so on later stage we call
|
||||
decide_logging_format_low
|
||||
|
||||
@returns 0 if no format is changed
|
||||
1 if there is change in binlog format
|
||||
/*
|
||||
In Some cases when decide_logging_format is called it does not have
|
||||
all information to decide the logging format. So that cases we call
|
||||
decide_logging_format_2 at later stages in execution.
|
||||
|
||||
One example would be binlog format for insert on duplicate key
|
||||
(IODKU) but column with unique key is not inserted. We do not have
|
||||
inserted columns info when we call decide_logging_format so on
|
||||
later stage we call reconsider_logging_format_for_iodup()
|
||||
*/
|
||||
int decide_logging_format_low(TABLE *table);
|
||||
void reconsider_logging_format_for_iodup(TABLE *table);
|
||||
|
||||
enum need_invoker { INVOKER_NONE=0, INVOKER_USER, INVOKER_ROLE};
|
||||
void binlog_invoker(bool role) { m_binlog_invoker= role ? INVOKER_ROLE : INVOKER_USER; }
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
||||
Copyright (c) 2010, 2019, MariaDB Corporation
|
||||
Copyright (c) 2010, 2022, MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -945,6 +945,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
}
|
||||
|
||||
THD_STAGE_INFO(thd, stage_update);
|
||||
|
||||
if (duplic == DUP_UPDATE)
|
||||
{
|
||||
restore_record(table,s->default_values); // Get empty record
|
||||
thd->reconsider_logging_format_for_iodup(table);
|
||||
}
|
||||
do
|
||||
{
|
||||
DBUG_PRINT("info", ("iteration %llu", iteration));
|
||||
@ -1057,7 +1063,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
break;
|
||||
}
|
||||
|
||||
thd->decide_logging_format_low(table);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (lock_type == TL_WRITE_DELAYED)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2009, 2022, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -4492,17 +4492,21 @@ void SELECT_LEX::update_used_tables()
|
||||
while ((tl= ti++))
|
||||
{
|
||||
TABLE_LIST *embedding= tl;
|
||||
do
|
||||
if (!is_eliminated_table(join->eliminated_tables, tl))
|
||||
{
|
||||
bool maybe_null;
|
||||
if ((maybe_null= MY_TEST(embedding->outer_join)))
|
||||
do
|
||||
{
|
||||
tl->table->maybe_null= maybe_null;
|
||||
break;
|
||||
bool maybe_null;
|
||||
if ((maybe_null= MY_TEST(embedding->outer_join)))
|
||||
{
|
||||
tl->table->maybe_null= maybe_null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ((embedding= embedding->embedding));
|
||||
}
|
||||
while ((embedding= embedding->embedding));
|
||||
if (tl->on_expr)
|
||||
|
||||
if (tl->on_expr && !is_eliminated_table(join->eliminated_tables, tl))
|
||||
{
|
||||
tl->on_expr->update_used_tables();
|
||||
tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
||||
@ -4526,8 +4530,11 @@ void SELECT_LEX::update_used_tables()
|
||||
if (embedding->on_expr &&
|
||||
embedding->nested_join->join_list.head() == tl)
|
||||
{
|
||||
embedding->on_expr->update_used_tables();
|
||||
embedding->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
||||
if (!is_eliminated_table(join->eliminated_tables, embedding))
|
||||
{
|
||||
embedding->on_expr->update_used_tables();
|
||||
embedding->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
||||
}
|
||||
}
|
||||
tl= embedding;
|
||||
embedding= tl->embedding;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2021, MariaDB
|
||||
Copyright (c) 2008, 2022, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -8712,6 +8712,7 @@ bool st_select_lex::add_window_def(THD *thd,
|
||||
fields_in_window_functions+= win_part_list_ptr->elements +
|
||||
win_order_list_ptr->elements;
|
||||
}
|
||||
win_def->win_spec_number= window_specs.elements;
|
||||
return (win_def == NULL || window_specs.push_back(win_def));
|
||||
}
|
||||
|
||||
@ -8739,6 +8740,7 @@ bool st_select_lex::add_window_spec(THD *thd,
|
||||
win_order_list_ptr->elements;
|
||||
}
|
||||
thd->lex->win_spec= win_spec;
|
||||
win_spec->win_spec_number= window_specs.elements;
|
||||
return (win_spec == NULL || window_specs.push_back(win_spec));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2009, 2022, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -24710,15 +24710,17 @@ change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
for (uint i= 0; (item= it++); i++)
|
||||
{
|
||||
Field *field;
|
||||
if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) ||
|
||||
enum Item::Type item_type= item->type();
|
||||
if ((item->with_sum_func && item_type != Item::SUM_FUNC_ITEM) ||
|
||||
item->with_window_func)
|
||||
item_field= item;
|
||||
else if (item->type() == Item::FIELD_ITEM)
|
||||
else if (item_type == Item::FIELD_ITEM ||
|
||||
item_type == Item::DEFAULT_VALUE_ITEM)
|
||||
{
|
||||
if (!(item_field= item->get_tmp_table_item(thd)))
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
else if (item->type() == Item::FUNC_ITEM &&
|
||||
else if (item_type == Item::FUNC_ITEM &&
|
||||
((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC)
|
||||
{
|
||||
field= item->get_tmp_table_field();
|
||||
@ -26547,7 +26549,7 @@ static void print_table_array(THD *thd,
|
||||
too)
|
||||
*/
|
||||
|
||||
static bool is_eliminated_table(table_map eliminated_tables, TABLE_LIST *tbl)
|
||||
bool is_eliminated_table(table_map eliminated_tables, TABLE_LIST *tbl)
|
||||
{
|
||||
return eliminated_tables &&
|
||||
((tbl->table && (tbl->table->map & eliminated_tables)) ||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define SQL_SELECT_INCLUDED
|
||||
|
||||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2008, 2022, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -2473,4 +2473,6 @@ int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort);
|
||||
JOIN_TAB *first_explain_order_tab(JOIN* join);
|
||||
JOIN_TAB *next_explain_order_tab(JOIN* join, JOIN_TAB* tab);
|
||||
|
||||
bool is_eliminated_table(table_map eliminated_tables, TABLE_LIST *tbl);
|
||||
|
||||
#endif /* SQL_SELECT_INCLUDED */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2016, 2017 MariaDB
|
||||
Copyright (c) 2016, 2022 MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -424,16 +424,49 @@ ORDER *st_select_lex::find_common_window_func_partition_fields(THD *thd)
|
||||
#define CMP_GT 2 // Greater then
|
||||
|
||||
static
|
||||
int compare_order_elements(ORDER *ord1, ORDER *ord2)
|
||||
int compare_order_elements(ORDER *ord1, int weight1,
|
||||
ORDER *ord2, int weight2)
|
||||
{
|
||||
if (*ord1->item == *ord2->item && ord1->direction == ord2->direction)
|
||||
return CMP_EQ;
|
||||
Item *item1= (*ord1->item)->real_item();
|
||||
Item *item2= (*ord2->item)->real_item();
|
||||
DBUG_ASSERT(item1->type() == Item::FIELD_ITEM &&
|
||||
item2->type() == Item::FIELD_ITEM);
|
||||
int cmp= ((Item_field *) item1)->field->field_index -
|
||||
((Item_field *) item2)->field->field_index;
|
||||
|
||||
bool item1_field= (item1->type() == Item::FIELD_ITEM);
|
||||
bool item2_field= (item2->type() == Item::FIELD_ITEM);
|
||||
|
||||
ptrdiff_t cmp;
|
||||
if (item1_field && item2_field)
|
||||
{
|
||||
DBUG_ASSERT(((Item_field *) item1)->field->table ==
|
||||
((Item_field *) item2)->field->table);
|
||||
cmp= ((Item_field *) item1)->field->field_index -
|
||||
((Item_field *) item2)->field->field_index;
|
||||
}
|
||||
else if (item1_field && !item2_field)
|
||||
return CMP_LT;
|
||||
else if (!item1_field && item2_field)
|
||||
return CMP_LT;
|
||||
else
|
||||
{
|
||||
/*
|
||||
Ok, item1_field==NULL and item2_field==NULL.
|
||||
We're not able to compare Item expressions. Order them according to
|
||||
their passed "weight" (which comes from Window_spec::win_spec_number):
|
||||
*/
|
||||
if (weight1 != weight2)
|
||||
cmp= weight1 - weight2;
|
||||
else
|
||||
{
|
||||
/*
|
||||
The weight is the same. That is, the elements come from the same
|
||||
window specification... This shouldn't happen.
|
||||
*/
|
||||
DBUG_ASSERT(0);
|
||||
cmp= item1 - item2;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmp == 0)
|
||||
{
|
||||
if (ord1->direction == ord2->direction)
|
||||
@ -446,7 +479,9 @@ int compare_order_elements(ORDER *ord1, ORDER *ord2)
|
||||
|
||||
static
|
||||
int compare_order_lists(SQL_I_List<ORDER> *part_list1,
|
||||
SQL_I_List<ORDER> *part_list2)
|
||||
int spec_number1,
|
||||
SQL_I_List<ORDER> *part_list2,
|
||||
int spec_number2)
|
||||
{
|
||||
if (part_list1 == part_list2)
|
||||
return CMP_EQ;
|
||||
@ -471,7 +506,8 @@ int compare_order_lists(SQL_I_List<ORDER> *part_list1,
|
||||
if (!elem1 || !elem2)
|
||||
break;
|
||||
|
||||
if ((cmp= compare_order_elements(elem1, elem2)))
|
||||
if ((cmp= compare_order_elements(elem1, spec_number1,
|
||||
elem2, spec_number2)))
|
||||
return cmp;
|
||||
}
|
||||
if (elem1)
|
||||
@ -566,7 +602,9 @@ int compare_window_spec_joined_lists(Window_spec *win_spec1,
|
||||
win_spec1->join_partition_and_order_lists();
|
||||
win_spec2->join_partition_and_order_lists();
|
||||
int cmp= compare_order_lists(win_spec1->partition_list,
|
||||
win_spec2->partition_list);
|
||||
win_spec1->win_spec_number,
|
||||
win_spec2->partition_list,
|
||||
win_spec2->win_spec_number);
|
||||
win_spec1->disjoin_partition_and_order_lists();
|
||||
win_spec2->disjoin_partition_and_order_lists();
|
||||
return cmp;
|
||||
@ -584,7 +622,9 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1,
|
||||
if (win_spec1 == win_spec2)
|
||||
return CMP_EQ;
|
||||
cmp= compare_order_lists(win_spec1->partition_list,
|
||||
win_spec2->partition_list);
|
||||
win_spec1->win_spec_number,
|
||||
win_spec2->partition_list,
|
||||
win_spec2->win_spec_number);
|
||||
if (cmp == CMP_EQ)
|
||||
{
|
||||
/*
|
||||
@ -603,7 +643,9 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1,
|
||||
}
|
||||
|
||||
cmp= compare_order_lists(win_spec1->order_list,
|
||||
win_spec2->order_list);
|
||||
win_spec1->win_spec_number,
|
||||
win_spec2->order_list,
|
||||
win_spec2->win_spec_number);
|
||||
|
||||
if (cmp != CMP_EQ)
|
||||
return cmp;
|
||||
@ -700,7 +742,9 @@ void order_window_funcs_by_window_specs(List<Item_window_func> *win_func_list)
|
||||
int cmp;
|
||||
if (win_spec_prev->partition_list == win_spec_curr->partition_list)
|
||||
cmp= compare_order_lists(win_spec_prev->order_list,
|
||||
win_spec_curr->order_list);
|
||||
win_spec_prev->win_spec_number,
|
||||
win_spec_curr->order_list,
|
||||
win_spec_curr->win_spec_number);
|
||||
else
|
||||
cmp= compare_window_spec_joined_lists(win_spec_prev, win_spec_curr);
|
||||
if (!(CMP_LT_C <= cmp && cmp <= CMP_GT_C))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2016, 2017 MariaDB
|
||||
Copyright (c) 2016, 2022 MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -120,10 +120,15 @@ class Window_spec : public Sql_alloc
|
||||
|
||||
Window_spec *referenced_win_spec;
|
||||
|
||||
Window_spec(LEX_CSTRING *win_ref,
|
||||
SQL_I_List<ORDER> *part_list,
|
||||
SQL_I_List<ORDER> *ord_list,
|
||||
Window_frame *win_frame)
|
||||
/*
|
||||
Window_spec objects are numbered by the number of their appearance in the
|
||||
query. This is used by compare_order_elements() to provide a predictable
|
||||
ordering of PARTITION/ORDER BY clauses.
|
||||
*/
|
||||
int win_spec_number;
|
||||
|
||||
Window_spec(LEX_CSTRING *win_ref, SQL_I_List<ORDER> *part_list,
|
||||
SQL_I_List<ORDER> *ord_list, Window_frame *win_frame)
|
||||
: window_names_are_checked(false), window_ref(win_ref),
|
||||
partition_list(part_list), save_partition_list(NULL),
|
||||
order_list(ord_list), save_order_list(NULL),
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2018, 2021, MariaDB Corporation.
|
||||
Copyright (c) 2019, 2022, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -376,6 +376,7 @@ rtr_update_mbr_field(
|
||||
|
||||
if (!rtr_update_mbr_field_in_place(index, rec,
|
||||
offsets, mbr, mtr)) {
|
||||
mem_heap_free(heap);
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
@ -2966,8 +2966,12 @@ row_ins_sec_index_entry_low(
|
||||
rtr_init_rtr_info(&rtr_info, false, &cursor,
|
||||
index, false);
|
||||
rtr_info_update_btr(&cursor, &rtr_info);
|
||||
mtr_start(&mtr);
|
||||
index->set_modified(mtr);
|
||||
mtr.start();
|
||||
if (index->table->is_temporary()) {
|
||||
mtr.set_log_mode(MTR_LOG_NO_REDO);
|
||||
} else {
|
||||
index->set_modified(mtr);
|
||||
}
|
||||
search_mode &= ulint(~BTR_MODIFY_LEAF);
|
||||
search_mode |= BTR_MODIFY_TREE;
|
||||
err = btr_cur_search_to_nth_level(
|
||||
|
Loading…
x
Reference in New Issue
Block a user