Skip to content

Commit 35059a8

Browse files
committed
Bug#21753180: handle_fatal_signal (sig=11) in my_strtod_int
This problem occurs on a query on a table with this definition: CREATE TABLE t1(a int, b blob, c blob); INSERT INTO t1 VALUES(1,2,1),(2,4,1); The query is: SELECT a, (SELECT SUM(a + c) FROM (SELECT b as c FROM t1) AS v1) FROM t1; We see there is an implicit grouping because of the SUM expression. When analyzing the SUM expression, the aggregation query block should be calculated as the inner-most query block that the individual columns are resolved from. "a" refers to t1, so it may be aggregated in the outer query block. "c" refers to v1, so it must be aggregated in the inner query block. Thus, the SUM expression should be aggregated in the inner query block, and the outer query block should be non-aggregated. However, Item_field::fix_fields() does not calculate this correctly. The "c" field will be wrapped in an Item_direct_view_ref object and the condition in this statement will be true (line 5943). if (from_field == view_ref_found) return false; It is correct that we shall not call set_field() for such items, but missing the calculation of in_sum_func->max_arg_level further down means that the aggregation level for the SUM expression is calculated to be the outer query block. Somehow, this causes the failure reported in the bug. This problem goes away when calculating max_arg_level also for fields that are resolved from views and derived tables.
1 parent fc21061 commit 35059a8

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

mysql-test/r/group_by.result

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3199,3 +3199,24 @@ a MAX(b)
31993199
9 10
32003200
10 10
32013201
DROP TABLE t0, t1;
3202+
# Bug#21753180: handle_fatal_signal (sig=11) in my_strtod_int
3203+
CREATE TABLE t1(
3204+
a INTEGER,
3205+
b BLOB(1),
3206+
c BLOB(1),
3207+
PRIMARY KEY(a,b(1)),
3208+
UNIQUE KEY (a,c(1))
3209+
);
3210+
INSERT INTO t1 VALUES(1,2,1),(2,4,1);
3211+
explain SELECT a, (SELECT SUM(a + c) FROM (SELECT b as c FROM t1) AS v1) FROM t1;
3212+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3213+
1 PRIMARY t1 NULL index NULL PRIMARY 7 NULL 2 100.00 Using index
3214+
2 DEPENDENT SUBQUERY t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
3215+
Warnings:
3216+
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
3217+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,(/* select#2 */ select sum((`test`.`t1`.`a` + `test`.`t1`.`b`)) from `test`.`t1`) AS `(SELECT SUM(a + c) FROM (SELECT b as c FROM t1) AS v1)` from `test`.`t1`
3218+
SELECT a, (SELECT SUM(a + c) FROM (SELECT b as c FROM t1) AS v1) FROM t1;
3219+
a (SELECT SUM(a + c) FROM (SELECT b as c FROM t1) AS v1)
3220+
1 8
3221+
2 10
3222+
DROP TABLE t1;

mysql-test/t/group_by.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2385,3 +2385,24 @@ eval EXPLAIN $query;
23852385
eval $query;
23862386

23872387
DROP TABLE t0, t1;
2388+
2389+
--echo # Bug#21753180: handle_fatal_signal (sig=11) in my_strtod_int
2390+
2391+
CREATE TABLE t1(
2392+
a INTEGER,
2393+
b BLOB(1),
2394+
c BLOB(1),
2395+
PRIMARY KEY(a,b(1)),
2396+
UNIQUE KEY (a,c(1))
2397+
);
2398+
2399+
INSERT INTO t1 VALUES(1,2,1),(2,4,1);
2400+
2401+
let $query=
2402+
SELECT a, (SELECT SUM(a + c) FROM (SELECT b as c FROM t1) AS v1) FROM t1;
2403+
2404+
eval explain $query;
2405+
2406+
eval $query;
2407+
2408+
DROP TABLE t1;

sql/item.cc

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5921,25 +5921,24 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
59215921
}
59225922

59235923
/*
5924-
if it is not expression from merged VIEW we will set this field.
5925-
5926-
We can leave expression substituted from view for next PS/SP rexecution
5927-
(i.e. do not register this substitution for reverting on cleanup()
5928-
(register_item_tree_changing())), because this subtree will be
5929-
fix_field'ed during setup_tables()->setup_underlying() (i.e. before
5930-
all other expressions of query, and references on tables which do
5931-
not present in query will not make problems.
5932-
5933-
Also we suppose that view can't be changed during PS/SP life.
5924+
If inside an aggregation function, set the correct aggregation level.
5925+
Even if a view reference is found, the level is still the query block
5926+
associated with the context of the current item:
59345927
*/
5935-
if (from_field == view_ref_found)
5936-
return false;
5937-
5938-
set_field(from_field);
5928+
DBUG_ASSERT(from_field != view_ref_found ||
5929+
context->select_lex ==
5930+
dynamic_cast<Item_ident *>(*reference)->context->select_lex);
59395931
if (thd->lex->in_sum_func &&
59405932
thd->lex->in_sum_func->nest_level == context->select_lex->nest_level)
59415933
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
59425934
context->select_lex->nest_level);
5935+
5936+
// If view column reference, Item in *reference is completely resolved:
5937+
if (from_field == view_ref_found)
5938+
return false;
5939+
5940+
// Not view reference, not outer reference; need to set properties:
5941+
set_field(from_field);
59435942
}
59445943
else if (thd->mark_used_columns != MARK_COLUMNS_NONE)
59455944
{

0 commit comments

Comments
 (0)