summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2023-01-13 10:18:30 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2023-01-13 10:18:30 +0200
commit73ecab3d26c055928673a2629f4513aa7008dbf0 (patch)
treeb04760b3369cd1d8fc03c7dec204f5a371335b29 /sql/item.cc
parent7d1df207c4ded0ac8aa61f0d35bcae7eda974c54 (diff)
parent71e8e4934db06c02db1b51716e9d4b3992505161 (diff)
downloadmariadb-git-73ecab3d26c055928673a2629f4513aa7008dbf0.tar.gz
Merge 10.4 into 10.5
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc102
1 files changed, 75 insertions, 27 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 57647dd2074..1a55317754e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -41,6 +41,7 @@
// find_item_in_list,
// RESOLVED_AGAINST_ALIAS, ...
#include "sql_expression_cache.h"
+#include "sql_lex.h" // empty_clex_str
const String my_null_string("NULL", 4, default_charset_info);
const String my_default_string("DEFAULT", 7, default_charset_info);
@@ -1303,12 +1304,11 @@ Item *Item_cache::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
Item *conv= example->safe_charset_converter(thd, tocs);
if (conv == example)
return this;
- Item_cache *cache;
- if (!conv || conv->fix_fields(thd, (Item **) NULL) ||
- unlikely(!(cache= new (thd->mem_root) Item_cache_str(thd, conv))))
- return NULL; // Safe conversion is not possible, or OEM
- cache->setup(thd, conv);
- return cache;
+ if (!conv || conv->fix_fields(thd, (Item **) NULL))
+ return NULL; // Safe conversion is not possible, or OOM
+ setup(thd, conv);
+ thd->change_item_tree(&example, conv);
+ return this;
}
@@ -1495,12 +1495,8 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
{
int res;
TABLE *table= field->table;
- THD *thd= table->in_use;
- Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
- Sql_mode_save sms(thd);
- thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
- thd->variables.sql_mode|= MODE_INVALID_DATES;
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
+ Use_relaxed_field_copy urfc(table->in_use);
res= save_in_field(field, no_conversions);
dbug_tmp_restore_column_map(&table->write_set, old_map);
return res;
@@ -2305,7 +2301,8 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
if (unlikely((!(used_tables() & ~PARAM_TABLE_BIT) ||
(type() == REF_ITEM &&
- ((Item_ref*)this)->ref_type() != Item_ref::VIEW_REF))))
+ ((Item_ref*)this)->ref_type() != Item_ref::VIEW_REF &&
+ ((Item_ref*)this)->ref_type() != Item_ref::DIRECT_REF))))
return;
}
@@ -2618,7 +2615,6 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll,
safe_args[1]= args[item_sep];
}
- bool res= FALSE;
uint i;
DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
@@ -2638,19 +2634,31 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll,
args[item_sep]= safe_args[1];
}
my_coll_agg_error(args, nargs, fname, item_sep);
- res= TRUE;
- break; // we cannot return here, we need to restore "arena".
+ return TRUE;
}
- thd->change_item_tree(arg, conv);
-
if (conv->fix_fields_if_needed(thd, arg))
+ return TRUE;
+
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ if (arena)
{
- res= TRUE;
- break; // we cannot return here, we need to restore "arena".
+ Item_direct_ref_to_item *ref=
+ new (thd->mem_root) Item_direct_ref_to_item(thd, *arg);
+ if ((ref == NULL) || ref->fix_fields(thd, (Item **)&ref))
+ {
+ thd->restore_active_arena(arena, &backup);
+ return TRUE;
+ }
+ *arg= ref;
+ thd->restore_active_arena(arena, &backup);
+ ref->change_item(thd, conv);
}
+ else
+ thd->change_item_tree(arg, conv);
}
- return res;
+ return FALSE;
}
@@ -7295,7 +7303,7 @@ bool Item_null::send(Protocol *protocol, st_value *buffer)
bool Item::cache_const_expr_analyzer(uchar **arg)
{
- bool *cache_flag= (bool*)*arg;
+ uchar *cache_flag= *arg;
if (!*cache_flag)
{
Item *item= real_item();
@@ -7334,9 +7342,9 @@ bool Item::cache_const_expr_analyzer(uchar **arg)
Item* Item::cache_const_expr_transformer(THD *thd, uchar *arg)
{
- if (*(bool*)arg)
+ if (*arg)
{
- *((bool*)arg)= FALSE;
+ *arg= FALSE;
Item_cache *cache= get_cache(thd);
if (!cache)
return NULL;
@@ -10281,8 +10289,8 @@ bool Item_cache_timestamp::cache_value()
if (!example)
return false;
value_cached= true;
- null_value= example->val_native_with_conversion_result(current_thd, &m_native,
- type_handler());
+ null_value_inside= null_value=
+ example->val_native_with_conversion_result(current_thd, &m_native, type_handler());
return true;
}
@@ -10854,8 +10862,6 @@ const char *dbug_print(SELECT_LEX_UNIT *x) { return dbug_print_unit(x); }
#endif /*DBUG_OFF*/
-
-
void Item::register_in(THD *thd)
{
next= thd->free_list;
@@ -10863,6 +10869,48 @@ void Item::register_in(THD *thd)
}
+Item_direct_ref_to_item::Item_direct_ref_to_item(THD *thd, Item *item)
+ : Item_direct_ref(thd, NULL, NULL, empty_clex_str, empty_clex_str)
+{
+ m_item= item;
+ ref= (Item**)&m_item;
+}
+
+bool Item_direct_ref_to_item::fix_fields(THD *thd, Item **)
+{
+ DBUG_ASSERT(m_item != NULL);
+ if (m_item->fix_fields_if_needed_for_scalar(thd, ref))
+ return TRUE;
+ set_properties();
+ return FALSE;
+}
+
+void Item_direct_ref_to_item::print(String *str, enum_query_type query_type)
+{
+ m_item->print(str, query_type);
+}
+
+Item *Item_direct_ref_to_item::safe_charset_converter(THD *thd,
+ CHARSET_INFO *tocs)
+{
+ Item *conv= m_item->safe_charset_converter(thd, tocs);
+ if (conv != m_item)
+ {
+ if (conv== NULL || conv->fix_fields(thd, &conv))
+ return NULL;
+ change_item(thd, conv);
+ }
+ return this;
+}
+
+void Item_direct_ref_to_item::change_item(THD *thd, Item *i)
+{
+ DBUG_ASSERT(i->is_fixed());
+ thd->change_item_tree(ref, i);
+ set_properties();
+}
+
+
bool Item::cleanup_excluding_immutables_processor (void *arg)
{
if (!(get_extraction_flag() == IMMUTABLE_FL))