Skip to content

Commit

Permalink
Revert "MDEV-24454 Crash at change_item_tree"
Browse files Browse the repository at this point in the history
This patch reverts the fixes of the bugs MDEV-24454 and MDEV-25631 from
the commit 3690c54.
It leaves the changes in plugin/feedback/feedback.cc and corresponding
test files introduced in this commit intact.

Proper fixes for the bug MDEV-24454 and MDEV-25631 will follow immediately.
  • Loading branch information
igorbabaev committed Jan 10, 2022
1 parent 80d3326 commit d6ee351
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 173 deletions.
43 changes: 0 additions & 43 deletions mysql-test/r/view.result
Original file line number Diff line number Diff line change
Expand Up @@ -6833,49 +6833,6 @@ sum(z)
DROP TABLE t1;
DROP VIEW v1;
#
# MDEV-24454: Crash at change_item_tree
#
CREATE TABLE t1(f0 INT);
CREATE VIEW v1 AS
SELECT
f0 AS f1
FROM t1;
CREATE VIEW v2 AS
SELECT
(SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ')
FROM v1 n) AS f2,
GROUP_CONCAT('' SEPARATOR ', ') AS f3
FROM v1;
CREATE VIEW v3 AS
SELECT 1 as f4 FROM v2;
CREATE PROCEDURE p1()
SELECT * FROM v3;
CALL p1();
f4
1
CALL p1();
f4
1
drop procedure p1;
drop view v1,v2,v3;
drop table t1;
#
# MDEV-25631: Crash in st_select_lex::mark_as_dependent with
# VIEW, aggregate and subquery
#
CREATE TABLE t1 (i1 int);
insert into t1 values (1),(2),(3);
CREATE VIEW v1 AS
SELECT t1.i1 FROM (t1 a JOIN t1 ON (t1.i1 = (SELECT t1.i1 FROM t1 b)));
SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
ERROR 21000: Subquery returns more than 1 row
delete from t1 where i1 > 1;
SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
1
1
drop view v1;
drop table t1;
#
# MDEV-26299: Some views force server (and mysqldump) to generate
# invalid SQL for their definitions
#
Expand Down
50 changes: 0 additions & 50 deletions mysql-test/t/view.test
Original file line number Diff line number Diff line change
Expand Up @@ -6559,56 +6559,6 @@ SELECT sum(z) FROM v1;
DROP TABLE t1;
DROP VIEW v1;

--echo #
--echo # MDEV-24454: Crash at change_item_tree
--echo #

CREATE TABLE t1(f0 INT);

CREATE VIEW v1 AS
SELECT
f0 AS f1
FROM t1;

CREATE VIEW v2 AS
SELECT
(SELECT GROUP_CONCAT(v1.f1 SEPARATOR ', ')
FROM v1 n) AS f2,
GROUP_CONCAT('' SEPARATOR ', ') AS f3
FROM v1;

CREATE VIEW v3 AS
SELECT 1 as f4 FROM v2;

CREATE PROCEDURE p1()
SELECT * FROM v3;

CALL p1();
CALL p1();

drop procedure p1;
drop view v1,v2,v3;
drop table t1;

--echo #
--echo # MDEV-25631: Crash in st_select_lex::mark_as_dependent with
--echo # VIEW, aggregate and subquery
--echo #

CREATE TABLE t1 (i1 int);
insert into t1 values (1),(2),(3); #not important
CREATE VIEW v1 AS
SELECT t1.i1 FROM (t1 a JOIN t1 ON (t1.i1 = (SELECT t1.i1 FROM t1 b)));

--error ER_SUBQUERY_NO_1_ROW
SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
delete from t1 where i1 > 1;
SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;

drop view v1;
drop table t1;


--echo #
--echo # MDEV-26299: Some views force server (and mysqldump) to generate
--echo # invalid SQL for their definitions
Expand Down
104 changes: 34 additions & 70 deletions sql/item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,11 @@ bool cmp_items(Item *a, Item *b)
/**
Set max_sum_func_level if it is needed
*/
inline void set_max_sum_func_level(SELECT_LEX *select)
inline void set_max_sum_func_level(THD *thd, SELECT_LEX *select)
{
LEX *lex_s= select->parent_lex;
if (lex_s->in_sum_func &&
lex_s->in_sum_func->nest_level >= select->nest_level)
set_if_bigger(lex_s->in_sum_func->max_sum_func_level,
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level >= select->nest_level)
set_if_bigger(thd->lex->in_sum_func->max_sum_func_level,
select->nest_level - 1);
}

Expand Down Expand Up @@ -781,7 +780,6 @@ Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg,
{
name = (char*) field_name_arg;
name_length= name ? strlen(name) : 0;
DBUG_ASSERT(!context || context->select_lex);
}


Expand All @@ -796,7 +794,6 @@ Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg, const char *field_name_ar
{
name = (char*) field_name_arg;
name_length= name ? strlen(name) : 0;
DBUG_ASSERT(!context || context->select_lex);
}


Expand All @@ -818,9 +815,7 @@ Item_ident::Item_ident(THD *thd, Item_ident *item)
cached_table(item->cached_table),
depended_from(item->depended_from),
can_be_depended(item->can_be_depended)
{
DBUG_ASSERT(!context || context->select_lex);
}
{}

void Item_ident::cleanup()
{
Expand Down Expand Up @@ -5162,14 +5157,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
*/
Name_resolution_context *last_checked_context= context;
Item **ref= (Item **) not_found_item;
/*
There are cases when name resolution context is absent (when we are not
doing name resolution), but here the name resolution context should
be present because we are doing name resolution
*/
DBUG_ASSERT(context);
SELECT_LEX *current_sel= context->select_lex;
LEX *lex_s= context->select_lex->parent_lex;
SELECT_LEX *current_sel= thd->lex->current_select;
Name_resolution_context *outer_context= 0;
SELECT_LEX *select= 0;
/* Currently derived tables cannot be correlated */
Expand Down Expand Up @@ -5270,18 +5258,18 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
return -1;
thd->change_item_tree(reference, rf);
select->inner_refs_list.push_back(rf, thd->mem_root);
rf->in_sum_func= lex_s->in_sum_func;
rf->in_sum_func= thd->lex->in_sum_func;
}
/*
A reference is resolved to a nest level that's outer or the same as
the nest level of the enclosing set function : adjust the value of
max_arg_level for the function if it's needed.
*/
if (lex_s->in_sum_func &&
lex_s->in_sum_func->nest_level >= select->nest_level)
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level >= select->nest_level)
{
Item::Type ref_type= (*reference)->type();
set_if_bigger(lex_s->in_sum_func->max_arg_level,
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
select->nest_level);
set_field(*from_field);
fixed= 1;
Expand All @@ -5302,10 +5290,10 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0), false);
if (lex_s->in_sum_func &&
lex_s->in_sum_func->nest_level >= select->nest_level)
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level >= select->nest_level)
{
set_if_bigger(lex_s->in_sum_func->max_arg_level,
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
select->nest_level);
}
/*
Expand Down Expand Up @@ -5397,7 +5385,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
{
outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf,
thd->mem_root);
((Item_outer_ref*)rf)->in_sum_func= lex_s->in_sum_func;
((Item_outer_ref*)rf)->in_sum_func= thd->lex->in_sum_func;
}
thd->change_item_tree(reference, rf);
/*
Expand All @@ -5412,7 +5400,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
set_max_sum_func_level(select);
set_max_sum_func_level(thd, select);
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex, rf,
rf, false);
Expand All @@ -5425,7 +5413,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
set_max_sum_func_level(select);
set_max_sum_func_level(thd, select);
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex,
this, (Item_ident*)*reference, false);
Expand Down Expand Up @@ -5502,20 +5490,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(fixed == 0);
Field *from_field= (Field *)not_found_field;
bool outer_fixed= false;
SELECT_LEX *select;
LEX *lex_s;
if (context)
{
select= context->select_lex;
lex_s= context->select_lex->parent_lex;
}
else
{
// No real name resolution, used somewhere in SP
DBUG_ASSERT(field);
select= NULL;
lex_s= NULL;
}
SELECT_LEX *select= thd->lex->current_select;

if (!field) // If field is not checked
{
Expand Down Expand Up @@ -5576,7 +5551,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
set_max_sum_func_level(select);
set_max_sum_func_level(thd, select);
set_field(new_field);
depended_from= (*((Item_field**)res))->depended_from;
return 0;
Expand Down Expand Up @@ -5605,7 +5580,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
set_max_sum_func_level(select);
set_max_sum_func_level(thd, select);
return FALSE;
}
}
Expand Down Expand Up @@ -5642,11 +5617,10 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
goto mark_non_agg_field;
}

if (lex_s &&
lex_s->in_sum_func &&
lex_s->in_sum_func->nest_level ==
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level ==
select->nest_level)
set_if_bigger(lex_s->in_sum_func->max_arg_level,
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
select->nest_level);
/*
if it is not expression from merged VIEW we will set this field.
Expand Down Expand Up @@ -5712,9 +5686,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (field->vcol_info)
fix_session_vcol_expr_for_read(thd, field, field->vcol_info);
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
!outer_fixed &&
!outer_fixed && !thd->lex->in_sum_func &&
select &&
!lex_s->in_sum_func &&
select->cur_pos_in_select_list != UNDEF_POS &&
select->join)
{
Expand Down Expand Up @@ -5749,13 +5722,13 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
*/
select_lex= context->select_lex;
}
if (!lex_s || !lex_s->in_sum_func)
if (!thd->lex->in_sum_func)
select_lex->set_non_agg_field_used(true);
else
{
if (outer_fixed)
lex_s->in_sum_func->outer_fields.push_back(this, thd->mem_root);
else if (lex_s->in_sum_func->nest_level !=
thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root);
else if (thd->lex->in_sum_func->nest_level !=
select->nest_level)
select_lex->set_non_agg_field_used(true);
}
Expand Down Expand Up @@ -7248,12 +7221,6 @@ Item *get_field_item_for_having(THD *thd, Item *item, st_select_lex *sel)
return NULL;
}

Item *Item_ident::derived_field_transformer_for_having(THD *thd, uchar *arg)
{
st_select_lex *sel= (st_select_lex *)arg;
context= &sel->context;
return this;
}

Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
{
Expand All @@ -7273,13 +7240,12 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
Item *Item_direct_view_ref::derived_field_transformer_for_having(THD *thd,
uchar *arg)
{
st_select_lex *sel= (st_select_lex *)arg;
context= &sel->context;
if ((*ref)->marker & SUBSTITUTION_FL)
{
this->marker|= SUBSTITUTION_FL;
return this;
}
st_select_lex *sel= (st_select_lex *)arg;
table_map tab_map= sel->master_unit()->derived->table->map;
if ((item_equal && !(item_equal->used_tables() & tab_map)) ||
!item_equal)
Expand Down Expand Up @@ -7575,9 +7541,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
{
enum_parsing_place place= NO_MATTER;
DBUG_ASSERT(fixed == 0);

SELECT_LEX *current_sel= context->select_lex;
LEX *lex_s= context->select_lex->parent_lex;
SELECT_LEX *current_sel= thd->lex->current_select;

if (set_properties_only)
{
Expand Down Expand Up @@ -7738,10 +7702,10 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
the nest level of the enclosing set function : adjust the value of
max_arg_level for the function if it's needed.
*/
if (lex_s->in_sum_func &&
lex_s->in_sum_func->nest_level >=
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level >=
last_checked_context->select_lex->nest_level)
set_if_bigger(lex_s->in_sum_func->max_arg_level,
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
last_checked_context->select_lex->nest_level);
return FALSE;
}
Expand All @@ -7761,10 +7725,10 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
the nest level of the enclosing set function : adjust the value of
max_arg_level for the function if it's needed.
*/
if (lex_s->in_sum_func &&
lex_s->in_sum_func->nest_level >=
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level >=
last_checked_context->select_lex->nest_level)
set_if_bigger(lex_s->in_sum_func->max_arg_level,
set_if_bigger(thd->lex->in_sum_func->max_arg_level,
last_checked_context->select_lex->nest_level);
}
}
Expand Down
1 change: 0 additions & 1 deletion sql/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -2630,7 +2630,6 @@ class Item_ident :public Item_result_field
Collect outer references
*/
virtual bool collect_outer_ref_processor(void *arg);
Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
friend bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name,
const char *table_name, List_iterator<Item> *it,
Expand Down
3 changes: 1 addition & 2 deletions sql/item_subselect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5190,9 +5190,8 @@ bool subselect_hash_sj_engine::make_semi_join_conds()
NULL, TL_READ);
tmp_table_ref->table= tmp_table;

context= new (thd->mem_root) Name_resolution_context;
context= new Name_resolution_context;
context->init();
context->select_lex= item_in->unit->first_select();
context->first_name_resolution_table=
context->last_name_resolution_table= tmp_table_ref;
semi_join_conds_context= context;
Expand Down
Loading

0 comments on commit d6ee351

Please sign in to comment.