Skip to content

Commit 74f90ab

Browse files
Chaithra Gopalareddyzmur
authored andcommitted
Bug#36593235: MySQL server 8.3.0 crashes at
Item_rollup_sum_switcher::current_arg Backport to 5.7.49. Problem is seen when a subquery containing a aggregate function with rollup is part of a row value comparator and if there were no rows returned from the subquery. cmp_item_row::store_value() evaluates the subquery and goes ahead to store the values of the expressions in the comparator without checking if the result was assigned for the subquery. This leads to evaluation of a rollup expression when it is marked as not to be evaluated as aggregation was completed earlier. For the failing query, AggregateIterator() does evaluate the expressions. However HAVING clause does not qualify the rows. So the result of the aggregation is never cached. If a subquery returns empty result, bring_value() would set the "null_value" to true. cmp_item_row::store_value() now stores the value of the underlying comparator objects only when the result is not null. Else the result is set to null. Change-Id: I7bb17e621f1e5b439f6284c279ce69b80dace237
1 parent c198c19 commit 74f90ab

File tree

2 files changed

+37
-13
lines changed

2 files changed

+37
-13
lines changed

sql/item_cmpfunc.cc

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
1+
/* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -4929,12 +4929,20 @@ void cmp_item_row::store_value(Item *item)
49294929
assert(comparators);
49304930
if (comparators)
49314931
{
4932-
item->bring_value();
49334932
item->null_value= 0;
4934-
for (uint i= 0; i < n; i++)
4933+
item->bring_value();
4934+
if (item->null_value)
49354935
{
4936-
comparators[i]->store_value(item->element_index(i));
4937-
item->null_value|= item->element_index(i)->null_value;
4936+
set_null_value(/*nv=*/true);
4937+
}
4938+
else
4939+
{
4940+
item->null_value= false;
4941+
for (uint i= 0; i < n; i++)
4942+
{
4943+
comparators[i]->store_value(item->element_index(i));
4944+
item->null_value|= item->element_index(i)->null_value;
4945+
}
49384946
}
49394947
}
49404948
DBUG_VOID_RETURN;
@@ -4952,15 +4960,23 @@ void cmp_item_row::store_value_by_template(cmp_item *t, Item *item)
49524960
n= tmpl->n;
49534961
if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
49544962
{
4955-
item->bring_value();
49564963
item->null_value= 0;
4957-
for (uint i=0; i < n; i++)
4964+
item->bring_value();
4965+
if (item->null_value)
49584966
{
4959-
if (!(comparators[i]= tmpl->comparators[i]->make_same()))
4960-
break; // new failed
4961-
comparators[i]->store_value_by_template(tmpl->comparators[i],
4962-
item->element_index(i));
4963-
item->null_value|= item->element_index(i)->null_value;
4967+
set_null_value(/*nv=*/true);
4968+
}
4969+
else
4970+
{
4971+
item->null_value= false;
4972+
for (uint i= 0; i < n; i++)
4973+
{
4974+
if (!(comparators[i]= tmpl->comparators[i]->make_same()))
4975+
break; // new failed
4976+
comparators[i]->store_value_by_template(tmpl->comparators[i],
4977+
item->element_index(i));
4978+
item->null_value|= item->element_index(i)->null_value;
4979+
}
49644980
}
49654981
}
49664982
}

sql/item_cmpfunc.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef ITEM_CMPFUNC_INCLUDED
22
#define ITEM_CMPFUNC_INCLUDED
33

4-
/* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
4+
/* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
55
66
This program is free software; you can redistribute it and/or modify
77
it under the terms of the GNU General Public License, version 2.0,
@@ -1419,6 +1419,7 @@ class cmp_item :public Sql_alloc
14191419
{
14201420
store_value(item);
14211421
}
1422+
virtual void set_null_value(bool nv) = 0;
14221423
};
14231424

14241425
/// cmp_item which stores a scalar (i.e. non-ROW).
@@ -1768,6 +1769,13 @@ class cmp_item_row :public cmp_item
17681769
int compare(const cmp_item *arg) const;
17691770
cmp_item *make_same();
17701771
void store_value_by_template(cmp_item *tmpl, Item *);
1772+
void set_null_value(bool nv)
1773+
{
1774+
for (uint i= 0; i < n; i++)
1775+
{
1776+
comparators[i]->set_null_value(nv);
1777+
}
1778+
}
17711779
friend void Item_func_in::fix_length_and_dec();
17721780
};
17731781

0 commit comments

Comments
 (0)