diff options
Diffstat (limited to 'sql/item_func.h')
-rw-r--r-- | sql/item_func.h | 201 |
1 files changed, 140 insertions, 61 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index 33aeddfe6e6..147dfcc9d36 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. 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 @@ -55,7 +55,7 @@ public: NOW_FUNC, TRIG_COND_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC, - NEG_FUNC }; + NEG_FUNC, GSYSVAR_FUNC }; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } @@ -141,9 +141,9 @@ public: inline uint argument_count() const { return arg_count; } inline void remove_arguments() { arg_count=0; } void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields); - void print(String *str); - void print_op(String *str); - void print_args(String *str, uint from); + virtual void print(String *str, enum_query_type query_type); + void print_op(String *str, enum_query_type query_type); + void print_args(String *str, uint from, enum_query_type query_type); virtual void fix_num_length_and_dec(); void count_only_length(); void count_real_length(); @@ -185,14 +185,21 @@ public: { return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep); } - bool walk(Item_processor processor, byte *arg); - Item *transform(Item_transformer transformer, byte *arg); - Item* compile(Item_analyzer analyzer, byte **arg_p, - Item_transformer transformer, byte *arg_t); + bool walk(Item_processor processor, bool walk_subquery, uchar *arg); + Item *transform(Item_transformer transformer, uchar *arg); + Item* compile(Item_analyzer analyzer, uchar **arg_p, + Item_transformer transformer, uchar *arg_t); void traverse_cond(Cond_traverser traverser, void * arg, traverse_order order); - bool is_expensive_processor(byte *arg); + bool is_expensive_processor(uchar *arg); virtual bool is_expensive() { return 0; } + inline double fix_result(double value) + { + if (isfinite(value)) + return value; + null_value=1; + return 0.0; + } }; @@ -294,7 +301,12 @@ class Item_num_op :public Item_func_numhybrid public: Item_num_op(Item *a,Item *b) :Item_func_numhybrid(a, b) {} virtual void result_precision()= 0; - void print(String *str) { print_op(str); } + + virtual inline void print(String *str, enum_query_type query_type) + { + print_op(str, query_type); + } + void find_num_type(); String *str_op(String *str) { DBUG_ASSERT(0); return 0; } }; @@ -339,9 +351,8 @@ public: longlong val_int_from_str(int *error); void fix_length_and_dec() { max_length=args[0]->max_length; unsigned_flag=0; } - void print(String *str); + virtual void print(String *str, enum_query_type query_type); uint decimal_precision() const { return args[0]->decimal_precision(); } - }; @@ -356,7 +367,7 @@ public: unsigned_flag=1; } longlong val_int(); - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; @@ -377,7 +388,7 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; } void fix_length_and_dec() {}; const char *func_name() const { return "decimal_typecast"; } - void print(String *); + virtual void print(String *str, enum_query_type query_type); }; @@ -386,6 +397,7 @@ class Item_func_additive_op :public Item_num_op public: Item_func_additive_op(Item *a,Item *b) :Item_num_op(a,b) {} void result_precision(); + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; @@ -420,6 +432,7 @@ public: double real_op(); my_decimal *decimal_op(my_decimal *); void result_precision(); + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; @@ -445,7 +458,13 @@ public: longlong val_int(); const char *func_name() const { return "DIV"; } void fix_length_and_dec(); - void print(String *str) { print_op(str); } + + virtual inline void print(String *str, enum_query_type query_type) + { + print_op(str, query_type); + } + + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; @@ -459,6 +478,7 @@ public: const char *func_name() const { return "%"; } void result_precision(); void fix_length_and_dec(); + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; @@ -474,6 +494,7 @@ public: void fix_length_and_dec(); void fix_num_length_and_dec(); uint decimal_precision() const { return args[0]->decimal_precision(); } + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; @@ -486,6 +507,7 @@ public: my_decimal *decimal_op(my_decimal *); const char *func_name() const { return "abs"; } void fix_length_and_dec(); + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; // A class to handle logarithmic and trigonometric functions @@ -500,18 +522,6 @@ class Item_dec_func :public Item_real_func decimals=NOT_FIXED_DEC; max_length=float_length(decimals); maybe_null=1; } - inline double fix_result(double value) - { -#ifndef HAVE_FINITE - return value; -#else - /* The following should be safe, even if we compare doubles */ - if (finite(value) && value != POSTFIX_ERROR) - return value; - null_value=1; - return 0.0; -#endif - } }; class Item_func_exp :public Item_dec_func @@ -652,6 +662,7 @@ public: longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; @@ -663,6 +674,7 @@ public: longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; /* This handles round and truncate */ @@ -692,6 +704,8 @@ public: bool const_item() const { return 0; } void update_used_tables(); bool fix_fields(THD *thd, Item **ref); +private: + void seed_random (Item * val); }; @@ -840,7 +854,7 @@ public: const char *func_name() const { return "locate"; } longlong val_int(); void fix_length_and_dec(); - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; @@ -897,7 +911,11 @@ public: Item_func_bit(Item *a, Item *b) :Item_int_func(a, b) {} Item_func_bit(Item *a) :Item_int_func(a) {} void fix_length_and_dec() { unsigned_flag= 1; } - void print(String *str) { print_op(str); } + + virtual inline void print(String *str, enum_query_type query_type) + { + print_op(str, query_type); + } }; class Item_func_bit_or :public Item_func_bit @@ -947,7 +965,11 @@ public: Item_func_bit_neg(Item *a) :Item_func_bit(a) {} longlong val_int(); const char *func_name() const { return "~"; } - void print(String *str) { Item_func::print(str); } + + virtual inline void print(String *str, enum_query_type query_type) + { + Item_func::print(str, query_type); + } }; @@ -969,15 +991,14 @@ public: class Item_func_benchmark :public Item_int_func { - ulong loop_count; public: - Item_func_benchmark(ulong loop_count_arg,Item *expr) - :Item_int_func(expr), loop_count(loop_count_arg) + Item_func_benchmark(Item *count_expr, Item *expr) + :Item_int_func(count_expr, expr) {} longlong val_int(); const char *func_name() const { return "benchmark"; } void fix_length_and_dec() { max_length=1; maybe_null=0; } - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; @@ -1074,7 +1095,7 @@ public: Item_result result_type () const { return udf.result_type(); } table_map not_null_tables() const { return 0; } bool is_expensive() { return 1; } - void print(String *str); + virtual void print(String *str, enum_query_type query_type); }; @@ -1276,6 +1297,17 @@ class Item_func_set_user_var :public Item_func { enum Item_result cached_result_type; user_var_entry *entry; + /* + The entry_thread_id variable is used: + 1) to skip unnecessary updates of the entry field (see above); + 2) to reset the entry field that was initialized in the other thread + (for example, an item tree of a trigger that updates user variables + may be shared between several connections, and the entry_thread_id field + prevents updates of one connection user variables from a concurrent + connection calling the same trigger that initially updated some + user variable it the first connection context). + */ + my_thread_id entry_thread_id; char buffer[MAX_FIELD_WIDTH]; String value; my_decimal decimal_buff; @@ -1291,7 +1323,8 @@ class Item_func_set_user_var :public Item_func public: LEX_STRING name; // keep it public Item_func_set_user_var(LEX_STRING a,Item *b) - :Item_func(b), cached_result_type(INT_RESULT), name(a) + :Item_func(b), cached_result_type(INT_RESULT), + entry(NULL), entry_thread_id(0), name(a) {} enum Functype functype() const { return SUSERVAR_FUNC; } double val_real(); @@ -1313,8 +1346,8 @@ public: enum Item_result result_type () const { return cached_result_type; } bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); - void print(String *str); - void print_as_stmt(String *str); + virtual void print(String *str, enum_query_type query_type); + void print_as_stmt(String *str, enum_query_type query_type); const char *func_name() const { return "set_user_var"; } int save_in_field(Field *field, bool no_conversions, bool can_use_result_field); @@ -1323,6 +1356,9 @@ public: return save_in_field(field, no_conversions, 1); } void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); } + bool register_field_in_read_map(uchar *arg); + bool set_entry(THD *thd, bool create_if_not_exists); + void cleanup(); }; @@ -1330,11 +1366,12 @@ class Item_func_get_user_var :public Item_func, private Settable_routine_parameter { user_var_entry *var_entry; + Item_result m_cached_result_type; public: LEX_STRING name; // keep it public Item_func_get_user_var(LEX_STRING a): - Item_func(), name(a) {} + Item_func(), m_cached_result_type(STRING_RESULT), name(a) {} enum Functype functype() const { return GUSERVAR_FUNC; } LEX_STRING get_name() { return name; } double val_real(); @@ -1342,19 +1379,17 @@ public: my_decimal *val_decimal(my_decimal*); String *val_str(String* str); void fix_length_and_dec(); - void print(String *str); + virtual void print(String *str, enum_query_type query_type); enum Item_result result_type() const; /* We must always return variables as strings to guard against selects of type select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b) */ - enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } const char *func_name() const { return "get_user_var"; } bool const_item() const; table_map used_tables() const { return const_item() ? 0 : RAND_TABLE_BIT; } bool eq(const Item *item, bool binary_cmp) const; - private: bool set_value(THD *thd, sp_rcontext *ctx, Item **it); @@ -1389,7 +1424,7 @@ public: my_decimal *val_decimal(my_decimal *decimal_buffer); /* fix_fields() binds variable name with its entry structure */ bool fix_fields(THD *thd, Item **ref); - void print(String *str); + virtual void print(String *str, enum_query_type query_type); void set_null_value(CHARSET_INFO* cs); void set_value(const char *str, uint length, CHARSET_INFO* cs); }; @@ -1397,36 +1432,60 @@ public: /* A system variable */ +#define GET_SYS_VAR_CACHE_LONG 1 +#define GET_SYS_VAR_CACHE_DOUBLE 2 +#define GET_SYS_VAR_CACHE_STRING 4 + class Item_func_get_system_var :public Item_func { sys_var *var; - enum_var_type var_type; + enum_var_type var_type, orig_var_type; LEX_STRING component; + longlong cached_llval; + double cached_dval; + String cached_strval; + my_bool cached_null_value; + query_id_t used_query_id; + uchar cache_present; + public: Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg, LEX_STRING *component_arg, const char *name_arg, size_t name_len_arg); - bool fix_fields(THD *thd, Item **ref); - /* - Stubs for pure virtual methods. Should never be called: this - item is always substituted with a constant in fix_fields(). - */ - double val_real() { DBUG_ASSERT(0); return 0.0; } - longlong val_int() { DBUG_ASSERT(0); return 0; } - String* val_str(String*) { DBUG_ASSERT(0); return 0; } - void fix_length_and_dec() { DBUG_ASSERT(0); } + enum Functype functype() const { return GSYSVAR_FUNC; } + void 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; } + enum Item_result result_type() const; + enum_field_types field_type() const; + double val_real(); + longlong val_int(); + String* val_str(String*); /* TODO: fix to support views */ const char *func_name() const { return "get_system_var"; } + /** + Indicates whether this system variable is written to the binlog or not. + + Variables are written to the binlog as part of "status_vars" in + Query_log_event, as an Intvar_log_event, or a Rand_log_event. + + @return true if the variable is written to the binlog, false otherwise. + */ + bool is_written_to_binlog(); + bool eq(const Item *item, bool binary_cmp) const; + + void cleanup(); }; class Item_func_inet_aton : public Item_int_func { public: - Item_func_inet_aton(Item *a) :Item_int_func(a) {} - longlong val_int(); - const char *func_name() const { return "inet_aton"; } - void fix_length_and_dec() { decimals = 0; max_length = 21; maybe_null=1;unsigned_flag=1;} + Item_func_inet_aton(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "inet_aton"; } + void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;} }; @@ -1467,7 +1526,7 @@ public: /* The following should be safe, even if we compare doubles */ longlong val_int() { DBUG_ASSERT(fixed == 1); return val_real() != 0.0; } double val_real(); - void print(String *str); + virtual void print(String *str, enum_query_type query_type); bool fix_index(); void init_search(bool no_order); @@ -1539,7 +1598,7 @@ private: sp_name *m_name; mutable sp_head *m_sp; TABLE *dummy_table; - char result_buf[64]; + uchar result_buf[64]; /* The result field of the concrete stored function. */ @@ -1613,7 +1672,7 @@ public: return str; } - virtual bool change_context_processor(byte *cntx) + virtual bool change_context_processor(uchar *cntx) { context= (Name_resolution_context *)cntx; return FALSE; } bool sp_check_access(THD * thd); @@ -1622,6 +1681,11 @@ public: bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(void); bool is_expensive() { return 1; } + + inline Field *get_sp_result_field() + { + return sp_result_field; + } }; @@ -1633,3 +1697,18 @@ public: const char *func_name() const { return "found_rows"; } void fix_length_and_dec() { decimals= 0; maybe_null=0; } }; + + +void uuid_short_init(); + +class Item_func_uuid_short :public Item_int_func +{ +public: + Item_func_uuid_short() :Item_int_func() {} + const char *func_name() const { return "uuid_short"; } + longlong val_int(); + void fix_length_and_dec() + { max_length= 21; unsigned_flag=1; } + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} +}; + |