Browse Source

Merge branch '10.5' into 10.6

pull/4024/head mariadb-10.6.22
Oleksandr Byelkin 5 months ago
parent
commit
19644f6821
  1. 4
      cmake/cpack_rpm.cmake
  2. 146
      mysql-test/main/derived_cond_pushdown.result
  3. 22
      mysql-test/main/derived_cond_pushdown.test
  4. 2
      mysql-test/main/derived_view.result
  5. 72
      mysql-test/main/insert.result
  6. 56
      mysql-test/main/insert.test
  7. 2
      mysql-test/main/insert_returning.result
  8. 2
      mysql-test/main/insert_returning.test
  9. 129
      mysql-test/main/insert_select.result
  10. 56
      mysql-test/main/insert_select.test
  11. 12
      mysql-test/main/lowercase_view.result
  12. 12
      mysql-test/main/lowercase_view.test
  13. 17
      mysql-test/main/merge.result
  14. 17
      mysql-test/main/merge.test
  15. 20
      mysql-test/main/multi_update.result
  16. 28
      mysql-test/main/multi_update.test
  17. 23
      mysql-test/main/query_cache.result
  18. 22
      mysql-test/main/query_cache.test
  19. 2
      mysql-test/main/sp-no-valgrind.test
  20. 20
      mysql-test/main/subselect.result
  21. 10
      mysql-test/main/subselect.test
  22. 12
      mysql-test/main/subselect_elimination.result
  23. 7
      mysql-test/main/subselect_elimination.test
  24. 20
      mysql-test/main/subselect_no_exists_to_in.result
  25. 20
      mysql-test/main/subselect_no_mat.result
  26. 20
      mysql-test/main/subselect_no_opts.result
  27. 20
      mysql-test/main/subselect_no_scache.result
  28. 20
      mysql-test/main/subselect_no_semijoin.result
  29. 49
      mysql-test/main/view.result
  30. 30
      mysql-test/main/view.test
  31. 1
      mysql-test/suite/galera/r/galera_as_slave_nonprim.result
  32. 80
      mysql-test/suite/galera/r/galera_toi_ddl_nonconflicting.result
  33. 6
      mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result
  34. 6
      mysql-test/suite/galera/t/galera_as_slave_nonprim.test
  35. 60
      mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test
  36. 39
      mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test
  37. 64
      mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test
  38. 1
      mysql-test/suite/sql_sequence/other.result
  39. 1
      mysql-test/suite/sql_sequence/other.test
  40. 12
      sql/item.h
  41. 24
      sql/item_subselect.cc
  42. 1
      sql/item_subselect.h
  43. 9
      sql/mysqld.cc
  44. 80
      sql/sql_base.cc
  45. 2
      sql/sql_base.h
  46. 2
      sql/sql_cache.cc
  47. 98
      sql/sql_insert.cc
  48. 2
      sql/sql_insert.h
  49. 45
      sql/sql_lex.cc
  50. 4
      sql/sql_lex.h
  51. 4
      sql/sql_prepare.cc
  52. 3
      sql/sql_update.cc
  53. 2
      sql/table.h
  54. 5
      support-files/mariadb.service.in
  55. 5
      support-files/mariadb@.service.in
  56. 159
      tests/mysql_client_test.c

4
cmake/cpack_rpm.cmake

@ -230,7 +230,7 @@ IF(WITH_WSREP)
"galera-4" "rsync" "grep" "gawk" "iproute"
"coreutils" "findutils" "tar")
SETA(CPACK_RPM_server_PACKAGE_RECOMMENDS "lsof" "socat")
SETA(CPACK_RPM_test_PACKAGE_REQUIRES "socat")
SETA(CPACK_RPM_test_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES}" "socat")
ENDIF()
SET(CPACK_RPM_server_PRE_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-prein.sh)
@ -277,7 +277,7 @@ ELSEIF(RPM MATCHES "fedora" OR RPM MATCHES "(rhel|centos)7")
ALTERNATIVE_NAME("server" "mariadb-server")
ALTERNATIVE_NAME("server" "mysql-compat-server")
ALTERNATIVE_NAME("test" "mariadb-test")
ELSEIF(RPM MATCHES "(rhel|centos|rocky)[89]")
ELSEIF(RPM MATCHES "(rhel|centos|rocky)")
SET(epoch 3:)
ALTERNATIVE_NAME("backup" "mariadb-backup")
ALTERNATIVE_NAME("client" "mariadb")

146
mysql-test/main/derived_cond_pushdown.result

@ -10247,9 +10247,8 @@ SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ) AS t WHERE f IS NOT NULL;
EXPLAIN INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ) AS t WHERE f IS NOT NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 144 Using where
2 DERIVED <derived4> ALL NULL NULL NULL NULL 12
2 DERIVED t1 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 12 Using temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
4 DERIVED t1 ALL NULL NULL NULL NULL 12
EXPLAIN FORMAT=JSON INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ) AS t WHERE f IS NOT NULL;
@ -10257,45 +10256,35 @@ EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 144,
"filtered": 100,
"attached_condition": "t.f is not null",
"materialized": {
"query_block": {
"select_id": 2,
"table": {
"table_name": "<derived4>",
"access_type": "ALL",
"rows": 12,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 4,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 12,
"filtered": 100
}
}
}
},
"block-nl-join": {
"temporary_table": {
"table": {
"table_name": "<derived4>",
"access_type": "ALL",
"rows": 12,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 4,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 12,
"filtered": 100,
"attached_condition": "t1.f is not null"
},
"buffer_type": "flat",
"buffer_size": "64",
"join_type": "BNL"
"filtered": 100
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 12,
"filtered": 100,
"attached_condition": "t1.f is not null"
},
"buffer_type": "flat",
"buffer_size": "64",
"join_type": "BNL"
}
}
}
@ -10326,43 +10315,33 @@ EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 16,
"filtered": 100,
"attached_condition": "t.f is not null",
"materialized": {
"query_block": {
"select_id": 2,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 8,
"filtered": 100,
"attached_condition": "t1.f is not null"
},
"table": {
"table_name": "<derived4>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "4",
"used_key_parts": ["f"],
"ref": ["test.t1.f"],
"rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 4,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 8,
"filtered": 100,
"attached_condition": "t1.f is not null"
}
}
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 8,
"filtered": 100,
"attached_condition": "t1.f is not null"
},
"table": {
"table_name": "<derived4>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "4",
"used_key_parts": ["f"],
"ref": ["test.t1.f"],
"rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 4,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 8,
"filtered": 100,
"attached_condition": "t1.f is not null"
}
}
}
@ -19134,4 +19113,25 @@ FROM cte2
GROUP BY 1 ;
( SELECT 1 FROM ( SELECT 1 FROM cte1) dt GROUP BY x HAVING x= 1 )
1
create table t1 (f int);
create view v1 as select f, count(*) c from t1 group by f;
#
# MDEV-25012 Server crash in find_field_in_tables, Assertion `name' failed in find_field_in_table_ref
#
select * from v1 where export_set(1, default(f), 'x', aes_decrypt('secret', f));
f c
show warnings;
Level Code Message
drop view v1;
drop table t1;
create table t(c3 longtext) ;
with cte1 as
(
select default(c3) as a
from t group by 1
)
select * from cte1
where cte1.a >= 1;
a
drop table t;
# End of 10.5 tests

22
mysql-test/main/derived_cond_pushdown.test

@ -4271,4 +4271,26 @@ SELECT
FROM cte2
GROUP BY 1 ;
create table t1 (f int);
create view v1 as select f, count(*) c from t1 group by f;
--echo #
--echo # MDEV-25012 Server crash in find_field_in_tables, Assertion `name' failed in find_field_in_table_ref
--echo #
select * from v1 where export_set(1, default(f), 'x', aes_decrypt('secret', f));
show warnings;
# cleanup
drop view v1;
drop table t1;
create table t(c3 longtext) ;
with cte1 as
(
select default(c3) as a
from t group by 1
)
select * from cte1
where cte1.a >= 1;
drop table t;
--echo # End of 10.5 tests

2
mysql-test/main/derived_view.result

@ -2385,6 +2385,8 @@ SELECT * FROM t1;
a
1
1
1
1
drop table t1,t2;
set optimizer_switch=@save968720_optimizer_switch;
#

72
mysql-test/main/insert.result

@ -806,5 +806,75 @@ a
8
drop table t1;
#
# End of 10.5 tests
# MDEV-32086 Server crash when inserting from derived table containing insert target table
# (part 2)
#
create table t1 (pk int, id int);
insert into t1 values (2,2), (3,3), (4,4);
select * from t1;
pk id
2 2
3 3
4 4
select 101+count(*)
from
(
select dt2.id
from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id<1000;
101+count(*)
104
prepare s from '
insert into t1 values(
(select 101+count(*)
from
(
select dt2.id
from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id<1000
), 123
)
';
execute s;
select * from t1;
pk id
2 2
3 3
4 4
104 123
select 101+count(*)
from
(
select dt2.id
from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id<1000;
101+count(*)
105
execute s;
select * from t1;
pk id
2 2
3 3
4 4
104 123
105 123
drop table t1;
#
# Try this: INSERT INTO t1 VALUES ... reference to t1
# RETURNING (subquery not touching t1)
create table t1 (a int, b int);
create table t2 (a int, b int);
# This is accepted:
insert into t1 (a) values
(3),
((select max(a) from t1))
returning
a, b, (select max(a) from t2);
a b (select max(a) from t2)
3 NULL NULL
NULL NULL NULL
drop table t1,t2;
# End of 10.5 tests

56
mysql-test/main/insert.test

@ -675,5 +675,59 @@ select * from t1;
drop table t1;
--echo #
--echo # End of 10.5 tests
--echo # MDEV-32086 Server crash when inserting from derived table containing insert target table
--echo # (part 2)
--echo #
create table t1 (pk int, id int);
insert into t1 values (2,2), (3,3), (4,4);
select * from t1;
select 101+count(*)
from
(
select dt2.id
from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id<1000;
prepare s from '
insert into t1 values(
(select 101+count(*)
from
(
select dt2.id
from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id<1000
), 123
)
';
execute s;
select * from t1;
select 101+count(*)
from
(
select dt2.id
from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id<1000;
execute s;
select * from t1;
drop table t1;
--echo #
--echo # Try this: INSERT INTO t1 VALUES ... reference to t1
--echo # RETURNING (subquery not touching t1)
create table t1 (a int, b int);
create table t2 (a int, b int);
--echo # This is accepted:
insert into t1 (a) values
(3),
((select max(a) from t1))
returning
a, b, (select max(a) from t2);
drop table t1,t2;
--echo # End of 10.5 tests

2
mysql-test/main/insert_returning.result

@ -498,6 +498,8 @@ t1 WHERE id1=1)
5 6
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT 1 UNION SELECT id2 FROM t2);
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
ERROR 42S02: Unknown table 'test.t1'
#

2
mysql-test/main/insert_returning.test

@ -199,6 +199,8 @@ INSERT INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM
t1 WHERE id1=1);
--error ER_UPDATE_TABLE_USED
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
--error ER_UPDATE_TABLE_USED
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT 1 UNION SELECT id2 FROM t2);
--error ER_BAD_TABLE_ERROR
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;

129
mysql-test/main/insert_select.result

@ -1030,6 +1030,133 @@ a
3
DROP VIEW v1;
DROP TABLE t1;
create table t1 (pk int, id int);
insert into t1 values (2,2), (3,3), (4,4);
insert into t1
select 1,10
from
(
select dt2.id from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id=3;
select * from t1;
pk id
2 2
3 3
4 4
1 10
explain insert into t1
select 1,10
from
(
select dt2.id from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id=3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where; Using temporary
1 SIMPLE t ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
explain format=json insert into t1
select 1,10
from
(
select dt2.id from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id=3;
EXPLAIN
{
"query_block": {
"select_id": 1,
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 4,
"filtered": 100,
"attached_condition": "t1.`id` = 3"
},
"block-nl-join": {
"table": {
"table_name": "t",
"access_type": "ALL",
"rows": 4,
"filtered": 100,
"attached_condition": "t.`id` = 3"
},
"buffer_type": "flat",
"buffer_size": "65",
"join_type": "BNL"
}
}
}
}
prepare stmt from "insert into t1
select 1,10
from
(
select dt2.id from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id=3";
execute stmt;
select * from t1;
pk id
2 2
3 3
4 4
1 10
1 10
execute stmt;
select * from t1;
pk id
2 2
3 3
4 4
1 10
1 10
1 10
deallocate prepare stmt;
create procedure p() insert into t1
select 1,10
from
(
select dt2.id from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id=3;
call p();
select * from t1;
pk id
2 2
3 3
4 4
1 10
1 10
1 10
1 10
call p();
select * from t1;
pk id
2 2
3 3
4 4
1 10
1 10
1 10
1 10
1 10
drop procedure p;
drop table t1;
#
# End of 10.5 test
# MDEV-33139: Crash of INSERT SELECT when preparing structures for
# split optimization
#
CREATE TABLE v0 ( v1 INT UNIQUE ) ;
INSERT INTO v0 ( v1 ) VALUES
( ( SELECT 1
FROM
( SELECT v1
FROM v0 GROUP BY v1 ) AS v6 NATURAL JOIN
v0 AS v2 NATURAL JOIN
v0 AS v4 NATURAL JOIN
v0 AS v3 NATURAL JOIN
( SELECT v1 FROM v0 ) AS v7 ) ) ;
DROP TABLE v0;
# End of 10.5 tests

56
mysql-test/main/insert_select.test

@ -591,6 +591,60 @@ SELECT * FROM t1;
DROP VIEW v1;
DROP TABLE t1;
#
# MDEV-32086: condition pushdown into two mergeable derived tables,
# one containing the other, when they are forced to be
# materialized in INSERT
#
create table t1 (pk int, id int);
insert into t1 values (2,2), (3,3), (4,4);
let $q=
insert into t1
select 1,10
from
(
select dt2.id from (select id from t1) dt2, t1 t where t.id=dt2.id
) dt
where dt.id=3;
eval $q;
select * from t1;
eval explain $q;
eval explain format=json $q;
eval prepare stmt from "$q";
execute stmt;
select * from t1;
execute stmt;
select * from t1;
deallocate prepare stmt;
eval create procedure p() $q;
call p();
select * from t1;
call p();
select * from t1;
drop procedure p;
drop table t1;
--echo #
--echo # End of 10.5 test
--echo # MDEV-33139: Crash of INSERT SELECT when preparing structures for
--echo # split optimization
--echo #
CREATE TABLE v0 ( v1 INT UNIQUE ) ;
INSERT INTO v0 ( v1 ) VALUES
( ( SELECT 1
FROM
( SELECT v1
FROM v0 GROUP BY v1 ) AS v6 NATURAL JOIN
v0 AS v2 NATURAL JOIN
v0 AS v4 NATURAL JOIN
v0 AS v3 NATURAL JOIN
( SELECT v1 FROM v0 ) AS v7 ) ) ;
DROP TABLE v0;
--echo # End of 10.5 tests

12
mysql-test/main/lowercase_view.result

@ -16,29 +16,17 @@ create view v1Aa as select * from t1aA;
create view v2aA as select * from v1aA;
create view v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
insert into v2Aa values ((select max(col1) from v1aA));
ERROR HY000: The definition of table 'v1aA' prevents operation INSERT on table 'v2Aa'
insert into t1aA values ((select max(col1) from v1Aa));
ERROR HY000: The definition of table 'v1Aa' prevents operation INSERT on table 't1aA'
insert into v2aA values ((select max(col1) from v1aA));
ERROR HY000: The definition of table 'v1aA' prevents operation INSERT on table 'v2aA'
insert into v2Aa values ((select max(col1) from t1Aa));
ERROR HY000: The definition of table 'v2Aa' prevents operation INSERT on table 'v2Aa'
insert into t1aA values ((select max(col1) from t1Aa));
ERROR HY000: Table 't1aA' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into v2aA values ((select max(col1) from t1aA));
ERROR HY000: The definition of table 'v2aA' prevents operation INSERT on table 'v2aA'
insert into v2Aa values ((select max(col1) from v2aA));
ERROR HY000: Table 'v2Aa' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into t1Aa values ((select max(col1) from v2Aa));
ERROR HY000: The definition of table 'v2Aa' prevents operation INSERT on table 't1Aa'
insert into v2aA values ((select max(col1) from v2Aa));
ERROR HY000: Table 'v2aA' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into v3Aa (col1) values ((select max(col1) from v1Aa));
ERROR HY000: The definition of table 'v1Aa' prevents operation INSERT on table 'v3Aa'
insert into v3aA (col1) values ((select max(col1) from t1aA));
ERROR HY000: The definition of table 'v3aA' prevents operation INSERT on table 'v3aA'
insert into v3Aa (col1) values ((select max(col1) from v2aA));
ERROR HY000: The definition of table 'v2aA' prevents operation INSERT on table 'v3Aa'
drop view v3aA,v2Aa,v1aA;
drop table t1Aa,t2Aa;
create table t1Aa (col1 int);

12
mysql-test/main/lowercase_view.test

@ -23,29 +23,17 @@ create table t2aA (col1 int);
create view v1Aa as select * from t1aA;
create view v2aA as select * from v1aA;
create view v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
-- error 1443
insert into v2Aa values ((select max(col1) from v1aA));
-- error 1443
insert into t1aA values ((select max(col1) from v1Aa));
-- error 1443
insert into v2aA values ((select max(col1) from v1aA));
-- error 1443
insert into v2Aa values ((select max(col1) from t1Aa));
-- error 1093
insert into t1aA values ((select max(col1) from t1Aa));
-- error 1443
insert into v2aA values ((select max(col1) from t1aA));
-- error 1093
insert into v2Aa values ((select max(col1) from v2aA));
-- error 1443
insert into t1Aa values ((select max(col1) from v2Aa));
-- error 1093
insert into v2aA values ((select max(col1) from v2Aa));
-- error 1443
insert into v3Aa (col1) values ((select max(col1) from v1Aa));
-- error 1443
insert into v3aA (col1) values ((select max(col1) from t1aA));
-- error 1443
insert into v3Aa (col1) values ((select max(col1) from v2aA));
drop view v3aA,v2Aa,v1aA;
drop table t1Aa,t2Aa;

17
mysql-test/main/merge.result

@ -3689,33 +3689,22 @@ insert into tmp (b) values (1);
insert into t1 (a) values (1);
insert into t3 (b) values (1);
insert into m1 (a) values ((select max(a) from m1));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from m2));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from t1));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from t2));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from t3, m1));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from t3, m2));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from t3, t1));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from t3, t2));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from tmp, m1));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from tmp, m2));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from tmp, t1));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from tmp, t2));
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into m1 (a) values ((select max(a) from v1));
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'
insert into m1 (a) values ((select max(a) from tmp, v1));
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'
select count(*) from m1;
count(*)
15
drop view v1;
drop temporary table tmp;
drop table t1, t2, t3, m1, m2;

17
mysql-test/main/merge.test

@ -2708,37 +2708,24 @@ insert into tmp (b) values (1);
insert into t1 (a) values (1);
insert into t3 (b) values (1);
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from m1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from m2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t3, m1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t3, m2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t3, t1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t3, t2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from tmp, m1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from tmp, m2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from tmp, t1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from tmp, t2));
--error ER_VIEW_PREVENT_UPDATE
insert into m1 (a) values ((select max(a) from v1));
--error ER_VIEW_PREVENT_UPDATE
insert into m1 (a) values ((select max(a) from tmp, v1));
select count(*) from m1;
drop view v1;

20
mysql-test/main/multi_update.result

@ -1371,3 +1371,23 @@ c1 c2 c3
12 5 8
drop table t1,t2,t3,t;
# End of 10.4 tests
#
# MDEV-31647 Stack looping and SIGSEGV in Item_args::walk_args on UPDATE
#
create table t1 (c int, c2 int) engine=innodb;
update t1 set c=0 where c=(
select 1 from (select 1 as v1) as v2
natural join t1) order by last_value (c2) over (order by c2);
ERROR HY000: Invalid use of group function
update t1 set c=0 where c=(
select 1 from (select 1 as v1) as v2
natural join t1) order by last_value (c2) over ();
ERROR HY000: Invalid use of group function
update t1 set c=0 where c=(
select 1 from (select 1 as v1) as v2
natural join t1) order by c2;
select 1 from (select 1 as v1) as v2
natural join t1 order by last_value (c2) over (order by c2);
1
drop table t1;
# End of 10.5 tests

28
mysql-test/main/multi_update.test

@ -1200,3 +1200,31 @@ select * from t1;
drop table t1,t2,t3,t;
--echo # End of 10.4 tests
--echo #
--echo # MDEV-31647 Stack looping and SIGSEGV in Item_args::walk_args on UPDATE
--echo #
--source include/have_innodb.inc
create table t1 (c int, c2 int) engine=innodb;
--error ER_INVALID_GROUP_FUNC_USE
update t1 set c=0 where c=(
select 1 from (select 1 as v1) as v2
natural join t1) order by last_value (c2) over (order by c2);
--error ER_INVALID_GROUP_FUNC_USE
update t1 set c=0 where c=(
select 1 from (select 1 as v1) as v2
natural join t1) order by last_value (c2) over ();
update t1 set c=0 where c=(
select 1 from (select 1 as v1) as v2
natural join t1) order by c2;
select 1 from (select 1 as v1) as v2
natural join t1 order by last_value (c2) over (order by c2);
drop table t1;
--echo # End of 10.5 tests

23
mysql-test/main/query_cache.result

@ -2241,6 +2241,29 @@ SET @qc= @@query_cache_size;
set global Query_cache_size=18446744073709547520;
SET GLOBAL query_cache_size= @qc;
#
# MDEV-34075 corruption when query cache cannot allocate block
#
set global query_cache_type=1;
create table t1 (c1 smallint null, c2 binary (25) not null, c3 tinyint(4) null, c4 binary (15) not null primary key, c5 smallint not null unique key,c6 decimal(10,8) not null default 3.141592) engine=innodb;
set global query_cache_size=81920;
select * from t1 where b=1 and c=1;
ERROR 42S22: Unknown column 'b' in 'WHERE'
set session query_cache_type=1;
drop table t1;
create table t1 (c1 int not null, c2 char(5)) engine=innodb partition by linear key(c1) partitions 99;
select * from t1 where c1 <='1998-12-29 00:00:00' order by c1,c2;
c1 c2
select group_concat(a separator '###') as names from t1 having left(names, 1)='j';
ERROR 42S22: Unknown column 'a' in 'SELECT'
select * from t1;
c1 c2
select count(*) from t1;
count(*)
0
select G.a, c.a from t1 c, t1 G;
ERROR 42S22: Unknown column 'G.a' in 'SELECT'
drop table t1;
#
# End of 10.5 tests
#
#

22
mysql-test/main/query_cache.test

@ -2,6 +2,8 @@
-- source include/long_test.inc
-- source include/no_valgrind_without_big.inc
-- source include/no_view_protocol.inc
-- source include/have_partition.inc
-- source include/have_innodb.inc
--disable_ps2_protocol
set @save_query_cache_size=@@query_cache_size;
@ -1852,6 +1854,26 @@ set global Query_cache_size=18446744073709547520;
SET GLOBAL query_cache_size= @qc;
--enable_warnings
--echo #
--echo # MDEV-34075 corruption when query cache cannot allocate block
--echo #
set global query_cache_type=1;
create table t1 (c1 smallint null, c2 binary (25) not null, c3 tinyint(4) null, c4 binary (15) not null primary key, c5 smallint not null unique key,c6 decimal(10,8) not null default 3.141592) engine=innodb;
set global query_cache_size=81920;
--error ER_BAD_FIELD_ERROR
select * from t1 where b=1 and c=1;
set session query_cache_type=1;
drop table t1;
create table t1 (c1 int not null, c2 char(5)) engine=innodb partition by linear key(c1) partitions 99;
select * from t1 where c1 <='1998-12-29 00:00:00' order by c1,c2;
--error ER_BAD_FIELD_ERROR
select group_concat(a separator '###') as names from t1 having left(names, 1)='j';
select * from t1;
select count(*) from t1;
--error ER_BAD_FIELD_ERROR
select G.a, c.a from t1 c, t1 G;
drop table t1;
--echo #
--echo # End of 10.5 tests
--echo #

2
mysql-test/main/sp-no-valgrind.test

@ -1,5 +1,5 @@
--source include/not_msan.inc
--source include/not_valgrind.inc
--source include/not_valgrind_build.inc
--echo # MDEV-20699 do not cache SP in SHOW CREATE
--echo # Warmup round, this might allocate some memory for session variable

20
mysql-test/main/subselect.result

@ -679,22 +679,24 @@ create table t3 (b int);
insert into t2 values (1);
insert into t3 values (1),(2);
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
select * from t1;
x
NULL
1
insert into t2 values (1);
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -702,6 +704,7 @@ x
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -711,6 +714,7 @@ x
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
3
@ -727,7 +731,7 @@ insert into t3 values (1),(2);
select * from t1;
x y
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 23000: Column 'x' cannot be null
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
ERROR 21000: Subquery returns more than 1 row
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
@ -795,13 +799,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
id
2
INSERT INTO t2 VALUES ((SELECT * FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t2 VALUES ((SELECT id FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
select * from t2;
id
1
2
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
SELECT * FROM t2;
id
1
2
2
2
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 values (1),(1);
UPDATE t2 SET id=(SELECT * FROM t1);

10
mysql-test/main/subselect.test

@ -419,7 +419,6 @@ create table t2 (a int) ENGINE=MyISAM;
create table t3 (b int);
insert into t2 values (1);
insert into t3 values (1),(2);
-- error ER_UPDATE_TABLE_USED
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
-- error ER_SUBQUERY_NO_1_ROW
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
@ -454,7 +453,7 @@ create table t3 (a int);
insert into t2 values (1);
insert into t3 values (1),(2);
select * from t1;
-- error ER_UPDATE_TABLE_USED
-- error ER_BAD_NULL_ERROR
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
-- error ER_SUBQUERY_NO_1_ROW
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
@ -494,10 +493,13 @@ EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
--disable_prepare_warnings
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
-- error ER_UPDATE_TABLE_USED
-- error ER_SUBQUERY_NO_1_ROW
INSERT INTO t2 VALUES ((SELECT * FROM t2));
-- error ER_UPDATE_TABLE_USED
-- error ER_SUBQUERY_NO_1_ROW
INSERT INTO t2 VALUES ((SELECT id FROM t2));
select * from t2;
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
SELECT * FROM t2;
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 values (1),(1);

12
mysql-test/main/subselect_elimination.result

@ -136,12 +136,22 @@ DROP TABLE t1;
# access within null pointer
CREATE TABLE x (x INT) ENGINE=InnoDB;
INSERT INTO x (x) VALUES (0);
select NULL IN (SELECT (SELECT x FROM (SELECT x FROM
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
AS x) IN (SELECT 0 AS x) AS x FROM x) as exp;
exp
NULL
INSERT INTO x (x) VALUES (x IN (SELECT (SELECT x FROM (SELECT x FROM
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
AS x) IN (SELECT 0 AS x) AS x FROM x));
ERROR HY000: Table 'x' is specified twice, both as a target for 'INSERT' and as a separate source for data
select * from x;
x
0
NULL
DROP TABLE x;
# MDEV-28622: Item_subselect eliminated flag set but Item still
# evaluated/used.

7
mysql-test/main/subselect_elimination.test

@ -133,12 +133,17 @@ DROP TABLE t1;
CREATE TABLE x (x INT) ENGINE=InnoDB;
INSERT INTO x (x) VALUES (0);
--error ER_UPDATE_TABLE_USED
select NULL IN (SELECT (SELECT x FROM (SELECT x FROM
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
AS x) IN (SELECT 0 AS x) AS x FROM x) as exp;
INSERT INTO x (x) VALUES (x IN (SELECT (SELECT x FROM (SELECT x FROM
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
AS x) IN (SELECT 0 AS x) AS x FROM x));
select * from x;
DROP TABLE x;
--echo # MDEV-28622: Item_subselect eliminated flag set but Item still

20
mysql-test/main/subselect_no_exists_to_in.result

@ -683,22 +683,24 @@ create table t3 (b int);
insert into t2 values (1);
insert into t3 values (1),(2);
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
select * from t1;
x
NULL
1
insert into t2 values (1);
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -706,6 +708,7 @@ x
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -715,6 +718,7 @@ x
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
3
@ -731,7 +735,7 @@ insert into t3 values (1),(2);
select * from t1;
x y
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 23000: Column 'x' cannot be null
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
ERROR 21000: Subquery returns more than 1 row
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
@ -799,13 +803,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
id
2
INSERT INTO t2 VALUES ((SELECT * FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t2 VALUES ((SELECT id FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
select * from t2;
id
1
2
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
SELECT * FROM t2;
id
1
2
2
2
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 values (1),(1);
UPDATE t2 SET id=(SELECT * FROM t1);

20
mysql-test/main/subselect_no_mat.result

@ -686,22 +686,24 @@ create table t3 (b int);
insert into t2 values (1);
insert into t3 values (1),(2);
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
select * from t1;
x
NULL
1
insert into t2 values (1);
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -709,6 +711,7 @@ x
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -718,6 +721,7 @@ x
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
3
@ -734,7 +738,7 @@ insert into t3 values (1),(2);
select * from t1;
x y
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 23000: Column 'x' cannot be null
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
ERROR 21000: Subquery returns more than 1 row
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
@ -802,13 +806,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
id
2
INSERT INTO t2 VALUES ((SELECT * FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t2 VALUES ((SELECT id FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
select * from t2;
id
1
2
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
SELECT * FROM t2;
id
1
2
2
2
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 values (1),(1);
UPDATE t2 SET id=(SELECT * FROM t1);

20
mysql-test/main/subselect_no_opts.result

@ -682,22 +682,24 @@ create table t3 (b int);
insert into t2 values (1);
insert into t3 values (1),(2);
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
select * from t1;
x
NULL
1
insert into t2 values (1);
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -705,6 +707,7 @@ x
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -714,6 +717,7 @@ x
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
3
@ -730,7 +734,7 @@ insert into t3 values (1),(2);
select * from t1;
x y
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 23000: Column 'x' cannot be null
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
ERROR 21000: Subquery returns more than 1 row
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
@ -798,13 +802,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
id
2
INSERT INTO t2 VALUES ((SELECT * FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t2 VALUES ((SELECT id FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
select * from t2;
id
1
2
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
SELECT * FROM t2;
id
1
2
2
2
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 values (1),(1);
UPDATE t2 SET id=(SELECT * FROM t1);

20
mysql-test/main/subselect_no_scache.result

@ -685,22 +685,24 @@ create table t3 (b int);
insert into t2 values (1);
insert into t3 values (1),(2);
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
select * from t1;
x
NULL
1
insert into t2 values (1);
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -708,6 +710,7 @@ x
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -717,6 +720,7 @@ x
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
3
@ -733,7 +737,7 @@ insert into t3 values (1),(2);
select * from t1;
x y
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 23000: Column 'x' cannot be null
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
ERROR 21000: Subquery returns more than 1 row
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
@ -801,13 +805,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
id
2
INSERT INTO t2 VALUES ((SELECT * FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t2 VALUES ((SELECT id FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
select * from t2;
id
1
2
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
SELECT * FROM t2;
id
1
2
2
2
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 values (1),(1);
UPDATE t2 SET id=(SELECT * FROM t1);

20
mysql-test/main/subselect_no_semijoin.result

@ -682,22 +682,24 @@ create table t3 (b int);
insert into t2 values (1);
insert into t3 values (1),(2);
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
select * from t1;
x
NULL
1
insert into t2 values (1);
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -705,6 +707,7 @@ x
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
select * from t1;
x
NULL
1
2
3
@ -714,6 +717,7 @@ x
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
select * from t1;
x
NULL
1
2
3
@ -730,7 +734,7 @@ insert into t3 values (1),(2);
select * from t1;
x y
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 23000: Column 'x' cannot be null
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
ERROR 21000: Subquery returns more than 1 row
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
@ -798,13 +802,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
id
2
INSERT INTO t2 VALUES ((SELECT * FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
INSERT INTO t2 VALUES ((SELECT id FROM t2));
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
ERROR 21000: Subquery returns more than 1 row
select * from t2;
id
1
2
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
SELECT * FROM t2;
id
1
2
2
2
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 values (1),(1);
UPDATE t2 SET id=(SELECT * FROM t1);

49
mysql-test/main/view.result

@ -944,31 +944,19 @@ create view v1 as select * from t1;
create view v2 as select * from v1;
create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
insert into v2 values ((select max(col1) from v1));
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v2'
insert into t1 values ((select max(col1) from v1));
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 't1'
insert into v2 values ((select max(col1) from v1));
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v2'
insert into v2 values ((select max(col1) from t1));
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v2'
insert into t1 values ((select max(col1) from t1));
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into v2 values ((select max(col1) from t1));
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v2'
insert into v2 values ((select max(col1) from v2));
ERROR HY000: Table 'v2' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into t1 values ((select max(col1) from v2));
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 't1'
insert into v2 values ((select max(col1) from v2));
ERROR HY000: Table 'v2' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into v3 (col1) values ((select max(col1) from v1));
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v3'
insert into v3 (col1) values ((select max(col1) from t1));
ERROR HY000: The definition of table 'v3' prevents operation INSERT on table 'v3'
insert into v3 (col1) values ((select max(col1) from v2));
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v3'
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2));
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v3'
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2 LIMIT 1));
ERROR 22003: Out of range value for column 'col1' at row 2
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
insert into t3 values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
ERROR 23000: Column 'col1' cannot be null
@ -978,6 +966,18 @@ insert into t1 (col1) values ((select max(col1) from v4));
select * from t1;
col1
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
1
2
3
@ -1332,9 +1332,26 @@ create view v3 as select * from t1 where 20 < (select (s1) from v2);
insert into v3 values (30);
ERROR HY000: The target table v3 of the INSERT is not insertable-into
create view v4 as select * from v2 where 20 < (select (s1) from t1);
select * from t1;
s1
insert into v4 values (30);
ERROR HY000: The target table v4 of the INSERT is not insertable-into
drop view v4, v3, v2, v1;
select * from t1;
s1
30
create view v5 as select * from v2 where s1 < (select min(s1) from t1) WITH CHECK OPTION;
# can't insert only less then minimum
insert into v5 values (40);
ERROR 44000: CHECK OPTION failed `test`.`v5`
# allow insert the new minimum
insert into v5 values (10);
# always emply view (can't be something less than minimum)
select * from v5;
s1
select * from t1;
s1
30
10
drop view v5, v4, v3, v2, v1;
drop table t1;
create table t1 (a int);
create view v1 as select * from t1;

30
mysql-test/main/view.test

@ -866,33 +866,21 @@ create table t3 (col1 datetime not null);
create view v1 as select * from t1;
create view v2 as select * from v1;
create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
-- error ER_VIEW_PREVENT_UPDATE
insert into v2 values ((select max(col1) from v1));
-- error ER_VIEW_PREVENT_UPDATE
insert into t1 values ((select max(col1) from v1));
-- error ER_VIEW_PREVENT_UPDATE
insert into v2 values ((select max(col1) from v1));
-- error ER_VIEW_PREVENT_UPDATE
insert into v2 values ((select max(col1) from t1));
-- error ER_UPDATE_TABLE_USED
insert into t1 values ((select max(col1) from t1));
-- error ER_VIEW_PREVENT_UPDATE
insert into v2 values ((select max(col1) from t1));
-- error ER_UPDATE_TABLE_USED
insert into v2 values ((select max(col1) from v2));
-- error ER_VIEW_PREVENT_UPDATE
insert into t1 values ((select max(col1) from v2));
-- error ER_UPDATE_TABLE_USED
insert into v2 values ((select max(col1) from v2));
-- error ER_VIEW_PREVENT_UPDATE
insert into v3 (col1) values ((select max(col1) from v1));
-- error ER_VIEW_PREVENT_UPDATE
insert into v3 (col1) values ((select max(col1) from t1));
-- error ER_VIEW_PREVENT_UPDATE
insert into v3 (col1) values ((select max(col1) from v2));
# check with TZ tables in list
-- error ER_VIEW_PREVENT_UPDATE
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2));
--error ER_WARN_DATA_OUT_OF_RANGE
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2 LIMIT 1));
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
-- error ER_BAD_NULL_ERROR
insert into t3 values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
@ -1210,9 +1198,19 @@ create view v3 as select * from t1 where 20 < (select (s1) from v2);
-- error ER_NON_INSERTABLE_TABLE
insert into v3 values (30);
create view v4 as select * from v2 where 20 < (select (s1) from t1);
-- error ER_NON_INSERTABLE_TABLE
select * from t1;
insert into v4 values (30);
drop view v4, v3, v2, v1;
select * from t1;
create view v5 as select * from v2 where s1 < (select min(s1) from t1) WITH CHECK OPTION;
--echo # can't insert only less then minimum
--error ER_VIEW_CHECK_FAILED
insert into v5 values (40);
--echo # allow insert the new minimum
insert into v5 values (10);
--echo # always emply view (can't be something less than minimum)
select * from v5;
select * from t1;
drop view v5, v4, v3, v2, v1;
drop table t1;
#

1
mysql-test/suite/galera/r/galera_as_slave_nonprim.result

@ -12,7 +12,6 @@ connection node_1;
connection node_4;
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
connection node_2;
connection node_1;
expected_error
1
connection node_2;

80
mysql-test/suite/galera/r/galera_toi_ddl_nonconflicting.result

@ -1,29 +1,69 @@
connection node_2;
connection node_1;
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 INTEGER);
INSERT INTO t1(f2) SELECT seq FROM seq_1_to_1000;
connection node_2a;
SET SESSION wsrep_sync_wait=0;
connection node_1a;
# Block the applier on node_1 and issue a ddl from node_2
SET SESSION wsrep_sync_wait=0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 (f1, f2) VALUES (DEFAULT, 123);;
# DDL 1
ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 VALUES (NULL, 10000, 10000);;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
# This will block on acquiring total order isolation
connection node_1;
# DDL 2
CREATE UNIQUE INDEX i1 ON t1(f2);;
connection node_1a;
# Signal DDL 1
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
connection node_2;
connection node_1;
connection node_2;
INSERT INTO t1 (f1, f2) VALUES (DEFAULT, 234);
SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
COUNT(*) = 3
1
SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
COUNT(*) = 2
1
SELECT COUNT(*) = 2 FROM t1;
COUNT(*) = 2
1
SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
EXPECT_3
3
SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
EXPECT_2
2
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL AUTO_INCREMENT,
`f2` int(11) DEFAULT NULL,
`f3` int(11) DEFAULT NULL,
PRIMARY KEY (`f1`),
UNIQUE KEY `i1` (`f2`)
) ENGINE=InnoDB AUTO_INCREMENT=2002 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
SELECT COUNT(*) AS EXPECT_1001 FROM t1;
EXPECT_1001
1001
connection node_1;
SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
COUNT(*) = 3
1
SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
COUNT(*) = 2
1
SELECT COUNT(*) = 2 FROM t1;
COUNT(*) = 2
1
SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
EXPECT_3
3
SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
EXPECT_2
2
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL AUTO_INCREMENT,
`f2` int(11) DEFAULT NULL,
`f3` int(11) DEFAULT NULL,
PRIMARY KEY (`f1`),
UNIQUE KEY `i1` (`f2`)
) ENGINE=InnoDB AUTO_INCREMENT=2047 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
SELECT COUNT(*) AS EXPECT_1001 FROM t1;
EXPECT_1001
1001
DROP TABLE t1;

6
mysql-test/suite/galera/r/galera_var_replicate_myisam_on.result

@ -203,6 +203,9 @@ id b
3 200
4 5
connection node_2;
SELECT COUNT(*) FROM t1;
COUNT(*)
10
SELECT * FROM t1 ORDER BY id;
id b
1 1
@ -228,6 +231,9 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (a INT, b INT, UNIQUE(a)) ENGINE=MyISAM;
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=1;
INSERT INTO t1 (a,b) VALUES (10,20);
SELECT * from t1;
a b
1 20
connection node_2;
SELECT * from t1;
a b

6
mysql-test/suite/galera/t/galera_as_slave_nonprim.test

@ -2,7 +2,7 @@
# Test the behavior of a Galera async slave if it goes non-prim. Async replication
# should abort with an error but it should be possible to restart it.
#
# The galera/galera_2node_slave.cnf describes the setup of the nodes
# The galera_3nodes_as_slave.cnf describes the setup of the nodes
#
--source include/have_innodb.inc
@ -45,9 +45,8 @@ SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1';
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
--connection node_2
--sleep 5
wait_for_slave_to_stop;
--let $value = query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1)
--connection node_1
--disable_query_log
--eval SELECT "$value" IN ("Error 'Unknown command' on query. Default database: 'test'. Query: 'BEGIN'", "Node has dropped from cluster") AS expected_error
--enable_query_log
@ -75,7 +74,6 @@ START SLAVE;
--connection node_4
DROP TABLE t1;
--sleep 2
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc

60
mysql-test/suite/galera/t/galera_toi_ddl_nonconflicting.test

@ -1,43 +1,81 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_sequence.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/galera_have_debug_sync.inc
#
# In this test, we simultaneously send two non-conflicting ALTER TABLE statements
#
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
--connection node_1
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 INTEGER);
INSERT INTO t1(f2) SELECT seq FROM seq_1_to_1000;
--connection node_2
--connection node_2a
SET SESSION wsrep_sync_wait=0;
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--send ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 (f1, f2) VALUES (DEFAULT, 123);
--let $wait_condition = SELECT COUNT(*) = 1000 FROM t1;
--source include/wait_condition.inc
--connection node_1a
--echo # Block the applier on node_1 and issue a ddl from node_2
SET SESSION wsrep_sync_wait=0;
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc
--connection node_2
--echo # DDL 1
--send ALTER TABLE t1 ADD COLUMN f3 INTEGER; INSERT INTO t1 VALUES (NULL, 10000, 10000);
--connection node_1a
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
--echo # This will block on acquiring total order isolation
--connection node_1
--echo # DDL 2
--send CREATE UNIQUE INDEX i1 ON t1(f2);
--connection node_1a
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'acquiring total order%' or STATE LIKE 'Waiting for table metadata%'
--source include/wait_condition.inc
--echo # Signal DDL 1
--source include/galera_clear_sync_point.inc
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_signal_sync_point.inc
--connection node_2
--reap
INSERT INTO t1 (f1, f2) VALUES (DEFAULT, 234);
--connection node_1
--reap
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
SELECT COUNT(*) = 2 FROM t1;
SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
SHOW CREATE TABLE t1;
SELECT COUNT(*) AS EXPECT_1001 FROM t1;
--connection node_1
--reap
--let $wait_condition = SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
SELECT COUNT(*) = 2 FROM t1;
SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
SELECT COUNT(*) AS EXPECT_2 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1';
SHOW CREATE TABLE t1;
SELECT COUNT(*) AS EXPECT_1001 FROM t1;
DROP TABLE t1;

39
mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test

@ -22,6 +22,8 @@ SET GLOBAL wsrep_on = ON;
DROP TABLE t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
SHOW TABLES;
# Drop schema that does not exist
@ -33,6 +35,8 @@ SET GLOBAL wsrep_on = ON;
DROP SCHEMA s1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME LIKE 's1';
--source include/wait_condition.inc
SHOW SCHEMAS;
# Drop index that does not exist using DROP INDEX
@ -45,6 +49,10 @@ SET GLOBAL wsrep_on = ON;
DROP INDEX idx1 ON t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE NAME LIKE 'idx1';
--source include/wait_condition.inc
SHOW CREATE TABLE t1;
DROP TABLE t1;
@ -58,6 +66,10 @@ SET GLOBAL wsrep_on = ON;
ALTER TABLE t1 DROP INDEX idx1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE NAME LIKE 'idx1';
--source include/wait_condition.inc
SHOW CREATE TABLE t1;
DROP TABLE t1;
@ -71,6 +83,11 @@ SET GLOBAL wsrep_on = ON;
ALTER TABLE t1 DROP COLUMN f2;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE NAME LIKE 'f2';
--source include/wait_condition.inc
SHOW CREATE TABLE t1;
DROP TABLE t1;
@ -93,6 +110,10 @@ DELETE FROM t1 WHERE f1 = 1;
SELECT COUNT(*) AS expect_0 FROM t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) AS expect_0 FROM t1;
DROP TABLE t1;
@ -112,6 +133,10 @@ COMMIT;
SELECT COUNT(*) AS expect_1 FROM t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) AS expect_1 FROM t1;
DROP TABLE t1;
@ -136,6 +161,8 @@ DELETE FROM t1;
SELECT COUNT(*) AS expect_0 FROM t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc
SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
@ -171,6 +198,8 @@ SET AUTOCOMMIT=ON;
SELECT COUNT(*) AS expect_0 FROM t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc
SELECT VARIABLE_VALUE expect_Primary FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
@ -202,6 +231,8 @@ DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1;
SELECT COUNT(*) expect_0 FROM t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc
SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';
@ -219,6 +250,10 @@ CREATE TABLE child (id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KE
INSERT INTO child VALUES (1,1),(2,2),(3,3);
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/parent';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/child';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 3 FROM child;
--source include/wait_condition.inc
@ -233,6 +268,10 @@ SELECT COUNT(*) AS expect_0 FROM parent;
SELECT COUNT(*) AS expect_0 FROM child;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/parent';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/child';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 0 FROM child;
--source include/wait_condition.inc
SELECT VARIABLE_VALUE = 'Primary' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status';

64
mysql-test/suite/galera/t/galera_var_replicate_myisam_on.test

@ -21,6 +21,11 @@ INSERT INTO t1 VALUES (2), (3);
INSERT INTO t1 SELECT 4 FROM DUAL UNION ALL SELECT 5 FROM DUAL;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_5 FROM t1;
DROP TABLE t1;
@ -36,6 +41,13 @@ REPLACE INTO t1 VALUES (1, 'klm'), (2,'xyz');
REPLACE INTO t1 SELECT 3, 'yyy' FROM DUAL;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1 WHERE f1 = 3 AND f2 = 'yyy';
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_3 FROM t1;
SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f1 = 1 AND f2 = 'klm';
SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f1 = 2 AND f2 = 'xyz';
@ -49,6 +61,9 @@ SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f1 = 3 AND f2 = 'yyy';
UPDATE t1 SET f2 = 'zzz' WHERE f2 = 'yyy';
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'zzz';
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'zzz';
#
@ -59,6 +74,9 @@ SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'zzz';
DELETE FROM t1 WHERE f2 = 'zzz';
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'zzz';
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_0 FROM t1 WHERE f2 = 'zzz';
#
@ -69,6 +87,9 @@ SELECT COUNT(*) AS EXPECT_0 FROM t1 WHERE f2 = 'zzz';
TRUNCATE TABLE t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 0 FROM t1;
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_0 FROM t1;
DROP TABLE t1;
@ -86,6 +107,15 @@ INSERT INTO t2 VALUES (1);
COMMIT;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM t2;
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_1 FROM t1;
SELECT COUNT(*) AS EXPECT_1 FROM t2;
@ -100,6 +130,11 @@ INSERT INTO t2 VALUES (2);
ROLLBACK;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 2 FROM t1;
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM t2;
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_2 FROM t1;
SELECT COUNT(*) AS EXPECT_1 FROM t2;
@ -119,7 +154,13 @@ INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
--connection node_2
# The MyISAM update is replicated immediately, so a duplicate key error happens even before the COMMIT
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
--source include/wait_condition.inc
# The MyISAM update is replicated when executed, so a duplicate key error happens even before the COMMIT
--error ER_DUP_ENTRY
INSERT INTO t1 VALUES (1);
@ -147,6 +188,10 @@ EXECUTE rep;
SELECT * FROM t1 ORDER BY id;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 11 FROM t1;
--source include/wait_condition.inc
SELECT * FROM t1 ORDER BY id;
DROP TABLE t1;
@ -173,6 +218,10 @@ CALL proc();
SELECT * FROM t1 ORDER BY id;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 11 FROM t1;
--source include/wait_condition.inc
SELECT * FROM t1 ORDER BY id;
DROP PROCEDURE proc;
@ -196,6 +245,13 @@ SELECT * FROM t1 ORDER BY id;
SELECT * FROM t2 ORDER BY id;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2';
--source include/wait_condition.inc
SELECT COUNT(*) FROM t1;
--let $wait_condition = SELECT COUNT(*) = 10 FROM t1;
--source include/wait_condition.inc
SELECT * FROM t1 ORDER BY id;
SELECT * FROM t2 ORDER BY id;
DROP TRIGGER tr1;
@ -206,8 +262,14 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (a INT, b INT, UNIQUE(a)) ENGINE=MyISAM;
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=1;
INSERT INTO t1 (a,b) VALUES (10,20);
SELECT * from t1;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
--source include/wait_condition.inc
SELECT * from t1;
--connection node_1
DROP TABLE t1;

1
mysql-test/suite/sql_sequence/other.result

@ -48,7 +48,6 @@ create sequence s2;
insert into s1 (next_not_cached_value, minimum_value) values (100,1000);
ERROR HY000: Field 'maximum_value' doesn't have a default value
insert into s1 values (next value for s1, 1,9223372036854775806,1,1,1000,0,0);
ERROR HY000: Table 's1' is specified twice, both as a target for 'INSERT' and as a separate source for data
insert into s1 values(1000,9223372036854775806,1,1,1,1000,0,0);
ERROR HY000: Sequence 'test.s1' has out of range value for options
insert into s1 values(0,9223372036854775806,1,1,1,1000,0,0);

1
mysql-test/suite/sql_sequence/other.test

@ -38,7 +38,6 @@ create sequence s1;
create sequence s2;
--error ER_NO_DEFAULT_FOR_FIELD
insert into s1 (next_not_cached_value, minimum_value) values (100,1000);
--error ER_UPDATE_TABLE_USED
insert into s1 values (next value for s1, 1,9223372036854775806,1,1,1000,0,0);
--error ER_SEQUENCE_INVALID_DATA
insert into s1 values(1000,9223372036854775806,1,1,1,1000,0,0);

12
sql/item.h

@ -757,6 +757,17 @@ public:
virtual const String *const_ptr_string() const { return NULL; }
};
struct subselect_table_finder_param
{
THD *thd;
/*
We're searching for different TABLE_LIST objects referring to the same
table as this one
*/
const TABLE_LIST *find;
/* NUL - not found, ERROR_TABLE - search error, or the found table reference */
TABLE_LIST *dup;
};
/****************************************************************************/
@ -2282,6 +2293,7 @@ public:
set_extraction_flag(*(int16*)arg);
return 0;
}
virtual bool subselect_table_finder_processor(void *arg) { return 0; };
/*
TRUE if the expression depends only on the table indicated by tab_map

24
sql/item_subselect.cc

@ -7137,3 +7137,27 @@ void Subq_materialization_tracker::report_partial_merge_keys(
for (uint i= 0; i < merge_keys_count; i++)
partial_match_array_sizes[i]= merge_keys[i]->get_key_buff_elements();
}
/*
Check if somewhere inside this subselect we read the table. This means a
full read "(SELECT ... FROM tbl)", outside reference to tbl.column does not
count
*/
bool
Item_subselect::subselect_table_finder_processor(void *arg)
{
subselect_table_finder_param *param= (subselect_table_finder_param *)arg;
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
{
TABLE_LIST *dup;
if ((dup= sl->find_table(param->thd, &param->find->db,
&param->find->table_name)))
{
param->dup= dup;
return TRUE;
}
}
return FALSE;
};

1
sql/item_subselect.h

@ -273,6 +273,7 @@ public:
{
return TRUE;
}
bool subselect_table_finder_processor(void *arg) override;
void register_as_with_rec_ref(With_element *with_elem);
void init_expr_cache_tracker(THD *thd);

9
sql/mysqld.cc

@ -8778,15 +8778,22 @@ char *set_server_version(char *buf, size_t size)
bool is_log= opt_log || global_system_variables.sql_log_slow || opt_bin_log;
bool is_debug= IF_DBUG(!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"), 0);
const char *is_valgrind=
#ifdef HAVE_VALGRIND
#ifdef HAVE_valgrind
!strstr(MYSQL_SERVER_SUFFIX_STR, "-valgrind") ? "-valgrind" :
#endif
"";
const char *is_asan=
#ifdef __SANITIZE_ADDRESS__
!strstr(MYSQL_SERVER_SUFFIX_STR, "-asan") ? "-asan" :
#endif
"";
return strxnmov(buf, size - 1,
MYSQL_SERVER_VERSION,
MYSQL_SERVER_SUFFIX_STR,
IF_EMBEDDED("-embedded", ""),
is_valgrind,
is_asan,
is_debug ? "-debug" : "",
is_log ? "-log" : "",
NullS);

80
sql/sql_base.cc

@ -19,6 +19,7 @@
#include "mariadb.h"
#include "sql_base.h" // setup_table_map
#include "sql_list.h"
#include "sql_priv.h"
#include "unireg.h"
#include "debug_sync.h"
@ -1161,7 +1162,6 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
t_name= &table->table_name;
t_alias= &table->alias;
retry:
DBUG_PRINT("info", ("real table: %s.%s", d_name->str, t_name->str));
for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0)
{
@ -1223,28 +1223,53 @@ retry:
DBUG_PRINT("info",
("found same copy of table or table which we should skip"));
}
if (res && res->belong_to_derived)
{
/*
We come here for queries of type:
INSERT INTO t1 (SELECT tmp.a FROM (select * FROM t1) as tmp);
DBUG_RETURN(res);
}
Try to fix by materializing the derived table
*/
TABLE_LIST *derived= res->belong_to_derived;
if (derived->is_merged_derived() && !derived->derived->is_excluded())
TABLE_LIST* unique_table_in_select_list(THD *thd, TABLE_LIST *table, SELECT_LEX *sel)
{
subselect_table_finder_param param= {thd, table, NULL};
List_iterator_fast<Item> it(sel->item_list);
Item *item;
while ((item= it++))
{
if (item->walk(&Item::subselect_table_finder_processor, FALSE, &param))
{
DBUG_PRINT("info",
("convert merged to materialization to resolve the conflict"));
derived->change_refs_to_fields();
derived->set_materialized_derived();
goto retry;
if (param.dup == NULL)
return ERROR_TABLE;
return param.dup;
}
DBUG_ASSERT(param.dup == NULL);
}
DBUG_RETURN(res);
return NULL;
}
typedef TABLE_LIST* (*find_table_callback)(THD *thd, TABLE_LIST *table,
TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel);
static
TABLE_LIST*
find_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel, find_table_callback callback );
TABLE_LIST* unique_table_callback(THD *thd, TABLE_LIST *table,
TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel)
{
return find_dup_table(thd, table, table_list, check_flag);
}
TABLE_LIST* unique_in_sel_table_callback(THD *thd, TABLE_LIST *table,
TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel)
{
return unique_table_in_select_list(thd, table, sel);
}
/**
Test that the subject table of INSERT/UPDATE/DELETE/CREATE
or (in case of MyISAMMRG) one of its children are not used later
@ -1263,6 +1288,25 @@ retry:
TABLE_LIST*
unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
uint check_flag)
{
return find_table(thd, table, table_list, check_flag, NULL,
&unique_table_callback);
}
TABLE_LIST*
unique_table_in_insert_returning_subselect(THD *thd, TABLE_LIST *table, SELECT_LEX *sel)
{
return find_table(thd, table, NULL, 0, sel,
&unique_in_sel_table_callback);
}
static
TABLE_LIST*
find_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel, find_table_callback callback )
{
TABLE_LIST *dup;
@ -1294,12 +1338,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
if (!tmp_parent)
break;
if ((dup= find_dup_table(thd, child, child->next_global, check_flag)))
if ((dup= (*callback)(thd, child, child->next_global, check_flag, sel)))
break;
}
}
else
dup= find_dup_table(thd, table, table_list, check_flag);
dup= (*callback)(thd, table, table_list, check_flag, sel);
return dup;
}

2
sql/sql_base.h

@ -294,6 +294,8 @@ bool open_and_lock_internal_tables(TABLE *table, bool lock);
bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
int decide_logging_format(THD *thd, TABLE_LIST *tables);
void close_thread_table(THD *thd, TABLE **table_ptr);
TABLE_LIST*
unique_table_in_insert_returning_subselect(THD *thd, TABLE_LIST *table, SELECT_LEX *sel);
TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
uint check_flag);
bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b);

2
sql/sql_cache.cc

@ -3553,6 +3553,7 @@ Query_cache::insert_table(THD *thd, size_t key_len, const char *key,
if (table_block == 0)
{
DBUG_PRINT("qcache", ("Can't write table name to cache"));
node->parent= NULL;
DBUG_RETURN(0);
}
Query_cache_table *header= table_block->table();
@ -3576,6 +3577,7 @@ Query_cache::insert_table(THD *thd, size_t key_len, const char *key,
DBUG_PRINT("qcache", ("Can't insert table to hash"));
// write_block_data return locked block
free_memory_block(table_block);
node->parent= NULL;
DBUG_RETURN(0);
}
char *db= header->db();

98
sql/sql_insert.cc

@ -57,6 +57,7 @@
*/
#include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
#include "sql_list.h"
#include "sql_priv.h"
#include "sql_insert.h"
#include "sql_update.h" // compare_record
@ -716,6 +717,8 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
Name_resolution_context_state ctx_state;
SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0;
unsigned char *readbuff= NULL;
List<List_item> insert_values_cache;
bool cache_insert_values= FALSE;
#ifndef EMBEDDED_LIBRARY
char *query= thd->query();
@ -773,7 +776,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
if ((res= mysql_prepare_insert(thd, table_list, fields, values,
update_fields, update_values, duplic,
&unused_conds, FALSE)))
&unused_conds, FALSE, &cache_insert_values)))
{
retval= thd->is_error();
if (res < 0)
@ -1007,8 +1010,41 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
if (returning)
fix_rownum_pointers(thd, thd->lex->returning(), &info.accepted_rows);
if (cache_insert_values)
{
insert_values_cache.empty();
while ((values= its++))
{
List<Item> *caches= new (thd->mem_root) List_item;
List_iterator_fast<Item> iv(*values);
Item *item;
if (caches == 0)
{
error= 1;
goto values_loop_end;
}
caches->empty();
while((item= iv++))
{
Item_cache *cache= item->get_cache(thd);
if (!cache)
{
error= 1;
goto values_loop_end;
}
cache->setup(thd, item);
caches->push_back(cache);
}
insert_values_cache.push_back(caches);
}
its.rewind();
}
do
{
List_iterator_fast<List_item> itc(insert_values_cache);
List_iterator_fast<List_item> *itr;
DBUG_PRINT("info", ("iteration %llu", iteration));
if (iteration && bulk_parameters_set(thd))
{
@ -1016,7 +1052,24 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
goto values_loop_end;
}
while ((values= its++))
if (cache_insert_values)
{
List_item *caches;
while ((caches= itc++))
{
List_iterator_fast<Item> ic(*caches);
Item_cache *cache;
while((cache= (Item_cache*) ic++))
{
cache->cache_value();
}
}
itc.rewind();
itr= &itc;
}
else
itr= &its;
while ((values= (*itr)++))
{
if (fields.elements || !value_count)
{
@ -1120,7 +1173,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
info.accepted_rows++;
thd->get_stmt_da()->inc_current_row_for_warning();
}
its.rewind();
itr->rewind();
iteration++;
} while (bulk_parameters_iterations(thd));
@ -1609,6 +1662,7 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
table_list Global/local table list
where Where clause (for insert ... select)
select_insert TRUE if INSERT ... SELECT statement
cache_insert_values insert's VALUES(...) has to be pre-computed
TODO (in far future)
In cases of:
@ -1630,7 +1684,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
List<Item> &fields, List_item *values,
List<Item> &update_fields, List<Item> &update_values,
enum_duplicates duplic, COND **where,
bool select_insert)
bool select_insert, bool * const cache_insert_values)
{
SELECT_LEX *select_lex= thd->lex->first_select_lex();
Name_resolution_context *context= &select_lex->context;
@ -1718,6 +1772,15 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(1);
}
/*
Check if we read from the same table we're inserting into.
Queries like INSERT INTO t1 VALUES ((SELECT ... FROM t1...)) have
to pre-compute the VALUES part.
Reading from the same table in the RETURNING clause is not allowed.
INSERT...SELECT detects this case in select_insert::prepare and also
uses buffering to handle it correcly.
*/
if (!select_insert)
{
Item *fake_conds= 0;
@ -1725,10 +1788,30 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
if ((duplicate= unique_table(thd, table_list, table_list->next_global,
CHECK_DUP_ALLOW_DIFFERENT_ALIAS)))
{
update_non_unique_table_error(table_list, "INSERT", duplicate);
DBUG_RETURN(1);
/*
This is INSERT INTO ... VALUES (...) and it must pre-compute the
values to be inserted.
*/
(*cache_insert_values)= true;
}
else
(*cache_insert_values)= false;
select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
if ((*cache_insert_values) && thd->lex->has_returning())
{
// Check if the table we're inserting into is also in RETURNING clause
TABLE_LIST *dup=
unique_table_in_insert_returning_subselect(thd, table_list,
thd->lex->returning());
if (dup)
{
if (dup != ERROR_TABLE)
update_non_unique_table_error(table_list, "INSERT", duplicate);
DBUG_RETURN(1);
}
}
}
/*
Only call prepare_for_posistion() if we are not performing a DELAYED
@ -3864,6 +3947,7 @@ int mysql_insert_select_prepare(THD *thd, select_result *sel_res)
int res;
LEX *lex= thd->lex;
SELECT_LEX *select_lex= lex->first_select_lex();
bool cache_insert_values= false;
DBUG_ENTER("mysql_insert_select_prepare");
/*
@ -3874,7 +3958,7 @@ int mysql_insert_select_prepare(THD *thd, select_result *sel_res)
if ((res= mysql_prepare_insert(thd, lex->query_tables, lex->field_list, 0,
lex->update_list, lex->value_list,
lex->duplicates,
&select_lex->where, TRUE)))
&select_lex->where, TRUE, &cache_insert_values)))
DBUG_RETURN(res);
/*

2
sql/sql_insert.h

@ -27,7 +27,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
List<Item> &fields, List_item *values,
List<Item> &update_fields,
List<Item> &update_values, enum_duplicates duplic,
COND **where, bool select_insert);
COND **where, bool select_insert, bool * const cache_results);
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag,

45
sql/sql_lex.cc

@ -11168,7 +11168,8 @@ st_select_lex::build_pushable_cond_for_having_pushdown(THD *thd, Item *cond)
Field_pair *get_corresponding_field_pair(Item *item,
List<Field_pair> pair_list)
{
DBUG_ASSERT(item->type() == Item::FIELD_ITEM ||
DBUG_ASSERT(item->type() == Item::DEFAULT_VALUE_ITEM ||
item->type() == Item::FIELD_ITEM ||
(item->type() == Item::REF_ITEM &&
((((Item_ref *) item)->ref_type() == Item_ref::VIEW_REF) ||
(((Item_ref *) item)->ref_type() == Item_ref::REF))));
@ -12151,6 +12152,48 @@ bool SELECT_LEX_UNIT::explainable() const
false;
}
/**
Find the real table in prepared SELECT tree
NOTE: all SELECT must be prepared (to have leaf table list).
NOTE: it looks only for real tables (not view or derived)
@param thd the current thread handle
@param db_name name of db of the table to look for
@param db_name name of db of the table to look for
@return first found table, NULL or ERROR_TABLE
*/
TABLE_LIST *SELECT_LEX::find_table(THD *thd,
const LEX_CSTRING *db_name,
const LEX_CSTRING *table_name)
{
uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
return NULL;
List_iterator_fast <TABLE_LIST> ti(leaf_tables);
TABLE_LIST *table;
while ((table= ti++))
{
if (cmp(&table->db, db_name) == 0 &&
cmp(&table->table_name, table_name) == 0)
return table;
}
for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit())
{
for (st_select_lex *sl= u->first_select(); sl; sl=sl->next_select())
{
if ((table= sl->find_table(thd, db_name, table_name)))
return table;
}
}
return NULL;
}
bool st_select_lex::is_query_topmost(THD *thd)
{

4
sql/sql_lex.h

@ -1686,6 +1686,10 @@ public:
void lex_start(LEX *plex);
bool is_unit_nest() { return (nest_flags & UNIT_NEST_FL); }
void mark_as_unit_nest() { nest_flags= UNIT_NEST_FL; }
TABLE_LIST *find_table(THD *thd,
const LEX_CSTRING *db_name,
const LEX_CSTRING *table_name);
};
typedef class st_select_lex SELECT_LEX;

4
sql/sql_prepare.cc

@ -1302,6 +1302,7 @@ static bool mysql_test_insert_common(Prepared_statement *stmt,
THD *thd= stmt->thd;
List_iterator_fast<List_item> its(values_list);
List_item *values;
bool cache_results= FALSE;
DBUG_ENTER("mysql_test_insert_common");
if (insert_precheck(thd, table_list))
@ -1334,7 +1335,8 @@ static bool mysql_test_insert_common(Prepared_statement *stmt,
}
if (mysql_prepare_insert(thd, table_list, fields, values, update_fields,
update_values, duplic, &unused_conds, FALSE))
update_values, duplic, &unused_conds, FALSE,
&cache_results))
goto error;
value_count= values->elements;

3
sql/sql_update.cc

@ -2343,7 +2343,8 @@ multi_update::initialize_tables(JOIN *join)
if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) &&
error_if_full_join(join)))
DBUG_RETURN(1);
if (join->implicit_grouping)
if (join->implicit_grouping ||
join->select_lex->have_window_funcs())
{
my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
DBUG_RETURN(1);

2
sql/table.h

@ -3026,6 +3026,8 @@ private:
ulonglong m_table_ref_version;
};
#define ERROR_TABLE ((TABLE_LIST*) 0x1)
class Item;
/*

5
support-files/mariadb.service.in

@ -51,11 +51,6 @@ Group=mysql
# These are enabled by default
AmbientCapabilities=CAP_IPC_LOCK
# CAP_DAC_OVERRIDE To allow auth_pam_tool (which is SUID root) to read /etc/shadow when it's chmod 0
# does nothing for non-root, not needed if /etc/shadow is u+r
# CAP_AUDIT_WRITE auth_pam_tool needs it on Debian for whatever reason
CapabilityBoundingSet=CAP_DAC_OVERRIDE CAP_AUDIT_WRITE
# PrivateDevices=true implies NoNewPrivileges=true and
# SUID auth_pam_tool suddenly doesn't do setuid anymore
PrivateDevices=false

5
support-files/mariadb@.service.in

@ -181,11 +181,6 @@ PrivateNetwork=false
# These are enabled by default
AmbientCapabilities=CAP_IPC_LOCK
# CAP_DAC_OVERRIDE To allow auth_pam_tool (which is SUID root) to read /etc/shadow when it's chmod 0
# does nothing for non-root, not needed if /etc/shadow is u+r
# CAP_AUDIT_WRITE auth_pam_tool needs it on Debian for whatever reason
CapabilityBoundingSet=CAP_DAC_OVERRIDE CAP_AUDIT_WRITE
# PrivateDevices=true implies NoNewPrivileges=true and
# SUID auth_pam_tool suddenly doesn't do setuid anymore
PrivateDevices=false

159
tests/mysql_client_test.c

@ -22629,6 +22629,164 @@ static void test_mdev_34958()
rc= mysql_query(mysql, "DROP TABLE t1, t2");
myquery(rc);
}
/* Server crash when inserting from derived table containing insert target table */
static void test_mdev_32086()
{
int rc;
MYSQL_STMT *stmt_insert;
MYSQL_BIND bind[2];
MYSQL_RES *result;
MYSQL_ROW row;
unsigned int vals[] = { 123, 124};
unsigned int vals_array_len = 2;
const char *insert_stmt= "\
insert into t1 values(\
(select 101+count(*)\
from\
(\
select dt2.id\
from (select id from t1) dt2, t1 t where t.id=dt2.id\
) dt\
where dt.id<1000\
), ?\
)";
/* Set up test's environment */
rc= mysql_query(mysql, "create table t1 (pk int, id int);");
myquery(rc);
rc= mysql_query(mysql, "insert into t1 values (2,2), (3,3), (4,4);");
myquery(rc);
stmt_insert = mysql_stmt_init(mysql);
if (!stmt_insert)
{
fprintf(stderr, "mysql_stmt_init failed: Error: %s\n",
mysql_error(mysql));
exit(1);
}
rc= mysql_stmt_prepare(stmt_insert, insert_stmt, strlen(insert_stmt));
if (rc)
{
fprintf(stderr, "mysql_stmt_prepare failed: %s\n",
mysql_stmt_error(stmt_insert));
exit(1);
}
memset(&bind[0], 0, sizeof(MYSQL_BIND));
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= vals;
rc= mysql_stmt_attr_set(stmt_insert, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
if (rc)
{
fprintf(stderr, "mysql_stmt_prepare failed: %s\n",
mysql_stmt_error(stmt_insert));
exit(1);
}
rc= mysql_stmt_bind_param(stmt_insert, bind);
if (rc)
{
fprintf(stderr, "mysql_stmt_bind_param failed: %s\n",
mysql_stmt_error(stmt_insert));
exit(1);
}
rc= mysql_stmt_execute(stmt_insert);
if (rc)
{
fprintf(stderr, "mysql_stmt_execute failed: %s\n",
mysql_stmt_error(stmt_insert));
exit(1);
}
/*
pk id
2 2
3 3
4 4
104 123
104 124
*/
rc= mysql_query(mysql, "select * from t1");
if (rc)
{
fprintf(stderr, "Query failed: %s\n", mysql_error(mysql));
}
result= mysql_store_result(mysql);
row= mysql_fetch_row(result);
DIE_UNLESS(atoi(row[0]) == 2 && atoi(row[1]) == 2);
row= mysql_fetch_row(result);
DIE_UNLESS(atoi(row[0]) == 3 && atoi(row[1]) == 3);
row= mysql_fetch_row(result);
DIE_UNLESS(atoi(row[0]) == 4 && atoi(row[1]) == 4);
row= mysql_fetch_row(result);
printf("\n %d, %d \n", atoi(row[0]), atoi(row[1]));
DIE_UNLESS(atoi(row[0]) == 104 && atoi(row[1]) == 123);
row= mysql_fetch_row(result);
printf("\n %d, %d \n", atoi(row[0]), atoi(row[1]));
DIE_UNLESS(atoi(row[0]) == 104 && atoi(row[1]) == 124);
row= mysql_fetch_row(result);
DIE_UNLESS(row == NULL);
mysql_free_result(result);
rc= mysql_stmt_execute(stmt_insert);
if (rc)
{
fprintf(stderr, "mysql_stmt_execute failed: %s\n",
mysql_stmt_error(stmt_insert));
exit(1);
}
/*
pk id
2 2
3 3
4 4
104 123
104 124
106 123
106 124
*/
rc= mysql_query(mysql, "select * from t1");
if (rc)
{
fprintf(stderr, "Query failed: %s\n", mysql_error(mysql));
}
result= mysql_store_result(mysql);
row= mysql_fetch_row(result);
DIE_UNLESS(atoi(row[0]) == 2 && atoi(row[1]) == 2);
row= mysql_fetch_row(result);
DIE_UNLESS(atoi(row[0]) == 3 && atoi(row[1]) == 3);
row= mysql_fetch_row(result);
DIE_UNLESS(atoi(row[0]) == 4 && atoi(row[1]) == 4);
row= mysql_fetch_row(result);
DIE_UNLESS(atoi(row[0]) == 104 && atoi(row[1]) == 123);
row= mysql_fetch_row(result);
DIE_UNLESS(atoi(row[0]) == 104 && atoi(row[1]) == 124);
row= mysql_fetch_row(result);
printf("\n %d, %d \n", atoi(row[0]), atoi(row[1]));
DIE_UNLESS(atoi(row[0]) == 106 && atoi(row[1]) == 123);
row= mysql_fetch_row(result);
printf("\n %d, %d \n", atoi(row[0]), atoi(row[1]));
DIE_UNLESS(atoi(row[0]) == 106 && atoi(row[1]) == 124);
row= mysql_fetch_row(result);
DIE_UNLESS(row == NULL);
mysql_free_result(result);
mysql_stmt_close(stmt_insert);
/* Clean up */
rc= mysql_query(mysql, "DROP TABLE t1");
myquery(rc);
}
#endif // EMBEDDED_LIBRARY
/*
@ -23115,6 +23273,7 @@ static struct my_tests_st my_tests[]= {
{ "test_mdev_34718_bd", test_mdev_34718_bd },
{ "test_mdev_34718_ad", test_mdev_34718_ad },
{ "test_mdev_34958", test_mdev_34958 },
{ "test_mdev_32086", test_mdev_32086 },
#endif
{ 0, 0 }
};

Loading…
Cancel
Save