summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-09-30 09:04:43 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-09-30 09:04:43 +0300
commit064cb58efea063595e336e4cd0feccb12d26f8cf (patch)
treef140b96c8a20172cbb484375e38a7aa481ab660b /sql/item.cc
parente5a9dcfda20e174525ad63a30e12f592aa9c96d3 (diff)
parent57fdd016ce6167c15ba9cd41048b8a42ba582447 (diff)
downloadmariadb-git-064cb58efea063595e336e4cd0feccb12d26f8cf.tar.gz
Merge 10.4 into 10.5
FIXME: Part of the MDEV-20699 test is disabled due to nonderterministic result.
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc104
1 files changed, 70 insertions, 34 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 8f6bfdc6b09..d696d532d80 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -70,11 +70,12 @@ bool cmp_items(Item *a, Item *b)
/**
Set max_sum_func_level if it is needed
*/
-inline void set_max_sum_func_level(THD *thd, SELECT_LEX *select)
+inline void set_max_sum_func_level(SELECT_LEX *select)
{
- 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,
+ 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,
select->nest_level - 1);
}
@@ -643,6 +644,7 @@ Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg,
cached_table(0), depended_from(0), can_be_depended(TRUE)
{
name= field_name_arg;
+ DBUG_ASSERT(!context || context->select_lex);
}
@@ -659,6 +661,7 @@ Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg,
cached_table(NULL), depended_from(NULL), can_be_depended(TRUE)
{
name= field_name_arg;
+ DBUG_ASSERT(!context || context->select_lex);
}
@@ -680,7 +683,9 @@ 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()
{
@@ -5498,7 +5503,14 @@ 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;
- SELECT_LEX *current_sel= thd->lex->current_select;
+ /*
+ 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;
Name_resolution_context *outer_context= 0;
SELECT_LEX *select= 0;
/* Currently derived tables cannot be correlated */
@@ -5600,18 +5612,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= thd->lex->in_sum_func;
+ rf->in_sum_func= lex_s->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 (thd->lex->in_sum_func &&
- thd->lex->in_sum_func->nest_level >= select->nest_level)
+ if (lex_s->in_sum_func &&
+ lex_s->in_sum_func->nest_level >= select->nest_level)
{
Item::Type ref_type= (*reference)->type();
- set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+ set_if_bigger(lex_s->in_sum_func->max_arg_level,
select->nest_level);
set_field(*from_field);
fixed= 1;
@@ -5632,10 +5644,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 (thd->lex->in_sum_func &&
- thd->lex->in_sum_func->nest_level >= select->nest_level)
+ if (lex_s->in_sum_func &&
+ lex_s->in_sum_func->nest_level >= select->nest_level)
{
- set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+ set_if_bigger(lex_s->in_sum_func->max_arg_level,
select->nest_level);
}
/*
@@ -5727,7 +5739,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= thd->lex->in_sum_func;
+ ((Item_outer_ref*)rf)->in_sum_func= lex_s->in_sum_func;
}
thd->change_item_tree(reference, rf);
/*
@@ -5742,7 +5754,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(thd, select);
+ set_max_sum_func_level(select);
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex, rf,
rf, false);
@@ -5755,7 +5767,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(thd, select);
+ set_max_sum_func_level(select);
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex,
this, (Item_ident*)*reference, false);
@@ -5834,7 +5846,20 @@ 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= thd->lex->current_select;
+ 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;
+ }
if (select && select->in_tvc)
{
@@ -5902,7 +5927,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(thd, select);
+ set_max_sum_func_level(select);
set_field(new_field);
depended_from= (*((Item_field**)res))->depended_from;
return 0;
@@ -5931,7 +5956,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(thd, select);
+ set_max_sum_func_level(select);
return FALSE;
}
}
@@ -5968,10 +5993,11 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
goto mark_non_agg_field;
}
- if (thd->lex->in_sum_func &&
- thd->lex->in_sum_func->nest_level ==
+ if (lex_s &&
+ lex_s->in_sum_func &&
+ lex_s->in_sum_func->nest_level ==
select->nest_level)
- set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+ set_if_bigger(lex_s->in_sum_func->max_arg_level,
select->nest_level);
/*
if it is not expression from merged VIEW we will set this field.
@@ -6037,8 +6063,9 @@ 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 && !thd->lex->in_sum_func &&
+ !outer_fixed &&
select &&
+ !lex_s->in_sum_func &&
select->cur_pos_in_select_list != UNDEF_POS &&
select->join)
{
@@ -6073,13 +6100,13 @@ mark_non_agg_field:
*/
select_lex= context->select_lex;
}
- if (!thd->lex->in_sum_func)
+ if (!lex_s || !lex_s->in_sum_func)
select_lex->set_non_agg_field_used(true);
else
{
if (outer_fixed)
- thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root);
- else if (thd->lex->in_sum_func->nest_level !=
+ lex_s->in_sum_func->outer_fields.push_back(this, thd->mem_root);
+ else if (lex_s->in_sum_func->nest_level !=
select->nest_level)
select_lex->set_non_agg_field_used(true);
}
@@ -7539,6 +7566,12 @@ 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)
{
@@ -7558,12 +7591,13 @@ 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)
@@ -7826,7 +7860,9 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
{
enum_parsing_place place= NO_MATTER;
DBUG_ASSERT(fixed == 0);
- SELECT_LEX *current_sel= thd->lex->current_select;
+
+ SELECT_LEX *current_sel= context->select_lex;
+ LEX *lex_s= context->select_lex->parent_lex;
if (set_properties_only)
{
@@ -7987,10 +8023,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 (thd->lex->in_sum_func &&
- thd->lex->in_sum_func->nest_level >=
+ if (lex_s->in_sum_func &&
+ lex_s->in_sum_func->nest_level >=
last_checked_context->select_lex->nest_level)
- set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+ set_if_bigger(lex_s->in_sum_func->max_arg_level,
last_checked_context->select_lex->nest_level);
return FALSE;
}
@@ -8010,10 +8046,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 (thd->lex->in_sum_func &&
- thd->lex->in_sum_func->nest_level >=
+ if (lex_s->in_sum_func &&
+ lex_s->in_sum_func->nest_level >=
last_checked_context->select_lex->nest_level)
- set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+ set_if_bigger(lex_s->in_sum_func->max_arg_level,
last_checked_context->select_lex->nest_level);
}
}