Skip to content

Commit 057f5c9

Browse files
Chaithra Gopalareddynawazn
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 42112a7 commit 057f5c9

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
@@ -6008,13 +6008,7 @@ bool Query_block::replace_item_in_expression(Item **expr, bool was_hidden,
60086008
// Save our original item name at this level
60096009
auto saved_item_name =
60106010
(*expr)->orig_name.is_set() ? (*expr)->orig_name : (*expr)->item_name;
6011-
// Replace in base_ref_items
6012-
for (size_t i = 0; i < fields.size(); i++) {
6013-
if (base_ref_items[i] == *expr) {
6014-
base_ref_items[i] = new_item;
6015-
break;
6016-
}
6017-
}
6011+
replace_referenced_item(*expr, new_item);
60186012
// Replace in fields
60196013
const auto it = find(fields.begin(), fields.end(), new_item);
60206014
if (it == fields.end()) {

0 commit comments

Comments
 (0)