diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2023-01-13 10:18:30 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2023-01-13 10:18:30 +0200 |
commit | 73ecab3d26c055928673a2629f4513aa7008dbf0 (patch) | |
tree | b04760b3369cd1d8fc03c7dec204f5a371335b29 /sql/item.cc | |
parent | 7d1df207c4ded0ac8aa61f0d35bcae7eda974c54 (diff) | |
parent | 71e8e4934db06c02db1b51716e9d4b3992505161 (diff) | |
download | mariadb-git-73ecab3d26c055928673a2629f4513aa7008dbf0.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 102 |
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)) |