diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2018-05-08 15:26:26 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2018-06-15 10:31:30 +0200 |
commit | 6b8802e8dd5467556a024d807a1df23940b00895 (patch) | |
tree | fe1a1b87c500abc375aa77a7bcfed085b5f6551c | |
parent | c55de8d40bba29503773a6a56d6f13f19ca7e339 (diff) | |
download | mariadb-git-6b8802e8dd5467556a024d807a1df23940b00895.tar.gz |
MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed in Locked_tables_list::unlock_locked_table
fix_length_and_dec now return result (error/OK)
-rw-r--r-- | mysql-test/r/alter_table.result | 11 | ||||
-rw-r--r-- | mysql-test/t/alter_table.test | 16 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 106 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 60 | ||||
-rw-r--r-- | sql/item_func.cc | 106 | ||||
-rw-r--r-- | sql/item_func.h | 118 | ||||
-rw-r--r-- | sql/item_geofunc.cc | 9 | ||||
-rw-r--r-- | sql/item_geofunc.h | 72 | ||||
-rw-r--r-- | sql/item_inetfunc.h | 12 | ||||
-rw-r--r-- | sql/item_jsonfunc.cc | 57 | ||||
-rw-r--r-- | sql/item_jsonfunc.h | 38 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 164 | ||||
-rw-r--r-- | sql/item_strfunc.h | 156 | ||||
-rw-r--r-- | sql/item_subselect.cc | 71 | ||||
-rw-r--r-- | sql/item_subselect.h | 22 | ||||
-rw-r--r-- | sql/item_sum.cc | 28 | ||||
-rw-r--r-- | sql/item_sum.h | 30 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 46 | ||||
-rw-r--r-- | sql/item_timefunc.h | 125 | ||||
-rw-r--r-- | sql/item_windowfunc.cc | 6 | ||||
-rw-r--r-- | sql/item_windowfunc.h | 9 | ||||
-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 |
26 files changed, 778 insertions, 518 deletions
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 89bf9ed638e..2bea055df4c 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -2369,5 +2369,16 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; # +# MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed +# in Locked_tables_list::unlock_locked_tables +# +CREATE TABLE t1 (d DATETIME DEFAULT CURRENT_TIMESTAMP, i INT) ENGINE=InnoDB; +INSERT INTO t1 (i) VALUES (1),(1); +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD UNIQUE(i); +ERROR 23000: Duplicate entry '1' for key 'i' +UNLOCK TABLES; +DROP TABLE t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index eddc9f704da..092569dcadb 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1932,5 +1932,21 @@ show create table t1; drop table t1; --echo # +--echo # MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed +--echo # in Locked_tables_list::unlock_locked_tables +--echo # + +CREATE TABLE t1 (d DATETIME DEFAULT CURRENT_TIMESTAMP, i INT) ENGINE=InnoDB; +INSERT INTO t1 (i) VALUES (1),(1); +LOCK TABLE t1 WRITE; +--error ER_DUP_ENTRY +ALTER TABLE t1 ADD UNIQUE(i); + +# Cleanup +UNLOCK TABLES; +DROP TABLE t1; + + +--echo # --echo # End of 10.2 tests --echo # diff --git a/sql/item.h b/sql/item.h index 423ee4cc089..5ed45c69e96 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4211,7 +4211,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, MEM_ROOT *mem_root); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f552a3eca58..b86c0079bce 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -526,7 +526,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 @@ -535,8 +535,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); } @@ -1156,12 +1156,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; } @@ -1780,10 +1781,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() @@ -1880,7 +1882,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(); @@ -1898,10 +1900,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++) @@ -1942,6 +1947,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; } @@ -2102,7 +2108,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() { THD *thd= current_thd; max_length= 1; @@ -2113,13 +2119,13 @@ 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 (agg_cmp_type(&m_compare_type, args, 3)) - return; + return TRUE; if (m_compare_type == STRING_RESULT && agg_arg_charsets_for_comparison(cmp_collation, args, 3)) - return; + return TRUE; /* When comparing as date/time, we need to convert non-temporal values @@ -2144,6 +2150,7 @@ void Item_func_between::fix_length_and_dec() m_compare_type= INT_RESULT; // Works for all types. } } + return FALSE; } @@ -2441,7 +2448,7 @@ void Item_func_if::cache_type_info(Item *source) } -void +bool Item_func_if::fix_length_and_dec() { // Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr. @@ -2452,15 +2459,15 @@ Item_func_if::fix_length_and_dec() // If both arguments are NULL, make resulting type BINARY(0). if (args[2]->type() == NULL_ITEM) set_handler_by_field_type(MYSQL_TYPE_STRING); - return; + return FALSE; } if (args[2]->type() == NULL_ITEM) { cache_type_info(args[1]); maybe_null= true; - return; + return FALSE; } - Item_func_case_abbreviation2::fix_length_and_dec2(args + 1); + return Item_func_case_abbreviation2::fix_length_and_dec2(args + 1); } @@ -2574,7 +2581,7 @@ void Item_func_nullif::update_used_tables() -void +bool Item_func_nullif::fix_length_and_dec() { /* @@ -2724,6 +2731,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]) : Item_cache::get_cache(thd, args[0]); + 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()); @@ -2737,7 +2746,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. @@ -2777,6 +2787,7 @@ Item_func_nullif::fix_length_and_dec() */ if (args[0] == m_arg0) m_arg0= NULL; + return FALSE; } @@ -3158,7 +3169,7 @@ static void change_item_tree_if_needed(THD *thd, Item **place, Item *new_value) } -void Item_func_case::fix_length_and_dec() +bool Item_func_case::fix_length_and_dec() { m_found_types= 0; if (else_expr_num == -1 || args[else_expr_num]->maybe_null) @@ -3175,7 +3186,7 @@ void Item_func_case::fix_length_and_dec() if (Item_func_case::result_type() == STRING_RESULT) { if (count_string_result_length(Item_func_case::field_type(), rets, nrets)) - return; + return TRUE; } else fix_attributes(rets, nrets); @@ -3189,7 +3200,7 @@ void Item_func_case::fix_length_and_dec() left_cmp_type= args[0]->cmp_type(); if (!(m_found_types= collect_cmp_types(args, nwhens + 1))) - return; + return TRUE; Item *date_arg= 0; if (m_found_types & (1U << TIME_RESULT)) @@ -3222,7 +3233,7 @@ void Item_func_case::fix_length_and_dec() CASE utf16_item WHEN CONVERT(latin1_item USING utf16) THEN ... END */ if (agg_arg_charsets_for_comparison(cmp_collation, args, nwhens + 1)) - return; + return TRUE; } for (uint i= 0; i <= (uint)TIME_RESULT; i++) @@ -3233,10 +3244,11 @@ void Item_func_case::fix_length_and_dec() if (!(cmp_items[i]= cmp_item::get_comparator((Item_result)i, date_arg, cmp_collation.collation))) - return; + return TRUE; } } } + return FALSE; } @@ -4117,7 +4129,6 @@ static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) (uchar *) y->ptr(),y->length()); } - /* Create 'array' for this IN predicate with the respect to its result type and put values from <in value list> in 'array'. @@ -4178,7 +4189,7 @@ bool Item_func_in::create_array(THD *thd) } -void Item_func_in::fix_length_and_dec() +bool Item_func_in::fix_length_and_dec() { Item **arg, **arg_end; bool const_itm= 1; @@ -4190,7 +4201,7 @@ void Item_func_in::fix_length_and_dec() m_compare_type= STRING_RESULT; left_cmp_type= args[0]->cmp_type(); if (!(found_types= collect_cmp_types(args, arg_count, true))) - return; + return TRUE; for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++) { @@ -4239,7 +4250,7 @@ void Item_func_in::fix_length_and_dec() { if (m_compare_type == STRING_RESULT && agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) - return; + return TRUE; arg_types_compatible= TRUE; if (m_compare_type == ROW_RESULT) @@ -4250,12 +4261,14 @@ void Item_func_in::fix_length_and_dec() if (bisection_possible) { array= new (thd->mem_root) in_row(thd, arg_count-1, 0); + if (!array) + return TRUE; cmp= &((in_row*)array)->tmp; } else { if (!(cmp= new (thd->mem_root) cmp_item_row)) - return; + return TRUE; cmp_items[ROW_RESULT]= cmp; } cmp->n= cols; @@ -4272,6 +4285,8 @@ void Item_func_in::fix_length_and_dec() else cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col; *cmp= new (thd->mem_root) cmp_item_datetime(date_arg); + if (!(*cmp)) + return TRUE; } } } @@ -4306,7 +4321,7 @@ void Item_func_in::fix_length_and_dec() } } if (create_array(thd)) - return; + return TRUE; } else { @@ -4314,7 +4329,7 @@ void Item_func_in::fix_length_and_dec() date_arg= find_date_time_item(thd, args, arg_count, 0, true); if (found_types & (1U << STRING_RESULT) && agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) - return; + return TRUE; for (i= 0; i <= (uint) TIME_RESULT; i++) { if (found_types & (1U << i) && !cmp_items[i]) @@ -4322,11 +4337,12 @@ void Item_func_in::fix_length_and_dec() if (!cmp_items[i] && !(cmp_items[i]= cmp_item::get_comparator((Item_result)i, date_arg, cmp_collation.collation))) - return; + return TRUE; } } } max_length= 1; + return FALSE; } @@ -4617,7 +4633,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; } @@ -5656,16 +5673,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; } @@ -5689,14 +5706,15 @@ 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]); + return FALSE; } @@ -6638,7 +6656,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; } @@ -6724,11 +6743,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); eval_item= cmp_item::get_comparator(item->cmp_type(), item, item->collation.collation); + return FALSE; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 78a9e384b55..a59432058eb 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -200,7 +200,7 @@ public: Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {} 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; } }; @@ -216,7 +216,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; } @@ -501,7 +501,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); @@ -711,7 +711,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; } @@ -878,7 +878,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(); virtual void print(String *str, enum_query_type query_type); bool eval_not_null_tables(void *opt_arg); void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); @@ -911,10 +911,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_strcmp>(thd, mem_root, this); } @@ -941,7 +943,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) @@ -966,10 +968,11 @@ public: String *str_op(String *); my_decimal *decimal_op(my_decimal *); bool date_op(MYSQL_TIME *ltime,uint fuzzydate); - void fix_length_and_dec() + bool fix_length_and_dec() { set_handler_by_field_type(agg_field_type(args, arg_count, true)); fix_attributes(args, arg_count); + return FALSE; } const char *func_name() const { return "coalesce"; } table_map not_null_tables() const { return 0; } @@ -986,10 +989,11 @@ public: class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type { protected: - void fix_length_and_dec2(Item **items) + bool fix_length_and_dec2(Item **items) { set_handler_by_field_type(agg_field_type(items, 2, true)); fix_attributes(items, 2); + return FALSE; } uint decimal_precision2(Item **args) const; public: @@ -1010,10 +1014,12 @@ public: String *str_op(String *str); my_decimal *decimal_op(my_decimal *); bool date_op(MYSQL_TIME *ltime,uint fuzzydate); - 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"; } Field *create_field_for_create_select(TABLE *table) @@ -1041,7 +1047,7 @@ public: my_decimal *decimal_op(my_decimal *); String *str_op(String *); bool fix_fields(THD *, Item **); - void fix_length_and_dec(); + bool fix_length_and_dec(); uint decimal_precision() const { return Item_func_case_abbreviation2::decimal_precision2(args + 1); @@ -1108,7 +1114,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); uint decimal_precision() const { return args[2]->decimal_precision(); } const char *func_name() const { return "nullif"; } @@ -1570,7 +1576,7 @@ public: my_decimal *decimal_op(my_decimal *); bool date_op(MYSQL_TIME *ltime, uint fuzzydate); bool fix_fields(THD *thd, Item **ref); - void fix_length_and_dec(); + bool fix_length_and_dec(); uint decimal_precision() const; table_map not_null_tables() const { return 0; } const char *func_name() const { return "case"; } @@ -1649,7 +1655,7 @@ public: longlong val_int(); bool fix_fields(THD *, Item **); bool create_array(THD *thd); - void fix_length_and_dec(); + bool fix_length_and_dec(); void cleanup() { uint i; @@ -1710,7 +1716,7 @@ public: int compare(cmp_item *arg); cmp_item *make_same(); void store_value_by_template(THD *thd, cmp_item *tmpl, Item *); - friend void Item_func_in::fix_length_and_dec(); + friend bool Item_func_in::fix_length_and_dec(); cmp_item *get_comparator(uint i) { return comparators[i]; } }; @@ -1724,7 +1730,7 @@ public: void set(uint pos,Item *item); uchar *get_value(Item *item); friend bool Item_func_in::create_array(THD *thd); - friend void Item_func_in::fix_length_and_dec(); + friend bool Item_func_in::fix_length_and_dec(); Item_result result_type() { return ROW_RESULT; } cmp_item *get_cmp_item() { return &tmp; } }; @@ -1756,7 +1762,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); }; @@ -1980,10 +1990,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(); @@ -2104,7 +2114,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, MEM_ROOT *mem_root) @@ -2142,7 +2152,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_regexp_instr>(thd, mem_root, this); } @@ -2378,7 +2388,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 cd23c0b64fe..4bdb18ad95a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -237,8 +237,7 @@ Item_func::fix_fields(THD *thd, Item **ref) with_subselect|= item->has_subquery(); } } - fix_length_and_dec(); - if (thd->is_error()) // An error inside fix_length_and_dec occurred + if (fix_length_and_dec()) return TRUE; fixed= 1; return FALSE; @@ -733,10 +732,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_int_func::fix_length_and_dec(); + if (Item_int_func::fix_length_and_dec()) + return TRUE; max_length= 10; + return FALSE; } @@ -755,7 +756,7 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref) function of two arguments. */ -void Item_num_op::fix_length_and_dec(void) +bool Item_num_op::fix_length_and_dec(void) { DBUG_ENTER("Item_num_op::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); @@ -791,7 +792,7 @@ void Item_num_op::fix_length_and_dec(void) result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" : result_type() == INT_RESULT ? "INT_RESULT" : "--ILLEGAL!!!--"))); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -801,7 +802,7 @@ void Item_num_op::fix_length_and_dec(void) type depends only on the first argument) */ -void Item_func_num1::fix_length_and_dec() +bool Item_func_num1::fix_length_and_dec() { DBUG_ENTER("Item_func_num1::fix_length_and_dec"); DBUG_PRINT("info", ("name %s", func_name())); @@ -832,7 +833,7 @@ void Item_func_num1::fix_length_and_dec() result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" : result_type() == INT_RESULT ? "INT_RESULT" : "--ILLEGAL!!!--"))); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -1417,12 +1418,14 @@ void Item_func_additive_op::result_precision() subtraction of UNSIGNED BIGINT to return negative values. */ -void Item_func_minus::fix_length_and_dec() +bool Item_func_minus::fix_length_and_dec() { - Item_num_op::fix_length_and_dec(); + if (Item_num_op::fix_length_and_dec()) + return TRUE; if (unsigned_flag && (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)) unsigned_flag=0; + return FALSE; } @@ -1720,11 +1723,12 @@ void Item_func_div::result_precision() } -void Item_func_div::fix_length_and_dec() +bool Item_func_div::fix_length_and_dec() { DBUG_ENTER("Item_func_div::fix_length_and_dec"); prec_increment= current_thd->variables.div_precincrement; - Item_num_op::fix_length_and_dec(); + if (Item_num_op::fix_length_and_dec()) + DBUG_RETURN(TRUE); switch (Item_func_div::result_type()) { case REAL_RESULT: { @@ -1755,7 +1759,7 @@ void Item_func_div::fix_length_and_dec() DBUG_ASSERT(0); } maybe_null= 1; // devision by zero - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -1831,7 +1835,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 */ @@ -1842,6 +1846,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; } @@ -1925,11 +1930,13 @@ void Item_func_mod::result_precision() } -void Item_func_mod::fix_length_and_dec() +bool Item_func_mod::fix_length_and_dec() { - Item_num_op::fix_length_and_dec(); + if (Item_num_op::fix_length_and_dec()) + return true; maybe_null= 1; unsigned_flag= args[0]->unsigned_flag; + return false; } @@ -1976,10 +1983,11 @@ my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value) } -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"); - Item_func_num1::fix_length_and_dec(); + if (Item_func_num1::fix_length_and_dec()) + DBUG_RETURN(TRUE); /* 1 add because sign can appear */ max_length= args[0]->max_length + 1; @@ -2005,7 +2013,7 @@ void Item_func_neg::fix_length_and_dec() } } unsigned_flag= 0; - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2045,10 +2053,12 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value) } -void Item_func_abs::fix_length_and_dec() +bool Item_func_abs::fix_length_and_dec() { - Item_func_num1::fix_length_and_dec(); + if (Item_func_num1::fix_length_and_dec()) + return TRUE; unsigned_flag= args[0]->unsigned_flag; + return FALSE; } @@ -2280,7 +2290,7 @@ longlong Item_func_bit_neg::val_int() // Conversion functions -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())); @@ -2328,7 +2338,7 @@ void Item_func_int_val::fix_length_and_dec() result_type() == INT_RESULT ? "INT_RESULT" : "--ILLEGAL!!!--"))); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2426,7 +2436,7 @@ my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value) } -void Item_func_round::fix_length_and_dec() +bool Item_func_round::fix_length_and_dec() { int decimals_to_set; longlong val1; @@ -2444,12 +2454,12 @@ void Item_func_round::fix_length_and_dec() } else set_handler_by_result_type(REAL_RESULT); - return; + return FALSE; } val1= args[1]->val_int(); if ((null_value= args[1]->null_value)) - return; + return FALSE; val1_unsigned= args[1]->unsigned_flag; if (val1 < 0) @@ -2462,7 +2472,7 @@ void Item_func_round::fix_length_and_dec() decimals= MY_MIN(decimals_to_set, NOT_FIXED_DEC); max_length= float_length(decimals); set_handler_by_result_type(REAL_RESULT); - return; + return FALSE; } switch (args[0]->result_type()) { @@ -2503,6 +2513,7 @@ void Item_func_round::fix_length_and_dec() case TIME_RESULT: DBUG_ASSERT(0); /* This result type isn't handled */ } + return FALSE; } double my_double_round(double value, longlong dec, bool dec_unsigned, @@ -2727,7 +2738,7 @@ double Item_func_units::val_real() } -void Item_func_min_max::fix_length_and_dec() +bool Item_func_min_max::fix_length_and_dec() { uint unsigned_count= 0; int max_int_part=0; @@ -2838,6 +2849,7 @@ void Item_func_min_max::fix_length_and_dec() set_handler_by_field_type(MYSQL_TYPE_DOUBLE); break; } + return FALSE; } @@ -3088,10 +3100,10 @@ longlong Item_func_coercibility::val_int() } -void Item_func_locate::fix_length_and_dec() +bool Item_func_locate::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); } @@ -3208,14 +3220,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; } @@ -3262,7 +3275,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 @@ -3284,7 +3297,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=','; @@ -3490,7 +3503,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; @@ -3828,13 +3842,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) @@ -4721,7 +4735,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; @@ -4735,6 +4749,7 @@ Item_func_set_user_var::fix_length_and_dec() args[0]->collation.collation); } unsigned_flag= args[0]->unsigned_flag; + return FALSE; } @@ -5573,7 +5588,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; @@ -5623,6 +5638,7 @@ void Item_func_get_user_var::fix_length_and_dec() set_handler_by_field_type(MYSQL_TYPE_LONG_BLOB); max_length= MAX_BLOB_WIDTH; } + return false; } @@ -5765,7 +5781,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; @@ -5777,7 +5793,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; @@ -5841,6 +5857,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; } @@ -6617,7 +6634,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"); @@ -6625,7 +6642,7 @@ void Item_func_sp::fix_length_and_dec() Type_std_attributes::set(sp_result_field); maybe_null= 1; - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -6964,9 +6981,10 @@ my_decimal *Item_func_last_value::val_decimal(my_decimal *decimal_value) } -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 3787b4f4924..0969cf2e3f0 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -399,8 +399,8 @@ public: { DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); } enum Item_result result_type () const { return REAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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; } }; @@ -577,7 +577,7 @@ class Item_func_num1: public Item_func_numhybrid public: Item_func_num1(THD *thd, Item *a): Item_func_numhybrid(thd, a) {} Item_func_num1(THD *thd, Item *a, Item *b): Item_func_numhybrid(thd, a, b) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); }; @@ -592,7 +592,7 @@ class Item_num_op :public Item_func_numhybrid { print_op(str, query_type); } - void fix_length_and_dec(); + bool fix_length_and_dec(); bool need_parentheses_in_default() { return true; } }; @@ -619,7 +619,7 @@ public: String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } - void fix_length_and_dec() {} + bool fix_length_and_dec() { return FALSE; } }; @@ -630,7 +630,7 @@ class Item_func_connection_id :public Item_int_func public: Item_func_connection_id(THD *thd): Item_int_func(thd) {} 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) @@ -656,7 +656,7 @@ public: null_value= args[0]->null_value; return value; } - void fix_length_and_dec() + bool fix_length_and_dec() { uint32 char_length= MY_MIN(args[0]->max_char_length(), MY_INT64_NUM_DECIMAL_DIGITS); @@ -667,6 +667,7 @@ public: */ set_if_bigger(char_length, 1U + (unsigned_flag ? 0 : 1)); fix_char_length(char_length); + return FALSE; } virtual void print(String *str, enum_query_type query_type); uint decimal_precision() const { return args[0]->decimal_precision(); } @@ -713,7 +714,7 @@ public: my_decimal *val_decimal(my_decimal*); enum Item_result result_type () const { return DECIMAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; } - void fix_length_and_dec() {} + bool fix_length_and_dec() { return FALSE; } const char *func_name() const { return "decimal_typecast"; } virtual void print(String *str, enum_query_type query_type); bool need_parentheses_in_default() { return true; } @@ -733,7 +734,7 @@ public: } double val_real(); enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } - void fix_length_and_dec() { maybe_null= 1; } + bool fix_length_and_dec() { maybe_null= 1; return FALSE; } const char *func_name() const { return "double_typecast"; } virtual void print(String *str, enum_query_type query_type); bool need_parentheses_in_default() { return true; } @@ -777,7 +778,7 @@ public: longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_minus>(thd, mem_root, this); } }; @@ -811,7 +812,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 result_precision(); Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_div>(thd, mem_root, this); } @@ -826,7 +827,7 @@ public: longlong val_int(); const char *func_name() const { return "DIV"; } enum precedence precedence() const { return MUL_PRECEDENCE; } - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type) { print_op(str, query_type); @@ -850,7 +851,7 @@ public: const char *func_name() const { return "%"; } enum precedence precedence() const { return MUL_PRECEDENCE; } 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, MEM_ROOT *mem_root) @@ -873,7 +874,7 @@ public: str->append(func_name()); args[0]->print_parenthesised(str, query_type, precedence()); } - void fix_length_and_dec(); + bool fix_length_and_dec(); uint decimal_precision() const { return args[0]->decimal_precision(); } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -891,7 +892,7 @@ public: longlong int_op(); my_decimal *decimal_op(my_decimal *); const char *func_name() const { return "abs"; } - 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, MEM_ROOT *mem_root) @@ -905,10 +906,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; } }; @@ -1066,7 +1068,7 @@ class Item_func_int_val :public Item_func_num1 { public: Item_func_int_val(THD *thd, Item *a): Item_func_num1(thd, a) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); }; @@ -1111,7 +1113,7 @@ public: double real_op(); longlong int_op(); my_decimal *decimal_op(my_decimal *); - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_round>(thd, mem_root, this); } }; @@ -1163,8 +1165,8 @@ 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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_units>(thd, mem_root, this); } }; @@ -1194,7 +1196,7 @@ public: String *val_str(String *); my_decimal *val_decimal(my_decimal *); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); - void fix_length_and_dec(); + bool fix_length_and_dec(); }; class Item_func_min :public Item_func_min_max @@ -1237,13 +1239,14 @@ public: bool const_item() const { return 0; } Item_result result_type() const { return args[0]->result_type(); } enum_field_types field_type() const { return args[0]->field_type(); } - void fix_length_and_dec() + bool fix_length_and_dec() { collation= args[0]->collation; max_length= args[0]->max_length; decimals=args[0]->decimals; /* The item could be a NULL constant. */ null_value= args[0]->is_null(); + return FALSE; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_rollup_const>(thd, mem_root, this); } @@ -1257,7 +1260,7 @@ public: Item_func_length(THD *thd, Item *a): Item_int_func(thd, a) {} longlong val_int(); const char *func_name() const { return "length"; } - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_length>(thd, mem_root, this); } }; @@ -1280,7 +1283,7 @@ public: Item_func_char_length(THD *thd, Item *a): Item_int_func(thd, a) {} longlong val_int(); const char *func_name() const { return "char_length"; } - void fix_length_and_dec() { max_length=10; } + bool fix_length_and_dec() { max_length=10; return FALSE; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_char_length>(thd, mem_root, this); } }; @@ -1291,7 +1294,7 @@ public: Item_func_coercibility(THD *thd, Item *a): Item_int_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; @@ -1313,7 +1316,7 @@ public: Item_func_locate(THD *thd, Item *a, Item *b, Item *c): Item_int_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(); virtual void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_locate>(thd, mem_root, this); } @@ -1329,7 +1332,7 @@ public: Item_func_field(THD *thd, List<Item> &list): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_field>(thd, mem_root, this); } }; @@ -1342,7 +1345,7 @@ public: Item_func_ascii(THD *thd, Item *a): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_ascii>(thd, mem_root, this); } }; @@ -1369,7 +1372,7 @@ public: Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_find_in_set>(thd, mem_root, this); } }; @@ -1381,7 +1384,7 @@ class Item_func_bit: public Item_int_func public: Item_func_bit(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {} Item_func_bit(THD *thd, Item *a): Item_int_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) { @@ -1418,7 +1421,7 @@ public: Item_func_bit_count(THD *thd, Item *a): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_bit_count>(thd, mem_root, this); } }; @@ -1469,12 +1472,13 @@ public: Item_func_last_insert_id(THD *thd, Item *a): Item_int_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; unsigned_flag=1; + return FALSE; } bool fix_fields(THD *thd, Item **ref); bool check_vcol_func_processor(void *arg) @@ -1494,7 +1498,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) { @@ -1652,7 +1656,7 @@ class Item_func_udf_float :public Item_udf_func double val_real(); String *val_str(String *str); enum_field_types field_type() const { return MYSQL_TYPE_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_udf_float>(thd, mem_root, this); } }; @@ -1671,7 +1675,7 @@ public: String *val_str(String *str); enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_udf_int>(thd, mem_root, this); } }; @@ -1690,7 +1694,7 @@ public: String *val_str(String *str); enum Item_result result_type () const { return DECIMAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_udf_decimal>(thd, mem_root, this); } }; @@ -1730,7 +1734,7 @@ public: } enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return string_field_type(); } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_udf_str>(thd, mem_root, this); } }; @@ -1782,7 +1786,7 @@ public: 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; } enum Item_result result_type () const { return STRING_RESULT; } - 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 */ @@ -1797,7 +1801,7 @@ class Item_func_get_lock :public Item_int_func Item_func_get_lock(THD *thd, Item *a, Item *b) :Item_int_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; @@ -1819,7 +1823,7 @@ public: Item_func_release_lock(THD *thd, Item *a): Item_int_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; @@ -1847,7 +1851,7 @@ public: Item_int_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); @@ -1865,7 +1869,7 @@ public: Item_master_gtid_wait(THD *thd, Item *a, Item *b): Item_int_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); @@ -1956,7 +1960,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(); Field *create_field_for_create_select(TABLE *table) { return result_type() != STRING_RESULT ? @@ -1997,7 +2001,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 @@ -2079,7 +2083,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; } @@ -2218,7 +2222,11 @@ public: Item_func_is_free_lock(THD *thd, Item *a): Item_int_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); @@ -2234,7 +2242,11 @@ public: Item_func_is_used_lock(THD *thd, Item *a): Item_int_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); @@ -2286,7 +2298,7 @@ public: Item_func_row_count(THD *thd): Item_int_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); @@ -2414,7 +2426,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() @@ -2450,7 +2462,7 @@ public: Item_func_found_rows(THD *thd): Item_int_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); @@ -2469,8 +2481,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) { @@ -2491,7 +2503,7 @@ public: longlong val_int(); String *val_str(String *); my_decimal *val_decimal(my_decimal *); - void fix_length_and_dec(); + bool fix_length_and_dec(); enum Item_result result_type () const { return last_value->result_type(); } const char *func_name() const { return "last_value"; } bool eval_not_null_tables(void *) diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 3119f5a577b..246be438e36 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -49,12 +49,13 @@ Field *Item_geometry_func::create_field_for_create_select(TABLE *t_arg) return result; } -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) 4294967295U; maybe_null= 1; + return FALSE; } @@ -223,11 +224,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=MAX_BLOB_WIDTH; maybe_null= 1; + return FALSE; } @@ -249,11 +251,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 199bc1f47de..acc94183d47 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(); enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; } Field *create_field_for_create_select(TABLE *table); }; @@ -90,7 +90,7 @@ public: Item_func_as_wkt(THD *thd, Item *a): Item_str_ascii_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_as_wkt>(thd, mem_root, this); } }; @@ -116,7 +116,7 @@ public: Item_func_as_geojson(THD *thd, Item *js, Item *max_dec_digits, Item *opt): Item_str_ascii_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_as_geojson>(thd, mem_root, this); } @@ -129,11 +129,12 @@ public: Item_func_geometry_type(THD *thd, Item *a): Item_str_ascii_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_geometry_type>(thd, mem_root, this); } @@ -308,9 +309,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) @@ -320,8 +322,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"; } @@ -510,7 +514,7 @@ public: Item_func_isempty(THD *thd, Item *a): Item_bool_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_isempty>(thd, mem_root, this); } @@ -526,7 +530,7 @@ public: Item_func_issimple(THD *thd, Item *a): Item_int_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_issimple>(thd, mem_root, this); } @@ -538,7 +542,7 @@ public: Item_func_isclosed(THD *thd, Item *a): Item_int_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_isclosed>(thd, mem_root, this); } @@ -561,7 +565,7 @@ public: Item_func_dimension(THD *thd, Item *a): Item_int_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_dimension>(thd, mem_root, this); } }; @@ -573,10 +577,12 @@ public: Item_func_x(THD *thd, Item *a): Item_real_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_x>(thd, mem_root, this); } @@ -590,10 +596,12 @@ public: Item_func_y(THD *thd, Item *a): Item_real_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_y>(thd, mem_root, this); } @@ -607,7 +615,7 @@ public: Item_func_numgeometries(THD *thd, Item *a): Item_int_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_numgeometries>(thd, mem_root, this); } }; @@ -620,7 +628,7 @@ public: Item_func_numinteriorring(THD *thd, Item *a): Item_int_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_numinteriorring>(thd, mem_root, this); } }; @@ -633,7 +641,7 @@ public: Item_func_numpoints(THD *thd, Item *a): Item_int_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_numpoints>(thd, mem_root, this); } }; @@ -646,10 +654,12 @@ public: Item_func_area(THD *thd, Item *a): Item_real_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_area>(thd, mem_root, this); } @@ -663,10 +673,12 @@ public: Item_func_glength(THD *thd, Item *a): Item_real_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_glength>(thd, mem_root, this); } @@ -680,7 +692,7 @@ public: Item_func_srid(THD *thd, Item *a): Item_int_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_srid>(thd, mem_root, this); } }; diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h index f19749df0af..670dce3da9f 100644 --- a/sql/item_inetfunc.h +++ b/sql/item_inetfunc.h @@ -30,12 +30,13 @@ public: Item_func_inet_aton(THD *thd, Item *a): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_inet_aton>(thd, mem_root, this); } @@ -53,11 +54,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_inet_ntoa>(thd, mem_root, this); } @@ -122,11 +124,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_inet6_aton>(thd, mem_root, this); } @@ -151,7 +154,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; @@ -161,6 +164,7 @@ public: fix_length_and_charset(8 * 4 + 7, default_charset()); maybe_null= 1; + return FALSE; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_inet6_ntoa>(thd, mem_root, this); } diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 794831ae1a5..72aeac5b930 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_int_func::fix_length_and_dec(); + if (Item_int_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_int_func::fix_length_and_dec(); + return Item_int_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_int_func::fix_length_and_dec(); + return Item_int_func::fix_length_and_dec(); } @@ -1454,7 +1460,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; @@ -1467,17 +1473,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; } @@ -1521,7 +1528,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; @@ -1536,6 +1543,7 @@ void Item_func_json_array_append::fix_length_and_dec() } fix_char_length_ulonglong(char_length); + return FALSE; } @@ -2122,11 +2130,12 @@ 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; + return FALSE; } @@ -2266,11 +2275,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; } @@ -2323,7 +2333,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; @@ -2339,6 +2349,7 @@ void Item_func_json_insert::fix_length_and_dec() fix_char_length_ulonglong(char_length); maybe_null= 1; + return FALSE; } @@ -2583,13 +2594,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; } @@ -2769,13 +2781,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; } @@ -2936,7 +2949,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); @@ -2958,6 +2971,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; } @@ -3135,11 +3149,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 927b60015b8..f331ee3b582 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_int_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_int_func::fix_length_and_dec(); + if (Item_int_func::fix_length_and_dec()) + return TRUE; maybe_null= 1; + return FALSE; } bool is_bool_type() { return true; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) @@ -71,7 +73,7 @@ public: Item_int_func(thd, js, i_path) {} const char *func_name() const { return "json_exists"; } bool is_bool_type() { return true; } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_json_exists>(thd, mem_root, this); } longlong val_int(); @@ -88,7 +90,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, MEM_ROOT *mem_root) @@ -117,7 +119,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_json_quote>(thd, mem_root, this); } @@ -132,7 +134,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_json_unquote>(thd, mem_root, this); } @@ -165,7 +167,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(); @@ -187,7 +189,7 @@ public: Item_func_json_contains(THD *thd, List<Item> &list): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_json_contains>(thd, mem_root, this); } @@ -209,7 +211,7 @@ public: Item_int_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, MEM_ROOT *mem_root) @@ -229,7 +231,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_json_array>(thd, mem_root, this); } @@ -244,7 +246,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"; } @@ -305,7 +307,7 @@ public: Item_func_json_length(THD *thd, List<Item> &list): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_json_length>(thd, mem_root, this); } @@ -332,7 +334,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_json_type>(thd, mem_root, this); } @@ -349,7 +351,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 @@ -369,7 +371,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"; } @@ -388,7 +390,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_json_keys>(thd, mem_root, this); } @@ -412,7 +414,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, MEM_ROOT *mem_root) @@ -440,7 +442,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 3d543c8c390..87c766340c7 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; } @@ -630,17 +636,18 @@ null: } -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; } /** @@ -992,12 +999,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, @@ -1009,6 +1016,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; } @@ -1062,11 +1070,12 @@ 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); DBUG_ASSERT(collation.collation != NULL); fix_char_length(args[0]->max_char_length()); + return FALSE; } /** @@ -1208,7 +1217,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()); @@ -1219,8 +1228,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; } @@ -1232,13 +1242,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; } @@ -1374,13 +1385,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; } @@ -1488,16 +1500,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; } @@ -1534,22 +1547,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; } @@ -1592,11 +1609,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; } @@ -1626,11 +1645,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; } @@ -1681,11 +1702,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()) { @@ -1706,14 +1728,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; } @@ -2037,11 +2061,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); @@ -2052,9 +2077,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) @@ -2194,7 +2220,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; @@ -2202,6 +2228,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) @@ -2347,13 +2374,14 @@ 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); DBUG_ASSERT(collation.collation != NULL); set_if_bigger(char_length, 4); fix_char_length(char_length); + return FALSE; } @@ -2529,7 +2557,7 @@ MY_LOCALE *Item_func_format::get_locale(Item *item) return lc; } -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; @@ -2539,6 +2567,7 @@ void Item_func_format::fix_length_and_dec() locale= args[2]->basic_const_item() ? get_locale(args[2]) : NULL; else locale= &my_locale_en_US; /* Two arguments */ + return FALSE; } @@ -2652,13 +2681,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++) { @@ -2667,6 +2696,7 @@ void Item_func_elt::fix_length_and_dec() } fix_char_length(char_length); maybe_null=1; // NULL if wrong first arg + return FALSE; } @@ -2713,16 +2743,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; } @@ -2853,9 +2884,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()) { @@ -2877,6 +2909,7 @@ void Item_func_repeat::fix_length_and_dec() max_length= MAX_BLOB_WIDTH; maybe_null= 1; } + return FALSE; } /** @@ -2938,7 +2971,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()) @@ -2954,12 +2987,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; } @@ -3009,11 +3043,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; } @@ -3049,11 +3084,11 @@ err: } -void Item_func_rpad::fix_length_and_dec() +bool Item_func_rpad::fix_length_and_dec() { // Handle character set for args[0] and args[2]. if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2)) - return; + return TRUE; if (args[1]->const_item()) { ulonglong char_length= (ulonglong) args[1]->val_int(); @@ -3071,6 +3106,7 @@ void Item_func_rpad::fix_length_and_dec() max_length= MAX_BLOB_WIDTH; maybe_null= 1; } + return FALSE; } @@ -3157,12 +3193,12 @@ String *Item_func_rpad::val_str(String *str) } -void Item_func_lpad::fix_length_and_dec() +bool Item_func_lpad::fix_length_and_dec() { // Handle character set for args[0] and args[2]. if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2)) - return; - + return TRUE; + if (args[1]->const_item()) { ulonglong char_length= (ulonglong) args[1]->val_int(); @@ -3180,6 +3216,7 @@ void Item_func_lpad::fix_length_and_dec() max_length= MAX_BLOB_WIDTH; maybe_null= 1; } + return FALSE; } @@ -3329,10 +3366,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) @@ -3354,7 +3392,7 @@ 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() { CHARSET_INFO *set_collation; const char *colname; @@ -3365,8 +3403,8 @@ void Item_func_set_collation::fix_length_and_dec() MY_CS_BINSORT,MYF(0)); else { - if (!(set_collation= mysqld_collation_get_by_name(colname))) - return; + if (!(set_collation= mysqld_collation_get_by_name(colname))) + return TRUE; } if (!set_collation || @@ -3374,11 +3412,12 @@ void Item_func_set_collation::fix_length_and_dec() { my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), colname, args[0]->collation.collation->csname); - return; + return TRUE; } collation.set(set_collation, DERIVATION_EXPLICIT, args[0]->collation.repertoire); max_length= args[0]->max_length; + return FALSE; } @@ -3437,7 +3476,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); @@ -3455,6 +3494,7 @@ void Item_func_weight_string::fix_length_and_dec() max_length= cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen); } maybe_null= 1; + return FALSE; } @@ -3838,15 +3878,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; } @@ -4246,12 +4287,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) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index c9956ab364e..a908aba2d2f 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -145,9 +145,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, MEM_ROOT *mem_root) @@ -160,7 +161,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_sha>(thd, mem_root, this); } @@ -172,7 +173,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_sha2>(thd, mem_root, this); } @@ -185,7 +186,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_to_base64>(thd, mem_root, this); } @@ -198,7 +199,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_from_base64>(thd, mem_root, this); } @@ -225,7 +226,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_aes_encrypt>(thd, mem_root, this); } @@ -236,7 +237,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_aes_decrypt>(thd, mem_root, this); } @@ -251,7 +252,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_concat>(thd, mem_root, this); } @@ -263,11 +264,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, MEM_ROOT *mem_root) @@ -280,7 +282,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, MEM_ROOT *mem_root) @@ -293,7 +295,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_reverse>(thd, mem_root, this); } @@ -307,7 +309,7 @@ public: Item_func_replace(THD *thd, Item *org, Item *find, Item *replace): Item_str_func(thd, org, find, replace) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "replace"; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_replace>(thd, mem_root, this); } @@ -333,7 +335,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, MEM_ROOT *mem_root) { return 0;} }; @@ -355,7 +357,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, MEM_ROOT *mem_root) { return 0; } }; @@ -369,7 +371,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_insert>(thd, mem_root, this); } @@ -393,7 +395,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_lcase>(thd, mem_root, this); } }; @@ -403,7 +405,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_ucase>(thd, mem_root, this); } }; @@ -415,7 +417,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_left>(thd, mem_root, this); } @@ -428,7 +430,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_right>(thd, mem_root, this); } @@ -442,7 +444,7 @@ public: Item_func_substr(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {} 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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_substr>(thd, mem_root, this); } @@ -456,7 +458,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_substr_index>(thd, mem_root, this); } @@ -488,7 +490,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"; } @@ -546,12 +548,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"); } @@ -572,11 +575,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, MEM_ROOT *mem_root) @@ -592,13 +596,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, MEM_ROOT *mem_root) @@ -631,7 +636,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) { @@ -655,7 +660,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_encode>(thd, mem_root, this); } @@ -705,10 +710,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()"; } @@ -733,10 +739,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()"; } @@ -776,8 +783,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"; } @@ -805,7 +815,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_soundex>(thd, mem_root, this); } @@ -819,7 +829,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_elt>(thd, mem_root, this); } @@ -833,7 +843,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_make_set>(thd, mem_root, this); } @@ -851,7 +861,7 @@ public: MY_LOCALE *get_locale(Item *item); 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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_format>(thd, mem_root, this); } @@ -867,9 +877,10 @@ public: Item_str_func(thd, list) { collation.set(cs); } String *val_str(String *); - 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); @@ -885,7 +896,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_repeat>(thd, mem_root, this); } @@ -897,7 +908,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_space>(thd, mem_root, this); } @@ -910,7 +921,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) { @@ -928,7 +939,7 @@ public: Item_func_rpad(THD *thd, Item *arg1, Item *arg2, Item *arg3): Item_str_func(thd, arg1, arg2, arg3) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "rpad"; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_rpad>(thd, mem_root, this); } @@ -942,7 +953,7 @@ public: Item_func_lpad(THD *thd, Item *arg1, Item *arg2, Item *arg3): Item_str_func(thd, arg1, arg2, arg3) {} String *val_str(String *); - void fix_length_and_dec(); + bool fix_length_and_dec(); const char *func_name() const { return "lpad"; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_lpad>(thd, mem_root, this); } @@ -956,11 +967,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_conv>(thd, mem_root, this); } @@ -975,11 +987,12 @@ public: Item_str_ascii_checksum_func(thd, a) {} const char *func_name() const { return "hex"; } String *val_str_ascii(String *); - void fix_length_and_dec() + bool fix_length_and_dec() { collation.set(default_charset()); decimals=0; fix_char_length(args[0]->max_length * 2); + return FALSE; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_func_hex>(thd, mem_root, this); } @@ -996,11 +1009,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_unhex>(thd, mem_root, this); } @@ -1019,11 +1033,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; } }; @@ -1064,10 +1079,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"; } @@ -1084,11 +1100,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) { @@ -1109,7 +1126,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_export_set>(thd, mem_root, this); } @@ -1123,12 +1140,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_quote>(thd, mem_root, this); } @@ -1211,7 +1229,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, MEM_ROOT *mem_root) @@ -1224,7 +1242,7 @@ public: Item_func_set_collation(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(); bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "collate"; } enum precedence precedence() const { return COLLATE_PRECEDENCE; } @@ -1245,11 +1263,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) @@ -1299,7 +1318,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)) @@ -1323,7 +1342,7 @@ public: Item_func_crc32(THD *thd, Item *a): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_crc32>(thd, mem_root, this); } @@ -1335,7 +1354,7 @@ class Item_func_uncompressed_length : public Item_int_func public: Item_func_uncompressed_length(THD *thd, Item *a): Item_int_func(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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_uncompressed_length>(thd, mem_root, this); } @@ -1353,7 +1372,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, MEM_ROOT *mem_root) @@ -1366,7 +1389,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, MEM_ROOT *mem_root) @@ -1378,11 +1405,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; } @@ -1410,7 +1438,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); @@ -1440,11 +1468,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_dyncol_json>(thd, mem_root, this); } @@ -1459,8 +1488,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; } @@ -1498,7 +1527,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, MEM_ROOT *mem_root) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index a8e83d298f6..8a9dd083911 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -305,10 +305,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; @@ -905,9 +909,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; } @@ -1195,18 +1201,19 @@ enum_field_types Item_singlerow_subselect::field_type() const return engine->field_type(); } -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; @@ -1222,6 +1229,7 @@ void Item_singlerow_subselect::fix_length_and_dec() for (uint i= 0; i < max_columns; i++) row[i]->maybe_null= TRUE; } + return FALSE; } @@ -1506,7 +1514,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(); @@ -1514,14 +1522,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(); @@ -1529,7 +1540,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); } @@ -3712,11 +3723,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); @@ -3732,44 +3743,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]= Item_cache::get_cache(thd, sel_item, sel_item->cmp_type()))) - return; + return TRUE; row[i]->setup(thd, sel_item); //psergey-backport-timours: row[i]->store(sel_item); } if (item_list.elements > 1) cmp_type= res_type= ROW_RESULT; + 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); @@ -5602,9 +5620,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 7e99e2c3075..bd6a1bdc498 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -196,7 +196,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: enum Item_result result_type() const; enum Item_result cmp_type() const; enum_field_types field_type() const; - void fix_length_and_dec(); + bool fix_length_and_dec(); uint cols(); Item* element_index(uint i) { return reinterpret_cast<Item*>(row[i]); } @@ -403,7 +403,7 @@ public: my_decimal *val_decimal(my_decimal *); bool val_bool(); 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; } @@ -626,7 +626,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 { @@ -810,7 +810,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 @@ -854,7 +854,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); }; @@ -870,7 +870,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(); uint8 uncacheable(); @@ -905,7 +905,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(); uint8 uncacheable(); @@ -963,7 +963,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() { return 1; } uint8 uncacheable() { return UNCACHEABLE_DEPENDENT_INJECTED; } @@ -1112,7 +1112,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, @@ -1385,7 +1385,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() { /* 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 cb150db3031..9e59ec4e373 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1132,9 +1132,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); @@ -1189,9 +1188,8 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) maybe_null= 1; result_field=0; 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; orig_args[0]= args[0]; @@ -1329,7 +1327,7 @@ void Item_sum_sum::clear() } -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; @@ -1364,7 +1362,7 @@ void Item_sum_sum::fix_length_and_dec() "--ILLEGAL!!!--"), max_length, (int)decimals)); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -1664,9 +1662,10 @@ void Item_sum_count::cleanup() /* Avgerage */ -void Item_sum_avg::fix_length_and_dec() +bool Item_sum_avg::fix_length_and_dec() { - Item_sum_sum::fix_length_and_dec(); + if (Item_sum_sum::fix_length_and_dec()) + return TRUE; maybe_null=null_value=1; prec_increment= current_thd->variables.div_precincrement; if (Item_sum_avg::result_type() == DECIMAL_RESULT) @@ -1686,6 +1685,7 @@ void Item_sum_avg::fix_length_and_dec() FLOATING_POINT_DECIMALS); max_length= MY_MIN(args[0]->max_length + prec_increment, float_length(decimals)); } + return FALSE; } @@ -1884,7 +1884,7 @@ Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item): } -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; @@ -1919,7 +1919,7 @@ void Item_sum_variance::fix_length_and_dec() DBUG_ASSERT(0); } DBUG_PRINT("info", ("Type: REAL_RESULT (%d, %d)", max_length, (int)decimals)); - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } @@ -2989,13 +2989,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 5c446e5779d..5c8ff520259 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -457,7 +457,8 @@ public: */ virtual void update_field()=0; virtual bool keep_field_type(void) const { return 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 (); @@ -752,8 +753,8 @@ public: my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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; } }; @@ -764,7 +765,7 @@ protected: double sum; 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): @@ -888,7 +889,7 @@ public: :Item_sum_sum(thd, item), count(item->count), prec_increment(item->prec_increment) {} - void fix_length_and_dec(); + bool fix_length_and_dec(); enum Sumfunctype sum_func () const { return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC; @@ -948,7 +949,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. */ @@ -1110,8 +1111,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; @@ -1401,7 +1405,7 @@ class Item_sum_udf_float :public Item_udf_sum enum Item_result result_type () const { return REAL_RESULT; } enum Item_result cmp_type () const { return REAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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, MEM_ROOT *mem_root) { return get_item_copy<Item_sum_udf_float>(thd, mem_root, this); } @@ -1424,7 +1428,7 @@ public: my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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, MEM_ROOT *mem_root) { return get_item_copy<Item_sum_udf_int>(thd, mem_root, this); } @@ -1466,7 +1470,7 @@ public: my_decimal *val_decimal(my_decimal *dec); enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return string_field_type(); } - void fix_length_and_dec(); + bool fix_length_and_dec(); Item *copy_or_same(THD* thd); Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_sum_udf_str>(thd, mem_root, this); } @@ -1488,7 +1492,7 @@ public: my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return DECIMAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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, MEM_ROOT *mem_root) { return get_item_copy<Item_sum_udf_decimal>(thd, mem_root, this); } @@ -1563,7 +1567,7 @@ public: 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; } enum Item_result result_type () const { return STRING_RESULT; } - 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 87c6489189c..bb75ad7c28c 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -953,7 +953,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; @@ -961,7 +961,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; } @@ -1101,7 +1102,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; @@ -1109,7 +1110,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; } @@ -1476,7 +1478,7 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval) } -void Item_temporal_func::fix_length_and_dec() +bool Item_temporal_func::fix_length_and_dec() { uint char_length= mysql_temporal_int_part_length(field_type()); /* @@ -1502,6 +1504,7 @@ void Item_temporal_func::fix_length_and_dec() DERIVATION_COERCIBLE : DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII); fix_char_length(char_length); + return FALSE; } String *Item_temporal_func::val_str(String *str) @@ -1873,7 +1876,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; locale= thd->variables.lc_time_names; @@ -1904,6 +1907,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; } @@ -2050,13 +2054,13 @@ 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; decimals= args[0]->decimals; - Item_temporal_func::fix_length_and_dec(); + return Item_temporal_func::fix_length_and_dec(); } @@ -2083,10 +2087,10 @@ bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime, } -void Item_func_convert_tz::fix_length_and_dec() +bool Item_func_convert_tz::fix_length_and_dec() { decimals= args[0]->temporal_precision(MYSQL_TYPE_DATETIME); - Item_temporal_func::fix_length_and_dec(); + return Item_temporal_func::fix_length_and_dec(); } @@ -2135,7 +2139,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; @@ -2190,7 +2194,7 @@ void Item_date_add_interval::fix_length_and_dec() } else decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec); - Item_temporal_func::fix_length_and_dec(); + return Item_temporal_func::fix_length_and_dec(); } @@ -2261,7 +2265,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) { @@ -2287,6 +2291,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; } @@ -2548,7 +2553,7 @@ end: } -void Item_char_typecast::fix_length_and_dec() +bool Item_char_typecast::fix_length_and_dec() { uint32 char_length; /* @@ -2594,6 +2599,7 @@ void Item_char_typecast::fix_length_and_dec() (cast_cs == &my_charset_bin ? 1 : args[0]->collation.collation->mbmaxlen)); max_length= char_length * cast_cs->mbmaxlen; + return FALSE; } @@ -2682,7 +2688,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; decimals= MY_MAX(args[0]->decimals, args[1]->decimals); @@ -2714,7 +2720,7 @@ void Item_func_add_time::fix_length_and_dec() decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME), args[1]->temporal_precision(MYSQL_TYPE_TIME)); } - Item_temporal_func::fix_length_and_dec(); + return Item_temporal_func::fix_length_and_dec(); } /** @@ -3203,10 +3209,10 @@ 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 (agg_arg_charsets(collation, args, 2, MY_COLL_ALLOW_CONV, 1)) - return; + return TRUE; if (collation.collation->mbminlen > 1) { #if MYSQL_VERSION_ID > 50500 @@ -3249,7 +3255,7 @@ void Item_func_str_to_date::fix_length_and_dec() } } cached_timestamp_type= mysql_type_to_time_type(field_type()); - Item_temporal_func::fix_length_and_dec(); + return Item_temporal_func::fix_length_and_dec(); } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 354a54a5c1a..c983e1a6f8a 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -49,9 +49,10 @@ public: Item_func_period_add(THD *thd, Item *a, Item *b): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_period_add>(thd, mem_root, this); } @@ -64,10 +65,11 @@ public: Item_func_period_diff(THD *thd, Item *a, Item *b): Item_int_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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_period_diff>(thd, mem_root, this); } @@ -80,11 +82,12 @@ public: Item_func_to_days(THD *thd, Item *a): Item_int_func(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); @@ -105,11 +108,12 @@ public: Item_func_to_seconds(THD *thd, Item *a): Item_int_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; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; maybe_null= 1; + return FALSE; } enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); @@ -131,11 +135,12 @@ public: Item_func_dayofmonth(THD *thd, Item *a): Item_int_func(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;} @@ -167,11 +172,12 @@ public: const char *func_name() const { return "month"; } enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } - 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;} @@ -191,7 +197,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) { @@ -212,11 +218,12 @@ public: Item_func_dayofyear(THD *thd, Item *a): Item_int_func(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;} @@ -235,11 +242,12 @@ public: Item_func_hour(THD *thd, Item *a): Item_int_func(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;} @@ -258,11 +266,12 @@ public: Item_func_minute(THD *thd, Item *a): Item_int_func(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;} @@ -281,11 +290,12 @@ public: Item_func_quarter(THD *thd, Item *a): Item_int_func(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;} @@ -304,11 +314,12 @@ public: Item_func_second(THD *thd, Item *a): Item_int_func(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;} @@ -328,11 +339,12 @@ public: Item_func_week(THD *thd, Item *a, Item *b): Item_int_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) { @@ -354,11 +366,12 @@ public: Item_func_yearweek(THD *thd, Item *a, Item *b): Item_int_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;} @@ -379,11 +392,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;} @@ -416,11 +430,12 @@ public: } enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } - 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;} @@ -441,7 +456,7 @@ class Item_func_dayname :public Item_func_weekday String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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) { @@ -457,7 +472,7 @@ protected: public: Item_func_seconds_hybrid(THD *thd): Item_func_numhybrid(thd) {} Item_func_seconds_hybrid(THD *thd, Item *a): Item_func_numhybrid(thd, a) {} - void fix_length_and_dec() + bool fix_length_and_dec() { if (arg_count) decimals= args[0]->temporal_precision(arg0_expected_type()); @@ -465,6 +480,7 @@ public: max_length=17 + (decimals ? decimals + 1 : 0); maybe_null= true; set_handler_by_result_type(decimals ? DECIMAL_RESULT : INT_RESULT); + return FALSE; } double real_op() { DBUG_ASSERT(0); return 0; } String *str_op(String *str) { DBUG_ASSERT(0); return 0; } @@ -556,7 +572,7 @@ public: save_date_in_field(field); } #endif - void fix_length_and_dec(); + bool fix_length_and_dec(); }; @@ -834,7 +850,7 @@ public: String *val_str(String *str); const char *func_name() const { return is_time_format ? "time_format" : "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) @@ -854,7 +870,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_from_unixtime>(thd, mem_root, this); } @@ -889,7 +905,7 @@ 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(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); void cleanup(); Item *get_copy(THD *thd, MEM_ROOT *mem_root) @@ -902,10 +918,10 @@ 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() { decimals= MY_MIN(args[0]->decimals, TIME_SECOND_PART_DIGITS); - Item_timefunc::fix_length_and_dec(); + return Item_timefunc::fix_length_and_dec(); } const char *func_name() const { return "sec_to_time"; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) @@ -923,7 +939,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); @@ -991,7 +1007,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;} @@ -1063,7 +1079,7 @@ public: bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "cast_as_char"; } String *val_str(String *a); - void fix_length_and_dec(); + bool fix_length_and_dec(); void print(String *str, enum_query_type query_type); bool need_parentheses_in_default() { return true; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) @@ -1077,11 +1093,11 @@ public: Item_temporal_typecast(THD *thd, Item *a): Item_temporal_func(thd, a) {} virtual const char *cast_type() const = 0; void print(String *str, enum_query_type query_type); - void fix_length_and_dec() + bool fix_length_and_dec() { if (decimals == NOT_FIXED_DEC) decimals= args[0]->temporal_precision(field_type()); - Item_temporal_func::fix_length_and_dec(); + return Item_temporal_func::fix_length_and_dec(); } }; @@ -1148,7 +1164,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"; } @@ -1161,11 +1177,11 @@ 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() { decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME), args[1]->temporal_precision(MYSQL_TYPE_TIME)); - Item_timefunc::fix_length_and_dec(); + return Item_timefunc::fix_length_and_dec(); } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); Item *get_copy(THD *thd, MEM_ROOT *mem_root) @@ -1178,10 +1194,10 @@ 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() { decimals= MY_MIN(args[2]->decimals, TIME_SECOND_PART_DIGITS); - Item_timefunc::fix_length_and_dec(); + return Item_timefunc::fix_length_and_dec(); } const char *func_name() const { return "maketime"; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); @@ -1196,10 +1212,11 @@ public: Item_func_microsecond(THD *thd, Item *a): Item_int_func(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; + return FALSE; } bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;} @@ -1220,10 +1237,11 @@ public: Item_int_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, MEM_ROOT *mem_root) @@ -1245,11 +1263,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, MEM_ROOT *mem_root) @@ -1271,7 +1290,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, MEM_ROOT *mem_root) { return get_item_copy<Item_func_str_to_date>(thd, mem_root, this); } }; diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index 52738bfab87..7cb07af440b 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -106,7 +106,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; @@ -268,7 +269,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 a1ef6854288..e5afb9e1555 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -516,10 +516,11 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count enum Item_result result_type () const { return REAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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); @@ -602,10 +603,11 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count enum Item_result result_type () const { return REAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_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, MEM_ROOT *mem_root) @@ -950,9 +952,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 af62a94afd0..738047fea9b 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, MEM_ROOT *mem_root) { return get_item_copy<Item_nodeset_context_cache>(thd, mem_root, this); } }; @@ -470,7 +471,7 @@ public: Item_func_xpath_position(THD *thd, Item *a, String *p): Item_int_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_int_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; @@ -2709,10 +2710,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 d281e076ec8..c46365ee5f0 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 4ebd5ef4954..10e9e65c0c4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13527,7 +13527,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 dd21c8fb107..9a87b0e7461 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4896,7 +4896,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, table_name, create_info, file, frm_only)) @@ -7398,10 +7403,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, |