diff options
Diffstat (limited to 'sql/item_func.h')
-rw-r--r-- | sql/item_func.h | 178 |
1 files changed, 139 insertions, 39 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index abaf07c51d5..3b1a38cf447 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1,4 +1,6 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. +#ifndef ITEM_FUNC_INCLUDED +#define ITEM_FUNC_INCLUDED +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. Copyright (c) 2009-2011 Monty Program Ab This program is free software; you can redistribute it and/or modify @@ -12,8 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Function items used by mysql */ @@ -149,7 +150,7 @@ public: void count_only_length(); void count_real_length(); void count_decimal_length(); - inline bool get_arg0_date(MYSQL_TIME *ltime, uint fuzzy_date) + inline bool get_arg0_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { return (null_value=args[0]->get_date(ltime, fuzzy_date)); } @@ -169,22 +170,49 @@ public: my_decimal *val_decimal(my_decimal *); - bool agg_arg_collations(DTCollation &c, Item **items, uint nitems, - uint flags) + bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, + uint flags, int item_sep) { - return agg_item_collations(c, func_name(), items, nitems, flags, 1); + return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep); } - bool agg_arg_collations_for_comparison(DTCollation &c, - Item **items, uint nitems, - uint flags) + /* + Aggregate arguments for string result, e.g: CONCAT(a,b) + - convert to @@character_set_connection if all arguments are numbers + - allow DERIVATION_NONE + */ + bool agg_arg_charsets_for_string_result(DTCollation &c, + Item **items, uint nitems, + int item_sep= 1) { - return agg_item_collations_for_comparison(c, func_name(), - items, nitems, flags); + return agg_item_charsets_for_string_result(c, func_name(), + items, nitems, item_sep); } - bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, - uint flags, int item_sep) + /* + Aggregate arguments for comparison, e.g: a=b, a LIKE b, a RLIKE b + - don't convert to @@character_set_connection if all arguments are numbers + - don't allow DERIVATION_NONE + */ + bool agg_arg_charsets_for_comparison(DTCollation &c, + Item **items, uint nitems, + int item_sep= 1) { - return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep); + return agg_item_charsets_for_comparison(c, func_name(), + items, nitems, item_sep); + } + /* + Aggregate arguments for string result, when some comparison + is involved internally, e.g: REPLACE(a,b,c) + - convert to @@character_set_connection if all arguments are numbers + - disallow DERIVATION_NONE + */ + bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c, + Item **items, + uint nitems, + int item_sep= 1) + { + return agg_item_charsets_for_string_result_with_comparison(c, func_name(), + items, nitems, + item_sep); } bool walk(Item_processor processor, bool walk_subquery, uchar *arg); Item *transform(Item_transformer transformer, uchar *arg); @@ -195,13 +223,56 @@ public: bool eval_not_null_tables(uchar *opt_arg); // bool is_expensive_processor(uchar *arg); // virtual bool is_expensive() { return 0; } - inline double fix_result(double value) + inline void raise_numeric_overflow(const char *type_name) + { + char buf[256]; + String str(buf, sizeof(buf), system_charset_info); + str.length(0); + print(&str, QT_ORDINARY); + my_error(ER_DATA_OUT_OF_RANGE, MYF(0), type_name, str.c_ptr_safe()); + } + inline double raise_float_overflow() { - if (isfinite(value)) - return value; - null_value=1; + raise_numeric_overflow("DOUBLE"); return 0.0; } + inline longlong raise_integer_overflow() + { + raise_numeric_overflow(unsigned_flag ? "BIGINT UNSIGNED": "BIGINT"); + return 0; + } + inline int raise_decimal_overflow() + { + raise_numeric_overflow("DECIMAL"); + return E_DEC_OVERFLOW; + } + /** + Throw an error if the input double number is not finite, i.e. is either + +/-INF or NAN. + */ + inline double check_float_overflow(double value) + { + return isfinite(value) ? value : raise_float_overflow(); + } + /** + Throw an error if the input BIGINT value represented by the + (longlong value, bool unsigned flag) pair cannot be returned by the + function, i.e. is not compatible with this Item's unsigned_flag. + */ + inline longlong check_integer_overflow(longlong value, bool val_unsigned) + { + if ((unsigned_flag && !val_unsigned && value < 0) || + (!unsigned_flag && val_unsigned && (ulonglong) value > LONGLONG_MAX)) + return raise_integer_overflow(); + return value; + } + /** + Throw an error if the error code of a DECIMAL operation is E_DEC_OVERFLOW. + */ + inline int check_decimal_overflow(int error) + { + return (error == E_DEC_OVERFLOW) ? raise_decimal_overflow() : error; + } bool has_timestamp_args() { @@ -306,10 +377,10 @@ public: class Item_real_func :public Item_func { public: - Item_real_func() :Item_func() {} - Item_real_func(Item *a) :Item_func(a) {} - Item_real_func(Item *a,Item *b) :Item_func(a,b) {} - Item_real_func(List<Item> &list) :Item_func(list) {} + Item_real_func() :Item_func() { collation.set_numeric(); } + Item_real_func(Item *a) :Item_func(a) { collation.set_numeric(); } + Item_real_func(Item *a,Item *b) :Item_func(a,b) { collation.set_numeric(); } + Item_real_func(List<Item> &list) :Item_func(list) { collation.set_numeric(); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *decimal_value); longlong val_int() @@ -328,13 +399,13 @@ public: Item_func_numhybrid() :Item_func(), hybrid_type(REAL_RESULT) {} Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT) - {} + { collation.set_numeric(); } Item_func_numhybrid(Item *a,Item *b) :Item_func(a,b), hybrid_type(REAL_RESULT) - {} + { collation.set_numeric(); } Item_func_numhybrid(List<Item> &list) :Item_func(list), hybrid_type(REAL_RESULT) - {} + { collation.set_numeric(); } enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec(); @@ -417,13 +488,18 @@ class Item_num_op :public Item_func_numhybrid class Item_int_func :public Item_func { public: - Item_int_func() :Item_func() { max_length= 21; } - Item_int_func(Item *a) :Item_func(a) { max_length= 21; } - Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length= 21; } + Item_int_func() :Item_func() + { collation.set_numeric(); fix_char_length(21); } + Item_int_func(Item *a) :Item_func(a) + { collation.set_numeric(); fix_char_length(21); } + Item_int_func(Item *a,Item *b) :Item_func(a,b) + { collation.set_numeric(); fix_char_length(21); } Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) - { max_length= 21; } - Item_int_func(List<Item> &list) :Item_func(list) { max_length= 21; } - Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {} + { collation.set_numeric(); fix_char_length(21); } + Item_int_func(List<Item> &list) :Item_func(list) + { collation.set_numeric(); fix_char_length(21); } + Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) + { collation.set_numeric(); } double val_real(); String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } @@ -453,7 +529,7 @@ public: longlong val_int(); longlong val_int_from_str(int *error); void fix_length_and_dec() - { max_length=args[0]->max_length; unsigned_flag=0; } + { fix_char_length(args[0]->max_char_length()); unsigned_flag=0; } virtual void print(String *str, enum_query_type query_type); uint decimal_precision() const { return args[0]->decimal_precision(); } }; @@ -466,7 +542,8 @@ public: const char *func_name() const { return "cast_as_unsigned"; } void fix_length_and_dec() { - max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2); + fix_char_length(min(args[0]->max_char_length(), + DECIMAL_MAX_PRECISION + 2)); unsigned_flag=1; } longlong val_int(); @@ -481,8 +558,9 @@ public: Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a) { decimals= (uint8) dec; - max_length= my_decimal_precision_to_length_no_truncation(len, dec, - unsigned_flag); + collation.set_numeric(); + fix_char_length(my_decimal_precision_to_length_no_truncation(len, dec, + unsigned_flag)); } String *val_str(String *str); double val_real(); @@ -764,6 +842,14 @@ public: const char *func_name() const { return "tan"; } }; +class Item_func_cot :public Item_dec_func +{ +public: + Item_func_cot(Item *a) :Item_dec_func(a) {} + double val_real(); + const char *func_name() const { return "cot"; } +}; + class Item_func_integer :public Item_int_func { public: @@ -879,12 +965,12 @@ protected: enum_field_types cached_field_type; public: Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list), - cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(FALSE) {} + cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(0) {} double val_real(); longlong val_int(); String *val_str(String *); my_decimal *val_decimal(my_decimal *); - bool get_date(MYSQL_TIME *res, uint fuzzy_date); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); void fix_length_and_dec(); enum Item_result result_type () const { return cmp_type; } enum_field_types field_type() const { return cached_field_type; } @@ -1573,7 +1659,8 @@ class Item_user_var_as_out_param :public Item LEX_STRING name; user_var_entry *entry; public: - Item_user_var_as_out_param(LEX_STRING a) : name(a) {} + Item_user_var_as_out_param(LEX_STRING a) : name(a) + { set_name(a.str, 0, system_charset_info); } /* We should return something different from FIELD_ITEM here */ enum Type type() const { return STRING_ITEM;} double val_real(); @@ -1908,3 +1995,16 @@ public: return trace_unsupported_by_check_vcol_func_processor(func_name()); } }; + +Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, + LEX_STRING component); +extern bool check_reserved_words(LEX_STRING *name); +extern enum_field_types agg_field_type(Item **items, uint nitems); +Item *find_date_time_item(Item **args, uint nargs, uint col); +double my_double_round(double value, longlong dec, bool dec_unsigned, + bool truncate); +bool eval_const_cond(COND *cond); + +extern bool volatile mqh_used; + +#endif /* ITEM_FUNC_INCLUDED */ |