Commit 687b7fd8 authored by Yuchen Pei's avatar Yuchen Pei

MDEV-25008 [poc] Estimate outer_lookup_keys later in mysql_delete and mysql_update

This helps make better choice of materialization vs in-to-exists
parent b8f92ade
......@@ -289,9 +289,9 @@ insert into t3 values (7), (5), (7), (3);
explain extended delete from t1 where a in (select pk from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00 Using where
2 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
2 MATERIALIZED t2 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index
Warnings:
Note 1003 /* select#1 */ delete from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on PRIMARY)))
Note 1003 /* select#1 */ delete from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`pk` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`pk`)))
delete from t1 where a in (select pk from t2);
select * from t1;
a
......
......@@ -243,7 +243,7 @@ rows_examined sql_text
4 UPDATE t1 SET a=a+sleep(.02) WHERE a>2
8 UPDATE t1 SET a=a+sleep(.02) ORDER BY a DESC
1 UPDATE t2 set b=b+sleep(.02) limit 1
4 UPDATE t1 SET a=a+sleep(.02) WHERE a in (SELECT b from t2)
6 UPDATE t1 SET a=a+sleep(.02) WHERE a in (SELECT b from t2)
6 DELETE FROM t1 WHERE a=a+sleep(.02) ORDER BY a LIMIT 2
disconnect con2;
connection default;
......
CREATE TABLE t1 (
id int NOT NULL PRIMARY KEY,
item_id varchar(100),
seller_name varchar(400),
variant varchar(400),
FULLTEXT KEY t1_serial_IDX (item_id,seller_name,variant)
)engine=innodb;
insert into t1 select seq,seq,seq,seq from seq_1_to_10000;
analyze format=json
DELETE FROM t1 WHERE id NOT IN
(SELECT m FROM (SELECT max(id) m FROM t1 GROUP BY item_id, seller_name, variant) AS innertable);
ANALYZE
{
"query_block": {
"select_id": 1,
"r_total_time_ms": 2162.554147,
"table": {
"delete": 1,
"table_name": "t1",
"access_type": "ALL",
"rows": 9803,
"r_rows": 10000,
"r_filtered": 0,
"r_total_time_ms": 476.8050484,
"attached_condition": "!(<in_optimizer>(t1.`id`,t1.`id` in (subquery#2)))"
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"r_loops": 1,
"r_total_time_ms": 1624.809141,
"table": {
"table_name": "<derived3>",
"access_type": "ALL",
"r_loops": 1,
"rows": 9803,
"r_rows": 10000,
"r_table_time_ms": 2.561216259,
"r_other_time_ms": 63.25389227,
"filtered": 100,
"r_filtered": 100,
"materialized": {
"query_block": {
"select_id": 3,
"r_loops": 1,
"r_total_time_ms": 1611.231086,
"filesort": {
"sort_key": "t1.item_id, t1.seller_name, t1.variant",
"r_loops": 1,
"r_total_time_ms": 27.04788886,
"r_used_priority_queue": false,
"r_output_rows": 10000,
"r_sort_passes": 1,
"r_buffer_size": "255Kb",
"r_sort_mode": "packed_sort_key,rowid",
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 9803,
"r_rows": 10000,
"r_table_time_ms": 633.6655697,
"r_other_time_ms": 898.0809074,
"filtered": 100,
"r_filtered": 100
}
}
}
}
}
}
}
}
]
}
}
analyze format=json
UPDATE t1 SET item_id="foo" WHERE id NOT IN
(SELECT m FROM (SELECT max(id) m FROM t1 GROUP BY item_id, seller_name, variant) AS innertable);
ANALYZE
{
"query_block": {
"select_id": 1,
"r_total_time_ms": 1741.85834,
"table": {
"update": 1,
"table_name": "t1",
"access_type": "index",
"key": "PRIMARY",
"key_length": "",
"used_key_parts": ["id"],
"rows": 9803,
"r_rows": 10000,
"r_filtered": 0,
"r_total_time_ms": 376.8910252,
"attached_condition": "!(<in_optimizer>(t1.`id`,t1.`id` in (subquery#2)))"
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"r_loops": 1,
"r_total_time_ms": 1311.436222,
"table": {
"table_name": "<derived3>",
"access_type": "ALL",
"r_loops": 1,
"rows": 9803,
"r_rows": 10000,
"r_table_time_ms": 2.477005695,
"r_other_time_ms": 60.04917769,
"filtered": 100,
"r_filtered": 100,
"materialized": {
"query_block": {
"select_id": 3,
"r_loops": 1,
"r_total_time_ms": 1298.122699,
"filesort": {
"sort_key": "t1.item_id, t1.seller_name, t1.variant",
"r_loops": 1,
"r_total_time_ms": 26.74490005,
"r_used_priority_queue": false,
"r_output_rows": 10000,
"r_sort_passes": 1,
"r_buffer_size": "255Kb",
"r_sort_mode": "packed_sort_key,rowid",
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 9803,
"r_rows": 10000,
"r_table_time_ms": 430.103423,
"r_other_time_ms": 791.9229759,
"filtered": 100,
"r_filtered": 100
}
}
}
}
}
}
}
}
]
}
}
drop table t1;
--source include/have_innodb.inc
--source include/have_sequence.inc
CREATE TABLE t1 (
id int NOT NULL PRIMARY KEY,
item_id varchar(100),
seller_name varchar(400),
variant varchar(400),
FULLTEXT KEY t1_serial_IDX (item_id,seller_name,variant)
)engine=innodb;
insert into t1 select seq,seq,seq,seq from seq_1_to_10000;
analyze format=json
DELETE FROM t1 WHERE id NOT IN
(SELECT m FROM (SELECT max(id) m FROM t1 GROUP BY item_id, seller_name, variant) AS innertable);
analyze format=json
UPDATE t1 SET item_id="foo" WHERE id NOT IN
(SELECT m FROM (SELECT max(id) m FROM t1 GROUP BY item_id, seller_name, variant) AS innertable);
drop table t1;
......@@ -251,7 +251,7 @@ Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be
EXPLAIN UPDATE t1 SET a = 10 WHERE 1 IN (SELECT 1 FROM t2 WHERE t2.b < 3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE 1 IN (SELECT 1 FROM t2 WHERE t2.b < 3);
......@@ -1027,15 +1027,15 @@ Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be
EXPLAIN UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED UPDATE t1 SET a = 10 WHERE a IN (SELECT a FROM t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
Note 1003 /* select#1 */ update `test`.`t1` set `test`.`t1`.`a` = 10 where <in_optimizer>(`test`.`t1`.`a`,<exists>(/* select#2 */ select `test`.`t2`.`a` from `test`.`t2` where <cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`))
Note 1003 /* select#1 */ update `test`.`t1` set `test`.`t1`.`a` = 10 where <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`a` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`a`)))
# Status of EXPLAIN EXTENDED query
Variable_name Value
Handler_read_key 4
......@@ -1059,8 +1059,8 @@ Handler_read_key 7
Handler_read_rnd_next 8
# Status of testing query execution:
Variable_name Value
Handler_read_key 4
Handler_read_rnd_next 10
Handler_read_key 7
Handler_read_rnd_next 8
Handler_update 3
DROP TABLE t1, t2;
......
......@@ -172,7 +172,7 @@ SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM v1) OR a = b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index a a 5 NULL 2 Using where; Using index
1 PRIMARY t3 ref b b 5 test.t2.a 2 Using index
2 SUBQUERY t1 const PRIMARY,a PRIMARY 4 const 1 Using where
2 MATERIALIZED t1 index PRIMARY,a a 5 NULL 2 Using index
SELECT * FROM t2,t3 WHERE (2,9) IN (SELECT DISTINCT a,pk FROM v1) OR a = b;
pk a b
0 4 4
......
......@@ -2757,8 +2757,16 @@ select 1
from t2 join t1 on
('i','w') not in (select t1.v1,t4.v2 from t4,t1,t3 where t3.v2 = t1.v1) LIMIT ROWS EXAMINED 500;
1
Warnings:
Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 500. The query result may be incomplete
1
1
1
1
1
1
1
1
1
1
SET join_cache_level= @save_join_cache_level;
DROP TABLE t1,t2,t3,t4;
#
......@@ -3101,10 +3109,10 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t2.b 1 100.00
2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
4 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 100.00
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from <materialize> (/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) join `test`.`t2` where `<subquery2>`.`c` = `test`.`t2`.`b`
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from <materialize> (/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1) in ( <materialize> (/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` ), <primary_index_lookup>(<cache>(`test`.`t1`.`a`) in <temporary table> on distinct_key where <cache>(`test`.`t1`.`a`) = `<subquery4>`.`d`)))) join `test`.`t2` where `<subquery2>`.`c` = `test`.`t2`.`b`
select b from t2
where b in (select c from t3
group by (select a from t1 where a = 1) in (select d from t4));
......@@ -3116,10 +3124,10 @@ group by (select a from t1 where a = 1) in
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
4 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 100.00
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <nop>(<in_optimizer>(`test`.`t2`.`b`,<min>(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) <= <cache>(`test`.`t2`.`b`)))
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <nop>(<in_optimizer>(`test`.`t2`.`b`,<min>(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1) in ( <materialize> (/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` ), <primary_index_lookup>(<cache>(`test`.`t1`.`a`) in <temporary table> on distinct_key where <cache>(`test`.`t1`.`a`) = `<subquery4>`.`d`)))) <= <cache>(`test`.`t2`.`b`)))
select b from t2
where b >= any (select c from t3
group by (select a from t1 where a = 1) in
......@@ -3132,10 +3140,10 @@ group by (select a from t1 where a = 1) in
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
4 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 100.00
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <not>(<in_optimizer>(`test`.`t2`.`b`,<min>(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) < <cache>(`test`.`t2`.`b`)))
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <not>(<in_optimizer>(`test`.`t2`.`b`,<min>(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1) in ( <materialize> (/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` ), <primary_index_lookup>(<cache>(`test`.`t1`.`a`) in <temporary table> on distinct_key where <cache>(`test`.`t1`.`a`) = `<subquery4>`.`d`)))) < <cache>(`test`.`t2`.`b`)))
select b from t2
where b <= all (select c from t3
group by (select a from t1 where a = 1) in
......@@ -3261,19 +3269,17 @@ EXPLAIN
"access_type": "ALL",
"rows": 3,
"filtered": 100,
"attached_condition": "t1.a = <cache>((<in_optimizer>((subquery#2),<exists>(subquery#3))) + 1)"
"attached_condition": "t1.a = <cache>((<in_optimizer>((subquery#2),(subquery#2) in (subquery#3))) + 1)"
},
"subqueries": [
{
"query_block": {
"select_id": 3,
"having_condition": "trigcond(t3.c is null)",
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "trigcond(1 = t3.c or t3.c is null)"
"filtered": 100
}
}
},
......
......@@ -353,9 +353,9 @@ WHERE t.a IN (SELECT b FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
3 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
3 MATERIALIZED t1 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t2` where <expr_cache><0>(<in_optimizer>(0,<exists>(/* select#3 */ select 0 from dual where <cache>(0) = 0)))
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t2` where <expr_cache><0>(<in_optimizer>(0,0 in ( <materialize> (/* select#3 */ select 0 from dual ), <primary_index_lookup>(0 in <temporary table> on distinct_key where 0 = `<subquery3>`.`b`))))
SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
WHERE t.a IN (SELECT b FROM t1);
a a b
......@@ -366,9 +366,9 @@ WHERE t.a IN (SELECT b FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
2 MATERIALIZED t1 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t2` where <expr_cache><0>(<in_optimizer>(0,<exists>(/* select#2 */ select 0 from dual where <cache>(0) = 0)))
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t2` where <expr_cache><0>(<in_optimizer>(0,0 in ( <materialize> (/* select#2 */ select 0 from dual ), <primary_index_lookup>(0 in <temporary table> on distinct_key where 0 = `<subquery2>`.`b`))))
DROP VIEW v1;
DROP TABLE t1,t2;
#
......
......@@ -4600,7 +4600,7 @@ Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` where 1
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
Warnings:
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` where 0
SET join_cache_level=@save_join_cache_level;
......
......@@ -794,7 +794,7 @@ EXPLAIN SELECT col_int_nokey FROM t2
WHERE ('h', 0) NOT IN ( SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2
3 DERIVED t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where
DROP TABLE t1,t2,h1;
DROP VIEW v1;
......
......@@ -2629,7 +2629,6 @@ static int fill_used_fields_bitmap(PARAM *param)
In the table struct the following information is updated:
quick_keys - Which keys can be used
quick_rows - How many rows the key matches
opt_range_condition_rows - E(# rows that will satisfy the table condition)
IMPLEMENTATION
......
......@@ -6606,11 +6606,8 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
}
else
{
/*
TODO: outer_join can be NULL for DELETE statements.
How to compute its cost?
*/
outer_lookup_keys= 1;
outer_lookup_keys=
(double) unit->outer_select()->table_list.first->table->stat_records();
}
/*
......
......@@ -404,8 +404,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
}
}
/* Apply the IN=>EXISTS transformation to all subqueries and optimize them. */
if (select_lex->optimize_unflattened_subqueries(false))
if (select_lex->optimize_unflattened_subqueries(true))
DBUG_RETURN(TRUE);
const_cond= (!conds || conds->const_item());
......@@ -534,6 +533,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(0); // Nothing to delete
}
if (select_lex->optimize_unflattened_subqueries(false))
DBUG_RETURN(TRUE);
/* If running in safe sql mode, don't allow updates without keys */
if (!select || !select->quick)
{
......
......@@ -535,7 +535,7 @@ int mysql_update(THD *thd,
switch_to_nullable_trigger_fields(values, table);
/* Apply the IN=>EXISTS transformation to all subqueries and optimize them */
if (select_lex->optimize_unflattened_subqueries(false))
if (select_lex->optimize_unflattened_subqueries(true))
DBUG_RETURN(TRUE);
if (select_lex->inner_refs_list.elements &&
......@@ -602,6 +602,9 @@ int mysql_update(THD *thd,
DBUG_RETURN(0);
}
if (select_lex->optimize_unflattened_subqueries(false))
DBUG_RETURN(TRUE);
/* If running in safe sql mode, don't allow updates without keys */
if (!select || !select->quick)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment