summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2022-01-05 20:23:52 -0800
committerIgor Babaev <igor@askmonty.org>2022-01-10 09:12:17 -0800
commitd6ee351bbb66b023e8c477b039aa469b053f84ad (patch)
tree041f2eeeb8d24d218f3d2f6f9293fa523bc361de
parent80d33261ea1a731f228b712b0e763740f87b89be (diff)
downloadmariadb-git-d6ee351bbb66b023e8c477b039aa469b053f84ad.tar.gz
Revert "MDEV-24454 Crash at change_item_tree"
This patch reverts the fixes of the bugs MDEV-24454 and MDEV-25631 from the commit 3690c549c6e72646ba74f6b4c83813ee4ac3aea4. 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.
-rw-r--r--mysql-test/r/view.result43
-rw-r--r--mysql-test/t/view.test50
-rw-r--r--sql/item.cc104
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_subselect.cc3
-rw-r--r--sql/item_sum.cc8
-rw-r--r--sql/sql_base.cc1
-rw-r--r--sql/sql_prepare.cc2
8 files changed, 39 insertions, 173 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 001d26fc466..d278eb1f870 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -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
#
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index e6e6ccce8bd..4fb1806fac9 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -6560,56 +6560,6 @@ 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
--echo #
diff --git a/sql/item.cc b/sql/item.cc
index a5b313b786d..2317d54d3e5 100644
--- a/sql/item.cc
+++ b/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);
}
}
diff --git a/sql/item.h b/sql/item.h
index 997352ef27a..086d85e989f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -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,
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 3f9a760ce09..25621dfe104 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -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;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index f20be3b5226..dd65f04a652 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -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;
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 5173df260d5..9a66b27a454 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -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;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index bb1a99d9eef..64e4cd30561 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -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;
}