diff options
Diffstat (limited to 'sql/item_func.h')
-rw-r--r-- | sql/item_func.h | 469 |
1 files changed, 340 insertions, 129 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index 41f2a52616d..0af90fab24b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1,7 +1,7 @@ #ifndef ITEM_FUNC_INCLUDED #define ITEM_FUNC_INCLUDED /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + Copyright (c) 2009, 2020, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -76,7 +76,7 @@ public: SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC, NEG_FUNC, GSYSVAR_FUNC, IN_OPTIMIZER_FUNC, DYNCOL_FUNC, - JSON_EXTRACT_FUNC, + JSON_EXTRACT_FUNC, JSON_VALID_FUNC, CASE_SEARCHED_FUNC, // Used by ColumnStore/Spider CASE_SIMPLE_FUNC // Used by ColumnStore/spider }; @@ -188,12 +188,10 @@ public: void signal_divide_by_null(); friend class udf_handler; - Field *create_field_for_create_select(TABLE *table) - { return tmp_table_field_from_field_type(table); } + Field *create_field_for_create_select(MEM_ROOT *root, TABLE *table) + { return tmp_table_field_from_field_type(root, table); } Item *get_tmp_table_item(THD *thd); - my_decimal *val_decimal(my_decimal *); - void fix_char_length_ulonglong(ulonglong max_char_length_arg) { ulonglong max_result_length= max_char_length_arg * @@ -212,6 +210,7 @@ public: void traverse_cond(Cond_traverser traverser, void * arg, traverse_order order); bool eval_not_null_tables(void *opt_arg); + bool find_not_null_fields(table_map allowed); // bool is_expensive_processor(void *arg); // virtual bool is_expensive() { return 0; } inline void raise_numeric_overflow(const char *type_name) @@ -406,13 +405,13 @@ public: class Item_real_func :public Item_func { public: - Item_real_func(THD *thd): Item_func(thd) { collation.set_numeric(); } + Item_real_func(THD *thd): Item_func(thd) { collation= DTCollation_numeric(); } Item_real_func(THD *thd, Item *a): Item_func(thd, a) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_real_func(THD *thd, Item *a, Item *b): Item_func(thd, a, b) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_real_func(THD *thd, List<Item> &list): Item_func(thd, list) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *decimal_value); longlong val_int() @@ -436,8 +435,7 @@ public: Functions whose returned field type is determined at fix_fields() time. */ class Item_hybrid_func: public Item_func, - public Type_handler_hybrid_field_type, - public Type_geometry_attributes + public Type_handler_hybrid_field_type { protected: bool fix_attributes(Item **item, uint nitems); @@ -452,34 +450,24 @@ public: :Item_func(thd, item), Type_handler_hybrid_field_type(item) { } const Type_handler *type_handler() const { return Type_handler_hybrid_field_type::type_handler(); } - Field::geometry_type get_geometry_type() const - { return Type_geometry_attributes::get_geometry_type(); }; - void set_geometry_type(uint type) - { - Type_geometry_attributes::set_geometry_type(type); - } void fix_length_and_dec_long_or_longlong(uint char_length, bool unsigned_arg) { - collation.set_numeric(); + collation= DTCollation_numeric(); unsigned_flag= unsigned_arg; max_length= char_length; -#if MARIADB_VERSION_ID < 100500 - set_handler(Type_handler::type_handler_long_or_longlong(char_length)); -#else set_handler(Type_handler::type_handler_long_or_longlong(char_length, unsigned_arg)); -#endif } void fix_length_and_dec_ulong_or_ulonglong_by_nbits(uint nbits) { uint digits= Type_handler_bit::Bit_decimal_notation_int_digits_by_nbits(nbits); - collation.set_numeric(); + collation= DTCollation_numeric(); unsigned_flag= true; max_length= digits; if (nbits > 32) - set_handler(&type_handler_longlong); + set_handler(&type_handler_ulonglong); else - set_handler(&type_handler_long); + set_handler(&type_handler_ulong); } }; @@ -503,10 +491,48 @@ public: to->length(0); return true; } - virtual const Type_handler *return_type_handler() const= 0; + virtual const Type_handler * + return_type_handler(const Item_handled_func *item) const= 0; + virtual const Type_handler * + type_handler_for_create_select(const Item_handled_func *item) const + { + return return_type_handler(item); + } virtual bool fix_length_and_dec(Item_handled_func *) const= 0; }; + class Handler_str: public Handler + { + public: + String *val_str_ascii(Item_handled_func *item, String *str) const + { + return item->Item::val_str_ascii(str); + } + double val_real(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + StringBuffer<64> tmp; + String *res= item->val_str(&tmp); + return res ? item->double_from_string_with_check(res) : 0.0; + } + longlong val_int(Item_handled_func *item) const + { + DBUG_ASSERT(item->is_fixed()); + StringBuffer<22> tmp; + String *res= item->val_str(&tmp); + return res ? item->longlong_from_string_with_check(res) : 0; + } + my_decimal *val_decimal(Item_handled_func *item, my_decimal *to) const + { + return item->val_decimal_from_string(to); + } + bool get_date(THD *thd, Item_handled_func *item, MYSQL_TIME *to, + date_mode_t fuzzydate) const + { + return item->get_date_from_string(thd, to, fuzzydate); + } + }; + /** Abstract class for functions returning TIME, DATE, DATETIME or string values, whose data type depends on parameters and is set at fix_fields time. @@ -529,10 +555,15 @@ public: class Handler_temporal_string: public Handler_temporal { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *) const { return &type_handler_string; } + const Type_handler * + type_handler_for_create_select(const Item_handled_func *item) const + { + return return_type_handler(item)->type_handler_for_tmp_table(item); + } double val_real(Item_handled_func *item) const { return Temporal_hybrid(item).to_double(); @@ -555,7 +586,7 @@ public: class Handler_date: public Handler_temporal { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *) const { return &type_handler_newdate; } @@ -586,7 +617,7 @@ public: class Handler_time: public Handler_temporal { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *) const { return &type_handler_time2; } @@ -616,7 +647,7 @@ public: class Handler_datetime: public Handler_temporal { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *) const { return &type_handler_datetime2; } @@ -639,6 +670,87 @@ public: }; + class Handler_int: public Handler + { + public: + String *val_str(Item_handled_func *item, String *to) const + { + longlong nr= val_int(item); + if (item->null_value) + return 0; + to->set_int(nr, item->unsigned_flag, item->collation.collation); + return to; + } + String *val_str_ascii(Item_handled_func *item, String *to) const + { + return item->Item::val_str_ascii(to); + } + double val_real(Item_handled_func *item) const + { + return item->unsigned_flag ? (double) ((ulonglong) val_int(item)) : + (double) val_int(item); + } + my_decimal *val_decimal(Item_handled_func *item, my_decimal *to) const + { + return item->val_decimal_from_int(to); + } + bool get_date(THD *thd, Item_handled_func *item, + MYSQL_TIME *to, date_mode_t fuzzydate) const + { + return item->get_date_from_int(thd, to, fuzzydate); + } + longlong val_int(Item_handled_func *item) const + { + Longlong_null tmp= to_longlong_null(item); + item->null_value= tmp.is_null(); + return tmp.value(); + } + virtual Longlong_null to_longlong_null(Item_handled_func *item) const= 0; + }; + + class Handler_slong: public Handler_int + { + public: + const Type_handler *return_type_handler(const Item_handled_func *item) const + { + return &type_handler_slong; + } + bool fix_length_and_dec(Item_handled_func *item) const + { + item->unsigned_flag= false; + item->collation= DTCollation_numeric(); + item->fix_char_length(11); + return false; + } + }; + + class Handler_slong2: public Handler_slong + { + public: + bool fix_length_and_dec(Item_handled_func *func) const + { + bool rc= Handler_slong::fix_length_and_dec(func); + func->max_length= 2; + return rc; + } + }; + + class Handler_ulonglong: public Handler_int + { + public: + const Type_handler *return_type_handler(const Item_handled_func *item) const + { + return &type_handler_ulonglong; + } + bool fix_length_and_dec(Item_handled_func *item) const + { + item->unsigned_flag= true; + item->collation= DTCollation_numeric(); + item->fix_char_length(21); + return false; + } + }; + protected: const Handler *m_func_handler; public: @@ -652,7 +764,15 @@ public: } const Type_handler *type_handler() const { - return m_func_handler->return_type_handler(); + return m_func_handler->return_type_handler(this); + } + Field *create_field_for_create_select(MEM_ROOT *root, TABLE *table) + { + DBUG_ASSERT(fixed); + const Type_handler *h= m_func_handler->type_handler_for_create_select(this); + return h->make_and_init_table_field(root, &name, + Record_addr(maybe_null), + *this, table); } String *val_str(String *to) { @@ -767,19 +887,19 @@ public: public: Item_func_hybrid_field_type(THD *thd): Item_hybrid_func(thd) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_func_hybrid_field_type(THD *thd, Item *a): Item_hybrid_func(thd, a) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_func_hybrid_field_type(THD *thd, Item *a, Item *b): Item_hybrid_func(thd, a, b) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_func_hybrid_field_type(THD *thd, Item *a, Item *b, Item *c): Item_hybrid_func(thd, a, b, c) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } Item_func_hybrid_field_type(THD *thd, List<Item> &list): Item_hybrid_func(thd, list) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } double val_real() { @@ -919,6 +1039,7 @@ public: Item_func_case_expression(THD *thd, List<Item> &list): Item_func_hybrid_field_type(thd, list) { } + bool find_not_null_fields(table_map allowed) { return false; } }; @@ -980,7 +1101,12 @@ public: /* Base class for operations like '+', '-', '*' */ class Item_num_op :public Item_func_numhybrid { - public: +protected: + bool check_arguments() const + { + return false; // Checked by aggregate_for_num_op() + } +public: Item_num_op(THD *thd, Item *a, Item *b): Item_func_numhybrid(thd, a, b) {} virtual void result_precision()= 0; @@ -991,7 +1117,7 @@ class Item_num_op :public Item_func_numhybrid bool fix_type_handler(const Type_aggregator *aggregator); void fix_length_and_dec_double() { - count_real_length(args, arg_count); + aggregate_numeric_attributes_real(args, arg_count); max_length= float_length(decimals); } void fix_length_and_dec_decimal() @@ -1028,22 +1154,26 @@ public: Min signed = -9,223,372,036,854,775,808 = 19 digits, 20 characters */ Item_int_func(THD *thd): Item_func(thd) - { collation.set_numeric(); fix_char_length(21); } + { collation= DTCollation_numeric(); fix_char_length(21); } Item_int_func(THD *thd, Item *a): Item_func(thd, a) - { collation.set_numeric(); fix_char_length(21); } + { collation= DTCollation_numeric(); fix_char_length(21); } Item_int_func(THD *thd, Item *a, Item *b): Item_func(thd, a, b) - { collation.set_numeric(); fix_char_length(21); } + { collation= DTCollation_numeric(); fix_char_length(21); } Item_int_func(THD *thd, Item *a, Item *b, Item *c): Item_func(thd, a, b, c) - { collation.set_numeric(); fix_char_length(21); } + { collation= DTCollation_numeric(); fix_char_length(21); } Item_int_func(THD *thd, Item *a, Item *b, Item *c, Item *d): Item_func(thd, a, b, c, d) - { collation.set_numeric(); fix_char_length(21); } + { collation= DTCollation_numeric(); fix_char_length(21); } Item_int_func(THD *thd, List<Item> &list): Item_func(thd, list) - { collation.set_numeric(); fix_char_length(21); } + { collation= DTCollation_numeric(); fix_char_length(21); } Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) - { collation.set_numeric(); } + { collation= DTCollation_numeric(); } double val_real(); String *val_str(String*str); + my_decimal *val_decimal(my_decimal *decimal_value) + { + return val_decimal_from_int(decimal_value); + } bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) { return get_date_from_int(thd, ltime, fuzzydate); } const Type_handler *type_handler() const= 0; @@ -1060,7 +1190,12 @@ public: Item_long_func(THD *thd, Item *a, Item *b, Item *c): Item_int_func(thd, a, b, c) {} Item_long_func(THD *thd, List<Item> &list): Item_int_func(thd, list) { } Item_long_func(THD *thd, Item_long_func *item) :Item_int_func(thd, item) {} - const Type_handler *type_handler() const { return &type_handler_long; } + const Type_handler *type_handler() const + { + if (unsigned_flag) + return &type_handler_ulong; + return &type_handler_slong; + } bool fix_length_and_dec() { max_length= 11; return FALSE; } }; @@ -1072,7 +1207,7 @@ public: {} longlong val_int(); bool fix_length_and_dec(); - const Type_handler *type_handler() const { return &type_handler_long; } + const Type_handler *type_handler() const { return &type_handler_slong; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_hash>(thd, this); } const char *func_name() const { return "<hash>"; } @@ -1101,7 +1236,12 @@ public: Item_int_func(thd, a, b, c, d) {} Item_longlong_func(THD *thd, List<Item> &list): Item_int_func(thd, list) { } Item_longlong_func(THD *thd, Item_longlong_func *item) :Item_int_func(thd, item) {} - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const + { + if (unsigned_flag) + return &type_handler_ulonglong; + return &type_handler_slonglong; + } }; @@ -1169,7 +1309,10 @@ public: } const char *func_name() const { return "cast_as_signed"; } const Type_handler *type_handler() const - { return type_handler_long_or_longlong(); } + { + return Type_handler::type_handler_long_or_longlong(max_char_length(), + false); + } longlong val_int() { longlong value= args[0]->val_int_signed_typecast(); @@ -1228,8 +1371,8 @@ public: const Type_handler *type_handler() const { if (max_char_length() <= MY_INT32_NUM_DECIMAL_DIGITS - 1) - return &type_handler_long; - return &type_handler_longlong; + return &type_handler_ulong; + return &type_handler_ulonglong; } longlong val_int() { @@ -1256,7 +1399,7 @@ public: :Item_func(thd, a) { decimals= (uint8) dec; - collation.set_numeric(); + collation= DTCollation_numeric(); fix_char_length(my_decimal_precision_to_length_no_truncation(len, dec, unsigned_flag)); } @@ -1831,6 +1974,7 @@ class Item_func_rand :public Item_real_func bool first_eval; // TRUE if val_real() is called 1st time bool check_arguments() const { return check_argument_types_can_return_int(0, arg_count); } + void seed_random (Item * val); public: Item_func_rand(THD *thd, Item *a): Item_real_func(thd, a), rand(0), first_eval(TRUE) {} @@ -1847,8 +1991,6 @@ public: } Item *get_copy(THD *thd) { return get_item_copy<Item_func_rand>(thd, this); } -private: - void seed_random (Item * val); }; @@ -1906,6 +2048,10 @@ class Item_func_min_max :public Item_hybrid_func String tmp_value; int cmp_sign; protected: + bool check_arguments() const + { + return false; // Checked by aggregate_for_min_max() + } bool fix_attributes(Item **item, uint nitems); public: Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg): @@ -2023,9 +2169,7 @@ public: const Type_handler *type_handler() const { return args[0]->type_handler(); } bool fix_length_and_dec() { - collation= args[0]->collation; - max_length= args[0]->max_length; - decimals=args[0]->decimals; + Type_std_attributes::set(*args[0]); return FALSE; } Item *get_copy(THD *thd) @@ -2095,6 +2239,10 @@ public: not_null_tables_cache= 0; return false; } + bool find_not_null_fields(table_map allowed) + { + return false; + } Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) { return this; } bool const_item() const { return true; } @@ -2199,84 +2347,99 @@ public: /* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */ -class Item_func_bit: public Item_longlong_func +class Item_func_bit_operator: public Item_handled_func { bool check_arguments() const { return check_argument_types_can_return_int(0, arg_count); } +protected: + bool fix_length_and_dec_op1_std(const Handler *ha_int, const Handler *ha_dec) + { + set_func_handler(args[0]->cmp_type() == INT_RESULT ? ha_int : ha_dec); + return m_func_handler->fix_length_and_dec(this); + } + bool fix_length_and_dec_op2_std(const Handler *ha_int, const Handler *ha_dec) + { + set_func_handler(args[0]->cmp_type() == INT_RESULT && + args[1]->cmp_type() == INT_RESULT ? ha_int : ha_dec); + return m_func_handler->fix_length_and_dec(this); + } public: - Item_func_bit(THD *thd, Item *a, Item *b): Item_longlong_func(thd, a, b) {} - Item_func_bit(THD *thd, Item *a): Item_longlong_func(thd, a) {} - bool fix_length_and_dec() { unsigned_flag= 1; return FALSE; } - - virtual inline void print(String *str, enum_query_type query_type) + Item_func_bit_operator(THD *thd, Item *a) + :Item_handled_func(thd, a) {} + Item_func_bit_operator(THD *thd, Item *a, Item *b) + :Item_handled_func(thd, a, b) {} + void print(String *str, enum_query_type query_type) { print_op(str, query_type); } bool need_parentheses_in_default() { return true; } }; -class Item_func_bit_or :public Item_func_bit +class Item_func_bit_or :public Item_func_bit_operator { public: - Item_func_bit_or(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} - longlong val_int(); + Item_func_bit_or(THD *thd, Item *a, Item *b) + :Item_func_bit_operator(thd, a, b) {} + bool fix_length_and_dec(); const char *func_name() const { return "|"; } enum precedence precedence() const { return BITOR_PRECEDENCE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_bit_or>(thd, this); } }; -class Item_func_bit_and :public Item_func_bit +class Item_func_bit_and :public Item_func_bit_operator { public: - Item_func_bit_and(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} - longlong val_int(); + Item_func_bit_and(THD *thd, Item *a, Item *b) + :Item_func_bit_operator(thd, a, b) {} + bool fix_length_and_dec(); const char *func_name() const { return "&"; } enum precedence precedence() const { return BITAND_PRECEDENCE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_bit_and>(thd, this); } }; -class Item_func_bit_count :public Item_long_func +class Item_func_bit_count :public Item_handled_func { bool check_arguments() const { return args[0]->check_type_can_return_int(func_name()); } public: - Item_func_bit_count(THD *thd, Item *a): Item_long_func(thd, a) {} - longlong val_int(); + Item_func_bit_count(THD *thd, Item *a): Item_handled_func(thd, a) {} const char *func_name() const { return "bit_count"; } - bool fix_length_and_dec() { max_length=2; return FALSE; } + bool fix_length_and_dec(); Item *get_copy(THD *thd) { return get_item_copy<Item_func_bit_count>(thd, this); } }; -class Item_func_shift_left :public Item_func_bit +class Item_func_shift_left :public Item_func_bit_operator { public: - Item_func_shift_left(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} - longlong val_int(); + Item_func_shift_left(THD *thd, Item *a, Item *b) + :Item_func_bit_operator(thd, a, b) {} + bool fix_length_and_dec(); const char *func_name() const { return "<<"; } enum precedence precedence() const { return SHIFT_PRECEDENCE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_shift_left>(thd, this); } }; -class Item_func_shift_right :public Item_func_bit +class Item_func_shift_right :public Item_func_bit_operator { public: - Item_func_shift_right(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} - longlong val_int(); + Item_func_shift_right(THD *thd, Item *a, Item *b) + :Item_func_bit_operator(thd, a, b) {} + bool fix_length_and_dec(); const char *func_name() const { return ">>"; } enum precedence precedence() const { return SHIFT_PRECEDENCE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_shift_right>(thd, this); } }; -class Item_func_bit_neg :public Item_func_bit +class Item_func_bit_neg :public Item_func_bit_operator { public: - Item_func_bit_neg(THD *thd, Item *a): Item_func_bit(thd, a) {} - longlong val_int(); + Item_func_bit_neg(THD *thd, Item *a): Item_func_bit_operator(thd, a) {} + bool fix_length_and_dec(); const char *func_name() const { return "~"; } enum precedence precedence() const { return NEG_PRECEDENCE; } void print(String *str, enum_query_type query_type) @@ -2467,6 +2630,10 @@ public: not_null_tables_cache= 0; return 0; } + bool find_not_null_fields(table_map allowed) + { + return false; + } bool is_expensive() { return 1; } virtual void print(String *str, enum_query_type query_type); bool check_vcol_func_processor(void *arg) @@ -2523,8 +2690,17 @@ public: Item_udf_func(thd, udf_arg, list) {} longlong val_int(); double val_real() { return (double) Item_func_udf_int::val_int(); } + my_decimal *val_decimal(my_decimal *decimal_value) + { + return val_decimal_from_int(decimal_value); + } String *val_str(String *str); - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const + { + if (unsigned_flag) + return &type_handler_ulonglong; + return &type_handler_slonglong; + } bool fix_length_and_dec() { decimals= 0; max_length= 21; return FALSE; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_udf_int>(thd, this); } @@ -2572,15 +2748,15 @@ public: char *end_not_used; String *res; res= val_str(&str_value); - return res ? my_strntod(res->charset(),(char*) res->ptr(), - res->length(), &end_not_used, &err_not_used) : 0.0; + return res ? res->charset()->strntod((char*) res->ptr(), res->length(), + &end_not_used, &err_not_used) : 0.0; } longlong val_int() { int err_not_used; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, - (char**) 0, &err_not_used) : (longlong) 0; + return res ? res->charset()->strntoll(res->ptr(),res->length(),10, + (char**) 0, &err_not_used) : (longlong) 0; } my_decimal *val_decimal(my_decimal *dec_buf) { @@ -2596,7 +2772,7 @@ public: { return get_item_copy<Item_func_udf_str>(thd, this); } }; -#else /* Dummy functions to get sql_yacc.cc compiled */ +#else /* Dummy functions to get yy_*.cc files compiled */ class Item_func_udf_float :public Item_real_func { @@ -2616,7 +2792,7 @@ public: Item_int_func(thd) {} Item_func_udf_int(THD *thd, udf_func *udf_arg, List<Item> &list): Item_int_func(thd, list) {} - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const { return &type_handler_slonglong; } longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } }; @@ -2628,7 +2804,7 @@ public: Item_int_func(thd) {} Item_func_udf_decimal(THD *thd, udf_func *udf_arg, List<Item> &list): Item_int_func(thd, list) {} - const Type_handler *type_handler() const { return &type_handler_longlong; } + const Type_handler *type_handler() const { return &type_handler_slonglong; } my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; } }; @@ -2652,19 +2828,13 @@ public: void mysql_ull_cleanup(THD *thd); void mysql_ull_set_explicit_lock_duration(THD *thd); -class Item_func_get_lock :public Item_long_func + +class Item_func_lock :public Item_long_func { - bool check_arguments() const - { - return args[0]->check_type_general_purpose_string(func_name()) || - args[1]->check_type_can_return_real(func_name()); - } - String value; public: - Item_func_get_lock(THD *thd, Item *a, Item *b) :Item_long_func(thd, a, b) {} - longlong val_int(); - const char *func_name() const { return "get_lock"; } - bool fix_length_and_dec() { max_length=1; maybe_null=1; return FALSE; } + Item_func_lock(THD *thd): Item_long_func(thd) { } + Item_func_lock(THD *thd, Item *a): Item_long_func(thd, a) {} + Item_func_lock(THD *thd, Item *a, Item *b): Item_long_func(thd, a, b) {} table_map used_tables() const { return used_tables_cache | RAND_TABLE_BIT; @@ -2675,34 +2845,54 @@ class Item_func_get_lock :public Item_long_func { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } - Item *get_copy(THD *thd) +}; + + +class Item_func_get_lock final :public Item_func_lock +{ + bool check_arguments() const + { + return args[0]->check_type_general_purpose_string(func_name()) || + args[1]->check_type_can_return_real(func_name()); + } + String value; + public: + Item_func_get_lock(THD *thd, Item *a, Item *b) :Item_func_lock(thd, a, b) {} + longlong val_int() final; + const char *func_name() const final { return "get_lock"; } + bool fix_length_and_dec() { max_length= 1; maybe_null= 1; return FALSE; } + Item *get_copy(THD *thd) final { return get_item_copy<Item_func_get_lock>(thd, this); } }; -class Item_func_release_lock :public Item_long_func + +class Item_func_release_all_locks final :public Item_func_lock +{ +public: + Item_func_release_all_locks(THD *thd): Item_func_lock(thd) + { unsigned_flag= 1; } + longlong val_int() final; + const char *func_name() const final { return "release_all_locks"; } + Item *get_copy(THD *thd) final + { return get_item_copy<Item_func_release_all_locks>(thd, this); } +}; + + +class Item_func_release_lock final :public Item_func_lock { bool check_arguments() const { return args[0]->check_type_general_purpose_string(func_name()); } String value; public: - Item_func_release_lock(THD *thd, Item *a): Item_long_func(thd, a) {} - longlong val_int(); + Item_func_release_lock(THD *thd, Item *a): Item_func_lock(thd, a) {} + longlong val_int() final; const char *func_name() const { return "release_lock"; } 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; - } - bool const_item() const { return 0; } - bool is_expensive() { return 1; } - bool check_vcol_func_processor(void *arg) - { - return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); - } - Item *get_copy(THD *thd) + Item *get_copy(THD *thd) final { return get_item_copy<Item_func_release_lock>(thd, this); } }; + /* replication functions */ class Item_master_pos_wait :public Item_longlong_func @@ -2781,10 +2971,15 @@ public: Item_func_user_var(THD *thd, Item_func_user_var *item) :Item_hybrid_func(thd, item), m_var_entry(item->m_var_entry), name(item->name) { } - Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src, - const Tmp_field_param *param); - Field *create_field_for_create_select(TABLE *table) - { return create_table_field_from_handler(table); } + Field *create_tmp_field_ex(MEM_ROOT *root, TABLE *table, Tmp_field_src *src, + const Tmp_field_param *param) + { + DBUG_ASSERT(fixed); + return create_tmp_field_ex_from_handler(root, table, src, param, + type_handler()); + } + Field *create_field_for_create_select(MEM_ROOT *root, TABLE *table) + { return create_table_field_from_handler(root, table); } bool check_vcol_func_processor(void *arg); bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) { @@ -2959,7 +3154,7 @@ public: { return 0; } - Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src, + Field *create_tmp_field_ex(MEM_ROOT *root, TABLE *table, Tmp_field_src *src, const Tmp_field_param *param) { DBUG_ASSERT(0); @@ -3078,6 +3273,10 @@ public: not_null_tables_cache= 0; return 0; } + bool find_not_null_fields(table_map allowed) + { + return false; + } bool fix_fields(THD *thd, Item **ref); bool eq(const Item *, bool binary_cmp) const; /* The following should be safe, even if we compare doubles */ @@ -3131,11 +3330,12 @@ private: }; -class Item_func_bit_xor : public Item_func_bit +class Item_func_bit_xor : public Item_func_bit_operator { public: - Item_func_bit_xor(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} - longlong val_int(); + Item_func_bit_xor(THD *thd, Item *a, Item *b) + :Item_func_bit_operator(thd, a, b) {} + bool fix_length_and_dec(); const char *func_name() const { return "^"; } enum precedence precedence() const { return BITXOR_PRECEDENCE; } Item *get_copy(THD *thd) @@ -3211,12 +3411,15 @@ public: set(handler, 0, 0); } const Type_handler *type_handler() const { return m_type_handler; } - Item *create_typecast_item(THD *thd, Item *item, CHARSET_INFO *cs= NULL) + Item *create_typecast_item(THD *thd, Item *item, + CHARSET_INFO *cs= NULL) const { return m_type_handler-> create_typecast_item(thd, item, Type_cast_attributes(length(), dec(), cs)); } + Item *create_typecast_item_or_error(THD *thd, Item *item, + CHARSET_INFO *cs= NULL) const; }; @@ -3277,13 +3480,13 @@ public: const Type_handler *type_handler() const; - Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src, + Field *create_tmp_field_ex(MEM_ROOT *root, TABLE *table, Tmp_field_src *src, const Tmp_field_param *param); - Field *create_field_for_create_select(TABLE *table) + Field *create_field_for_create_select(MEM_ROOT *root, TABLE *table) { return result_type() != STRING_RESULT ? sp_result_field : - create_table_field_from_handler(table); + create_table_field_from_handler(root, table); } void make_send_field(THD *thd, Send_field *tmp_field); @@ -3377,6 +3580,10 @@ public: } bool excl_dep_on_grouping_fields(st_select_lex *sel) { return false; } + bool find_not_null_fields(table_map allowed) + { + return false; + } }; @@ -3481,6 +3688,10 @@ public: not_null_tables_cache= 0; return 0; } + bool find_not_null_fields(table_map allowed) + { + return false; + } bool const_item() const { return 0; } void evaluate_sideeffects(); void update_used_tables() |