diff options
Diffstat (limited to 'sql/item_func.h')
-rw-r--r-- | sql/item_func.h | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index 80fa0b5d634..f562c87fe1c 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, 2011, Oracle and/or its affiliates. - Copyright (c) 2009-2011 Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab. 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 @@ -39,6 +39,8 @@ protected: 0 means get this number from first argument */ uint allowed_arg_cols; + /* maybe_null can't be changed by parameters or used table state */ + bool persistent_maybe_null; public: uint arg_count; table_map used_tables_cache, not_null_tables_cache; @@ -58,19 +60,19 @@ public: NOW_FUNC, TRIG_COND_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC, - NEG_FUNC, GSYSVAR_FUNC }; + NEG_FUNC, GSYSVAR_FUNC, DYNCOL_FUNC }; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } virtual enum Functype functype() const { return UNKNOWN_FUNC; } Item_func(void): - allowed_arg_cols(1), arg_count(0) + allowed_arg_cols(1), persistent_maybe_null(0), arg_count(0) { with_sum_func= 0; with_field= 0; } Item_func(Item *a): - allowed_arg_cols(1), arg_count(1) + allowed_arg_cols(1), persistent_maybe_null(0), arg_count(1) { args= tmp_arg; args[0]= a; @@ -78,7 +80,7 @@ public: with_field= a->with_field; } Item_func(Item *a,Item *b): - allowed_arg_cols(1), arg_count(2) + allowed_arg_cols(1), persistent_maybe_null(0), arg_count(2) { args= tmp_arg; args[0]= a; args[1]= b; @@ -86,7 +88,7 @@ public: with_field= a->with_field || b->with_field; } Item_func(Item *a,Item *b,Item *c): - allowed_arg_cols(1) + allowed_arg_cols(1), persistent_maybe_null(0) { arg_count= 0; if ((args= (Item**) sql_alloc(sizeof(Item*)*3))) @@ -98,7 +100,7 @@ public: } } Item_func(Item *a,Item *b,Item *c,Item *d): - allowed_arg_cols(1) + allowed_arg_cols(1), persistent_maybe_null(0) { arg_count= 0; if ((args= (Item**) sql_alloc(sizeof(Item*)*4))) @@ -112,7 +114,7 @@ public: } } Item_func(Item *a,Item *b,Item *c,Item *d,Item* e): - allowed_arg_cols(1) + allowed_arg_cols(1), persistent_maybe_null(0) { arg_count= 5; if ((args= (Item**) sql_alloc(sizeof(Item*)*5))) @@ -170,6 +172,18 @@ public: my_decimal *val_decimal(my_decimal *); + void fix_char_length_ulonglong(ulonglong max_char_length_arg) + { + ulonglong max_result_length= max_char_length_arg * + collation.collation->mbmaxlen; + if (max_result_length >= MAX_BLOB_WIDTH) + { + max_length= MAX_BLOB_WIDTH; + set_persist_maybe_null(1); + } + else + max_length= (uint32) max_result_length; + } bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, uint flags, int item_sep) { @@ -371,6 +385,11 @@ public: info.bool_function= &Item::restore_to_before_no_rows_in_result; walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info); } + inline void set_persist_maybe_null(bool mb_null) + { + maybe_null= mb_null; + persistent_maybe_null= 1; + } }; @@ -586,7 +605,7 @@ public: } double val_real(); enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } - void fix_length_and_dec() { maybe_null= 1; } + void fix_length_and_dec() { set_persist_maybe_null(1); } const char *func_name() const { return "double_typecast"; } virtual void print(String *str, enum_query_type query_type); }; @@ -727,7 +746,7 @@ class Item_dec_func :public Item_real_func void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); - maybe_null=1; + set_persist_maybe_null(1); } }; @@ -1059,7 +1078,7 @@ public: Item_func_coercibility(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "coercibility"; } - void fix_length_and_dec() { max_length=10; maybe_null= 0; } + void fix_length_and_dec() { max_length=10; set_persist_maybe_null(0); } table_map not_null_tables() const { return 0; } }; @@ -1201,6 +1220,7 @@ public: const char *func_name() const { return "last_insert_id"; } void fix_length_and_dec() { + unsigned_flag= TRUE; if (arg_count) max_length= args[0]->max_length; unsigned_flag=1; @@ -1221,7 +1241,7 @@ public: {} longlong val_int(); const char *func_name() const { return "benchmark"; } - void fix_length_and_dec() { max_length=1; maybe_null=0; } + void fix_length_and_dec() { max_length=1; set_persist_maybe_null(0); } virtual void print(String *str, enum_query_type query_type); bool check_vcol_func_processor(uchar *int_arg) { @@ -1474,7 +1494,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; } + void fix_length_and_dec() { set_persist_maybe_null(1); max_length=0; } }; #endif /* HAVE_DLOPEN */ @@ -1495,7 +1515,7 @@ class Item_func_get_lock :public Item_int_func Item_func_get_lock(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "get_lock"; } - void fix_length_and_dec() { max_length=1; maybe_null=1;} + void fix_length_and_dec() { max_length=1; set_persist_maybe_null(1);} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1509,7 +1529,7 @@ public: Item_func_release_lock(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "release_lock"; } - void fix_length_and_dec() { max_length=1; maybe_null=1;} + void fix_length_and_dec() { max_length=1; set_persist_maybe_null(1);} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1527,7 +1547,7 @@ public: Item_master_pos_wait(Item *a,Item *b, Item *c, Item *d) :Item_int_func(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;} + void fix_length_and_dec() { max_length=21; set_persist_maybe_null(1);} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1744,7 +1764,8 @@ 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;} + void fix_length_and_dec() + { decimals= 0; max_length= 21; set_persist_maybe_null(1); unsigned_flag= 1; } }; @@ -1813,7 +1834,8 @@ public: Item_func_is_free_lock(Item *a) :Item_int_func(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;} + void fix_length_and_dec() + { decimals= 0; max_length= 1; set_persist_maybe_null(1); } bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1827,7 +1849,8 @@ public: Item_func_is_used_lock(Item *a) :Item_int_func(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;} + void fix_length_and_dec() + { decimals= 0; max_length= 10; set_persist_maybe_null(1);} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1850,7 +1873,7 @@ public: Item_func_row_count() :Item_int_func() {} longlong val_int(); const char *func_name() const { return "row_count"; } - void fix_length_and_dec() { decimals= 0; maybe_null=0; } + void fix_length_and_dec() { decimals= 0; set_persist_maybe_null(0); } bool check_vcol_func_processor(uchar *int_arg) { @@ -1887,7 +1910,8 @@ private: bool init_result_field(THD *thd); protected: - bool is_expensive_processor(uchar *arg) { return TRUE; } + bool is_expensive_processor(uchar *arg) + { return is_expensive(); } public: @@ -1966,7 +1990,7 @@ public: bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(void); - bool is_expensive() { return 1; } + bool is_expensive(); inline Field *get_sp_result_field() { @@ -1990,7 +2014,7 @@ public: Item_func_found_rows() :Item_int_func() {} longlong val_int(); const char *func_name() const { return "found_rows"; } - void fix_length_and_dec() { decimals= 0; maybe_null=0; } + void fix_length_and_dec() { decimals= 0; set_persist_maybe_null(0); } bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -2033,6 +2057,11 @@ public: enum_field_types field_type() const { return last_value->field_type(); } bool const_item() const { return 0; } void evaluate_sideeffects(); + void update_used_tables() + { + Item_func::update_used_tables(); + maybe_null= last_value->maybe_null; + } }; |