Skip to content

Commit eab3609

Browse files
Chaithra Gopalareddydahlerlend
authored andcommitted
Bug#35231475: Segmentation fault in Item_ref::real_item with
CTE query When transforming a subquery to a derived table, if a new field is added, it should increment the reference count. However, this was not done when a view reference was replaced with a new field. This made the field referenced to be deleted when it was wrongly concluded that the field is unused. Problem arises because the same underlying field is referenced by all the view references created for that field. For a query like this one: WITH cte AS (SELECT (SELECT COUNT(f1) FROM t1), COUNT(dt.f2), dt.f3 FROM (SELECT * FROM t1) AS dt) SELECT * FROM cte; it gets transformed into select `derived_2_6`.`COUNT(f1)` AS `(SELECT COUNT(f1) FROM t1)`, `derived_2_5`.`COUNT(dt.f2)` AS `COUNT(dt.f2)`, `derived_2_5`.`Name_exp_1` AS `f3` from (select count(`test`.`t1`.`f2`) AS `COUNT(dt.f2)`, `test`.`t1`.`f3` AS `Name_exp_1` from `test`.`t1`) `derived_2_5` left join (select count(`test`.`t1`.`f1`) AS `COUNT(f1)` from `test`.`t1`) `derived_2_6` on(true) where true; The expression "Name_exp_1" is a view reference because the derived table "dt" gets merged. When this is replaced with an "Item_field" during subquery to derived transformation, we do not increment the reference count. Later, we see that the derived table "cte" which is resolved after the creation of the derived tables "derived_2_5" and "derived_2_6" gets merged. While deleting the un-used fields for this derived table, we delete the field "f3" even though it is still used in the query. Fix is to correctly increment the ref count for the new field created. Change-Id: I4035d86990e3cfb099144b7f304b864eb0451f5d
1 parent 83df4d3 commit eab3609

File tree

1 file changed

+1
-7
lines changed

1 file changed

+1
-7
lines changed

sql/sql_resolver.cc

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5731,13 +5731,7 @@ bool Query_block::replace_item_in_expression(Item **expr, bool was_hidden,
57315731
// Save our original item name at this level
57325732
auto saved_item_name =
57335733
(*expr)->orig_name.is_set() ? (*expr)->orig_name : (*expr)->item_name;
5734-
// Replace in base_ref_items
5735-
for (size_t i = 0; i < fields.size(); i++) {
5736-
if (base_ref_items[i] == *expr) {
5737-
base_ref_items[i] = new_item;
5738-
break;
5739-
}
5740-
}
5734+
replace_referenced_item(*expr, new_item);
57415735
// Replace in fields
57425736
const auto it = find(fields.begin(), fields.end(), new_item);
57435737
if (it == fields.end()) {

0 commit comments

Comments
 (0)