Skip to content

Commit 15f94b3

Browse files
author
Chaithra Gopalareddy
committed
Bug#35689804: Depending on the data inserted, the results of the
PREPARE and the general query run are different. When a condition which is being pushed down to a derived table is cloned and if any of the expressions in the condition have parameters in the underlying derived table, for some cases, type propagation was not happening (even after the call to fix_fields()). It is expected that a call to propagate_type() is made for such cases. This was missed. So we fix this by making a call to propagate_type() now. Change-Id: I1191aaa3f095dd54451667631678260c0169e764
1 parent a1d235e commit 15f94b3

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

mysql-test/r/derived_condition_pushdown.result

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,3 +2225,60 @@ SELECT * FROM (SELECT f1 FROM t1 UNION SELECT f1 FROM t1) AS dt WHERE f1 = 'å';
22252225
f1
22262226
å
22272227
DROP TABLE t1;
2228+
#
2229+
# Bug#35689804: Depending on the data inserted, the results of
2230+
# the PREPARE and the general query run are different.
2231+
#
2232+
CREATE TABLE t1 (f1 INTEGER, f2 VARCHAR(30) COLLATE utf8mb4_bin NOT NULL);
2233+
INSERT INTO t1(f2) VALUES ('680519363848');
2234+
SET @a1 = 'Y';
2235+
SET @a2 = 'Y';
2236+
SET @a3 = 'N';
2237+
SET @a4 = 'Y';
2238+
SET @a5 = 'Y';
2239+
SET @a6 = 'Y';
2240+
SET @a7 = 'N';
2241+
SET @a8 = 'Y';
2242+
SET @a9 = 'Y';
2243+
PREPARE stmt FROM "SELECT *
2244+
FROM (SELECT IF(f2 = ?, ?, CASE WHEN f2 IS NULL THEN ? ELSE ? END) AS case_f
2245+
FROM t1
2246+
UNION ALL
2247+
SELECT IF(f2 = ?, ?, CASE WHEN f2 IS NULL THEN ? ELSE ? END) AS case_f
2248+
FROM t1) AS dt1
2249+
WHERE case_f = ?";
2250+
EXECUTE stmt USING @a1, @a2, @a3, @a4, @a5, @a6, @a7, @a8, @a9;
2251+
case_f
2252+
Y
2253+
Y
2254+
PREPARE stmt FROM "EXPLAIN FORMAT=tree SELECT *
2255+
FROM (SELECT IF(f2 = ?, ?, CASE WHEN f2 IS NULL THEN ? ELSE ? END) AS case_f
2256+
FROM t1
2257+
UNION ALL
2258+
SELECT IF(f2 = ?, ?, CASE WHEN f2 IS NULL THEN ? ELSE ? END) AS case_f
2259+
FROM t1) AS dt1
2260+
WHERE case_f = ?";
2261+
EXECUTE stmt USING @a1, @a2, @a3, @a4, @a5, @a6, @a7, @a8, @a9;
2262+
EXPLAIN
2263+
-> Table scan on dt1 (rows=2)
2264+
-> Union all materialize (rows=2)
2265+
-> Filter: (if((t1.f2 = 'Y'),'Y',<cache>((case when (t1.f2 is null) then 'N' else 'Y' end))) = 'Y') (rows=1)
2266+
-> Table scan on t1 (rows=1)
2267+
-> Filter: (if((t1.f2 = 'Y'),'Y',<cache>((case when (t1.f2 is null) then 'N' else 'Y' end))) = 'Y') (rows=1)
2268+
-> Table scan on t1 (rows=1)
2269+
2270+
SET optimizer_switch="derived_merge=off";
2271+
SET @a1 = 'Y';
2272+
PREPARE stmt FROM "SELECT * FROM (SELECT ? AS case_f FROM t1) as dt1 WHERE case_f = 'Y'";
2273+
EXECUTE stmt USING @a1;
2274+
case_f
2275+
Y
2276+
PREPARE stmt FROM "EXPLAIN FORMAT=tree SELECT * FROM (SELECT ? AS case_f FROM t1) as dt1 WHERE case_f = 'Y'";
2277+
EXECUTE stmt USING @a1;
2278+
EXPLAIN
2279+
-> Table scan on dt1 (rows=1)
2280+
-> Materialize (rows=1)
2281+
-> Table scan on t1 (rows=1)
2282+
2283+
SET optimizer_switch=default;
2284+
DROP TABLE t1;

mysql-test/t/derived_condition_pushdown.test

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,3 +1421,54 @@ INSERT INTO t1 VALUES('å');
14211421
SELECT * FROM (SELECT f1 FROM t1 UNION SELECT f1 FROM t1) AS dt WHERE f1 = 'å';
14221422

14231423
DROP TABLE t1;
1424+
1425+
--echo #
1426+
--echo # Bug#35689804: Depending on the data inserted, the results of
1427+
--echo # the PREPARE and the general query run are different.
1428+
--echo #
1429+
1430+
CREATE TABLE t1 (f1 INTEGER, f2 VARCHAR(30) COLLATE utf8mb4_bin NOT NULL);
1431+
INSERT INTO t1(f2) VALUES ('680519363848');
1432+
1433+
# Query from the bug report
1434+
let query =
1435+
SELECT *
1436+
FROM (SELECT IF(f2 = ?, ?, CASE WHEN f2 IS NULL THEN ? ELSE ? END) AS case_f
1437+
FROM t1
1438+
UNION ALL
1439+
SELECT IF(f2 = ?, ?, CASE WHEN f2 IS NULL THEN ? ELSE ? END) AS case_f
1440+
FROM t1) AS dt1
1441+
WHERE case_f = ?;
1442+
1443+
SET @a1 = 'Y';
1444+
SET @a2 = 'Y';
1445+
SET @a3 = 'N';
1446+
SET @a4 = 'Y';
1447+
SET @a5 = 'Y';
1448+
SET @a6 = 'Y';
1449+
SET @a7 = 'N';
1450+
SET @a8 = 'Y';
1451+
SET @a9 = 'Y';
1452+
1453+
eval PREPARE stmt FROM "$query";
1454+
eval EXECUTE stmt USING @a1, @a2, @a3, @a4, @a5, @a6, @a7, @a8, @a9;
1455+
eval PREPARE stmt FROM "EXPLAIN FORMAT=tree $query";
1456+
--replace_regex $elide_costs
1457+
--skip_if_hypergraph # Depends on the query plan.
1458+
eval EXECUTE stmt USING @a1, @a2, @a3, @a4, @a5, @a6, @a7, @a8, @a9;
1459+
1460+
# Simplified query
1461+
SET optimizer_switch="derived_merge=off";
1462+
let query =
1463+
SELECT * FROM (SELECT ? AS case_f FROM t1) as dt1 WHERE case_f = 'Y';
1464+
SET @a1 = 'Y';
1465+
eval PREPARE stmt FROM "$query";
1466+
eval EXECUTE stmt USING @a1;
1467+
eval PREPARE stmt FROM "EXPLAIN FORMAT=tree $query";
1468+
--replace_regex $elide_costs
1469+
--skip_if_hypergraph # Depends on the query plan.
1470+
eval EXECUTE stmt USING @a1;
1471+
1472+
SET optimizer_switch=default;
1473+
1474+
DROP TABLE t1;

sql/sql_derived.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,10 @@ Item *resolve_expression(THD *thd, Item *item, Query_block *query_block) {
677677
<< thd->lex->current_query_block()->nest_level;
678678

679679
bool ret = item->fix_fields(thd, &item);
680+
// For items with params, propagate the default data type.
681+
if (item->data_type() == MYSQL_TYPE_INVALID &&
682+
item->propagate_type(thd, item->default_data_type()))
683+
return nullptr;
680684
// Restore original state back
681685
thd->want_privilege = save_old_privilege;
682686
thd->lex->set_current_query_block(saved_current_query_block);

0 commit comments

Comments
 (0)