mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Revert "MDEV-24454 Crash at change_item_tree"
This patch reverts the fixes of the bugs MDEV-24454 and MDEV-25631 from
the commit 3690c549c6
.
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.
This commit is contained in:
parent
80d33261ea
commit
d6ee351bbb
8 changed files with 39 additions and 173 deletions
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
104
sql/item.cc
104
sql/item.cc
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
/*
|
||||
|
@ -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);
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -5749,13 +5722,13 @@ mark_non_agg_field:
|
|||
*/
|
||||
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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2630,7 +2630,6 @@ public:
|
|||
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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -68,7 +68,6 @@ size_t Item_sum::ram_limitation(THD *thd)
|
|||
bool Item_sum::init_sum_func_check(THD *thd)
|
||||
{
|
||||
SELECT_LEX *curr_sel= thd->lex->current_select;
|
||||
LEX *lex_s= (curr_sel ? curr_sel->parent_lex : thd->lex);
|
||||
if (curr_sel && !curr_sel->name_visibility_map)
|
||||
{
|
||||
for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select())
|
||||
|
@ -83,9 +82,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||
return TRUE;
|
||||
}
|
||||
/* Set a reference to the nesting set function if there is any */
|
||||
in_sum_func= lex_s->in_sum_func;
|
||||
in_sum_func= thd->lex->in_sum_func;
|
||||
/* Save a pointer to object to be used in items for nested set functions */
|
||||
lex_s->in_sum_func= this;
|
||||
thd->lex->in_sum_func= this;
|
||||
nest_level= thd->lex->current_select->nest_level;
|
||||
ref_by= 0;
|
||||
aggr_level= -1;
|
||||
|
@ -152,7 +151,6 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||
bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
{
|
||||
SELECT_LEX *curr_sel= thd->lex->current_select;
|
||||
LEX *lex_s= curr_sel->parent_lex;
|
||||
nesting_map allow_sum_func= (thd->lex->allow_sum_func &
|
||||
curr_sel->name_visibility_map);
|
||||
bool invalid= FALSE;
|
||||
|
@ -312,7 +310,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||
}
|
||||
aggr_sel->set_agg_func_used(true);
|
||||
update_used_tables();
|
||||
lex_s->in_sum_func= in_sum_func;
|
||||
thd->lex->in_sum_func= in_sum_func;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -6440,7 +6440,6 @@ set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref)
|
|||
if (!(context= new (thd->mem_root) Name_resolution_context))
|
||||
return TRUE;
|
||||
context->init();
|
||||
context->select_lex= table_ref->select_lex;
|
||||
context->first_name_resolution_table=
|
||||
context->last_name_resolution_table= table_ref;
|
||||
item->context= context;
|
||||
|
|
|
@ -3060,7 +3060,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
|
|||
}
|
||||
for (; sl; sl= sl->next_select_in_list())
|
||||
{
|
||||
sl->parent_lex->in_sum_func= NULL;
|
||||
if (sl->changed_elements & TOUCHED_SEL_COND)
|
||||
{
|
||||
/* remove option which was put by mysql_explain_union() */
|
||||
|
@ -3191,6 +3190,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
|
|||
lex->result->set_thd(thd);
|
||||
}
|
||||
lex->allow_sum_func= 0;
|
||||
lex->in_sum_func= NULL;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue