diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2018-06-19 14:51:50 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2018-06-19 14:51:50 +0200 |
commit | 083279f7838d45c475344d20585ead72a147a21d (patch) | |
tree | c3ff5b3f6af1c9009b35d9b2560a7073be41ce90 /sql | |
parent | 0121d5a790983c08dabedc66e70f862e47f7c8c7 (diff) | |
parent | 6b8802e8dd5467556a024d807a1df23940b00895 (diff) | |
download | mariadb-git-083279f7838d45c475344d20585ead72a147a21d.tar.gz |
Merge commit '6b8802e8dd5467556a024d807a1df23940b00895' into bb-10.3-fix_len_decbb-10.3-fix_len_dec
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 98 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 82 | ||||
-rw-r--r-- | sql/item_func.cc | 143 | ||||
-rw-r--r-- | sql/item_func.h | 159 | ||||
-rw-r--r-- | sql/item_geofunc.cc | 9 | ||||
-rw-r--r-- | sql/item_geofunc.h | 77 | ||||
-rw-r--r-- | sql/item_inetfunc.h | 12 | ||||
-rw-r--r-- | sql/item_jsonfunc.cc | 57 | ||||
-rw-r--r-- | sql/item_jsonfunc.h | 40 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 164 | ||||
-rw-r--r-- | sql/item_strfunc.h | 192 | ||||
-rw-r--r-- | sql/item_subselect.cc | 71 | ||||
-rw-r--r-- | sql/item_subselect.h | 22 | ||||
-rw-r--r-- | sql/item_sum.cc | 50 | ||||
-rw-r--r-- | sql/item_sum.h | 34 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 38 | ||||
-rw-r--r-- | sql/item_timefunc.h | 146 | ||||
-rw-r--r-- | sql/item_vers.h | 8 | ||||
-rw-r--r-- | sql/item_windowfunc.cc | 6 | ||||
-rw-r--r-- | sql/item_windowfunc.h | 15 | ||||
-rw-r--r-- | sql/item_xmlfunc.cc | 13 | ||||
-rw-r--r-- | sql/item_xmlfunc.h | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 | ||||
-rw-r--r-- | sql/sql_table.cc | 14 |
25 files changed, 865 insertions, 592 deletions
diff --git a/sql/item.h b/sql/item.h index 10ce987e289..0ee60afb3be 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4674,7 +4674,7 @@ public: also to make printing of items inherited from Item_sum uniform. */ virtual const char *func_name() const= 0; - virtual void fix_length_and_dec()= 0; + virtual bool fix_length_and_dec()= 0; bool const_item() const { return const_item_cache; } table_map used_tables() const { return used_tables_cache; } Item* build_clone(THD *thd); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3034636dca3..37ec33c8358 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -449,7 +449,7 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp) } -void Item_bool_rowready_func2::fix_length_and_dec() +bool Item_bool_rowready_func2::fix_length_and_dec() { max_length= 1; // Function returns 0 or 1 @@ -458,8 +458,8 @@ void Item_bool_rowready_func2::fix_length_and_dec() we have to check for out of memory conditions here */ if (!args[0] || !args[1]) - return; - setup_args_and_comparator(current_thd, &cmp); + return FALSE; + return setup_args_and_comparator(current_thd, &cmp); } @@ -1107,12 +1107,13 @@ int Arg_comparator::compare_e_str_json() } -void Item_func_truth::fix_length_and_dec() +bool Item_func_truth::fix_length_and_dec() { maybe_null= 0; null_value= 0; decimals= 0; max_length= 1; + return FALSE; } @@ -1731,10 +1732,11 @@ longlong Item_func_eq::val_int() /** Same as Item_func_eq, but NULL = NULL. */ -void Item_func_equal::fix_length_and_dec() +bool Item_func_equal::fix_length_and_dec() { - Item_bool_rowready_func2::fix_length_and_dec(); + bool rc= Item_bool_rowready_func2::fix_length_and_dec(); maybe_null=null_value=0; + return rc; } longlong Item_func_equal::val_int() @@ -1831,7 +1833,7 @@ bool Item_func_interval::fix_fields(THD *thd, Item **ref) } -void Item_func_interval::fix_length_and_dec() +bool Item_func_interval::fix_length_and_dec() { uint rows= row->cols(); @@ -1849,10 +1851,13 @@ void Item_func_interval::fix_length_and_dec() not_null_consts&= el->const_item() && !el->is_null(); } - if (not_null_consts && - (intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) * - (rows - 1)))) + if (not_null_consts) { + intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) * + (rows - 1)); + if (!intervals) + return TRUE; + if (use_decimal_comparison) { for (uint i= 1; i < rows; i++) @@ -1893,6 +1898,7 @@ void Item_func_interval::fix_length_and_dec() with_sum_func= with_sum_func || row->with_sum_func; with_param= with_param || row->with_param; with_field= with_field || row->with_field; + return FALSE; } @@ -2053,7 +2059,7 @@ void Item_func_between::fix_after_pullout(st_select_lex *new_parent, eval_not_null_tables(NULL); } -void Item_func_between::fix_length_and_dec() +bool Item_func_between::fix_length_and_dec() { max_length= 1; @@ -2062,15 +2068,16 @@ void Item_func_between::fix_length_and_dec() we have to check for out of memory conditions here */ if (!args[0] || !args[1] || !args[2]) - return; + return TRUE; if (m_comparator.aggregate_for_comparison(Item_func_between::func_name(), args, 3, true)) { DBUG_ASSERT(current_thd->is_error()); - return; + return TRUE; } - m_comparator.type_handler()->Item_func_between_fix_length_and_dec(this); + return m_comparator.type_handler()-> + Item_func_between_fix_length_and_dec(this); } @@ -2093,7 +2100,7 @@ bool Item_func_between::fix_length_and_dec_numeric(THD *thd) } } } - return false; + return FALSE; } @@ -2455,7 +2462,7 @@ void Item_func_nullif::update_used_tables() -void +bool Item_func_nullif::fix_length_and_dec() { /* @@ -2605,6 +2612,8 @@ Item_func_nullif::fix_length_and_dec() m_cache= args[0]->cmp_type() == STRING_RESULT ? new (thd->mem_root) Item_cache_str_for_nullif(thd, args[0]) : args[0]->get_cache(thd); + if (!m_cache) + return TRUE; m_cache->setup(thd, args[0]); m_cache->store(args[0]); m_cache->set_used_tables(args[0]->used_tables()); @@ -2618,7 +2627,8 @@ Item_func_nullif::fix_length_and_dec() fix_char_length(args[2]->max_char_length()); maybe_null=1; m_arg0= args[0]; - setup_args_and_comparator(thd, &cmp); + if (setup_args_and_comparator(thd, &cmp)) + return TRUE; /* A special code for EXECUTE..PREPARE. @@ -2658,6 +2668,7 @@ Item_func_nullif::fix_length_and_dec() */ if (args[0] == m_arg0) m_arg0= NULL; + return FALSE; } @@ -3053,26 +3064,26 @@ bool Item_func_case_simple::prepare_predicant_and_values(THD *thd, } -void Item_func_case_searched::fix_length_and_dec() +bool Item_func_case_searched::fix_length_and_dec() { THD *thd= current_thd; - aggregate_then_and_else_arguments(thd, when_count()); + return aggregate_then_and_else_arguments(thd, when_count()); } -void Item_func_case_simple::fix_length_and_dec() +bool Item_func_case_simple::fix_length_and_dec() { THD *thd= current_thd; - if (!aggregate_then_and_else_arguments(thd, when_count() + 1)) - aggregate_switch_and_when_arguments(thd, false); + return (aggregate_then_and_else_arguments(thd, when_count() + 1) || + aggregate_switch_and_when_arguments(thd, false)); } -void Item_func_decode_oracle::fix_length_and_dec() +bool Item_func_decode_oracle::fix_length_and_dec() { THD *thd= current_thd; - if (!aggregate_then_and_else_arguments(thd, when_count() + 1)) - aggregate_switch_and_when_arguments(thd, true); + return (aggregate_then_and_else_arguments(thd, when_count() + 1) || + aggregate_switch_and_when_arguments(thd, true)); } @@ -4178,7 +4189,7 @@ bool Item_func_in::prepare_predicant_and_values(THD *thd, uint *found_types) } -void Item_func_in::fix_length_and_dec() +bool Item_func_in::fix_length_and_dec() { THD *thd= current_thd; uint found_types; @@ -4188,18 +4199,20 @@ void Item_func_in::fix_length_and_dec() if (prepare_predicant_and_values(thd, &found_types)) { DBUG_ASSERT(thd->is_error()); // Must set error - return; + return TRUE; } if (arg_types_compatible) // Bisection condition #1 { - m_comparator.type_handler()-> - Item_func_in_fix_comparator_compatible_types(thd, this); + if (m_comparator.type_handler()-> + Item_func_in_fix_comparator_compatible_types(thd, this)) + return TRUE; } else { DBUG_ASSERT(m_comparator.cmp_type() != ROW_RESULT); - fix_for_scalar_comparison_using_cmp_items(thd, found_types); + if ( fix_for_scalar_comparison_using_cmp_items(thd, found_types)) + return TRUE; } DBUG_EXECUTE_IF("Item_func_in", @@ -4207,6 +4220,7 @@ void Item_func_in::fix_length_and_dec() ER_UNKNOWN_ERROR, "DBUG: types_compatible=%s bisect=%s", arg_types_compatible ? "yes" : "no", array != NULL ? "yes" : "no");); + return FALSE; } @@ -4634,7 +4648,8 @@ Item_cond::fix_fields(THD *thd, Item **ref) with_window_func|= item->with_window_func; maybe_null|= item->maybe_null; } - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; fixed= 1; return FALSE; } @@ -5669,16 +5684,16 @@ bool Item_func_regex::fix_fields(THD *thd, Item **ref) return Item_bool_func::fix_fields(thd, ref); } -void +bool Item_func_regex::fix_length_and_dec() { - Item_bool_func::fix_length_and_dec(); - - if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) - return; + if (Item_bool_func::fix_length_and_dec() || + agg_arg_charsets_for_comparison(cmp_collation, args, 2)) + return TRUE; re.init(cmp_collation.collation, 0); re.fix_owner(this, args[0], args[1]); + return FALSE; } @@ -5702,15 +5717,16 @@ bool Item_func_regexp_instr::fix_fields(THD *thd, Item **ref) } -void +bool Item_func_regexp_instr::fix_length_and_dec() { if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) - return; + return TRUE; re.init(cmp_collation.collation, 0); re.fix_owner(this, args[0], args[1]); max_length= MY_INT32_NUM_DECIMAL_DIGITS; // See also Item_func_locate + return FALSE; } @@ -6653,7 +6669,8 @@ bool Item_equal::fix_fields(THD *thd, Item **ref) } if (prev_equal_field && last_equal_field != first_equal_field) last_equal_field->next_equal_field= first_equal_field; - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; fixed= 1; return FALSE; } @@ -6739,11 +6756,12 @@ longlong Item_equal::val_int() } -void Item_equal::fix_length_and_dec() +bool Item_equal::fix_length_and_dec() { Item *item= get_first(NO_PARTICULAR_TAB, NULL); const Type_handler *handler= item->type_handler(); eval_item= handler->make_cmp_item(current_thd, item->collation.collation); + return eval_item == NULL; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 30d682f05aa..c321b826ea4 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -218,7 +218,7 @@ public: const Type_handler *type_handler() const { return &type_handler_long; } bool is_bool_type() { return true; } virtual CHARSET_INFO *compare_collation() const { return NULL; } - void fix_length_and_dec() { decimals=0; max_length=1; } + bool fix_length_and_dec() { decimals=0; max_length=1; return FALSE; } uint decimal_precision() const { return 1; } bool need_parentheses_in_default() { return true; } }; @@ -234,7 +234,7 @@ class Item_func_truth : public Item_bool_func public: virtual bool val_bool(); virtual longlong val_int(); - virtual void fix_length_and_dec(); + virtual bool fix_length_and_dec(); virtual void print(String *str, enum_query_type query_type); enum precedence precedence() const { return CMP_PRECEDENCE; } @@ -521,7 +521,7 @@ public: cond); return this; } - void fix_length_and_dec(); + bool fix_length_and_dec(); int set_cmp_func() { return cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, true); @@ -734,7 +734,7 @@ public: Item_func_equal(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {} longlong val_int(); - void fix_length_and_dec(); + bool fix_length_and_dec(); table_map not_null_tables() const { return 0; } enum Functype functype() const { return EQUAL_FUNC; } enum Functype rev_functype() const { return EQUAL_FUNC; } @@ -903,7 +903,7 @@ public: enum Functype functype() const { return BETWEEN; } const char *func_name() const { return "between"; } enum precedence precedence() const { return BETWEEN_PRECEDENCE; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool fix_length_and_dec_string(THD *) { return agg_arg_charsets_for_comparison(cmp_collation, args, 3); @@ -950,10 +950,12 @@ public: longlong val_int(); uint decimal_precision() const { return 1; } const char *func_name() const { return "strcmp"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - agg_arg_charsets_for_comparison(cmp_collation, args, 2); - fix_char_length(2); // returns "1" or "0" or "-1" + if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) + return TRUE; + fix_char_length(2); + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_strcmp>(thd, this); } @@ -982,7 +984,7 @@ public: { } bool fix_fields(THD *, Item **); longlong val_int(); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "interval"; } uint decimal_precision() const { return 2; } void print(String *str, enum_query_type query_type) @@ -1008,10 +1010,12 @@ public: my_decimal *decimal_op(my_decimal *); bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate); bool time_op(MYSQL_TIME *ltime); - void fix_length_and_dec() + bool fix_length_and_dec() { - if (!aggregate_for_result(func_name(), args, arg_count, true)) - fix_attributes(args, arg_count); + if (aggregate_for_result(func_name(), args, arg_count, true)) + return TRUE; + fix_attributes(args, arg_count); + return FALSE; } const char *func_name() const { return "coalesce"; } table_map not_null_tables() const { return 0; } @@ -1029,10 +1033,12 @@ public: class Item_func_case_abbreviation2 :public Item_func_case_expression { protected: - void fix_length_and_dec2(Item **items) + bool fix_length_and_dec2(Item **items) { - if (!aggregate_for_result(func_name(), items, 2, true)) - fix_attributes(items, 2); + if (aggregate_for_result(func_name(), items, 2, true)) + return TRUE; + fix_attributes(items, 2); + return FALSE; } void cache_type_info(const Item *source, bool maybe_null_arg) @@ -1042,7 +1048,7 @@ protected: maybe_null= maybe_null_arg; } - void fix_length_and_dec2_eliminate_null(Item **items) + bool fix_length_and_dec2_eliminate_null(Item **items) { // Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr. if (items[0]->type() == NULL_ITEM) @@ -1058,8 +1064,10 @@ protected: } else { - fix_length_and_dec2(items); + if (fix_length_and_dec2(items)) + return TRUE; } + return FALSE; } public: @@ -1081,10 +1089,12 @@ public: my_decimal *decimal_op(my_decimal *); bool date_op(MYSQL_TIME *ltime, ulonglong fuzzydate); bool time_op(MYSQL_TIME *ltime); - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_case_abbreviation2::fix_length_and_dec2(args); + if (Item_func_case_abbreviation2::fix_length_and_dec2(args)) + return TRUE; maybe_null= args[1]->maybe_null; + return FALSE; } const char *func_name() const { return "ifnull"; } @@ -1150,9 +1160,9 @@ public: Item_func_case_abbreviation2_switch(thd, a, b, c) {} bool fix_fields(THD *, Item **); - void fix_length_and_dec() + bool fix_length_and_dec() { - fix_length_and_dec2_eliminate_null(args + 1); + return fix_length_and_dec2_eliminate_null(args + 1); } const char *func_name() const { return "if"; } bool eval_not_null_tables(void *opt_arg); @@ -1174,9 +1184,9 @@ public: Item_func_case_abbreviation2_switch(thd, a, b, c) {} const char *func_name() const { return "nvl2"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - fix_length_and_dec2_eliminate_null(args + 1); + return fix_length_and_dec2_eliminate_null(args + 1); } Item *get_copy(THD *thd) { return get_item_copy<Item_func_nvl2>(thd, this); } @@ -1236,7 +1246,7 @@ public: longlong int_op(); String *str_op(String *str); my_decimal *decimal_op(my_decimal *); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool walk(Item_processor processor, bool walk_subquery, void *arg); const char *func_name() const { return "nullif"; } void print(String *str, enum_query_type query_type); @@ -2145,7 +2155,7 @@ public: reorder_args(0); } void print(String *str, enum_query_type query_type); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) { // None of the arguments are in a comparison context @@ -2197,7 +2207,7 @@ public: DBUG_VOID_RETURN; } void print(String *str, enum_query_type query_type); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond); Item *find_item(); Item *build_clone(THD *thd) @@ -2222,7 +2232,7 @@ public: { } const char *func_name() const { return "decode_oracle"; } void print(String *str, enum_query_type query_type); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *find_item(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_decode_oracle>(thd, this); } @@ -2310,7 +2320,7 @@ public: { } longlong val_int(); bool fix_fields(THD *, Item **); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool compatible_types_scalar_bisection_possible() { DBUG_ASSERT(m_comparator.cmp_type() != ROW_RESULT); @@ -2469,7 +2479,11 @@ public: } CHARSET_INFO *compare_collation() const { return args[0]->collation.collation; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; } + bool fix_length_and_dec() + { + decimals=0; max_length=1; maybe_null=0; + return FALSE; + } bool count_sargable_conds(void *arg); }; @@ -2693,10 +2707,10 @@ public: const char *func_name() const { return "like"; } enum precedence precedence() const { return CMP_PRECEDENCE; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= 1; - agg_arg_charsets_for_comparison(cmp_collation, args, 2); + return agg_arg_charsets_for_comparison(cmp_collation, args, 2); } void cleanup(); @@ -2817,7 +2831,7 @@ public: } longlong val_int(); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "regexp"; } enum precedence precedence() const { return CMP_PRECEDENCE; } Item *get_copy(THD *thd) @@ -2867,7 +2881,7 @@ public: } longlong val_int(); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "regexp_instr"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_regexp_instr>(thd, this); } @@ -3103,7 +3117,7 @@ public: longlong val_int(); const char *func_name() const { return "multiple equal"; } void sort(Item_field_cmpfunc compare, void *arg); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); void cleanup() { diff --git a/sql/item_func.cc b/sql/item_func.cc index 567c813de3c..5693484ad3b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -377,8 +377,7 @@ Item_func::fix_fields(THD *thd, Item **ref) } if (check_arguments()) return true; - fix_length_and_dec(); - if (unlikely(thd->is_error())) // An error inside fix_length_and_dec occurred + if (fix_length_and_dec()) return TRUE; fixed= 1; return FALSE; @@ -762,10 +761,12 @@ String *Item_int_func::val_str(String *str) } -void Item_func_connection_id::fix_length_and_dec() +bool Item_func_connection_id::fix_length_and_dec() { - Item_long_func::fix_length_and_dec(); + if (Item_long_func::fix_length_and_dec()) + return TRUE; max_length= 10; + return FALSE; } @@ -792,19 +793,19 @@ bool Item_num_op::fix_type_handler(const Type_aggregator *aggregator) } -void Item_func_plus::fix_length_and_dec(void) +bool Item_func_plus::fix_length_and_dec(void) { DBUG_ENTER("Item_func_plus::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_plus; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_for_result;); DBUG_ASSERT(aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_plus::type_handler()->Item_func_plus_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_plus::type_handler()->Item_func_plus_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1319,19 +1320,19 @@ void Item_func_minus::fix_unsigned_flag() } -void Item_func_minus::fix_length_and_dec() +bool Item_func_minus::fix_length_and_dec() { DBUG_ENTER("Item_func_minus::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_minus; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;); DBUG_ASSERT(!aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_minus::type_handler()->Item_func_minus_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_minus::type_handler()->Item_func_minus_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1551,19 +1552,19 @@ void Item_func_mul::result_precision() } -void Item_func_mul::fix_length_and_dec(void) +bool Item_func_mul::fix_length_and_dec(void) { DBUG_ENTER("Item_func_mul::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_mul; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_for_result;); DBUG_ASSERT(aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_mul::type_handler()->Item_func_mul_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_mul::type_handler()->Item_func_mul_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1658,7 +1659,7 @@ void Item_func_div::fix_length_and_dec_int(void) } -void Item_func_div::fix_length_and_dec(void) +bool Item_func_div::fix_length_and_dec() { DBUG_ENTER("Item_func_div::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); @@ -1668,12 +1669,12 @@ void Item_func_div::fix_length_and_dec(void) const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_div; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;); DBUG_ASSERT(!aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_div::type_handler()->Item_func_div_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_div::type_handler()->Item_func_div_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1749,7 +1750,7 @@ longlong Item_func_int_div::val_int() } -void Item_func_int_div::fix_length_and_dec() +bool Item_func_int_div::fix_length_and_dec() { Item_result argtype= args[0]->result_type(); /* use precision ony for the data type it is applicable for and valid */ @@ -1760,6 +1761,7 @@ void Item_func_int_div::fix_length_and_dec() MY_INT64_NUM_DECIMAL_DIGITS : char_length); maybe_null=1; unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag; + return false; } @@ -1843,7 +1845,7 @@ void Item_func_mod::result_precision() } -void Item_func_mod::fix_length_and_dec() +bool Item_func_mod::fix_length_and_dec() { DBUG_ENTER("Item_func_mod::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); @@ -1851,12 +1853,12 @@ void Item_func_mod::fix_length_and_dec() const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_mod; DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;); DBUG_ASSERT(!aggregator->is_commutative()); - if (!fix_type_handler(aggregator)) - { - Item_func_mod::type_handler()->Item_func_mod_fix_length_and_dec(this); - DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - } - DBUG_VOID_RETURN; + if (fix_type_handler(aggregator)) + DBUG_RETURN(TRUE); + if (Item_func_mod::type_handler()->Item_func_mod_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); + DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); + DBUG_RETURN(FALSE); } @@ -1954,13 +1956,15 @@ void Item_func_neg::fix_length_and_dec_decimal() } -void Item_func_neg::fix_length_and_dec() +bool Item_func_neg::fix_length_and_dec() { DBUG_ENTER("Item_func_neg::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); - args[0]->cast_to_int_type_handler()->Item_func_neg_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_func_neg_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -1999,7 +2003,6 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value) return 0; } - void Item_func_abs::fix_length_and_dec_int() { max_length= args[0]->max_length; @@ -2026,13 +2029,15 @@ void Item_func_abs::fix_length_and_dec_decimal() } -void Item_func_abs::fix_length_and_dec() +bool Item_func_abs::fix_length_and_dec() { DBUG_ENTER("Item_func_abs::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); - args[0]->cast_to_int_type_handler()->Item_func_abs_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_func_abs_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2298,14 +2303,15 @@ void Item_func_int_val::fix_length_and_dec_double() } -void Item_func_int_val::fix_length_and_dec() +bool Item_func_int_val::fix_length_and_dec() { DBUG_ENTER("Item_func_int_val::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); - args[0]->cast_to_int_type_handler()-> - Item_func_int_val_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_func_int_val_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr())); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2485,7 +2491,6 @@ void Item_func_round::fix_arg_int() } else fix_length_and_dec_double(args[0]->decimals); - } @@ -3042,14 +3047,15 @@ longlong Item_func_field::val_int() } -void Item_func_field::fix_length_and_dec() +bool Item_func_field::fix_length_and_dec() { maybe_null=0; max_length=3; cmp_type= args[0]->result_type(); for (uint i=1; i < arg_count ; i++) cmp_type= item_cmp_type(cmp_type, args[i]->result_type()); if (cmp_type == STRING_RESULT) - agg_arg_charsets_for_comparison(cmp_collation, args, arg_count); + return agg_arg_charsets_for_comparison(cmp_collation, args, arg_count); + return FALSE; } @@ -3096,7 +3102,7 @@ longlong Item_func_ord::val_int() /* Returns number of found type >= 1 or 0 if not found */ /* This optimizes searching in enums to bit testing! */ -void Item_func_find_in_set::fix_length_and_dec() +bool Item_func_find_in_set::fix_length_and_dec() { decimals=0; max_length=3; // 1-999 @@ -3118,7 +3124,7 @@ void Item_func_find_in_set::fix_length_and_dec() } } } - agg_arg_charsets_for_comparison(cmp_collation, args, 2); + return agg_arg_charsets_for_comparison(cmp_collation, args, 2); } static const char separator=','; @@ -3319,7 +3325,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, DBUG_RETURN(TRUE); } } - func->fix_length_and_dec(); + if (func->fix_length_and_dec()) + DBUG_RETURN(TRUE); initid.max_length=func->max_length; initid.maybe_null=func->maybe_null; initid.const_item=func->const_item_cache; @@ -3659,13 +3666,13 @@ String *Item_func_udf_decimal::val_str(String *str) /* Default max_length is max argument length */ -void Item_func_udf_str::fix_length_and_dec() +bool Item_func_udf_str::fix_length_and_dec() { DBUG_ENTER("Item_func_udf_str::fix_length_and_dec"); max_length=0; for (uint i = 0; i < arg_count; i++) set_if_bigger(max_length,args[i]->max_length); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } String *Item_func_udf_str::val_str(String *str) @@ -4573,7 +4580,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) } -void +bool Item_func_set_user_var::fix_length_and_dec() { maybe_null=args[0]->maybe_null; @@ -4587,6 +4594,7 @@ Item_func_set_user_var::fix_length_and_dec() args[0]->collation.collation); } unsigned_flag= args[0]->unsigned_flag; + return FALSE; } @@ -5426,7 +5434,7 @@ err: return 1; } -void Item_func_get_user_var::fix_length_and_dec() +bool Item_func_get_user_var::fix_length_and_dec() { THD *thd=current_thd; int error; @@ -5475,6 +5483,7 @@ void Item_func_get_user_var::fix_length_and_dec() set_handler(&type_handler_long_blob); max_length= MAX_BLOB_WIDTH; } + return false; } @@ -5627,7 +5636,7 @@ void Item_func_get_system_var::update_null_value() } -void Item_func_get_system_var::fix_length_and_dec() +bool Item_func_get_system_var::fix_length_and_dec() { char *cptr; maybe_null= TRUE; @@ -5639,7 +5648,7 @@ void Item_func_get_system_var::fix_length_and_dec() { my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name.str, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); - return; + return TRUE; } /* As there was no local variable, return the global value */ var_type= OPT_GLOBAL; @@ -5703,6 +5712,7 @@ void Item_func_get_system_var::fix_length_and_dec() my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); break; } + return FALSE; } @@ -6362,7 +6372,7 @@ bool Item_func_sp::is_expensive() @note called from Item::fix_fields. */ -void Item_func_sp::fix_length_and_dec() +bool Item_func_sp::fix_length_and_dec() { DBUG_ENTER("Item_func_sp::fix_length_and_dec"); @@ -6372,7 +6382,7 @@ void Item_func_sp::fix_length_and_dec() collation.derivation= DERIVATION_COERCIBLE; maybe_null= 1; - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -6687,11 +6697,12 @@ bool Item_func_last_value::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) } -void Item_func_last_value::fix_length_and_dec() +bool Item_func_last_value::fix_length_and_dec() { last_value= args[arg_count -1]; Type_std_attributes::set(last_value); maybe_null= last_value->maybe_null; + return FALSE; } diff --git a/sql/item_func.h b/sql/item_func.h index 049ef82f71e..b4f3cce612d 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -397,8 +397,12 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date_from_real(ltime, fuzzydate); } const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() - { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } + bool fix_length_and_dec() + { + decimals= NOT_FIXED_DEC; + max_length= float_length(decimals); + return FALSE; + } }; @@ -784,7 +788,7 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date_from_int(ltime, fuzzydate); } const Type_handler *type_handler() const= 0; - void fix_length_and_dec() {} + bool fix_length_and_dec() { return FALSE; } }; @@ -798,7 +802,7 @@ public: Item_long_func(THD *thd, List<Item> &list): Item_int_func(thd, list) { } Item_long_func(THD *thd, Item_long_func *item) :Item_int_func(thd, item) {} const Type_handler *type_handler() const { return &type_handler_long; } - void fix_length_and_dec() { max_length= 11; } + bool fix_length_and_dec() { max_length= 11; return FALSE; } }; @@ -860,7 +864,7 @@ class Item_func_connection_id :public Item_long_func public: Item_func_connection_id(THD *thd): Item_long_func(thd) { unsigned_flag=1; } const char *func_name() const { return "connection_id"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } bool check_vcol_func_processor(void *arg) @@ -917,9 +921,9 @@ public: set_if_bigger(char_length, 1U + (unsigned_flag ? 0 : 1)); fix_char_length(char_length); } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_func_signed_fix_length_and_dec(this); + return args[0]->type_handler()->Item_func_signed_fix_length_and_dec(this); } virtual void print(String *str, enum_query_type query_type); uint decimal_precision() const { return args[0]->decimal_precision(); } @@ -949,9 +953,9 @@ public: null_value= args[0]->null_value; return value; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_func_unsigned_fix_length_and_dec(this); + return args[0]->type_handler()->Item_func_unsigned_fix_length_and_dec(this); } uint decimal_precision() const { return max_length; } virtual void print(String *str, enum_query_type query_type); @@ -980,9 +984,10 @@ public: { return get_date_from_decimal(ltime, fuzzydate); } const Type_handler *type_handler() const { return &type_handler_newdecimal; } void fix_length_and_dec_generic() {} - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_decimal_typecast_fix_length_and_dec(this); + return + args[0]->type_handler()->Item_decimal_typecast_fix_length_and_dec(this); } const char *func_name() const { return "decimal_typecast"; } virtual void print(String *str, enum_query_type query_type); @@ -1003,9 +1008,10 @@ public: } double val_real(); void fix_length_and_dec_generic() { maybe_null= 1; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_double_typecast_fix_length_and_dec(this); + return + args[0]->type_handler()->Item_double_typecast_fix_length_and_dec(this); } const char *func_name() const { return "double_typecast"; } virtual void print(String *str, enum_query_type query_type); @@ -1032,7 +1038,7 @@ public: Item_func_additive_op(thd, a, b) {} const char *func_name() const { return "+"; } enum precedence precedence() const { return ADD_PRECEDENCE; } - void fix_length_and_dec(); + bool fix_length_and_dec(); longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); @@ -1050,7 +1056,7 @@ public: longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); - void fix_length_and_dec(); + bool fix_length_and_dec(); void fix_unsigned_flag(); void fix_length_and_dec_double() { @@ -1083,7 +1089,7 @@ public: double real_op(); my_decimal *decimal_op(my_decimal *); void result_precision(); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} Item *get_copy(THD *thd) @@ -1101,7 +1107,7 @@ public: my_decimal *decimal_op(my_decimal *); const char *func_name() const { return "/"; } enum precedence precedence() const { return MUL_PRECEDENCE; } - void fix_length_and_dec(); + bool fix_length_and_dec(); void fix_length_and_dec_double(); void fix_length_and_dec_int(); void result_precision(); @@ -1120,7 +1126,7 @@ public: enum precedence precedence() const { return MUL_PRECEDENCE; } const Type_handler *type_handler() const { return type_handler_long_or_longlong(); } - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type) { print_op(str, query_type); @@ -1144,7 +1150,7 @@ public: const char *func_name() const { return "MOD"; } enum precedence precedence() const { return MUL_PRECEDENCE; } void result_precision(); - void fix_length_and_dec(); + bool fix_length_and_dec(); void fix_length_and_dec_double() { Item_num_op::fix_length_and_dec_double(); @@ -1187,7 +1193,7 @@ public: void fix_length_and_dec_int(); void fix_length_and_dec_double(); void fix_length_and_dec_decimal(); - void fix_length_and_dec(); + bool fix_length_and_dec(); uint decimal_precision() const { return args[0]->decimal_precision(); } bool need_parentheses_in_default() { return true; } Item *get_copy(THD *thd) @@ -1206,7 +1212,7 @@ public: void fix_length_and_dec_int(); void fix_length_and_dec_double(); void fix_length_and_dec_decimal(); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_abs>(thd, this); } }; @@ -1220,10 +1226,11 @@ class Item_dec_func :public Item_real_func public: Item_dec_func(THD *thd, Item *a): Item_real_func(thd, a) {} Item_dec_func(THD *thd, Item *a, Item *b): Item_real_func(thd, a, b) {} - void fix_length_and_dec() + bool fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); maybe_null=1; + return FALSE; } }; @@ -1383,7 +1390,7 @@ public: Item_func_int_val(THD *thd, Item *a): Item_func_num1(thd, a) {} void fix_length_and_dec_double(); void fix_length_and_dec_int_or_decimal(); - void fix_length_and_dec(); + bool fix_length_and_dec(); }; @@ -1429,9 +1436,9 @@ public: void fix_arg_decimal(); void fix_arg_int(); void fix_arg_double(); - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_func_round_fix_length_and_dec(this); + return args[0]->type_handler()->Item_func_round_fix_length_and_dec(this); } Item *get_copy(THD *thd) { return get_item_copy<Item_func_round>(thd, this); } @@ -1473,7 +1480,7 @@ public: Item_func_sign(THD *thd, Item *a): Item_long_func(thd, a) {} const char *func_name() const { return "sign"; } uint decimal_precision() const { return 1; } - void fix_length_and_dec() { fix_char_length(2); } + bool fix_length_and_dec() { fix_char_length(2); return FALSE; } longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_sign>(thd, this); } @@ -1492,8 +1499,12 @@ public: Item_real_func(thd, a), name(name_arg), mul(mul_arg), add(add_arg) {} double val_real(); const char *func_name() const { return name; } - void fix_length_and_dec() - { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } + bool fix_length_and_dec() + { + decimals= NOT_FIXED_DEC; + max_length= float_length(decimals); + return FALSE; + } Item *get_copy(THD *thd) { return get_item_copy<Item_func_units>(thd, this); } }; @@ -1577,11 +1588,12 @@ public: Item_func::aggregate_attributes_real(items, nitems); max_length= float_length(decimals); } - void fix_length_and_dec() + bool fix_length_and_dec() { if (aggregate_for_min_max(func_name(), args, arg_count)) - return; + return true; fix_attributes(args, arg_count); + return false; } }; @@ -1626,11 +1638,12 @@ public: const char *func_name() const { return "rollup_const"; } bool const_item() const { return 0; } const Type_handler *type_handler() const { return args[0]->type_handler(); } - void fix_length_and_dec() + bool fix_length_and_dec() { collation= args[0]->collation; max_length= args[0]->max_length; decimals=args[0]->decimals; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_rollup_const>(thd, this); } @@ -1643,7 +1656,7 @@ class Item_long_func_length: public Item_long_func { return args[0]->check_type_can_return_str(func_name()); } public: Item_long_func_length(THD *thd, Item *a): Item_long_func(thd, a) {} - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } }; @@ -1663,9 +1676,10 @@ class Item_func_bit_length :public Item_longlong_func String value; public: Item_func_bit_length(THD *thd, Item *a): Item_longlong_func(thd, a) {} - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= 11; // 0x100000000*8 = 34,359,738,368 + return FALSE; } longlong val_int(); const char *func_name() const { return "bit_length"; } @@ -1692,7 +1706,7 @@ public: Item_func_coercibility(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "coercibility"; } - void fix_length_and_dec() { max_length=10; maybe_null= 0; } + bool fix_length_and_dec() { max_length=10; maybe_null= 0; return FALSE; } bool eval_not_null_tables(void *) { not_null_tables_cache= 0; @@ -1728,10 +1742,10 @@ public: :Item_long_func(thd, a, b, c) {} const char *func_name() const { return "locate"; } longlong val_int(); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= MY_INT32_NUM_DECIMAL_DIGITS; - agg_arg_charsets_for_comparison(cmp_collation, args, 2); + return agg_arg_charsets_for_comparison(cmp_collation, args, 2); } virtual void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) @@ -1748,7 +1762,7 @@ public: Item_func_field(THD *thd, List<Item> &list): Item_long_func(thd, list) {} longlong val_int(); const char *func_name() const { return "field"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_field>(thd, this); } }; @@ -1763,7 +1777,7 @@ public: Item_func_ascii(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "ascii"; } - void fix_length_and_dec() { max_length=3; } + bool fix_length_and_dec() { max_length=3; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_ascii>(thd, this); } }; @@ -1775,7 +1789,7 @@ class Item_func_ord :public Item_long_func String value; public: Item_func_ord(THD *thd, Item *a): Item_long_func(thd, a) {} - void fix_length_and_dec() { fix_char_length(7); } + bool fix_length_and_dec() { fix_char_length(7); return FALSE; } longlong val_int(); const char *func_name() const { return "ord"; } Item *get_copy(THD *thd) @@ -1795,7 +1809,7 @@ public: Item_long_func(thd, a, b), enum_value(0) {} longlong val_int(); const char *func_name() const { return "find_in_set"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_find_in_set>(thd, this); } }; @@ -1809,7 +1823,7 @@ class Item_func_bit: public Item_longlong_func public: Item_func_bit(THD *thd, Item *a, Item *b): Item_longlong_func(thd, a, b) {} Item_func_bit(THD *thd, Item *a): Item_longlong_func(thd, a) {} - void fix_length_and_dec() { unsigned_flag= 1; } + bool fix_length_and_dec() { unsigned_flag= 1; return FALSE; } virtual inline void print(String *str, enum_query_type query_type) { @@ -1848,7 +1862,7 @@ public: Item_func_bit_count(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "bit_count"; } - void fix_length_and_dec() { max_length=2; } + bool fix_length_and_dec() { max_length=2; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_bit_count>(thd, this); } }; @@ -1901,11 +1915,12 @@ public: Item_func_last_insert_id(THD *thd, Item *a): Item_longlong_func(thd, a) {} longlong val_int(); const char *func_name() const { return "last_insert_id"; } - void fix_length_and_dec() + bool fix_length_and_dec() { unsigned_flag= true; if (arg_count) max_length= args[0]->max_length; + return FALSE; } bool fix_fields(THD *thd, Item **ref); bool check_vcol_func_processor(void *arg) @@ -1930,7 +1945,7 @@ public: {} longlong val_int(); const char *func_name() const { return "benchmark"; } - void fix_length_and_dec() { max_length=1; maybe_null=0; } + bool fix_length_and_dec() { max_length=1; maybe_null=0; return FALSE; } virtual void print(String *str, enum_query_type query_type); bool check_vcol_func_processor(void *arg) { @@ -1950,7 +1965,7 @@ class Item_func_sleep :public Item_long_func { return args[0]->check_type_can_return_real(func_name()); } public: Item_func_sleep(THD *thd, Item *a): Item_long_func(thd, a) {} - void fix_length_and_dec() { fix_char_length(1); } + bool fix_length_and_dec() { fix_char_length(1); return FALSE; } bool const_item() const { return 0; } const char *func_name() const { return "sleep"; } table_map used_tables() const @@ -2094,7 +2109,7 @@ class Item_func_udf_float :public Item_udf_func double val_real(); String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() { fix_num_length_and_dec(); } + bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_float>(thd, this); } }; @@ -2112,7 +2127,7 @@ public: double val_real() { return (double) Item_func_udf_int::val_int(); } String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_longlong; } - void fix_length_and_dec() { decimals= 0; max_length= 21; } + bool fix_length_and_dec() { decimals= 0; max_length= 21; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_int>(thd, this); } }; @@ -2130,7 +2145,7 @@ public: my_decimal *val_decimal(my_decimal *); String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_newdecimal; } - void fix_length_and_dec() { fix_num_length_and_dec(); } + bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_decimal>(thd, this); } }; @@ -2169,7 +2184,7 @@ public: return dec_buf; } const Type_handler *type_handler() const { return string_type_handler(); } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_str>(thd, this); } }; @@ -2222,7 +2237,7 @@ public: { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } - void fix_length_and_dec() { maybe_null=1; max_length=0; } + bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; } }; #endif /* HAVE_DLOPEN */ @@ -2242,7 +2257,7 @@ class Item_func_get_lock :public Item_long_func Item_func_get_lock(THD *thd, Item *a, Item *b) :Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "get_lock"; } - void fix_length_and_dec() { max_length=1; maybe_null=1;} + bool fix_length_and_dec() { max_length=1; maybe_null=1; return FALSE; } table_map used_tables() const { return used_tables_cache | RAND_TABLE_BIT; @@ -2266,7 +2281,7 @@ public: Item_func_release_lock(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "release_lock"; } - void fix_length_and_dec() { max_length= 1; maybe_null= 1;} + bool fix_length_and_dec() { max_length= 1; maybe_null= 1; return FALSE; } table_map used_tables() const { return used_tables_cache | RAND_TABLE_BIT; @@ -2303,7 +2318,7 @@ public: Item_longlong_func(thd, a, b, c, d) {} longlong val_int(); const char *func_name() const { return "master_pos_wait"; } - void fix_length_and_dec() { max_length=21; maybe_null=1;} + bool fix_length_and_dec() { max_length=21; maybe_null=1; return FALSE; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2328,7 +2343,7 @@ public: :Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "master_gtid_wait"; } - void fix_length_and_dec() { max_length=2; } + bool fix_length_and_dec() { max_length=2; return FALSE; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2425,7 +2440,7 @@ public: void save_item_result(Item *item); bool update(); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type); enum precedence precedence() const { return ASSIGN_PRECEDENCE; } void print_as_stmt(String *str, enum_query_type query_type); @@ -2460,7 +2475,7 @@ public: longlong val_int(); my_decimal *val_decimal(my_decimal*); String *val_str(String* str); - void fix_length_and_dec(); + bool fix_length_and_dec(); virtual void print(String *str, enum_query_type query_type); /* We must always return variables as strings to guard against selects of type @@ -2577,7 +2592,7 @@ public: size_t name_len_arg); enum Functype functype() const { return GSYSVAR_FUNC; } void update_null_value(); - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type); bool const_item() const { return true; } table_map used_tables() const { return 0; } @@ -2721,7 +2736,11 @@ public: Item_func_is_free_lock(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "is_free_lock"; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} + bool fix_length_and_dec() + { + decimals=0; max_length=1; maybe_null=1; + return FALSE; + } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2739,7 +2758,11 @@ public: Item_func_is_used_lock(THD *thd, Item *a): Item_long_func(thd, a) {} longlong val_int(); const char *func_name() const { return "is_used_lock"; } - void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;} + bool fix_length_and_dec() + { + decimals=0; max_length=10; maybe_null=1; + return FALSE; + } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2788,7 +2811,7 @@ public: Item_func_row_count(THD *thd): Item_longlong_func(thd) {} longlong val_int(); const char *func_name() const { return "row_count"; } - void fix_length_and_dec() { decimals= 0; maybe_null=0; } + bool fix_length_and_dec() { decimals= 0; maybe_null=0; return FALSE; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2906,7 +2929,7 @@ public: virtual enum Functype functype() const { return FUNC_SP; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(void); + bool fix_length_and_dec(void); bool is_expensive(); inline Field *get_sp_result_field() @@ -2946,7 +2969,7 @@ public: Item_func_found_rows(THD *thd): Item_longlong_func(thd) {} longlong val_int(); const char *func_name() const { return "found_rows"; } - void fix_length_and_dec() { decimals= 0; maybe_null=0; } + bool fix_length_and_dec() { decimals= 0; maybe_null=0; return FALSE; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); @@ -2989,10 +3012,11 @@ public: { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - void fix_length_and_dec() + bool fix_length_and_dec() { maybe_null= null_value= false; max_length= 11; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_sqlcode>(thd, this); } @@ -3008,8 +3032,8 @@ public: const char *func_name() const { return "uuid_short"; } longlong val_int(); bool const_item() const { return false; } - void fix_length_and_dec() - { max_length= 21; unsigned_flag=1; } + bool fix_length_and_dec() + { max_length= 21; unsigned_flag=1; return FALSE; } table_map used_tables() const { return RAND_TABLE_BIT; } bool check_vcol_func_processor(void *arg) { @@ -3031,7 +3055,7 @@ public: String *val_str(String *); my_decimal *val_decimal(my_decimal *); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "last_value"; } const Type_handler *type_handler() const { return last_value->type_handler(); } bool eval_not_null_tables(void *) @@ -3063,11 +3087,12 @@ public: Item_longlong_func(thd), table_list(table_list_arg) {} longlong val_int(); const char *func_name() const { return "nextval"; } - void fix_length_and_dec() + bool fix_length_and_dec() { unsigned_flag= 0; max_length= MAX_BIGINT_WIDTH; maybe_null= 1; /* In case of errors */ + return FALSE; } /* update_table() function must be called during the value function diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index aee44a7a01f..4c2a2fa8b11 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -40,12 +40,13 @@ #include "opt_range.h" -void Item_geometry_func::fix_length_and_dec() +bool Item_geometry_func::fix_length_and_dec() { collation.set(&my_charset_bin); decimals=0; max_length= (uint32) UINT_MAX32; maybe_null= 1; + return FALSE; } @@ -214,11 +215,12 @@ String *Item_func_as_wkt::val_str_ascii(String *str) } -void Item_func_as_wkt::fix_length_and_dec() +bool Item_func_as_wkt::fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); max_length= (uint32) UINT_MAX32; maybe_null= 1; + return FALSE; } @@ -240,11 +242,12 @@ String *Item_func_as_wkb::val_str(String *str) } -void Item_func_as_geojson::fix_length_and_dec() +bool Item_func_as_geojson::fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); max_length=MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 8101433abb5..0e727829ce7 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -38,7 +38,7 @@ public: Item_geometry_func(THD *thd, Item *a, Item *b, Item *c): Item_str_func(thd, a, b, c) {} Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); const Type_handler *type_handler() const { return &type_handler_geometry; } }; @@ -253,7 +253,7 @@ public: :Item_str_ascii_func_args_geometry(thd, a) {} const char *func_name() const { return "st_astext"; } String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_as_wkt>(thd, this); } }; @@ -266,12 +266,13 @@ public: const char *func_name() const { return "st_aswkb"; } String *val_str(String *); const Type_handler *type_handler() const { return &type_handler_long_blob; } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(&my_charset_bin); decimals=0; max_length= (uint32) UINT_MAX32; maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_as_wkb>(thd, this); } @@ -294,7 +295,7 @@ public: Item_func_as_geojson(THD *thd, Item *js, Item *max_dec_digits, Item *opt) :Item_str_ascii_func_args_geometry(thd, js, max_dec_digits, opt) {} const char *func_name() const { return "st_asgeojson"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str_ascii(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_as_geojson>(thd, this); } @@ -308,11 +309,12 @@ public: :Item_str_ascii_func_args_geometry(thd, a) {} String *val_str_ascii(String *); const char *func_name() const { return "st_geometrytype"; } - void fix_length_and_dec() + bool fix_length_and_dec() { // "GeometryCollection" is the longest fix_length_and_charset(20, default_charset()); maybe_null= 1; + return FALSE; }; Item *get_copy(THD *thd) { return get_item_copy<Item_func_geometry_type>(thd, this); } @@ -504,9 +506,10 @@ public: item_type=it; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_geometry_func::fix_length_and_dec(); + if (Item_geometry_func::fix_length_and_dec()) + return TRUE; for (unsigned int i= 0; i < arg_count; ++i) { if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY) @@ -516,8 +519,10 @@ public: str.append('\0'); my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric", str.ptr()); + return TRUE; } } + return FALSE; } const char *func_name() const { return "geometrycollection"; } @@ -727,7 +732,7 @@ public: :Item_bool_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_isempty"; } - void fix_length_and_dec() { maybe_null= 1; } + bool fix_length_and_dec() { maybe_null= 1; return FALSE; } bool need_parentheses_in_default() { return false; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_isempty>(thd, this); } @@ -744,7 +749,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_issimple"; } - void fix_length_and_dec() { decimals=0; max_length=2; } + bool fix_length_and_dec() { decimals=0; max_length=2; return FALSE; } uint decimal_precision() const { return 1; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_issimple>(thd, this); } @@ -757,7 +762,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_isclosed"; } - void fix_length_and_dec() { decimals=0; max_length=2; } + bool fix_length_and_dec() { decimals=0; max_length=2; return FALSE; } uint decimal_precision() const { return 1; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_isclosed>(thd, this); } @@ -780,7 +785,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_dimension"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_dimension>(thd, this); } }; @@ -792,10 +797,12 @@ public: Item_func_x(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {} double val_real(); const char *func_name() const { return "st_x"; } - void fix_length_and_dec() - { - Item_real_func::fix_length_and_dec(); - maybe_null= 1; + bool fix_length_and_dec() + { + if (Item_real_func::fix_length_and_dec()) + return TRUE; + maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_x>(thd, this); } @@ -808,10 +815,12 @@ public: Item_func_y(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {} double val_real(); const char *func_name() const { return "st_y"; } - void fix_length_and_dec() - { - Item_real_func::fix_length_and_dec(); - maybe_null= 1; + bool fix_length_and_dec() + { + if (Item_real_func::fix_length_and_dec()) + return TRUE; + maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_y>(thd, this); } @@ -825,7 +834,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_numgeometries"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_numgeometries>(thd, this); } }; @@ -838,7 +847,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_numinteriorrings"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_numinteriorring>(thd, this); } }; @@ -851,7 +860,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "st_numpoints"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_numpoints>(thd, this); } }; @@ -863,10 +872,12 @@ public: Item_func_area(THD *thd, Item *a): Item_real_func_args_geometry(thd, a) {} double val_real(); const char *func_name() const { return "st_area"; } - void fix_length_and_dec() - { - Item_real_func::fix_length_and_dec(); - maybe_null= 1; + bool fix_length_and_dec() + { + if (Item_real_func::fix_length_and_dec()) + return TRUE; + maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_area>(thd, this); } @@ -881,10 +892,12 @@ public: :Item_real_func_args_geometry(thd, a) {} double val_real(); const char *func_name() const { return "st_length"; } - void fix_length_and_dec() - { - Item_real_func::fix_length_and_dec(); - maybe_null= 1; + bool fix_length_and_dec() + { + if (Item_real_func::fix_length_and_dec()) + return TRUE; + maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_glength>(thd, this); } @@ -898,7 +911,7 @@ public: :Item_long_func_args_geometry(thd, a) {} longlong val_int(); const char *func_name() const { return "srid"; } - void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_srid>(thd, this); } }; @@ -944,7 +957,7 @@ class Item_func_gis_debug: public Item_long_func public: Item_func_gis_debug(THD *thd, Item *a): Item_long_func(thd, a) { null_value= false; } - void fix_length_and_dec() { fix_char_length(10); } + bool fix_length_and_dec() { fix_char_length(10); return FALSE; } const char *func_name() const { return "st_gis_debug"; } longlong val_int(); bool check_vcol_func_processor(void *arg) diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h index d934cef43dd..024ff8ce4f0 100644 --- a/sql/item_inetfunc.h +++ b/sql/item_inetfunc.h @@ -32,12 +32,13 @@ public: Item_func_inet_aton(THD *thd, Item *a): Item_longlong_func(thd, a) {} longlong val_int(); const char *func_name() const { return "inet_aton"; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_inet_aton>(thd, this); } @@ -55,11 +56,12 @@ public: { } String* val_str(String* str); const char *func_name() const { return "inet_ntoa"; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals= 0; fix_length_and_charset(3 * 8 + 7, default_charset()); maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_inet_ntoa>(thd, this); } @@ -124,11 +126,12 @@ public: virtual const char *func_name() const { return "inet6_aton"; } - virtual void fix_length_and_dec() + virtual bool fix_length_and_dec() { decimals= 0; fix_length_and_charset(16, &my_charset_bin); maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_inet6_aton>(thd, this); } @@ -153,7 +156,7 @@ public: virtual const char *func_name() const { return "inet6_ntoa"; } - virtual void fix_length_and_dec() + virtual bool fix_length_and_dec() { decimals= 0; @@ -163,6 +166,7 @@ public: fix_length_and_charset(8 * 4 + 7, default_charset()); maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_inet6_ntoa>(thd, this); } diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index e67357000da..52042c56fcc 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -388,11 +388,13 @@ longlong Item_func_json_valid::val_int() } -void Item_func_json_exists::fix_length_and_dec() +bool Item_func_json_exists::fix_length_and_dec() { - Item_bool_func::fix_length_and_dec(); + if (Item_bool_func::fix_length_and_dec()) + return TRUE; maybe_null= 1; path.set_constant_flag(args[1]->const_item()); + return FALSE; } @@ -439,12 +441,13 @@ err_return: } -void Item_func_json_value::fix_length_and_dec() +bool Item_func_json_value::fix_length_and_dec() { collation.set(args[0]->collation); max_length= args[0]->max_length; path.set_constant_flag(args[1]->const_item()); maybe_null= 1; + return FALSE; } @@ -546,7 +549,7 @@ bool Item_func_json_query::check_and_get_value(json_engine_t *je, String *res, } -void Item_func_json_quote::fix_length_and_dec() +bool Item_func_json_quote::fix_length_and_dec() { collation.set(&my_charset_utf8mb4_bin); /* @@ -554,6 +557,7 @@ void Item_func_json_quote::fix_length_and_dec() of the argument turn into '\uXXXX\uXXXX', which is 12. */ max_length= args[0]->max_length * 12 + 2; + return FALSE; } @@ -581,12 +585,13 @@ String *Item_func_json_quote::val_str(String *str) } -void Item_func_json_unquote::fix_length_and_dec() +bool Item_func_json_unquote::fix_length_and_dec() { collation.set(&my_charset_utf8_general_ci, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); max_length= args[0]->max_length; maybe_null= 1; + return FALSE; } @@ -702,13 +707,14 @@ void Item_json_str_multipath::cleanup() } -void Item_func_json_extract::fix_length_and_dec() +bool Item_func_json_extract::fix_length_and_dec() { collation.set(args[0]->collation); max_length= args[0]->max_length * (arg_count - 1); mark_constant_paths(paths, args+1, arg_count-1); maybe_null= 1; + return FALSE; } @@ -937,14 +943,14 @@ double Item_func_json_extract::val_real() } -void Item_func_json_contains::fix_length_and_dec() +bool Item_func_json_contains::fix_length_and_dec() { a2_constant= args[1]->const_item(); a2_parsed= FALSE; maybe_null= 1; if (arg_count > 2) path.set_constant_flag(args[2]->const_item()); - Item_bool_func::fix_length_and_dec(); + return Item_bool_func::fix_length_and_dec(); } @@ -1190,13 +1196,13 @@ bool Item_func_json_contains_path::fix_fields(THD *thd, Item **ref) } -void Item_func_json_contains_path::fix_length_and_dec() +bool Item_func_json_contains_path::fix_length_and_dec() { ooa_constant= args[1]->const_item(); ooa_parsed= FALSE; maybe_null= 1; mark_constant_paths(paths, args+2, arg_count-2); - Item_bool_func::fix_length_and_dec(); + return Item_bool_func::fix_length_and_dec(); } @@ -1455,7 +1461,7 @@ append_null: } -void Item_func_json_array::fix_length_and_dec() +bool Item_func_json_array::fix_length_and_dec() { ulonglong char_length= 2; uint n_arg; @@ -1468,17 +1474,18 @@ void Item_func_json_array::fix_length_and_dec() DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); tmp_val.set_charset(&my_charset_utf8_general_ci); max_length= 2; - return; + return FALSE; } if (agg_arg_charsets_for_string_result(collation, args, arg_count)) - return; + return TRUE; for (n_arg=0 ; n_arg < arg_count ; n_arg++) char_length+= args[n_arg]->max_char_length() + 4; fix_char_length_ulonglong(char_length); tmp_val.set_charset(collation.collation); + return FALSE; } @@ -1522,7 +1529,7 @@ err_return: } -void Item_func_json_array_append::fix_length_and_dec() +bool Item_func_json_array_append::fix_length_and_dec() { uint n_arg; ulonglong char_length; @@ -1537,6 +1544,7 @@ void Item_func_json_array_append::fix_length_and_dec() } fix_char_length_ulonglong(char_length); + return FALSE; } @@ -2124,12 +2132,13 @@ null_return: } -void Item_func_json_length::fix_length_and_dec() +bool Item_func_json_length::fix_length_and_dec() { if (arg_count > 1) path.set_constant_flag(args[1]->const_item()); maybe_null= 1; max_length= 10; + return FALSE; } @@ -2269,11 +2278,12 @@ longlong Item_func_json_depth::val_int() } -void Item_func_json_type::fix_length_and_dec() +bool Item_func_json_type::fix_length_and_dec() { collation.set(&my_charset_utf8_general_ci); max_length= 12; maybe_null= 1; + return FALSE; } @@ -2326,7 +2336,7 @@ error: } -void Item_func_json_insert::fix_length_and_dec() +bool Item_func_json_insert::fix_length_and_dec() { uint n_arg; ulonglong char_length; @@ -2342,6 +2352,7 @@ void Item_func_json_insert::fix_length_and_dec() fix_char_length_ulonglong(char_length); maybe_null= 1; + return FALSE; } @@ -2586,13 +2597,14 @@ return_null: } -void Item_func_json_remove::fix_length_and_dec() +bool Item_func_json_remove::fix_length_and_dec() { collation.set(args[0]->collation); max_length= args[0]->max_length; mark_constant_paths(paths, args+1, arg_count-1); maybe_null= 1; + return FALSE; } @@ -2772,13 +2784,14 @@ null_return: } -void Item_func_json_keys::fix_length_and_dec() +bool Item_func_json_keys::fix_length_and_dec() { collation.set(args[0]->collation); max_length= args[0]->max_length; maybe_null= 1; if (arg_count > 1) path.set_constant_flag(args[1]->const_item()); + return FALSE; } @@ -2939,7 +2952,7 @@ bool Item_func_json_search::fix_fields(THD *thd, Item **ref) static const uint SQR_MAX_BLOB_WIDTH= (uint) sqrt(MAX_BLOB_WIDTH); -void Item_func_json_search::fix_length_and_dec() +bool Item_func_json_search::fix_length_and_dec() { collation.set(args[0]->collation); @@ -2961,6 +2974,7 @@ void Item_func_json_search::fix_length_and_dec() if (arg_count > 4) mark_constant_paths(paths, args+4, arg_count-4); maybe_null= 1; + return FALSE; } @@ -3138,11 +3152,12 @@ const char *Item_func_json_format::func_name() const } -void Item_func_json_format::fix_length_and_dec() +bool Item_func_json_format::fix_length_and_dec() { decimals= 0; max_length= args[0]->max_length; maybe_null= 1; + return FALSE; } diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 354de69eee4..af0995b9605 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -49,10 +49,12 @@ public: Item_func_json_valid(THD *thd, Item *json) : Item_bool_func(thd, json) {} longlong val_int(); const char *func_name() const { return "json_valid"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_bool_func::fix_length_and_dec(); + if (Item_bool_func::fix_length_and_dec()) + return TRUE; maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_valid>(thd, this); } @@ -69,7 +71,7 @@ public: Item_func_json_exists(THD *thd, Item *js, Item *i_path): Item_bool_func(thd, js, i_path) {} const char *func_name() const { return "json_exists"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_exists>(thd, this); } longlong val_int(); @@ -86,7 +88,7 @@ public: Item_func_json_value(THD *thd, Item *js, Item *i_path): Item_str_func(thd, js, i_path) {} const char *func_name() const { return "json_value"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); virtual bool check_and_get_value(json_engine_t *je, String *res, int *error); Item *get_copy(THD *thd) @@ -115,7 +117,7 @@ protected: public: Item_func_json_quote(THD *thd, Item *s): Item_str_func(thd, s) {} const char *func_name() const { return "json_quote"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_quote>(thd, this); } @@ -130,7 +132,7 @@ protected: public: Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s) {} const char *func_name() const { return "json_unquote"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_unquote>(thd, this); } @@ -163,7 +165,7 @@ public: Item_json_str_multipath(thd, list) {} const char *func_name() const { return "json_extract"; } enum Functype functype() const { return JSON_EXTRACT_FUNC; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); longlong val_int(); double val_real(); @@ -185,7 +187,7 @@ public: Item_func_json_contains(THD *thd, List<Item> &list): Item_bool_func(thd, list) {} const char *func_name() const { return "json_contains"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_contains>(thd, this); } @@ -207,7 +209,7 @@ public: Item_bool_func(thd, list), tmp_paths(0) {} const char *func_name() const { return "json_contains_path"; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); void cleanup(); longlong val_int(); Item *get_copy(THD *thd) @@ -227,7 +229,7 @@ public: Item_str_func(thd, list) {} String *val_str(String *); bool is_json_type() { return true; } - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "json_array"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_array>(thd, this); } @@ -242,7 +244,7 @@ protected: public: Item_func_json_array_append(THD *thd, List<Item> &list): Item_json_str_multipath(thd, list) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); uint get_n_paths() const { return arg_count/2; } const char *func_name() const { return "json_array_append"; } @@ -309,7 +311,7 @@ public: Item_func_json_length(THD *thd, List<Item> &list): Item_long_func(thd, list) {} const char *func_name() const { return "json_length"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_length>(thd, this); } @@ -325,7 +327,7 @@ protected: public: Item_func_json_depth(THD *thd, Item *js): Item_long_func(thd, js) {} const char *func_name() const { return "json_depth"; } - void fix_length_and_dec() { max_length= 10; } + bool fix_length_and_dec() { max_length= 10; return FALSE; } longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_depth>(thd, this); } @@ -339,7 +341,7 @@ protected: public: Item_func_json_type(THD *thd, Item *js): Item_str_func(thd, js) {} const char *func_name() const { return "json_type"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_type>(thd, this); } @@ -356,7 +358,7 @@ public: Item_func_json_insert(bool i_mode, bool r_mode, THD *thd, List<Item> &list): Item_json_str_multipath(thd, list), mode_insert(i_mode), mode_replace(r_mode) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); uint get_n_paths() const { return arg_count/2; } const char *func_name() const @@ -376,7 +378,7 @@ protected: public: Item_func_json_remove(THD *thd, List<Item> &list): Item_json_str_multipath(thd, list) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); uint get_n_paths() const { return arg_count - 1; } const char *func_name() const { return "json_remove"; } @@ -395,7 +397,7 @@ public: Item_func_json_keys(THD *thd, List<Item> &list): Item_str_func(thd, list) {} const char *func_name() const { return "json_keys"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_keys>(thd, this); } @@ -419,7 +421,7 @@ public: Item_json_str_multipath(thd, list) {} const char *func_name() const { return "json_search"; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *); uint get_n_paths() const { return arg_count > 4 ? arg_count - 4 : 0; } Item *get_copy(THD *thd) @@ -447,7 +449,7 @@ public: Item_str_func(thd, list), fmt(DETAILED) {} const char *func_name() const; - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str(String *str); String *val_json(String *str); bool is_json_type() { return true; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6af49d494d4..c914c6cbdf8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -188,10 +188,11 @@ String *Item_func_sha::val_str_ascii(String *str) return 0; } -void Item_func_sha::fix_length_and_dec() +bool Item_func_sha::fix_length_and_dec() { // size of hex representation of hash fix_length_and_charset(MY_SHA1_HASH_SIZE * 2, default_charset()); + return FALSE; } String *Item_func_sha2::val_str_ascii(String *str) @@ -267,7 +268,7 @@ String *Item_func_sha2::val_str_ascii(String *str) } -void Item_func_sha2::fix_length_and_dec() +bool Item_func_sha2::fix_length_and_dec() { maybe_null= 1; max_length = 0; @@ -292,6 +293,7 @@ void Item_func_sha2::fix_length_and_dec() ER_THD(thd, ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2"); } + return FALSE; } /* Implementation of AES encryption routines */ @@ -344,23 +346,25 @@ String *Item_aes_crypt::val_str(String *str2) return 0; } -void Item_func_aes_encrypt::fix_length_and_dec() +bool Item_func_aes_encrypt::fix_length_and_dec() { max_length=my_aes_get_size(MY_AES_ECB, args[0]->max_length); what= ENCRYPTION_FLAG_ENCRYPT; + return FALSE; } -void Item_func_aes_decrypt::fix_length_and_dec() +bool Item_func_aes_decrypt::fix_length_and_dec() { max_length=args[0]->max_length; maybe_null= 1; what= ENCRYPTION_FLAG_DECRYPT; + return FALSE; } -void Item_func_to_base64::fix_length_and_dec() +bool Item_func_to_base64::fix_length_and_dec() { maybe_null= args[0]->maybe_null; collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); @@ -375,6 +379,7 @@ void Item_func_to_base64::fix_length_and_dec() DBUG_ASSERT(length > 0); fix_char_length_ulonglong((ulonglong) length - 1); } + return FALSE; } @@ -410,7 +415,7 @@ String *Item_func_to_base64::val_str_ascii(String *str) } -void Item_func_from_base64::fix_length_and_dec() +bool Item_func_from_base64::fix_length_and_dec() { if (args[0]->max_length > (uint) my_base64_decode_max_arg_length()) { @@ -422,6 +427,7 @@ void Item_func_from_base64::fix_length_and_dec() fix_char_length_ulonglong((ulonglong) length); } maybe_null= 1; // Can be NULL, e.g. in case of badly formed input string + return FALSE; } @@ -670,17 +676,18 @@ bool Item_func_concat::append_value(THD *thd, String *res, const String *app) } -void Item_func_concat::fix_length_and_dec() +bool Item_func_concat::fix_length_and_dec() { ulonglong char_length= 0; if (agg_arg_charsets_for_string_result(collation, args, arg_count)) - return; + return TRUE; for (uint i=0 ; i < arg_count ; i++) char_length+= args[i]->max_char_length(); fix_char_length_ulonglong(char_length); + return FALSE; } /** @@ -1032,12 +1039,12 @@ null: } -void Item_func_concat_ws::fix_length_and_dec() +bool Item_func_concat_ws::fix_length_and_dec() { ulonglong char_length; if (agg_arg_charsets_for_string_result(collation, args, arg_count)) - return; + return TRUE; /* arg_count cannot be less than 2, @@ -1049,6 +1056,7 @@ void Item_func_concat_ws::fix_length_and_dec() char_length+= args[i]->max_char_length(); fix_char_length_ulonglong(char_length); + return FALSE; } @@ -1102,11 +1110,13 @@ String *Item_func_reverse::val_str(String *str) } -void Item_func_reverse::fix_length_and_dec() +bool Item_func_reverse::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); fix_char_length(args[0]->max_char_length()); + return FALSE; } /** @@ -1259,7 +1269,7 @@ null: } -void Item_func_replace::fix_length_and_dec() +bool Item_func_replace::fix_length_and_dec() { ulonglong char_length= (ulonglong) args[0]->max_char_length(); int diff=(int) (args[2]->max_char_length() - args[1]->max_char_length()); @@ -1270,8 +1280,9 @@ void Item_func_replace::fix_length_and_dec() } if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3)) - return; + return TRUE; fix_char_length_ulonglong(char_length); + return FALSE; } @@ -1283,13 +1294,14 @@ bool Item_func_regexp_replace::fix_fields(THD *thd, Item **ref) } -void Item_func_regexp_replace::fix_length_and_dec() +bool Item_func_regexp_replace::fix_length_and_dec() { if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3)) - return; + return TRUE; max_length= MAX_BLOB_WIDTH; re.init(collation.collation, 0); re.fix_owner(this, args[0], args[1]); + return FALSE; } @@ -1425,13 +1437,14 @@ bool Item_func_regexp_substr::fix_fields(THD *thd, Item **ref) } -void Item_func_regexp_substr::fix_length_and_dec() +bool Item_func_regexp_substr::fix_length_and_dec() { if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2)) - return; + return TRUE; fix_char_length(args[0]->max_char_length()); re.init(collation.collation, 0); re.fix_owner(this, args[0], args[1]); + return FALSE; } @@ -1539,16 +1552,17 @@ null: } -void Item_func_insert::fix_length_and_dec() +bool Item_func_insert::fix_length_and_dec() { ulonglong char_length; // Handle character set for args[0] and args[3]. if (agg_arg_charsets_for_string_result(collation, args, 2, 3)) - return; + return TRUE; char_length= ((ulonglong) args[0]->max_char_length() + (ulonglong) args[3]->max_char_length()); fix_char_length_ulonglong(char_length); + return FALSE; } @@ -1585,22 +1599,26 @@ String *Item_str_conv::val_str(String *str) } -void Item_func_lcase::fix_length_and_dec() +bool Item_func_lcase::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); multiply= collation.collation->casedn_multiply; converter= collation.collation->cset->casedn; fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply); + return FALSE; } -void Item_func_ucase::fix_length_and_dec() +bool Item_func_ucase::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); multiply= collation.collation->caseup_multiply; converter= collation.collation->cset->caseup; fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply); + return FALSE; } @@ -1643,11 +1661,13 @@ void Item_str_func::left_right_max_length() } -void Item_func_left::fix_length_and_dec() +bool Item_func_left::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); left_right_max_length(); + return FALSE; } @@ -1677,11 +1697,13 @@ String *Item_func_right::val_str(String *str) } -void Item_func_right::fix_length_and_dec() +bool Item_func_right::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); left_right_max_length(); + return FALSE; } @@ -1732,11 +1754,12 @@ String *Item_func_substr::val_str(String *str) } -void Item_func_substr::fix_length_and_dec() +bool Item_func_substr::fix_length_and_dec() { max_length=args[0]->max_length; - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); if (args[1]->const_item()) { @@ -1757,14 +1780,16 @@ void Item_func_substr::fix_length_and_dec() set_if_smaller(max_length,(uint) length); } max_length*= collation.collation->mbmaxlen; + return FALSE; } -void Item_func_substr_index::fix_length_and_dec() -{ +bool Item_func_substr_index::fix_length_and_dec() +{ if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2)) - return; + return TRUE; fix_char_length(args[0]->max_char_length()); + return FALSE; } @@ -2088,11 +2113,12 @@ String *Item_func_trim::val_str(String *str) return trimmed_value(res, (uint32) (ptr - res->ptr()), (uint32) (end - ptr)); } -void Item_func_trim::fix_length_and_dec() +bool Item_func_trim::fix_length_and_dec() { if (arg_count == 1) { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); remove.set_charset(collation.collation); remove.set_ascii(" ",1); @@ -2103,9 +2129,10 @@ void Item_func_trim::fix_length_and_dec() // Note that we pass args[1] as the first item, and args[0] as the second. if (agg_arg_charsets_for_string_result_with_comparison(collation, &args[1], 2, -1)) - return; + return TRUE; } fix_char_length(args[0]->max_char_length()); + return FALSE; } void Item_func_trim::print(String *str, enum_query_type query_type) @@ -2245,7 +2272,7 @@ bool Item_func_encode::seed() return FALSE; } -void Item_func_encode::fix_length_and_dec() +bool Item_func_encode::fix_length_and_dec() { max_length=args[0]->max_length; maybe_null=args[0]->maybe_null || args[1]->maybe_null; @@ -2253,6 +2280,7 @@ void Item_func_encode::fix_length_and_dec() /* Precompute the seed state if the item is constant. */ seeded= args[1]->const_item() && (args[1]->result_type() == STRING_RESULT) && !seed(); + return FALSE; } String *Item_func_encode::val_str(String *str) @@ -2417,13 +2445,15 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref) return 0; } -void Item_func_soundex::fix_length_and_dec() +bool Item_func_soundex::fix_length_and_dec() { uint32 char_length= args[0]->max_char_length(); - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); set_if_bigger(char_length, 4); fix_char_length(char_length); + return FALSE; } @@ -2581,7 +2611,7 @@ String *Item_func_soundex::val_str(String *str) const int FORMAT_MAX_DECIMALS= 30; -void Item_func_format::fix_length_and_dec() +bool Item_func_format::fix_length_and_dec() { uint32 char_length= args[0]->max_char_length(); uint32 max_sep_count= (char_length / 3) + (decimals ? 1 : 0) + /*sign*/1; @@ -2591,6 +2621,7 @@ void Item_func_format::fix_length_and_dec() locale= args[2]->basic_const_item() ? args[2]->locale_from_val_str() : NULL; else locale= &my_locale_en_US; /* Two arguments */ + return FALSE; } @@ -2704,13 +2735,13 @@ String *Item_func_format::val_str_ascii(String *str) } -void Item_func_elt::fix_length_and_dec() +bool Item_func_elt::fix_length_and_dec() { uint32 char_length= 0; decimals=0; if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1)) - return; + return TRUE; for (uint i= 1 ; i < arg_count ; i++) { @@ -2719,6 +2750,7 @@ void Item_func_elt::fix_length_and_dec() } fix_char_length(char_length); maybe_null=1; // NULL if wrong first arg + return FALSE; } @@ -2765,16 +2797,17 @@ String *Item_func_elt::val_str(String *str) } -void Item_func_make_set::fix_length_and_dec() +bool Item_func_make_set::fix_length_and_dec() { uint32 char_length= arg_count - 2; /* Separators */ if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1)) - return; + return TRUE; for (uint i=1 ; i < arg_count ; i++) char_length+= args[i]->max_char_length(); fix_char_length(char_length); + return FALSE; } @@ -2927,9 +2960,10 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value, } -void Item_func_repeat::fix_length_and_dec() +bool Item_func_repeat::fix_length_and_dec() { - agg_arg_charsets_for_string_result(collation, args, 1); + if (agg_arg_charsets_for_string_result(collation, args, 1)) + return TRUE; DBUG_ASSERT(collation.collation != NULL); if (args[1]->const_item()) { @@ -2951,6 +2985,7 @@ void Item_func_repeat::fix_length_and_dec() max_length= MAX_BLOB_WIDTH; maybe_null= 1; } + return FALSE; } /** @@ -3012,7 +3047,7 @@ err: } -void Item_func_space::fix_length_and_dec() +bool Item_func_space::fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); if (args[0]->const_item()) @@ -3028,12 +3063,13 @@ void Item_func_space::fix_length_and_dec() if (count > INT_MAX32) count= INT_MAX32; fix_char_length_ulonglong(count); - return; + return FALSE; } end: max_length= MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } @@ -3083,11 +3119,12 @@ err: } -void Item_func_binlog_gtid_pos::fix_length_and_dec() +bool Item_func_binlog_gtid_pos::fix_length_and_dec() { collation.set(system_charset_info); max_length= MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } @@ -3123,18 +3160,18 @@ err: } -void Item_func_pad::fix_length_and_dec() +bool Item_func_pad::fix_length_and_dec() { if (arg_count == 3) { // Handle character set for args[0] and args[2]. if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2)) - return; + return TRUE; } else { if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1)) - return; + return TRUE; pad_str.set_charset(collation.collation); pad_str.length(0); pad_str.append(" ", 1); @@ -3157,6 +3194,7 @@ void Item_func_pad::fix_length_and_dec() max_length= MAX_BLOB_WIDTH; maybe_null= 1; } + return FALSE; } @@ -3411,10 +3449,11 @@ String *Item_func_conv_charset::val_str(String *str) 0 : str; } -void Item_func_conv_charset::fix_length_and_dec() +bool Item_func_conv_charset::fix_length_and_dec() { DBUG_ASSERT(collation.derivation == DERIVATION_IMPLICIT); fix_char_length(args[0]->max_char_length()); + return FALSE; } void Item_func_conv_charset::print(String *str, enum_query_type query_type) @@ -3436,17 +3475,18 @@ String *Item_func_set_collation::val_str(String *str) return str; } -void Item_func_set_collation::fix_length_and_dec() +bool Item_func_set_collation::fix_length_and_dec() { if (!my_charset_same(args[0]->collation.collation, m_set_collation)) { my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), m_set_collation->name, args[0]->collation.collation->csname); - return; + return TRUE; } collation.set(m_set_collation, DERIVATION_EXPLICIT, args[0]->collation.repertoire); max_length= args[0]->max_length; + return FALSE; } @@ -3489,7 +3529,7 @@ String *Item_func_collation::val_str(String *str) } -void Item_func_weight_string::fix_length_and_dec() +bool Item_func_weight_string::fix_length_and_dec() { CHARSET_INFO *cs= args[0]->collation.collation; collation.set(&my_charset_bin, args[0]->collation.derivation); @@ -3507,6 +3547,7 @@ void Item_func_weight_string::fix_length_and_dec() max_length= (uint32)cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen); } maybe_null= 1; + return FALSE; } @@ -3878,15 +3919,16 @@ String* Item_func_export_set::val_str(String* str) return str; } -void Item_func_export_set::fix_length_and_dec() +bool Item_func_export_set::fix_length_and_dec() { uint32 length= MY_MAX(args[1]->max_char_length(), args[2]->max_char_length()); uint32 sep_length= (arg_count > 3 ? args[3]->max_char_length() : 1); if (agg_arg_charsets_for_string_result(collation, args + 1, MY_MIN(4, arg_count) - 1)) - return; + return TRUE; fix_char_length(length * 64 + sep_length * 63); + return FALSE; } @@ -4286,12 +4328,13 @@ bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref) } -void Item_func_dyncol_create::fix_length_and_dec() +bool Item_func_dyncol_create::fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; maybe_null= TRUE; collation.set(&my_charset_bin); decimals= 0; + return FALSE; } bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg) @@ -5211,10 +5254,11 @@ Item_temptable_rowid::Item_temptable_rowid(TABLE *table_arg) max_length= table->file->ref_length; } -void Item_temptable_rowid::fix_length_and_dec() +bool Item_temptable_rowid::fix_length_and_dec() { used_tables_cache= table->map; const_item_cache= false; + return FALSE; } String *Item_temptable_rowid::val_str(String *str) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index eb084c3f58d..29af0b43d9d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -144,9 +144,10 @@ class Item_func_md5 :public Item_str_ascii_checksum_func public: Item_func_md5(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { fix_length_and_charset(32, default_charset()); + return FALSE; } const char *func_name() const { return "md5"; } Item *get_copy(THD *thd) @@ -159,7 +160,7 @@ class Item_func_sha :public Item_str_ascii_checksum_func public: Item_func_sha(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "sha"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_sha>(thd, this); } @@ -171,7 +172,7 @@ public: Item_func_sha2(THD *thd, Item *a, Item *b) :Item_str_ascii_checksum_func(thd, a, b) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "sha2"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_sha2>(thd, this); } @@ -184,7 +185,7 @@ public: Item_func_to_base64(THD *thd, Item *a) :Item_str_ascii_checksum_func(thd, a) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "to_base64"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_to_base64>(thd, this); } @@ -197,7 +198,7 @@ public: Item_func_from_base64(THD *thd, Item *a) :Item_str_binary_checksum_func(thd, a) { } String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "from_base64"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_from_base64>(thd, this); } @@ -224,7 +225,7 @@ class Item_func_aes_encrypt :public Item_aes_crypt public: Item_func_aes_encrypt(THD *thd, Item *a, Item *b) :Item_aes_crypt(thd, a, b) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "aes_encrypt"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_aes_encrypt>(thd, this); } @@ -235,7 +236,7 @@ class Item_func_aes_decrypt :public Item_aes_crypt public: Item_func_aes_decrypt(THD *thd, Item *a, Item *b): Item_aes_crypt(thd, a, b) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "aes_decrypt"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_aes_decrypt>(thd, this); } @@ -259,7 +260,7 @@ public: Item_func_concat(THD *thd, List<Item> &list): Item_str_func(thd, list) {} Item_func_concat(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "concat"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_concat>(thd, this); } @@ -294,11 +295,12 @@ public: Item_func_decode_histogram(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(system_charset_info); max_length= MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } const char *func_name() const { return "decode_histogram"; } Item *get_copy(THD *thd) @@ -311,7 +313,7 @@ class Item_func_concat_ws :public Item_str_func public: Item_func_concat_ws(THD *thd, List<Item> &list): Item_str_func(thd, list) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "concat_ws"; } table_map not_null_tables() const { return 0; } Item *get_copy(THD *thd) @@ -324,7 +326,7 @@ class Item_func_reverse :public Item_str_func public: Item_func_reverse(THD *thd, Item *a): Item_str_func(thd, a) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "reverse"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_reverse>(thd, this); } @@ -338,7 +340,7 @@ public: Item_func_replace(THD *thd, Item *org, Item *find, Item *replace): Item_str_func(thd, org, find, replace) {} String *val_str(String *to) { return val_str_internal(to, NULL); }; - void fix_length_and_dec(); + bool fix_length_and_dec(); String *val_str_internal(String *str, String *empty_string_for_null); const char *func_name() const { return "replace"; } Item *get_copy(THD *thd) @@ -378,7 +380,7 @@ public: } String *val_str(String *str); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "regexp_replace"; } Item *get_copy(THD *thd) { return 0;} }; @@ -400,7 +402,7 @@ public: } String *val_str(String *str); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "regexp_substr"; } Item *get_copy(THD *thd) { return 0; } }; @@ -414,7 +416,7 @@ public: Item *new_str): Item_str_func(thd, org, start, length, new_str) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "insert"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_insert>(thd, this); } @@ -438,7 +440,7 @@ class Item_func_lcase :public Item_str_conv public: Item_func_lcase(THD *thd, Item *item): Item_str_conv(thd, item) {} const char *func_name() const { return "lcase"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_lcase>(thd, this); } }; @@ -448,7 +450,7 @@ class Item_func_ucase :public Item_str_conv public: Item_func_ucase(THD *thd, Item *item): Item_str_conv(thd, item) {} const char *func_name() const { return "ucase"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_ucase>(thd, this); } }; @@ -460,7 +462,7 @@ class Item_func_left :public Item_str_func public: Item_func_left(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "left"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_left>(thd, this); } @@ -473,7 +475,7 @@ class Item_func_right :public Item_str_func public: Item_func_right(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "right"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_right>(thd, this); } @@ -490,7 +492,7 @@ public: Item_func_substr(THD *thd, Item *a, Item *b, Item *c): Item_str_func(thd, a, b, c) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "substr"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_substr>(thd, this); } @@ -508,10 +510,11 @@ public: Item_func_substr(thd, a, b) {} Item_func_substr_oracle(THD *thd, Item *a, Item *b, Item *c): Item_func_substr(thd, a, b, c) {} - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_substr::fix_length_and_dec(); + bool res= Item_func_substr::fix_length_and_dec(); maybe_null= true; + return res; } const char *func_name() const { return "substr_oracle"; } Item *get_copy(THD *thd) @@ -525,7 +528,7 @@ public: Item_func_substr_index(THD *thd, Item *a,Item *b,Item *c): Item_str_func(thd, a, b, c) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "substring_index"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_substr_index>(thd, this); } @@ -561,7 +564,7 @@ public: Item_func_trim(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} Item_func_trim(THD *thd, Item *a): Item_str_func(thd, a) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "trim"; } void print(String *str, enum_query_type query_type); virtual const char *mode_name() const { return "both"; } @@ -581,10 +584,11 @@ public: Item_func_trim(thd, a, b) {} Item_func_trim_oracle(THD *thd, Item *a): Item_func_trim(thd, a) {} const char *func_name() const { return "trim_oracle"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_trim::fix_length_and_dec(); + bool res= Item_func_trim::fix_length_and_dec(); maybe_null= true; + return res; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_trim_oracle>(thd, this); } @@ -615,10 +619,11 @@ public: Item_func_ltrim(thd, a, b) {} Item_func_ltrim_oracle(THD *thd, Item *a): Item_func_ltrim(thd, a) {} const char *func_name() const { return "ltrim_oracle"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_ltrim::fix_length_and_dec(); + bool res= Item_func_ltrim::fix_length_and_dec(); maybe_null= true; + return res; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_ltrim_oracle>(thd, this); } @@ -649,10 +654,11 @@ public: Item_func_rtrim(thd, a, b) {} Item_func_rtrim_oracle(THD *thd, Item *a): Item_func_rtrim(thd, a) {} const char *func_name() const { return "rtrim_oracle"; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_rtrim::fix_length_and_dec(); + bool res= Item_func_rtrim::fix_length_and_dec(); maybe_null= true; + return res; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_rtrim_oracle>(thd, this); } @@ -681,12 +687,13 @@ public: Item_str_ascii_checksum_func(thd, a), alg(al), deflt(0) {} String *val_str_ascii(String *str); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec() + bool fix_length_and_dec() { fix_length_and_charset((alg == 1 ? SCRAMBLED_PASSWORD_CHAR_LENGTH : SCRAMBLED_PASSWORD_CHAR_LENGTH_323), default_charset()); + return FALSE; } const char *func_name() const { return ((deflt || alg == 1) ? "password" : "old_password"); } @@ -707,11 +714,12 @@ public: Item_func_des_encrypt(THD *thd, Item *a, Item *b) :Item_str_binary_checksum_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { maybe_null=1; /* 9 = MAX ((8- (arg_len % 8)) + 1) */ max_length = args[0]->max_length + 9; + return FALSE; } const char *func_name() const { return "des_encrypt"; } Item *get_copy(THD *thd) @@ -727,13 +735,14 @@ public: Item_func_des_decrypt(THD *thd, Item *a, Item *b) :Item_str_binary_checksum_func(thd, a, b) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { maybe_null=1; /* 9 = MAX ((8- (arg_len % 8)) + 1) */ max_length= args[0]->max_length; if (max_length >= 9U) max_length-= 9U; + return FALSE; } const char *func_name() const { return "des_decrypt"; } Item *get_copy(THD *thd) @@ -766,7 +775,7 @@ public: constructor_helper(); } String *val_str(String *); - void fix_length_and_dec() { maybe_null=1; max_length = 13; } + bool fix_length_and_dec() { maybe_null=1; max_length = 13; return FALSE; } const char *func_name() const { return "encrypt"; } bool check_vcol_func_processor(void *arg) { @@ -790,7 +799,7 @@ public: Item_func_encode(THD *thd, Item *a, Item *seed_arg): Item_str_binary_checksum_func(thd, a, seed_arg) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "encode"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_encode>(thd, this); } @@ -840,10 +849,11 @@ class Item_func_database :public Item_func_sysconst public: Item_func_database(THD *thd): Item_func_sysconst(thd) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen; maybe_null=1; + return FALSE; } const char *func_name() const { return "database"; } const char *fully_qualified_func_name() const { return "database()"; } @@ -863,10 +873,11 @@ public: { str->append(func_name()); } - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= 512 * system_charset_info->mbmaxlen; null_value= maybe_null= false; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_sqlerrm>(thd, this); } @@ -889,10 +900,11 @@ public: return (null_value ? 0 : &str_value); } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= (uint32) (username_char_length + HOSTNAME_LENGTH + 1) * SYSTEM_CHARSET_MBMAXLEN; + return FALSE; } const char *func_name() const { return "user"; } const char *fully_qualified_func_name() const { return "user()"; } @@ -932,8 +944,11 @@ public: Item_func_current_role(THD *thd, Name_resolution_context *context_arg): Item_func_sysconst(thd), context(context_arg) {} bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec() - { max_length= (uint32) username_char_length * SYSTEM_CHARSET_MBMAXLEN; } + bool fix_length_and_dec() + { + max_length= (uint32) username_char_length * SYSTEM_CHARSET_MBMAXLEN; + return FALSE; + } int save_in_field(Field *field, bool no_conversions) { return save_str_value_in_field(field, &str_value); } const char *func_name() const { return "current_role"; } @@ -961,7 +976,7 @@ class Item_func_soundex :public Item_str_func public: Item_func_soundex(THD *thd, Item *a): Item_str_func(thd, a) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "soundex"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_soundex>(thd, this); } @@ -975,7 +990,7 @@ public: double val_real(); longlong val_int(); String *val_str(String *str); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "elt"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_elt>(thd, this); } @@ -989,7 +1004,7 @@ class Item_func_make_set :public Item_str_func public: Item_func_make_set(THD *thd, List<Item> &list): Item_str_func(thd, list) {} String *val_str(String *str); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "make_set"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_make_set>(thd, this); } @@ -1006,7 +1021,7 @@ public: Item_str_ascii_func(thd, org, dec, lang) {} String *val_str_ascii(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "format"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_format>(thd, this); } @@ -1026,9 +1041,10 @@ public: { collation.set(cs); } String *val_str(String *); void append_char(String * str, int32 num); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= arg_count * 4; + return FALSE; } const char *func_name() const { return "char"; } void print(String *str, enum_query_type query_type); @@ -1042,9 +1058,10 @@ public: Item_func_chr(THD *thd, Item *arg1, CHARSET_INFO *cs): Item_func_char(thd, arg1, cs) {} String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= 4; + return FALSE; } const char *func_name() const { return "chr"; } Item *get_copy(THD *thd) @@ -1058,7 +1075,7 @@ public: Item_func_repeat(THD *thd, Item *arg1, Item *arg2): Item_str_func(thd, arg1, arg2) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "repeat"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_repeat>(thd, this); } @@ -1070,7 +1087,7 @@ class Item_func_space :public Item_str_func public: Item_func_space(THD *thd, Item *arg1): Item_str_func(thd, arg1) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "space"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_space>(thd, this); } @@ -1083,7 +1100,7 @@ public: Item_func_binlog_gtid_pos(THD *thd, Item *arg1, Item *arg2): Item_str_func(thd, arg1, arg2) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "binlog_gtid_pos"; } bool check_vcol_func_processor(void *arg) { @@ -1103,7 +1120,7 @@ public: Item_str_func(thd, arg1, arg2, arg3) {} Item_func_pad(THD *thd, Item *arg1, Item *arg2): Item_str_func(thd, arg1, arg2) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); }; @@ -1130,10 +1147,11 @@ public: Item_func_rpad(thd, arg1, arg2, arg3) {} Item_func_rpad_oracle(THD *thd, Item *arg1, Item *arg2): Item_func_rpad(thd, arg1, arg2) {} - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_rpad::fix_length_and_dec(); + bool res= Item_func_rpad::fix_length_and_dec(); maybe_null= true; + return res; } const char *func_name() const { return "rpad_oracle"; } Item *get_copy(THD *thd) @@ -1164,10 +1182,11 @@ public: Item_func_lpad(thd, arg1, arg2, arg3) {} Item_func_lpad_oracle(THD *thd, Item *arg1, Item *arg2): Item_func_lpad(thd, arg1, arg2) {} - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_func_lpad::fix_length_and_dec(); + bool res= Item_func_lpad::fix_length_and_dec(); maybe_null= true; + return res; } const char *func_name() const { return "lpad_oracle"; } Item *get_copy(THD *thd) @@ -1182,11 +1201,12 @@ public: Item_str_func(thd, a, b, c) {} const char *func_name() const { return "conv"; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(default_charset()); max_length=64; maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_conv>(thd, this); } @@ -1216,12 +1236,13 @@ public: DBUG_ASSERT(fixed); return m_arg0_type_handler->Item_func_hex_val_str_ascii(this, str); } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); decimals=0; fix_char_length(args[0]->max_length * 2); m_arg0_type_handler= args[0]->type_handler(); + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_hex>(thd, this); } @@ -1238,11 +1259,12 @@ public: } const char *func_name() const { return "unhex"; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(&my_charset_bin); decimals=0; max_length=(1+args[0]->max_length)/2; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_unhex>(thd, this); } @@ -1261,11 +1283,12 @@ public: Item_str_func(thd, a, b), is_min(is_min_arg) { maybe_null= 1; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(args[0]->collation); decimals=0; max_length= MAX_BLOB_WIDTH; + return FALSE; } }; @@ -1306,10 +1329,11 @@ public: tmp->set_charset(&my_charset_bin); return tmp; } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(&my_charset_bin); max_length=args[0]->max_length; + return FALSE; } void print(String *str, enum_query_type query_type); const char *func_name() const { return "cast_as_binary"; } @@ -1326,11 +1350,12 @@ public: Item_load_file(THD *thd, Item *a): Item_str_func(thd, a) {} String *val_str(String *); const char *func_name() const { return "load_file"; } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(&my_charset_bin, DERIVATION_COERCIBLE); maybe_null=1; max_length=MAX_BLOB_WIDTH; + return FALSE; } bool check_vcol_func_processor(void *arg) { @@ -1351,7 +1376,7 @@ class Item_func_export_set: public Item_str_func Item_func_export_set(THD *thd, Item *a, Item *b, Item* c, Item* d, Item* e): Item_str_func(thd, a, b, c, d, e) {} String *val_str(String *str); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "export_set"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_export_set>(thd, this); } @@ -1365,12 +1390,13 @@ public: Item_func_quote(THD *thd, Item *a): Item_str_func(thd, a) {} const char *func_name() const { return "quote"; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(args[0]->collation); ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2 * collation.collation->mbmaxlen; max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH); + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_quote>(thd, this); } @@ -1453,7 +1479,7 @@ public: return 1; return res; } - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "convert"; } void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) @@ -1467,7 +1493,7 @@ public: Item_func_set_collation(THD *thd, Item *a, CHARSET_INFO *set_collation): Item_str_func(thd, a), m_set_collation(set_collation) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "collate"; } enum precedence precedence() const { return COLLATE_PRECEDENCE; } @@ -1488,11 +1514,12 @@ class Item_func_expr_str_metadata :public Item_str_func { public: Item_func_expr_str_metadata(THD *thd, Item *a): Item_str_func(thd, a) { } - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(system_charset_info); max_length= 64 * collation.collation->mbmaxlen; // should be enough maybe_null= 0; + return FALSE; }; table_map not_null_tables() const { return 0; } Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) @@ -1542,7 +1569,7 @@ public: } const char *func_name() const { return "weight_string"; } String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const { if (!Item_str_func::eq(item, binary_cmp)) @@ -1568,7 +1595,7 @@ public: Item_func_crc32(THD *thd, Item *a): Item_long_func(thd, a) { unsigned_flag= 1; } const char *func_name() const { return "crc32"; } - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_crc32>(thd, this); } @@ -1581,7 +1608,7 @@ public: Item_func_uncompressed_length(THD *thd, Item *a) :Item_long_func_length(thd, a) {} const char *func_name() const{return "uncompressed_length";} - void fix_length_and_dec() { max_length=10; maybe_null= true; } + bool fix_length_and_dec() { max_length=10; maybe_null= true; return FALSE; } longlong val_int(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_uncompressed_length>(thd, this); } @@ -1599,7 +1626,11 @@ class Item_func_compress: public Item_str_binary_checksum_func public: Item_func_compress(THD *thd, Item *a) :Item_str_binary_checksum_func(thd, a) {} - void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;} + bool fix_length_and_dec() + { + max_length= (args[0]->max_length * 120) / 100 + 12; + return FALSE; + } const char *func_name() const{return "compress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION Item *get_copy(THD *thd) @@ -1612,7 +1643,11 @@ class Item_func_uncompress: public Item_str_binary_checksum_func public: Item_func_uncompress(THD *thd, Item *a) :Item_str_binary_checksum_func(thd, a) {} - void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; } + bool fix_length_and_dec() + { + maybe_null= 1; max_length= MAX_BLOB_WIDTH; + return FALSE; + } const char *func_name() const{return "uncompress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION Item *get_copy(THD *thd) @@ -1624,11 +1659,12 @@ class Item_func_uuid: public Item_str_func { public: Item_func_uuid(THD *thd): Item_str_func(thd) {} - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(system_charset_info, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); fix_char_length(MY_UUID_STRING_LENGTH); + return FALSE; } bool const_item() const { return false; } table_map used_tables() const { return RAND_TABLE_BIT; } @@ -1656,7 +1692,7 @@ protected: public: Item_func_dyncol_create(THD *thd, List<Item> &args, DYNCALL_CREATE_DEF *dfs); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const{ return "column_create"; } String *val_str(String *); void print(String *str, enum_query_type query_type); @@ -1686,11 +1722,12 @@ public: {collation.set(DYNCOL_UTF);} const char *func_name() const{ return "column_json"; } String *val_str(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; maybe_null= 1; decimals= 0; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_dyncol_json>(thd, this); } @@ -1705,8 +1742,8 @@ class Item_dyncol_get: public Item_str_func public: Item_dyncol_get(THD *thd, Item *str, Item *num): Item_str_func(thd, str, num) {} - void fix_length_and_dec() - { maybe_null= 1;; max_length= MAX_BLOB_WIDTH; } + bool fix_length_and_dec() + { maybe_null= 1;; max_length= MAX_BLOB_WIDTH; return FALSE; } /* Mark that collation can change between calls */ bool dynamic_result() { return 1; } @@ -1744,7 +1781,8 @@ class Item_func_dyncol_list: public Item_str_func public: Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str) {collation.set(DYNCOL_UTF);} - void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; }; + bool fix_length_and_dec() + { maybe_null= 1; max_length= MAX_BLOB_WIDTH; return FALSE; }; const char *func_name() const{ return "column_list"; } String *val_str(String *); Item *get_copy(THD *thd) @@ -1767,7 +1805,7 @@ public: String *val_str(String *str); enum Functype functype() const { return TEMPTABLE_ROWID; } const char *func_name() const { return "<rowid>"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_temptable_rowid>(thd, this); } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 4280a67e356..1947a45186a 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -310,10 +310,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) if (engine->cols() > max_columns) { my_error(ER_OPERAND_COLUMNS, MYF(0), 1); - + res= TRUE; + goto end; + } + if (fix_length_and_dec()) + { + res= TRUE; goto end; } - fix_length_and_dec(); } else goto end; @@ -910,9 +914,11 @@ Item::Type Item_subselect::type() const } -void Item_subselect::fix_length_and_dec() +bool Item_subselect::fix_length_and_dec() { - engine->fix_length_and_dec(0); + if (engine->fix_length_and_dec(0)) + return TRUE; + return FALSE; } @@ -1186,18 +1192,19 @@ const Type_handler *Item_singlerow_subselect::type_handler() const return engine->type_handler(); } -void Item_singlerow_subselect::fix_length_and_dec() +bool Item_singlerow_subselect::fix_length_and_dec() { if ((max_columns= engine->cols()) == 1) { - engine->fix_length_and_dec(row= &value); + if (engine->fix_length_and_dec(row= &value)) + return TRUE; } else { if (!(row= (Item_cache**) current_thd->alloc(sizeof(Item_cache*) * - max_columns))) - return; - engine->fix_length_and_dec(row); + max_columns)) || + engine->fix_length_and_dec(row)) + return TRUE; value= *row; } unsigned_flag= value->unsigned_flag; @@ -1213,6 +1220,7 @@ void Item_singlerow_subselect::fix_length_and_dec() for (uint i= 0; i < max_columns; i++) row[i]->maybe_null= TRUE; } + return FALSE; } @@ -1497,7 +1505,7 @@ void Item_exists_subselect::init_length_and_dec() } -void Item_exists_subselect::fix_length_and_dec() +bool Item_exists_subselect::fix_length_and_dec() { DBUG_ENTER("Item_exists_subselect::fix_length_and_dec"); init_length_and_dec(); @@ -1505,14 +1513,17 @@ void Item_exists_subselect::fix_length_and_dec() We need only 1 row to determine existence (i.e. any EXISTS that is not an IN always requires LIMIT 1) */ + Item *item= new (thd->mem_root) Item_int(thd, (int32) 1); + if (!item) + DBUG_RETURN(TRUE); thd->change_item_tree(&unit->global_parameters()->select_limit, - new (thd->mem_root) Item_int(thd, (int32) 1)); + item); DBUG_PRINT("info", ("Set limit to 1")); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } -void Item_in_subselect::fix_length_and_dec() +bool Item_in_subselect::fix_length_and_dec() { DBUG_ENTER("Item_in_subselect::fix_length_and_dec"); init_length_and_dec(); @@ -1520,7 +1531,7 @@ void Item_in_subselect::fix_length_and_dec() Unlike Item_exists_subselect, LIMIT 1 is set later for Item_in_subselect, depending on the chosen strategy. */ - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -3705,11 +3716,11 @@ bool subselect_single_select_engine::no_rows() } -/* - makes storage for the output values for the subquery and calcuates +/** + Makes storage for the output values for the subquery and calcuates their data and column types and their nullability. -*/ -void subselect_engine::set_row(List<Item> &item_list, Item_cache **row) +*/ +bool subselect_engine::set_row(List<Item> &item_list, Item_cache **row) { Item *sel_item; List_iterator_fast<Item> li(item_list); @@ -3722,44 +3733,51 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row) item->unsigned_flag= sel_item->unsigned_flag; maybe_null= sel_item->maybe_null; if (!(row[i]= sel_item->get_cache(thd))) - return; + return TRUE; row[i]->setup(thd, sel_item); //psergey-backport-timours: row[i]->store(sel_item); } if (item_list.elements > 1) set_handler(&type_handler_row); + return FALSE; } -void subselect_single_select_engine::fix_length_and_dec(Item_cache **row) +bool subselect_single_select_engine::fix_length_and_dec(Item_cache **row) { DBUG_ASSERT(row || select_lex->item_list.elements==1); - set_row(select_lex->item_list, row); + if (set_row(select_lex->item_list, row)) + return TRUE; item->collation.set(row[0]->collation); if (cols() != 1) maybe_null= 0; + return FALSE; } -void subselect_union_engine::fix_length_and_dec(Item_cache **row) +bool subselect_union_engine::fix_length_and_dec(Item_cache **row) { DBUG_ASSERT(row || unit->first_select()->item_list.elements==1); if (unit->first_select()->item_list.elements == 1) { - set_row(unit->types, row); + if (set_row(unit->types, row)) + return TRUE; item->collation.set(row[0]->collation); } else { bool maybe_null_saved= maybe_null; - set_row(unit->types, row); + if (set_row(unit->types, row)) + return TRUE; maybe_null= maybe_null_saved; } + return FALSE; } -void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row) +bool subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row) { //this never should be called DBUG_ASSERT(0); + return FALSE; } int read_first_record_seq(JOIN_TAB *tab); @@ -5586,9 +5604,10 @@ void subselect_hash_sj_engine::print(String *str, enum_query_type query_type) )); } -void subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row) +bool subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row) { DBUG_ASSERT(FALSE); + return FALSE; } void subselect_hash_sj_engine::exclude() diff --git a/sql/item_subselect.h b/sql/item_subselect.h index dfe3287615b..363dbba4ddd 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -197,7 +197,7 @@ public: const_item_cache= 0; forced_const= TRUE; } - virtual void fix_length_and_dec(); + virtual bool fix_length_and_dec(); table_map used_tables() const; table_map not_null_tables() const { return 0; } bool const_item() const; @@ -306,7 +306,7 @@ public: bool val_bool(); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); const Type_handler *type_handler() const; - void fix_length_and_dec(); + bool fix_length_and_dec(); uint cols() const; Item* element_index(uint i) { return reinterpret_cast<Item*>(row[i]); } @@ -404,7 +404,7 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date_from_int(ltime, fuzzydate); } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type); bool select_transformer(JOIN *join); void top_level_item() { abort_on_null=1; } @@ -627,7 +627,7 @@ public: void print(String *str, enum_query_type query_type); enum precedence precedence() const { return CMP_PRECEDENCE; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); bool const_item() const { @@ -808,7 +808,7 @@ public: void set_thd(THD *thd_arg); THD * get_thd() { return thd ? thd : current_thd; } virtual int prepare(THD *)= 0; - virtual void fix_length_and_dec(Item_cache** row)= 0; + virtual bool fix_length_and_dec(Item_cache** row)= 0; /* Execute the engine @@ -849,7 +849,7 @@ public: virtual int get_identifier() { DBUG_ASSERT(0); return 0; } virtual void force_reexecution() {} protected: - void set_row(List<Item> &item_list, Item_cache **row); + bool set_row(List<Item> &item_list, Item_cache **row); }; @@ -865,7 +865,7 @@ public: Item_subselect *item); void cleanup(); int prepare(THD *thd); - void fix_length_and_dec(Item_cache** row); + bool fix_length_and_dec(Item_cache** row); int exec(); uint cols() const; uint8 uncacheable(); @@ -901,7 +901,7 @@ public: Item_subselect *item); void cleanup(); int prepare(THD *); - void fix_length_and_dec(Item_cache** row); + bool fix_length_and_dec(Item_cache** row); int exec(); uint cols() const; uint8 uncacheable(); @@ -959,7 +959,7 @@ public: ~subselect_uniquesubquery_engine(); void cleanup(); int prepare(THD *); - void fix_length_and_dec(Item_cache** row); + bool fix_length_and_dec(Item_cache** row); int exec(); uint cols() const { return 1; } uint8 uncacheable() { return UNCACHEABLE_DEPENDENT_INJECTED; } @@ -1108,7 +1108,7 @@ public: TODO: factor out all these methods in a base subselect_index_engine class because all of them have dummy implementations and should never be called. */ - void fix_length_and_dec(Item_cache** row);//=>base class + bool fix_length_and_dec(Item_cache** row);//=>base class void exclude(); //=>base class //=>base class bool change_result(Item_subselect *si, @@ -1381,7 +1381,7 @@ public: uint count_columns_with_nulls_arg); int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; } int exec(); - void fix_length_and_dec(Item_cache**) {} + bool fix_length_and_dec(Item_cache**) { return FALSE; } uint cols() const { /* TODO: what is the correct value? */ return 1; } uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; } void exclude() {} diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 0e506cc26f2..3163fb9ea2e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1139,9 +1139,8 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) result_field=0; max_length=float_length(decimals); null_value=1; - fix_length_and_dec(); - - if (check_sum_func(thd, ref)) + if (fix_length_and_dec() || + check_sum_func(thd, ref)) return TRUE; memcpy (orig_args, args, sizeof (Item *) * arg_count); @@ -1167,7 +1166,9 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) with_param= args[0]->with_param; with_window_func|= args[0]->with_window_func; - fix_length_and_dec(); + if (fix_length_and_dec()) + DBUG_RETURN(TRUE); + if (!is_window_func_sum_expr()) setup_hybrid(thd, args[0], NULL); result_field=0; @@ -1181,11 +1182,11 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) } -void Item_sum_hybrid::fix_length_and_dec() +bool Item_sum_hybrid::fix_length_and_dec() { DBUG_ASSERT(args[0]->field_type() == args[0]->real_item()->field_type()); DBUG_ASSERT(args[0]->result_type() == args[0]->real_item()->result_type()); - (void) args[0]->type_handler()->Item_sum_hybrid_fix_length_and_dec(this); + return args[0]->type_handler()->Item_sum_hybrid_fix_length_and_dec(this); } @@ -1304,7 +1305,8 @@ Item_sum_sp::fix_fields(THD *thd, Item **ref) result_field= NULL; max_length= float_length(decimals); null_value= 1; - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; if (check_sum_func(thd, ref)) return TRUE; @@ -1386,14 +1388,14 @@ Item_sum_sp::cleanup() @note called from Item::fix_fields. */ -void +bool Item_sum_sp::fix_length_and_dec() { DBUG_ENTER("Item_sum_sp::fix_length_and_dec"); DBUG_ASSERT(sp_result_field); Type_std_attributes::set(sp_result_field->type_std_attributes()); - Item_sum::fix_length_and_dec(); - DBUG_VOID_RETURN; + bool res= Item_sum::fix_length_and_dec(); + DBUG_RETURN(res); } const char * @@ -1489,14 +1491,16 @@ void Item_sum_sum::fix_length_and_dec_decimal() } -void Item_sum_sum::fix_length_and_dec() +bool Item_sum_sum::fix_length_and_dec() { DBUG_ENTER("Item_sum_sum::fix_length_and_dec"); maybe_null=null_value=1; - args[0]->cast_to_int_type_handler()->Item_sum_sum_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_sum_sum_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s (%d, %d)", type_handler()->name().ptr(), max_length, (int) decimals)); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -1913,15 +1917,17 @@ void Item_sum_avg::fix_length_and_dec_double() } -void Item_sum_avg::fix_length_and_dec() +bool Item_sum_avg::fix_length_and_dec() { DBUG_ENTER("Item_sum_avg::fix_length_and_dec"); prec_increment= current_thd->variables.div_precincrement; maybe_null=null_value=1; - args[0]->cast_to_int_type_handler()->Item_sum_avg_fix_length_and_dec(this); + if (args[0]->cast_to_int_type_handler()-> + Item_sum_avg_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s (%d, %d)", type_handler()->name().ptr(), max_length, (int) decimals)); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2133,7 +2139,7 @@ void Item_sum_variance::fix_length_and_dec_decimal() } -void Item_sum_variance::fix_length_and_dec() +bool Item_sum_variance::fix_length_and_dec() { DBUG_ENTER("Item_sum_variance::fix_length_and_dec"); maybe_null= null_value= 1; @@ -2145,11 +2151,11 @@ void Item_sum_variance::fix_length_and_dec() type of the result is an implementation-defined aproximate numeric type. */ - - args[0]->type_handler()->Item_sum_variance_fix_length_and_dec(this); + if (args[0]->type_handler()->Item_sum_variance_fix_length_and_dec(this)) + DBUG_RETURN(TRUE); DBUG_PRINT("info", ("Type: %s (%d, %d)", type_handler()->name().ptr(), max_length, (int)decimals)); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -3375,13 +3381,13 @@ my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec) /** Default max_length is max argument length. */ -void Item_sum_udf_str::fix_length_and_dec() +bool Item_sum_udf_str::fix_length_and_dec() { DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec"); max_length=0; for (uint i = 0; i < arg_count; i++) set_if_bigger(max_length,args[i]->max_length); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } diff --git a/sql/item_sum.h b/sql/item_sum.h index b66f6ab6143..b400ebd5f80 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -457,7 +457,8 @@ public: Updated value is then saved in the field. */ virtual void update_field()=0; - virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } + virtual bool fix_length_and_dec() + { maybe_null=1; null_value=1; return FALSE; } virtual Item *result_item(THD *thd, Field *field); void update_used_tables (); @@ -753,8 +754,8 @@ public: String *val_str(String*str); my_decimal *val_decimal(my_decimal *); const Type_handler *type_handler() const { return &type_handler_longlong; } - void fix_length_and_dec() - { decimals=0; max_length=21; maybe_null=null_value=0; } + bool fix_length_and_dec() + { decimals=0; max_length=21; maybe_null=null_value=0; return FALSE; } }; @@ -770,7 +771,7 @@ protected: my_decimal direct_sum_decimal; my_decimal dec_buffs[2]; uint curr_dec_buff; - void fix_length_and_dec(); + bool fix_length_and_dec(); public: Item_sum_sum(THD *thd, Item *item_par, bool distinct): @@ -905,7 +906,7 @@ public: void fix_length_and_dec_double(); void fix_length_and_dec_decimal(); - void fix_length_and_dec(); + bool fix_length_and_dec(); enum Sumfunctype sum_func () const { return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC; @@ -965,7 +966,7 @@ But, this falls prey to catastrophic cancellation. Instead, use the recurrence class Item_sum_variance : public Item_sum_num { - void fix_length_and_dec(); + bool fix_length_and_dec(); public: double recurrence_m, recurrence_s; /* Used in recurrence relation. */ @@ -1052,7 +1053,7 @@ protected: cmp_sign(item->cmp_sign), was_values(item->was_values) { } bool fix_fields(THD *, Item **); - void fix_length_and_dec(); + bool fix_length_and_dec(); void setup_hybrid(THD *thd, Item *item, Item *value_arg); void clear(); void direct_add(Item *item); @@ -1132,8 +1133,11 @@ public: longlong val_int(); void reset_field(); void update_field(); - void fix_length_and_dec() - { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; } + bool fix_length_and_dec() + { + decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; + return FALSE; + } void cleanup() { bits= reset_bits; @@ -1302,7 +1306,7 @@ public: { return create_table_field_from_handler(table); } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); const char *func_name() const; const Type_handler *type_handler() const; @@ -1562,7 +1566,7 @@ class Item_sum_udf_float :public Item_udf_sum String *val_str(String*str); my_decimal *val_decimal(my_decimal *); const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() { fix_num_length_and_dec(); } + bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) { return get_item_copy<Item_sum_udf_float>(thd, this); } @@ -1584,7 +1588,7 @@ public: String *val_str(String*str); my_decimal *val_decimal(my_decimal *); const Type_handler *type_handler() const { return &type_handler_longlong; } - void fix_length_and_dec() { decimals=0; max_length=21; } + bool fix_length_and_dec() { decimals=0; max_length=21; return FALSE; } Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) { return get_item_copy<Item_sum_udf_int>(thd, this); } @@ -1625,7 +1629,7 @@ public: } my_decimal *val_decimal(my_decimal *dec); const Type_handler *type_handler() const { return string_type_handler(); } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) { return get_item_copy<Item_sum_udf_str>(thd, this); } @@ -1646,7 +1650,7 @@ public: longlong val_int(); my_decimal *val_decimal(my_decimal *); const Type_handler *type_handler() const { return &type_handler_newdecimal; } - void fix_length_and_dec() { fix_num_length_and_dec(); } + bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; } Item *copy_or_same(THD* thd); Item *get_copy(THD *thd) { return get_item_copy<Item_sum_udf_decimal>(thd, this); } @@ -1720,7 +1724,7 @@ public: { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } - void fix_length_and_dec() { maybe_null=1; max_length=0; } + bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } void clear() {} bool add() { return 0; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index e01114fb0ad..b4d929e0f70 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -954,7 +954,7 @@ longlong Item_func_month::val_int() } -void Item_func_monthname::fix_length_and_dec() +bool Item_func_monthname::fix_length_and_dec() { THD* thd= current_thd; CHARSET_INFO *cs= thd->variables.collation_connection; @@ -962,7 +962,8 @@ void Item_func_monthname::fix_length_and_dec() collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire()); decimals=0; max_length= locale->max_month_name_length * collation.collation->mbmaxlen; - maybe_null=1; + maybe_null=1; + return FALSE; } @@ -1102,7 +1103,7 @@ longlong Item_func_weekday::val_int() odbc_type) + MY_TEST(odbc_type); } -void Item_func_dayname::fix_length_and_dec() +bool Item_func_dayname::fix_length_and_dec() { THD* thd= current_thd; CHARSET_INFO *cs= thd->variables.collation_connection; @@ -1110,7 +1111,8 @@ void Item_func_dayname::fix_length_and_dec() collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire()); decimals=0; max_length= locale->max_day_name_length * collation.collation->mbmaxlen; - maybe_null=1; + maybe_null=1; + return FALSE; } @@ -1842,7 +1844,7 @@ overflow: return 0; } -void Item_func_date_format::fix_length_and_dec() +bool Item_func_date_format::fix_length_and_dec() { THD* thd= current_thd; if (!is_time_format) @@ -1881,6 +1883,7 @@ void Item_func_date_format::fix_length_and_dec() set_if_smaller(max_length,MAX_BLOB_WIDTH); } maybe_null=1; // If wrong date + return FALSE; } @@ -2034,13 +2037,14 @@ null_date: } -void Item_func_from_unixtime::fix_length_and_dec() -{ +bool Item_func_from_unixtime::fix_length_and_dec() +{ THD *thd= current_thd; thd->time_zone_used= 1; tz= thd->variables.time_zone; fix_attributes_datetime_not_fixed_dec(args[0]->decimals); maybe_null= true; + return FALSE; } @@ -2112,7 +2116,7 @@ void Item_func_convert_tz::cleanup() } -void Item_date_add_interval::fix_length_and_dec() +bool Item_date_add_interval::fix_length_and_dec() { enum_field_types arg0_field_type; @@ -2121,7 +2125,7 @@ void Item_date_add_interval::fix_length_and_dec() my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), args[0]->type_handler()->name().ptr(), "interval", func_name()); - return; + return TRUE; } /* The field type for the result of an Item_datefunc is defined as @@ -2189,6 +2193,7 @@ void Item_date_add_interval::fix_length_and_dec() fix_char_length_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec); } maybe_null= true; + return FALSE; } @@ -2259,7 +2264,7 @@ void Item_extract::print(String *str, enum_query_type query_type) str->append(')'); } -void Item_extract::fix_length_and_dec() +bool Item_extract::fix_length_and_dec() { maybe_null=1; // If wrong date switch (int_type) { @@ -2285,6 +2290,7 @@ void Item_extract::fix_length_and_dec() case INTERVAL_SECOND_MICROSECOND: set_time_length(8); break; // ssffffff case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */ } + return FALSE; } @@ -2688,7 +2694,7 @@ err: } -void Item_func_add_time::fix_length_and_dec() +bool Item_func_add_time::fix_length_and_dec() { enum_field_types arg0_field_type; @@ -2698,7 +2704,7 @@ void Item_func_add_time::fix_length_and_dec() my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), args[0]->type_handler()->name().ptr(), args[1]->type_handler()->name().ptr(), func_name()); - return; + return TRUE; } /* The field type for the result of an Item_func_add_time function is defined @@ -2734,6 +2740,7 @@ void Item_func_add_time::fix_length_and_dec() fix_char_length_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec); } maybe_null= true; + return FALSE; } /** @@ -3220,7 +3227,7 @@ get_date_time_result_type(const char *format, uint length) } -void Item_func_str_to_date::fix_length_and_dec() +bool Item_func_str_to_date::fix_length_and_dec() { if (!args[0]->type_handler()->is_traditional_type() || !args[1]->type_handler()->is_traditional_type()) @@ -3228,10 +3235,10 @@ void Item_func_str_to_date::fix_length_and_dec() my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), args[0]->type_handler()->name().ptr(), args[1]->type_handler()->name().ptr(), func_name()); - return; + return TRUE; } if (agg_arg_charsets(collation, args, 2, MY_COLL_ALLOW_CONV, 1)) - return; + return TRUE; if (collation.collation->mbminlen > 1) internal_charset= &my_charset_utf8mb4_general_ci; @@ -3275,6 +3282,7 @@ void Item_func_str_to_date::fix_length_and_dec() } } cached_timestamp_type= mysql_timestamp_type(); + return FALSE; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 30d5018ff36..51ce3bf2988 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -62,9 +62,10 @@ public: Item_func_period_add(THD *thd, Item *a, Item *b): Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "period_add"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { max_length=6*MY_CHARSET_BIN_MB_MAXLEN; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_period_add>(thd, this); } @@ -79,10 +80,11 @@ public: Item_func_period_diff(THD *thd, Item *a, Item *b): Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "period_diff"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; + return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_period_diff>(thd, this); } @@ -95,11 +97,12 @@ public: Item_func_to_days(THD *thd, Item *a): Item_long_func_date_field(thd, a) {} longlong val_int(); const char *func_name() const { return "to_days"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; - maybe_null=1; + maybe_null=1; + return FALSE; } enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); @@ -122,11 +125,12 @@ public: Item_func_to_seconds(THD *thd, Item *a): Item_longlong_func(thd, a) {} longlong val_int(); const char *func_name() const { return "to_seconds"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; fix_char_length(12); maybe_null= 1; + return FALSE; } enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); @@ -148,11 +152,12 @@ public: Item_func_dayofmonth(THD *thd, Item *a): Item_long_func_date_field(thd, a) {} longlong val_int(); const char *func_name() const { return "dayofmonth"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - maybe_null=1; + maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -187,11 +192,12 @@ public: } const char *func_name() const { return "month"; } const Type_handler *type_handler() const { return &type_handler_long; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals= 0; fix_char_length(2); maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -211,7 +217,7 @@ public: Item_func_monthname(THD *thd, Item *a): Item_str_func(thd, a) {} const char *func_name() const { return "monthname"; } String *val_str(String *str); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool check_partition_func_processor(void *int_arg) {return TRUE;} bool check_valid_arguments_processor(void *int_arg) { @@ -232,11 +238,12 @@ public: Item_func_dayofyear(THD *thd, Item *a): Item_long_func_date_field(thd, a) {} longlong val_int(); const char *func_name() const { return "dayofyear"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals= 0; fix_char_length(3); maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -255,11 +262,12 @@ public: Item_func_hour(THD *thd, Item *a): Item_long_func_time_field(thd, a) {} longlong val_int(); const char *func_name() const { return "hour"; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -278,11 +286,12 @@ public: Item_func_minute(THD *thd, Item *a): Item_long_func_time_field(thd, a) {} longlong val_int(); const char *func_name() const { return "minute"; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -301,11 +310,12 @@ public: Item_func_quarter(THD *thd, Item *a): Item_long_func_date_field(thd, a) {} longlong val_int(); const char *func_name() const { return "quarter"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=1*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -324,11 +334,12 @@ public: Item_func_second(THD *thd, Item *a): Item_long_func_time_field(thd, a) {} longlong val_int(); const char *func_name() const { return "second"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -353,11 +364,12 @@ public: Item_func_week(THD *thd, Item *a, Item *b): Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "week"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_vcol_func_processor(void *arg) { @@ -385,11 +397,12 @@ public: :Item_long_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "yearweek"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -410,11 +423,12 @@ public: const char *func_name() const { return "year"; } enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; max_length=4*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -450,11 +464,12 @@ public: return type_handler()->Item_get_date(this, ltime, fuzzydate); } const Type_handler *type_handler() const { return &type_handler_long; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals= 0; fix_char_length(1); maybe_null=1; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -474,7 +489,7 @@ class Item_func_dayname :public Item_func_weekday const char *func_name() const { return "dayname"; } String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_varchar; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool check_partition_func_processor(void *int_arg) {return TRUE;} bool check_vcol_func_processor(void *arg) { @@ -535,9 +550,10 @@ public: return FALSE; return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC); } - void fix_length_and_dec() + bool fix_length_and_dec() { - fix_length_and_dec_generic(arg_count ? args[0]->datetime_precision() : 0); + fix_length_and_dec_generic(arg_count ? args[0]->datetime_precision() : 0); + return FALSE; } longlong int_op(); my_decimal *decimal_op(my_decimal* buf); @@ -558,9 +574,10 @@ public: { return !has_time_args(); } - void fix_length_and_dec() + bool fix_length_and_dec() { fix_length_and_dec_generic(args[0]->time_precision()); + return FALSE; } longlong int_op(); my_decimal *decimal_op(my_decimal* buf); @@ -629,10 +646,11 @@ public: Item_datefunc(THD *thd, Item *a): Item_temporal_func(thd, a) { } Item_datefunc(THD *thd, Item *a, Item *b): Item_temporal_func(thd, a, b) { } const Type_handler *type_handler() const { return &type_handler_newdate; } - void fix_length_and_dec() + bool fix_length_and_dec() { fix_attributes_date(); maybe_null= (arg_count > 0); + return FALSE; } }; @@ -670,7 +688,7 @@ public: Item_func_curtime(THD *thd, uint dec): Item_timefunc(thd), last_query_id(0) { decimals= dec; } bool fix_fields(THD *, Item **); - void fix_length_and_dec() { fix_attributes_time(decimals); } + bool fix_length_and_dec() { fix_attributes_time(decimals); return FALSE; } bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); /* Abstract method that defines which time zone is used for conversion. @@ -757,7 +775,8 @@ public: Item_func_now(THD *thd, uint dec): Item_datetimefunc(thd), last_query_id(0) { decimals= dec; } bool fix_fields(THD *, Item **); - void fix_length_and_dec() { fix_attributes_datetime(decimals); } + bool fix_length_and_dec() + { fix_attributes_datetime(decimals); return FALSE;} bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)=0; bool check_vcol_func_processor(void *arg) @@ -864,7 +883,7 @@ public: Item_str_func(thd, a, b, c), locale(0), is_time_format(false) {} String *val_str(String *str); const char *func_name() const { return "date_format"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); uint format_length(const String *format); bool eq(const Item *item, bool binary_cmp) const; bool check_vcol_func_processor(void *arg) @@ -897,7 +916,7 @@ class Item_func_from_unixtime :public Item_datetimefunc public: Item_func_from_unixtime(THD *thd, Item *a): Item_datetimefunc(thd, a) {} const char *func_name() const { return "from_unixtime"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); Item *get_copy(THD *thd) { return get_item_copy<Item_func_from_unixtime>(thd, this); } @@ -937,10 +956,11 @@ class Item_func_convert_tz :public Item_datetimefunc Item_func_convert_tz(THD *thd, Item *a, Item *b, Item *c): Item_datetimefunc(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {} const char *func_name() const { return "convert_tz"; } - void fix_length_and_dec() + bool fix_length_and_dec() { fix_attributes_datetime(args[0]->datetime_precision()); maybe_null= true; + return FALSE; } bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); void cleanup(); @@ -956,10 +976,11 @@ class Item_func_sec_to_time :public Item_timefunc public: Item_func_sec_to_time(THD *thd, Item *item): Item_timefunc(thd, item) {} bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); - void fix_length_and_dec() + bool fix_length_and_dec() { fix_attributes_time(args[0]->decimals); maybe_null= true; + return FALSE; } const char *func_name() const { return "sec_to_time"; } Item *get_copy(THD *thd) @@ -977,7 +998,7 @@ public: Item_temporal_hybrid_func(thd, a, b),int_type(type_arg), date_sub_interval(neg_arg) {} const char *func_name() const { return "date_add_interval"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); bool eq(const Item *item, bool binary_cmp) const; void print(String *str, enum_query_type query_type); @@ -1045,7 +1066,7 @@ class Item_extract :public Item_int_func longlong val_int(); enum Functype functype() const { return EXTRACT_FUNC; } const char *func_name() const { return "extract"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; void print(String *str, enum_query_type query_type); bool check_partition_func_processor(void *int_arg) {return FALSE;} @@ -1125,9 +1146,9 @@ public: fix_length_and_dec_generic(); m_suppress_warning_to_error_escalation= true; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_char_typecast_fix_length_and_dec(this); + return args[0]->type_handler()->Item_char_typecast_fix_length_and_dec(this); } void print(String *str, enum_query_type query_type); bool need_parentheses_in_default() { return true; } @@ -1152,9 +1173,9 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *cast_type() const { return "date"; } const Type_handler *type_handler() const { return &type_handler_newdate; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_date_typecast_fix_length_and_dec(this); + return args[0]->type_handler()->Item_date_typecast_fix_length_and_dec(this); } Item *get_copy(THD *thd) { return get_item_copy<Item_date_typecast>(thd, this); } @@ -1170,9 +1191,10 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *cast_type() const { return "time"; } const Type_handler *type_handler() const { return &type_handler_time2; } - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_time_typecast_fix_length_and_dec(this); + return args[0]->type_handler()-> + Item_time_typecast_fix_length_and_dec(this); } Item *get_copy(THD *thd) { return get_item_copy<Item_time_typecast>(thd, this); } @@ -1188,9 +1210,10 @@ public: const char *cast_type() const { return "datetime"; } const Type_handler *type_handler() const { return &type_handler_datetime2; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); - void fix_length_and_dec() + bool fix_length_and_dec() { - args[0]->type_handler()->Item_datetime_typecast_fix_length_and_dec(this); + return args[0]->type_handler()-> + Item_datetime_typecast_fix_length_and_dec(this); } Item *get_copy(THD *thd) { return get_item_copy<Item_datetime_typecast>(thd, this); } @@ -1220,7 +1243,7 @@ public: Item_func_add_time(THD *thd, Item *a, Item *b, bool type_arg, bool neg_arg): Item_temporal_hybrid_func(thd, a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); void print(String *str, enum_query_type query_type); const char *func_name() const { return "add_time"; } @@ -1235,11 +1258,12 @@ class Item_func_timediff :public Item_timefunc public: Item_func_timediff(THD *thd, Item *a, Item *b): Item_timefunc(thd, a, b) {} const char *func_name() const { return "timediff"; } - void fix_length_and_dec() + bool fix_length_and_dec() { uint dec= MY_MAX(args[0]->time_precision(), args[1]->time_precision()); fix_attributes_time(dec); maybe_null= true; + return FALSE; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); Item *get_copy(THD *thd) @@ -1257,10 +1281,11 @@ public: Item_func_maketime(THD *thd, Item *a, Item *b, Item *c): Item_timefunc(thd, a, b, c) {} - void fix_length_and_dec() + bool fix_length_and_dec() { fix_attributes_time(args[2]->decimals); maybe_null= true; + return FALSE; } const char *func_name() const { return "maketime"; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); @@ -1275,11 +1300,12 @@ public: Item_func_microsecond(THD *thd, Item *a): Item_long_func_time_field(thd, a) {} longlong val_int(); const char *func_name() const { return "microsecond"; } - void fix_length_and_dec() - { + bool fix_length_and_dec() + { decimals=0; maybe_null=1; fix_char_length(6); + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -1302,10 +1328,11 @@ public: Item_longlong_func(thd, a, b), int_type(type_arg) {} const char *func_name() const { return "timestampdiff"; } longlong val_int(); - void fix_length_and_dec() + bool fix_length_and_dec() { decimals=0; maybe_null=1; + return FALSE; } virtual void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) @@ -1327,11 +1354,12 @@ public: {} String *val_str_ascii(String *str); const char *func_name() const { return "get_format"; } - void fix_length_and_dec() + bool fix_length_and_dec() { maybe_null= 1; decimals=0; fix_length_and_charset(17, default_charset()); + return FALSE; } virtual void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) @@ -1353,7 +1381,7 @@ public: {} bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *func_name() const { return "str_to_date"; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_str_to_date>(thd, this); } }; diff --git a/sql/item_vers.h b/sql/item_vers.h index 17ad3daa73c..8b9c0e6056c 100644 --- a/sql/item_vers.h +++ b/sql/item_vers.h @@ -38,7 +38,8 @@ public: bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); Item *get_copy(THD *thd) { return get_item_copy<Item_func_trt_ts>(thd, this); } - void fix_length_and_dec() { fix_attributes_datetime(decimals); } + bool fix_length_and_dec() + { fix_attributes_datetime(decimals); return FALSE; } }; class Item_func_trt_id : public Item_longlong_func @@ -69,10 +70,11 @@ public: return NULL; } - void fix_length_and_dec() + bool fix_length_and_dec() { - Item_int_func::fix_length_and_dec(); + bool res= Item_int_func::fix_length_and_dec(); max_length= 20; + return res; } longlong val_int(); diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index 66c4f5be665..b523235b3ad 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -122,7 +122,8 @@ Item_window_func::fix_fields(THD *thd, Item **ref) with_window_func= true; with_sum_func= false; - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; max_length= window_func()->max_length; maybe_null= window_func()->maybe_null; @@ -362,7 +363,8 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref) maybe_null= 1; result_field=0; null_value=1; - fix_length_and_dec(); + if (fix_length_and_dec()) + return TRUE; if (check_sum_func(thd, ref)) return TRUE; diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index cb85a2c06d1..48851da7d96 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -526,10 +526,11 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count bool add(); const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. + return FALSE; } void setup_window_func(THD *thd, Window_spec *window_spec); @@ -614,10 +615,11 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count void update_field() {} const Type_handler *type_handler() const { return &type_handler_double; } - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. + return FALSE; } Item *get_copy(THD *thd) @@ -820,10 +822,11 @@ public: const Type_handler *type_handler() const {return Type_handler_hybrid_field_type::type_handler();} - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. + return FALSE; } Item *get_copy(THD *thd) @@ -950,10 +953,11 @@ public: const Type_handler *type_handler() const {return Type_handler_hybrid_field_type::type_handler();} - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. + return FALSE; } Item *get_copy(THD *thd) @@ -1292,9 +1296,10 @@ public: void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array, List<Item> &fields, uint flags); - void fix_length_and_dec() + bool fix_length_and_dec() { decimals = window_func()->decimals; + return FALSE; } const char* func_name() const { return "WF"; } diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 63cc07fa34c..63734ecf9ac 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -222,13 +222,14 @@ public: return str; } enum Item_result result_type () const { return STRING_RESULT; } - void fix_length_and_dec() + bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; collation.collation= pxml->charset(); // To avoid premature evaluation, mark all nodeset functions as non-const. used_tables_cache= RAND_TABLE_BIT; const_item_cache= false; + return FALSE; } const char *func_name() const { return "nodeset"; } bool check_vcol_func_processor(void *arg) @@ -456,7 +457,7 @@ public: Item_nodeset_func(thd, pxml), string_cache(str_arg) { } String *val_nodeset(String *res) { return string_cache; } - void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; } + bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH;; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_nodeset_context_cache>(thd, this); } }; @@ -470,7 +471,7 @@ public: Item_func_xpath_position(THD *thd, Item *a, String *p): Item_long_func(thd, a), pxml(p) {} const char *func_name() const { return "xpath_position"; } - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } longlong val_int() { String *flt= args[0]->val_nodeset(&tmp_value); @@ -491,7 +492,7 @@ public: Item_func_xpath_count(THD *thd, Item *a, String *p): Item_long_func(thd, a), pxml(p) {} const char *func_name() const { return "xpath_count"; } - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } longlong val_int() { uint predicate_supplied_context_size; @@ -2728,10 +2729,10 @@ my_xpath_parse(MY_XPATH *xpath, const char *str, const char *strend) } -void Item_xml_str_func::fix_length_and_dec() +bool Item_xml_str_func::fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; - agg_arg_charsets_for_comparison(collation, args, arg_count); + return agg_arg_charsets_for_comparison(collation, args, arg_count); } diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index 33e85ba5628..6846063aab7 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -82,7 +82,7 @@ public: maybe_null= TRUE; } bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); bool const_item() const { return const_item_cache && (!nodeset_func || nodeset_func->const_item()); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 54bb877ea2f..73bd29642ef 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14034,7 +14034,8 @@ COND *Item_func_eq::build_equal_items(THD *thd, List_iterator_fast<Item_equal> it(cond_equal.current_level); while ((item_equal= it++)) { - item_equal->fix_length_and_dec(); + if (item_equal->fix_length_and_dec()) + return NULL; item_equal->update_used_tables(); set_if_bigger(thd->lex->current_select->max_equal_elems, item_equal->n_field_items()); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6835d92773c..2b0c4439146 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4961,7 +4961,12 @@ int create_table_impl(THD *thd, file= mysql_create_frm_image(thd, orig_db, orig_table_name, create_info, alter_info, create_table_mode, key_info, key_count, frm); - if (!file) + /* + TODO: remove this check of thd->is_error() (now it intercept + errors in some val_*() methoids and bring some single place to + such error interception). + */ + if (!file || thd->is_error()) goto err; if (rea_create_table(thd, frm, path, db->str, table_name->str, create_info, file, frm_only)) @@ -7621,10 +7626,15 @@ static bool mysql_inplace_alter_table(THD *thd, /* Replace the old .FRM with the new .FRM, but keep the old name for now. Rename to the new name (if needed) will be handled separately below. + + TODO: remove this check of thd->is_error() (now it intercept + errors in some val_*() methoids and bring some single place to + such error interception). */ if (mysql_rename_table(db_type, &alter_ctx->new_db, &alter_ctx->tmp_name, &alter_ctx->db, &alter_ctx->alias, - FN_FROM_IS_TMP | NO_HA_TABLE)) + FN_FROM_IS_TMP | NO_HA_TABLE) || + thd->is_error()) { // Since changes were done in-place, we can't revert them. (void) quick_rm_table(thd, db_type, |