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
|
# do it himself. No database directories should be removed while the server
|
||||||
# is running!
|
# is running!
|
||||||
stop_server() {
|
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
|
set +e
|
||||||
if [ -x /usr/sbin/invoke-rc.d ]; then
|
if [ -x /usr/sbin/invoke-rc.d ]; then
|
||||||
invoke-rc.d mysql stop
|
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.
|
# is running! Another mysqld in e.g. a different chroot is fine for us.
|
||||||
stop_server() {
|
stop_server() {
|
||||||
if [ ! -x /etc/init.d/mysql ]; then return; fi
|
if [ ! -x /etc/init.d/mysql ]; then return; fi
|
||||||
|
# Return immediately if there are no mysql processes running on a host
|
||||||
# Return immediately if there are no mysql processes running
|
# (leave containerized processes with the same name in other namespaces)
|
||||||
# as there is no point in trying to shutdown in that case.
|
# 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
|
set +e
|
||||||
if [ -x /usr/sbin/invoke-rc.d ]; then
|
if [ -x /usr/sbin/invoke-rc.d ]; then
|
||||||
|
@ -3406,6 +3406,24 @@ SELECT 1 FROM t1 GROUP BY DEFAULT(pk);
|
|||||||
1
|
1
|
||||||
1
|
1
|
||||||
DROP TABLE t1;
|
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
|
# end of 10.2 test
|
||||||
#
|
#
|
||||||
# MDEV-22703 DEFAULT() on a BLOB column can overwrite the default
|
# 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 (),();
|
INSERT INTO t1 VALUES (),();
|
||||||
SELECT 1 FROM t1 GROUP BY DEFAULT(pk);
|
SELECT 1 FROM t1 GROUP BY DEFAULT(pk);
|
||||||
DROP TABLE t1;
|
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 # end of 10.2 test
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -661,3 +661,14 @@ group by (select a),(select 1)
|
|||||||
);
|
);
|
||||||
1
|
1
|
||||||
drop table t1;
|
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
|
--enable_warnings
|
||||||
drop table t1;
|
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
|
ERROR HY000: Expression #1 of ORDER BY contains aggregate function and applies to a UNION
|
||||||
DROP TABLE t1;
|
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
|
# 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 ());
|
SELECT 1 UNION SELECT a FROM t1 ORDER BY (row_number() over ());
|
||||||
DROP TABLE t1;
|
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 #
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
--echo #
|
--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
|
ERROR HY000: Expression #1 of ORDER BY contains aggregate function and applies to a UNION
|
||||||
DROP TABLE t1;
|
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
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -61,10 +61,3 @@ select count(*) from t1 where MBRWithin(t1.c2, @g1);
|
|||||||
count(*)
|
count(*)
|
||||||
57344
|
57344
|
||||||
drop table t1;
|
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.
|
# Clean up.
|
||||||
drop table t1;
|
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
|
include/master-slave.inc
|
||||||
[connection master]
|
[connection master]
|
||||||
|
# Case 1: UNSAFE
|
||||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
|
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,
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT,
|
||||||
UNIQUE(b), c int) engine=innodb;
|
UNIQUE(b), c int) engine=innodb;
|
||||||
@ -37,6 +38,7 @@ drop table t1;
|
|||||||
connection slave;
|
connection slave;
|
||||||
start slave;
|
start slave;
|
||||||
include/wait_for_slave_to_start.inc
|
include/wait_for_slave_to_start.inc
|
||||||
|
# Case 2: UNSAFE
|
||||||
connection master;
|
connection master;
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||||
UNIQUE(b), c int) engine=innodb;
|
UNIQUE(b), c int) engine=innodb;
|
||||||
@ -45,8 +47,12 @@ connection master;
|
|||||||
INSERT INTO t1 VALUES (default, 1, 1);
|
INSERT INTO t1 VALUES (default, 1, 1);
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO t1 VALUES (default, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
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;
|
connection master1;
|
||||||
INSERT INTO t1 VALUES(default, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
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;
|
connection master;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
@ -62,6 +68,7 @@ a b c
|
|||||||
connection master;
|
connection master;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
connection slave;
|
connection slave;
|
||||||
|
# Case 3A: UNSAFE
|
||||||
connection master;
|
connection master;
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||||
UNIQUE(b), c int, d int ) engine=innodb;
|
UNIQUE(b), c int, d int ) engine=innodb;
|
||||||
@ -93,6 +100,67 @@ a b c d
|
|||||||
connection master;
|
connection master;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
connection slave;
|
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;
|
connection master;
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||||
UNIQUE(b), c int) engine=innodb;
|
UNIQUE(b), c int) engine=innodb;
|
||||||
@ -101,8 +169,12 @@ connection master;
|
|||||||
INSERT INTO t1 VALUES (1, 1, 1);
|
INSERT INTO t1 VALUES (1, 1, 1);
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
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;
|
connection master1;
|
||||||
INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c);
|
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;
|
connection master;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
include/master-slave.inc
|
include/master-slave.inc
|
||||||
[connection master]
|
[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 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 TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB;
|
||||||
CREATE TRIGGER trig1 AFTER INSERT ON t1
|
CREATE TRIGGER trig1 AFTER INSERT ON t1
|
||||||
@ -50,13 +49,9 @@ connection master;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1(i INT, j INT, UNIQUE KEY(i), UNIQUE KEY(j)) ENGINE=INNODB;
|
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;
|
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;
|
START TRANSACTION;
|
||||||
LOCK TABLES t1 WRITE;
|
LOCK TABLES t1 WRITE;
|
||||||
INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1;
|
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;
|
UNLOCK TABLES;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
connection slave;
|
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_innodb.inc;
|
||||||
-- source include/have_binlog_format_statement.inc
|
-- source include/have_binlog_format_statement.inc
|
||||||
source include/master-slave.inc;
|
source include/master-slave.inc;
|
||||||
# MDEV-17614
|
# MDEV-17614 INSERT on dup key update is replication unsafe
|
||||||
# INSERT on dup key update is replication unsafe
|
#
|
||||||
# There can be three case
|
# The following cases are tested below:
|
||||||
# 1. 2 unique key, Replication is unsafe.
|
# 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
|
# 2. 2 unique key, with one auto increment key and implicit value to it.
|
||||||
# 3. n no of unique keys (n>1) but insert is only in 1 unique key
|
# It is UNSAFE because autoinc column values of being inserted records
|
||||||
# 4. 2 unique key , with one auto increment key(but user gives auto inc value), unsafe to replicate
|
# 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");
|
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,
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT,
|
||||||
UNIQUE(b), c int) engine=innodb;
|
UNIQUE(b), c int) engine=innodb;
|
||||||
@ -42,7 +49,8 @@ drop table t1;
|
|||||||
connection slave;
|
connection slave;
|
||||||
start slave;
|
start slave;
|
||||||
--source include/wait_for_slave_to_start.inc
|
--source include/wait_for_slave_to_start.inc
|
||||||
# Case 2
|
|
||||||
|
--echo # Case 2: UNSAFE
|
||||||
--connection master
|
--connection master
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||||
UNIQUE(b), c int) engine=innodb;
|
UNIQUE(b), c int) engine=innodb;
|
||||||
@ -64,7 +72,7 @@ connection master;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
--sync_slave_with_master
|
--sync_slave_with_master
|
||||||
|
|
||||||
# Case 3
|
--echo # Case 3A: UNSAFE
|
||||||
--connection master
|
--connection master
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT,
|
||||||
UNIQUE(b), c int, d int ) engine=innodb;
|
UNIQUE(b), c int, d int ) engine=innodb;
|
||||||
@ -85,7 +93,50 @@ connection master;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
--sync_slave_with_master
|
--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
|
--connection master
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT,
|
||||||
UNIQUE(b), c int) engine=innodb;
|
UNIQUE(b), c int) engine=innodb;
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
--source include/have_binlog_format_mixed.inc
|
--source include/have_binlog_format_mixed.inc
|
||||||
--source include/master-slave.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
|
# Case-1: BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS
|
||||||
# Statement is unsafe because it invokes a trigger or a
|
# Statement is unsafe because it invokes a trigger or a
|
||||||
# stored function that inserts into an AUTO_INCREMENT column.
|
# stored function that inserts into an AUTO_INCREMENT column.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
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
|
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
|
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);
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (KEY *keyinfo= table->s->key_info; keyinfo < end ; keyinfo++)
|
||||||
|
{
|
||||||
|
if (keyinfo->flags & HA_NOSAME)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys
|
We assume that the following cases will guarantee that the
|
||||||
can be unsafe.
|
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.
|
||||||
*/
|
*/
|
||||||
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)
|
|
||||||
{
|
|
||||||
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 (uint j= 0; j < keyinfo->user_defined_key_parts; j++)
|
for (uint j= 0; j < keyinfo->user_defined_key_parts; j++)
|
||||||
{
|
{
|
||||||
field= keyinfo->key_part[j].field;
|
Field *field= keyinfo->key_part[j].field;
|
||||||
if (!bitmap_is_set(table->write_set, field->field_index))
|
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;
|
goto exit;
|
||||||
}
|
}
|
||||||
unique_keys++;
|
}
|
||||||
|
if (unique_keys++)
|
||||||
|
break;
|
||||||
exit:;
|
exit:;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (unique_keys > 1)
|
if (unique_keys > 1)
|
||||||
|
{
|
||||||
|
if (bf == BINLOG_FORMAT_STMT && !lex->is_stmt_unsafe())
|
||||||
{
|
{
|
||||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
|
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
|
||||||
binlog_unsafe_warning_flags|= lex->get_stmt_unsafe_flags();
|
binlog_unsafe_warning_flags|= lex->get_stmt_unsafe_flags();
|
||||||
|
}
|
||||||
set_current_stmt_binlog_format_row_if_mixed();
|
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) 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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -4514,18 +4514,18 @@ public:
|
|||||||
mdl_context.release_transactional_locks();
|
mdl_context.release_transactional_locks();
|
||||||
}
|
}
|
||||||
int decide_logging_format(TABLE_LIST *tables);
|
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};
|
enum need_invoker { INVOKER_NONE=0, INVOKER_USER, INVOKER_ROLE};
|
||||||
void binlog_invoker(bool role) { m_binlog_invoker= role ? INVOKER_ROLE : INVOKER_USER; }
|
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) 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
|
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
|
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);
|
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
|
do
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("iteration %llu", iteration));
|
DBUG_PRINT("info", ("iteration %llu", iteration));
|
||||||
@ -1057,7 +1063,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
thd->decide_logging_format_low(table);
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if (lock_type == TL_WRITE_DELAYED)
|
if (lock_type == TL_WRITE_DELAYED)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
|
/* 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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -4492,6 +4492,8 @@ void SELECT_LEX::update_used_tables()
|
|||||||
while ((tl= ti++))
|
while ((tl= ti++))
|
||||||
{
|
{
|
||||||
TABLE_LIST *embedding= tl;
|
TABLE_LIST *embedding= tl;
|
||||||
|
if (!is_eliminated_table(join->eliminated_tables, tl))
|
||||||
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
bool maybe_null;
|
bool maybe_null;
|
||||||
@ -4502,7 +4504,9 @@ void SELECT_LEX::update_used_tables()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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->update_used_tables();
|
||||||
tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
||||||
@ -4525,10 +4529,13 @@ void SELECT_LEX::update_used_tables()
|
|||||||
{
|
{
|
||||||
if (embedding->on_expr &&
|
if (embedding->on_expr &&
|
||||||
embedding->nested_join->join_list.head() == tl)
|
embedding->nested_join->join_list.head() == tl)
|
||||||
|
{
|
||||||
|
if (!is_eliminated_table(join->eliminated_tables, embedding))
|
||||||
{
|
{
|
||||||
embedding->on_expr->update_used_tables();
|
embedding->on_expr->update_used_tables();
|
||||||
embedding->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
embedding->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
tl= embedding;
|
tl= embedding;
|
||||||
embedding= tl->embedding;
|
embedding= tl->embedding;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
/* 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
|
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
|
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 +
|
fields_in_window_functions+= win_part_list_ptr->elements +
|
||||||
win_order_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));
|
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;
|
win_order_list_ptr->elements;
|
||||||
}
|
}
|
||||||
thd->lex->win_spec= win_spec;
|
thd->lex->win_spec= win_spec;
|
||||||
|
win_spec->win_spec_number= window_specs.elements;
|
||||||
return (win_spec == NULL || window_specs.push_back(win_spec));
|
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) 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
|
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
|
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++)
|
for (uint i= 0; (item= it++); i++)
|
||||||
{
|
{
|
||||||
Field *field;
|
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->with_window_func)
|
||||||
item_field= item;
|
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)))
|
if (!(item_field= item->get_tmp_table_item(thd)))
|
||||||
DBUG_RETURN(true);
|
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)
|
((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC)
|
||||||
{
|
{
|
||||||
field= item->get_tmp_table_field();
|
field= item->get_tmp_table_field();
|
||||||
@ -26547,7 +26549,7 @@ static void print_table_array(THD *thd,
|
|||||||
too)
|
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 &&
|
return eliminated_tables &&
|
||||||
((tbl->table && (tbl->table->map & eliminated_tables)) ||
|
((tbl->table && (tbl->table->map & eliminated_tables)) ||
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define SQL_SELECT_INCLUDED
|
#define SQL_SELECT_INCLUDED
|
||||||
|
|
||||||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
/* 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
|
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
|
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 *first_explain_order_tab(JOIN* join);
|
||||||
JOIN_TAB *next_explain_order_tab(JOIN* join, JOIN_TAB* tab);
|
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 */
|
#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
|
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
|
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
|
#define CMP_GT 2 // Greater then
|
||||||
|
|
||||||
static
|
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)
|
if (*ord1->item == *ord2->item && ord1->direction == ord2->direction)
|
||||||
return CMP_EQ;
|
return CMP_EQ;
|
||||||
Item *item1= (*ord1->item)->real_item();
|
Item *item1= (*ord1->item)->real_item();
|
||||||
Item *item2= (*ord2->item)->real_item();
|
Item *item2= (*ord2->item)->real_item();
|
||||||
DBUG_ASSERT(item1->type() == Item::FIELD_ITEM &&
|
|
||||||
item2->type() == Item::FIELD_ITEM);
|
bool item1_field= (item1->type() == Item::FIELD_ITEM);
|
||||||
int cmp= ((Item_field *) item1)->field->field_index -
|
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;
|
((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 (cmp == 0)
|
||||||
{
|
{
|
||||||
if (ord1->direction == ord2->direction)
|
if (ord1->direction == ord2->direction)
|
||||||
@ -446,7 +479,9 @@ int compare_order_elements(ORDER *ord1, ORDER *ord2)
|
|||||||
|
|
||||||
static
|
static
|
||||||
int compare_order_lists(SQL_I_List<ORDER> *part_list1,
|
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)
|
if (part_list1 == part_list2)
|
||||||
return CMP_EQ;
|
return CMP_EQ;
|
||||||
@ -471,7 +506,8 @@ int compare_order_lists(SQL_I_List<ORDER> *part_list1,
|
|||||||
if (!elem1 || !elem2)
|
if (!elem1 || !elem2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((cmp= compare_order_elements(elem1, elem2)))
|
if ((cmp= compare_order_elements(elem1, spec_number1,
|
||||||
|
elem2, spec_number2)))
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
if (elem1)
|
if (elem1)
|
||||||
@ -566,7 +602,9 @@ int compare_window_spec_joined_lists(Window_spec *win_spec1,
|
|||||||
win_spec1->join_partition_and_order_lists();
|
win_spec1->join_partition_and_order_lists();
|
||||||
win_spec2->join_partition_and_order_lists();
|
win_spec2->join_partition_and_order_lists();
|
||||||
int cmp= compare_order_lists(win_spec1->partition_list,
|
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_spec1->disjoin_partition_and_order_lists();
|
||||||
win_spec2->disjoin_partition_and_order_lists();
|
win_spec2->disjoin_partition_and_order_lists();
|
||||||
return cmp;
|
return cmp;
|
||||||
@ -584,7 +622,9 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1,
|
|||||||
if (win_spec1 == win_spec2)
|
if (win_spec1 == win_spec2)
|
||||||
return CMP_EQ;
|
return CMP_EQ;
|
||||||
cmp= compare_order_lists(win_spec1->partition_list,
|
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)
|
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,
|
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)
|
if (cmp != CMP_EQ)
|
||||||
return cmp;
|
return cmp;
|
||||||
@ -700,7 +742,9 @@ void order_window_funcs_by_window_specs(List<Item_window_func> *win_func_list)
|
|||||||
int cmp;
|
int cmp;
|
||||||
if (win_spec_prev->partition_list == win_spec_curr->partition_list)
|
if (win_spec_prev->partition_list == win_spec_curr->partition_list)
|
||||||
cmp= compare_order_lists(win_spec_prev->order_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
|
else
|
||||||
cmp= compare_window_spec_joined_lists(win_spec_prev, win_spec_curr);
|
cmp= compare_window_spec_joined_lists(win_spec_prev, win_spec_curr);
|
||||||
if (!(CMP_LT_C <= cmp && cmp <= CMP_GT_C))
|
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
|
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
|
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 *referenced_win_spec;
|
||||||
|
|
||||||
Window_spec(LEX_CSTRING *win_ref,
|
/*
|
||||||
SQL_I_List<ORDER> *part_list,
|
Window_spec objects are numbered by the number of their appearance in the
|
||||||
SQL_I_List<ORDER> *ord_list,
|
query. This is used by compare_order_elements() to provide a predictable
|
||||||
Window_frame *win_frame)
|
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),
|
: window_names_are_checked(false), window_ref(win_ref),
|
||||||
partition_list(part_list), save_partition_list(NULL),
|
partition_list(part_list), save_partition_list(NULL),
|
||||||
order_list(ord_list), save_order_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) 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
|
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
|
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,
|
if (!rtr_update_mbr_field_in_place(index, rec,
|
||||||
offsets, mbr, mtr)) {
|
offsets, mbr, mtr)) {
|
||||||
|
mem_heap_free(heap);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2966,8 +2966,12 @@ row_ins_sec_index_entry_low(
|
|||||||
rtr_init_rtr_info(&rtr_info, false, &cursor,
|
rtr_init_rtr_info(&rtr_info, false, &cursor,
|
||||||
index, false);
|
index, false);
|
||||||
rtr_info_update_btr(&cursor, &rtr_info);
|
rtr_info_update_btr(&cursor, &rtr_info);
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
|
if (index->table->is_temporary()) {
|
||||||
|
mtr.set_log_mode(MTR_LOG_NO_REDO);
|
||||||
|
} else {
|
||||||
index->set_modified(mtr);
|
index->set_modified(mtr);
|
||||||
|
}
|
||||||
search_mode &= ulint(~BTR_MODIFY_LEAF);
|
search_mode &= ulint(~BTR_MODIFY_LEAF);
|
||||||
search_mode |= BTR_MODIFY_TREE;
|
search_mode |= BTR_MODIFY_TREE;
|
||||||
err = btr_cur_search_to_nth_level(
|
err = btr_cur_search_to_nth_level(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user