diff options
author | bell@sanja.is.com.ua <> | 2004-03-18 15:21:06 +0200 |
---|---|---|
committer | bell@sanja.is.com.ua <> | 2004-03-18 15:21:06 +0200 |
commit | 613104ad2591e8958869b85172794cfb33eb2595 (patch) | |
tree | 55a6329f97a0caf55caa7c27ba9a689a9859565e /sql | |
parent | 1e0ccbd9b07f62051f8f5910c500932f0caae147 (diff) | |
parent | 2b45b53066da7181c9cd7551331c2439c03d8793 (diff) | |
download | mariadb-git-613104ad2591e8958869b85172794cfb33eb2595.tar.gz |
merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 110 | ||||
-rw-r--r-- | sql/item.h | 93 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 177 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 33 | ||||
-rw-r--r-- | sql/item_func.cc | 86 | ||||
-rw-r--r-- | sql/item_func.h | 29 | ||||
-rw-r--r-- | sql/item_geofunc.cc | 24 | ||||
-rw-r--r-- | sql/item_row.cc | 2 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 59 | ||||
-rw-r--r-- | sql/item_strfunc.h | 3 | ||||
-rw-r--r-- | sql/item_subselect.cc | 21 | ||||
-rw-r--r-- | sql/item_sum.cc | 30 | ||||
-rw-r--r-- | sql/item_sum.h | 31 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 44 | ||||
-rw-r--r-- | sql/item_timefunc.h | 35 | ||||
-rw-r--r-- | sql/item_uniq.h | 5 | ||||
-rw-r--r-- | sql/sql_base.cc | 24 | ||||
-rw-r--r-- | sql/sql_derived.cc | 6 | ||||
-rw-r--r-- | sql/sql_help.cc | 17 | ||||
-rw-r--r-- | sql/sql_load.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 79 | ||||
-rw-r--r-- | sql/sql_select.h | 2 | ||||
-rw-r--r-- | sql/sql_show.cc | 2 | ||||
-rw-r--r-- | sql/sql_union.cc | 9 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 27 |
28 files changed, 759 insertions, 199 deletions
diff --git a/sql/field.cc b/sql/field.cc index 00b7b9ebdb9..6a891fac5c6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5733,7 +5733,7 @@ create_field::create_field(Field *old_field,Field *orig_field) { pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1); pos[tmp.length()]=0; - def=new Item_string(pos,tmp.length(), charset); + def= new Item_string(pos, tmp.length(), charset); } } #ifdef HAVE_SPATIAL diff --git a/sql/item.cc b/sql/item.cc index 657b8e1edbe..2a0afe27949 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -103,21 +103,33 @@ void Item::print_item_w_name(String *str) Item_ident::Item_ident(const char *db_name_par,const char *table_name_par, const char *field_name_par) - :db_name(db_name_par),table_name(table_name_par),field_name(field_name_par), + :changed_during_fix_field(0), db_name(db_name_par), + table_name(table_name_par), field_name(field_name_par), depended_from(0) { name = (char*) field_name_par; } // Constructor used by Item_field & Item_ref (see Item comment) -Item_ident::Item_ident(THD *thd, Item_ident *item): - Item(thd, item), - db_name(item->db_name), - table_name(item->table_name), - field_name(item->field_name), - depended_from(item->depended_from) +Item_ident::Item_ident(THD *thd, Item_ident *item) + :Item(thd, item), + changed_during_fix_field(0), + db_name(item->db_name), + table_name(item->table_name), + field_name(item->field_name), + depended_from(item->depended_from) {} +void Item_ident::cleanup() +{ + Item::cleanup(); + if (changed_during_fix_field) + { + *changed_during_fix_field= this; + changed_during_fix_field= 0; + } +} + bool Item_ident::remove_dependence_processor(byte * arg) { DBUG_ENTER("Item_ident::remove_dependence_processor"); @@ -289,11 +301,15 @@ bool DTCollation::aggregate(DTCollation &dt) return 0; } -Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) +Item_field::Item_field(Field *f, bool already_fixed) + :Item_ident(NullS, f->table_name, f->field_name) +#ifndef DBUG_OFF + ,double_fix(0) +#endif { set_field(f); collation.set(DERIVATION_IMPLICIT); - fixed= 1; // This item is not needed in fix_fields + fixed= already_fixed; } // Constructor need to process subselect with temporary tables (see Item) @@ -301,6 +317,9 @@ Item_field::Item_field(THD *thd, Item_field *item) :Item_ident(thd, item), field(item->field), result_field(item->result_field) +#ifndef DBUG_OFF + ,double_fix(0) +#endif { collation.set(DERIVATION_IMPLICIT); } @@ -341,6 +360,7 @@ const char *Item_ident::full_name() const /* ARGSUSED */ String *Item_field::val_str(String *str) { + DBUG_ASSERT(fixed == 1); if ((null_value=field->is_null())) return 0; str->set_charset(str_value.charset()); @@ -349,6 +369,7 @@ String *Item_field::val_str(String *str) double Item_field::val() { + DBUG_ASSERT(fixed == 1); if ((null_value=field->is_null())) return 0.0; return field->val_real(); @@ -356,6 +377,7 @@ double Item_field::val() longlong Item_field::val_int() { + DBUG_ASSERT(fixed == 1); if ((null_value=field->is_null())) return 0; return field->val_int(); @@ -465,6 +487,7 @@ Item *Item_field::get_tmp_table_item(THD *thd) String *Item_int::val_str(String *str) { + DBUG_ASSERT(fixed == 1); str->set(value, &my_charset_bin); return str; } @@ -479,6 +502,7 @@ void Item_int::print(String *str) String *Item_uint::val_str(String *str) { + DBUG_ASSERT(fixed == 1); str->set((ulonglong) value, &my_charset_bin); return str; } @@ -494,6 +518,7 @@ void Item_uint::print(String *str) String *Item_real::val_str(String *str) { + DBUG_ASSERT(fixed == 1); str->set(value,decimals,&my_charset_bin); return str; } @@ -510,11 +535,25 @@ void Item_string::print(String *str) bool Item_null::eq(const Item *item, bool binary_cmp) const { return item->type() == type(); } -double Item_null::val() { null_value=1; return 0.0; } -longlong Item_null::val_int() { null_value=1; return 0; } +double Item_null::val() +{ + // NULL can be used without fix_fields + null_value=1; + return 0.0; +} +longlong Item_null::val_int() +{ + // NULL can be used without fix_fields + null_value=1; + return 0; +} /* ARGSUSED */ String *Item_null::val_str(String *str) -{ null_value=1; return 0;} +{ + // NULL can be used without fix_fields + null_value=1; + return 0; +} /*********************** Item_param related ******************************/ @@ -650,6 +689,7 @@ bool Item_param::get_time(TIME *res) double Item_param::val() { + DBUG_ASSERT(fixed == 1); int err; switch (item_result_type) { case STRING_RESULT: @@ -665,8 +705,9 @@ double Item_param::val() longlong Item_param::val_int() { - int err; - switch (item_result_type) { + DBUG_ASSERT(fixed == 1); + int err; + switch (item_result_type) { case STRING_RESULT: return my_strntoll(str_value.charset(), str_value.ptr(),str_value.length(),10, @@ -681,6 +722,7 @@ longlong Item_param::val_int() String *Item_param::val_str(String* str) { + DBUG_ASSERT(fixed == 1); switch (item_result_type) { case INT_RESULT: str->set(int_value, &my_charset_bin); @@ -699,7 +741,8 @@ String *Item_param::val_str(String* str) */ String *Item_param::query_val_str(String* str) -{ +{ + DBUG_ASSERT(fixed == 1); switch (item_result_type) { case INT_RESULT: case REAL_RESULT: @@ -772,6 +815,7 @@ void Item_copy_string::copy() /* ARGSUSED */ String *Item_copy_string::val_str(String *str) { + // Item_copy_string is used without fix_fields call if (null_value) return (String*) 0; return &str_value; @@ -786,28 +830,41 @@ bool Item::fix_fields(THD *thd, struct st_table_list *list, Item ** ref) { + + // We do not check fields which are fixed during construction + DBUG_ASSERT(fixed == 0 || type() == INT_ITEM || type() == CACHE_ITEM || + type() == STRING_ITEM || type() == MYSQL_TYPE_DATETIME); fixed= 1; return 0; } double Item_ref_null_helper::val() { + DBUG_ASSERT(fixed == 1); double tmp= (*ref)->val_result(); owner->was_null|= null_value= (*ref)->null_value; return tmp; } + + longlong Item_ref_null_helper::val_int() { + DBUG_ASSERT(fixed == 1); longlong tmp= (*ref)->val_int_result(); owner->was_null|= null_value= (*ref)->null_value; return tmp; } + + String* Item_ref_null_helper::val_str(String* s) { + DBUG_ASSERT(fixed == 1); String* tmp= (*ref)->str_result(s); owner->was_null|= null_value= (*ref)->null_value; return tmp; } + + bool Item_ref_null_helper::get_date(TIME *ltime, uint fuzzydate) { return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate)); @@ -847,6 +904,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0 || double_fix == 0); if (!field) // If field is not checked { TABLE_LIST *where= 0; @@ -952,6 +1010,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ref, (char *)table_name, (char *)field_name); + register_item_tree_changing(ref); if (!rf) return 1; /* @@ -1005,6 +1064,11 @@ void Item_field::cleanup() { DBUG_ENTER("Item_field::cleanup"); Item_ident::cleanup(); + /* + Even if this object was created by direct link to field in setup_wild() + it will be linked correctly next tyme by name of field and table alias. + I.e. we can drop 'field'. + */ field= result_field= 0; DBUG_VOID_RETURN; } @@ -1323,6 +1387,7 @@ Item_varbinary::Item_varbinary(const char *str, uint str_length) longlong Item_varbinary::val_int() { + DBUG_ASSERT(fixed == 1); char *end=(char*) str_value.ptr()+str_value.length(), *ptr=end-min(str_value.length(),sizeof(longlong)); @@ -1479,6 +1544,7 @@ bool Item_field::send(Protocol *protocol, String *buffer) bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { + DBUG_ASSERT(fixed == 0); uint counter; if (!ref) { @@ -1582,8 +1648,9 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item Item_field* fld; - if (!((*reference)= fld= new Item_field(tmp))) + if (!((*reference)= fld= new Item_field(tmp, 1))) return 1; + register_item_tree_changing(reference); mark_as_dependent(thd, last, thd->lex->current_select, fld); return 0; } @@ -1695,8 +1762,12 @@ bool Item_default_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items) { + DBUG_ASSERT(fixed == 0); if (!arg) + { + fixed= 1; return 0; + } if (arg->fix_fields(thd, table_list, &arg)) return 1; @@ -1717,6 +1788,7 @@ bool Item_default_value::fix_fields(THD *thd, def_field->move_field(def_field->table->default_values - def_field->table->record[0]); set_field(def_field); + fixed= 1; return 0; } @@ -1743,6 +1815,7 @@ bool Item_insert_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items) { + DBUG_ASSERT(fixed == 0); if (arg->fix_fields(thd, table_list, &arg)) return 1; @@ -1773,6 +1846,7 @@ bool Item_insert_value::fix_fields(THD *thd, set_field(new Field_null(0, 0, Field::NONE, tmp_field->field_name, tmp_field->table, &my_charset_bin)); } + fixed= 1; return 0; } @@ -1936,7 +2010,8 @@ void Item_cache_str::store(Item *item) double Item_cache_str::val() -{ +{ + DBUG_ASSERT(fixed == 1); int err; if (value) return my_strntod(value->charset(), (char*) value->ptr(), @@ -1948,6 +2023,7 @@ double Item_cache_str::val() longlong Item_cache_str::val_int() { + DBUG_ASSERT(fixed == 1); int err; if (value) return my_strntoll(value->charset(), value->ptr(), diff --git a/sql/item.h b/sql/item.h index 984c4d0c7f5..7f50495d23b 100644 --- a/sql/item.h +++ b/sql/item.h @@ -233,7 +233,7 @@ public: Field *tmp_table_field_from_field_type(TABLE *table); /* Used in sql_select.cc:eliminate_not_funcs() */ - virtual Item *neg_transformer() { return NULL; } + virtual Item *neg_transformer(THD *thd) { return NULL; } void delete_self() { cleanup(); @@ -245,6 +245,7 @@ public: class st_select_lex; class Item_ident :public Item { + Item **changed_during_fix_field; public: const char *db_name; const char *table_name; @@ -254,7 +255,9 @@ public: const char *field_name_par); Item_ident(THD *thd, Item_ident *item); const char *full_name() const; - + void cleanup(); + void register_item_tree_changing(Item **ref) + { changed_during_fix_field= ref; } bool remove_dependence_processor(byte * arg); }; @@ -264,15 +267,21 @@ class Item_field :public Item_ident void set_field(Field *field); public: Field *field,*result_field; - // Item_field() {} +#ifndef DBUG_OFF + bool double_fix; +#endif Item_field(const char *db_par,const char *table_name_par, const char *field_name_par) - :Item_ident(db_par,table_name_par,field_name_par),field(0),result_field(0) + :Item_ident(db_par,table_name_par,field_name_par), + field(0), result_field(0) +#ifndef DBUG_OFF + ,double_fix(0) +#endif { collation.set(DERIVATION_IMPLICIT); } // Constructor need to process subselect with temporary tables (see Item) Item_field(THD *thd, Item_field *item); - Item_field(Field *field); + Item_field(Field *field, bool already_fixed); enum Type type() const { return FIELD_ITEM; } bool eq(const Item *item, bool binary_cmp) const; double val(); @@ -324,6 +333,7 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_NULL; } bool fix_fields(THD *thd, struct st_table_list *list, Item **item) { + DBUG_ASSERT(fixed == 0); bool res= Item::fix_fields(thd, list, item); max_length=0; return res; @@ -407,26 +417,25 @@ public: enum Type type() const { return INT_ITEM; } enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } - longlong val_int() { return value; } - double val() { return (double) value; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } + double val() { DBUG_ASSERT(fixed == 1); return (double) value; } String *val_str(String*); int save_in_field(Field *field, bool no_conversions); bool basic_const_item() const { return 1; } Item *new_item() { return new Item_int(name,value,max_length); } - void cleanup() { fixed= 1; } // to prevent drop fixed flag - void print(String *str); -}; - - -class Item_uint :public Item_int + // to prevent drop fixed flag (no need parent cleanup call) + void cleanup() { fixed= 1; } + void print(String *strclass Item_uint :public Item_int { public: Item_uint(const char *str_arg, uint length) : Item_int(str_arg, (longlong) strtoull(str_arg,(char**) 0,10), length) + Item_int(str_arg, (longlong) strtoull(str_arg,(char**) 0,10), length) { unsigned_flag= 1; } Item_uint(uint32 i) :Item_int((longlong) i, 10) { unsigned_flag= 1; } - double val() { return ulonglong2double((ulonglong)value); } + double val() + { DBUG_ASSERT(fixed == 1); return ulonglong2double((ulonglong)value); } String *val_str(String*); Item *new_item() { return new Item_uint(name,max_length); } int save_in_field(Field *field, bool no_conversions); @@ -456,8 +465,12 @@ public: int save_in_field(Field *field, bool no_conversions); enum Type type() const { return REAL_ITEM; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } - double val() { return value; } - longlong val_int() { return (longlong) (value+(value > 0 ? 0.5 : -0.5));} + double val() { DBUG_ASSERT(fixed == 1); return value; } + longlong val_int() + { + DBUG_ASSERT(fixed == 1); + return (longlong) (value+(value > 0 ? 0.5 : -0.5)); + } String *val_str(String*); bool basic_const_item() const { return 1; } Item *new_item() { return new Item_real(name,value,decimals,max_length); } @@ -492,6 +505,8 @@ public: max_length= str_value.numchars()*cs->mbmaxlen; set_name(str, length, cs); decimals=NOT_FIXED_DEC; + // it is constant => can be used without fix_fields (and frequently used) + fixed= 1; } Item_string(const char *name_par, const char *str, uint length, CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE) @@ -501,21 +516,29 @@ public: max_length= str_value.numchars()*cs->mbmaxlen; set_name(name_par,0,cs); decimals=NOT_FIXED_DEC; + // it is constant => can be used without fix_fields (and frequently used) + fixed= 1; } enum Type type() const { return STRING_ITEM; } double val() - { + { + DBUG_ASSERT(fixed == 1); int err; return my_strntod(str_value.charset(), (char*) str_value.ptr(), str_value.length(), (char**) 0, &err); } longlong val_int() { + DBUG_ASSERT(fixed == 1); int err; return my_strntoll(str_value.charset(), str_value.ptr(), str_value.length(), 10, (char**) 0, &err); } - String *val_str(String*) { return (String*) &str_value; } + String *val_str(String*) + { + DBUG_ASSERT(fixed == 1); + return (String*) &str_value; + } int save_in_field(Field *field, bool no_conversions); enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_STRING; } @@ -529,6 +552,11 @@ public: String *const_string() { return &str_value; } inline void append(char *str, uint length) { str_value.append(str, length); } void print(String *str); + void cleanup() + { + // it is constant => can be used without fix_fields (and frequently used) + fixed= 1; + } }; /* for show tables */ @@ -570,9 +598,10 @@ class Item_varbinary :public Item public: Item_varbinary(const char *str,uint str_length); enum Type type() const { return VARBIN_ITEM; } - double val() { return (double) Item_varbinary::val_int(); } + double val() + { DBUG_ASSERT(fixed == 1); return (double) Item_varbinary::val_int(); } longlong val_int(); - String *val_str(String*) { return &str_value; } + String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; } int save_in_field(Field *field, bool no_conversions); enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_STRING; } @@ -899,7 +928,8 @@ public: static Item_cache* get_cache(Item_result type); table_map used_tables() const { return used_table_map; } virtual void keep_array() {} - void cleanup() { fixed= 1; } // to prevent drop fixed flag + // to prevent drop fixed flag (no need parent cleanup call) + void cleanup() { fixed= 1; } void print(String *str); }; @@ -910,9 +940,14 @@ public: Item_cache_int(): Item_cache() {} void store(Item *item); - double val() { return (double) value; } - longlong val_int() { return value; } - String* val_str(String *str) { str->set(value, default_charset()); return str; } + double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } + String* val_str(String *str) + { + DBUG_ASSERT(fixed == 1); + str->set(value, default_charset()); + return str; + } enum Item_result result_type() const { return INT_RESULT; } }; @@ -923,8 +958,12 @@ public: Item_cache_real(): Item_cache() {} void store(Item *item); - double val() { return value; } - longlong val_int() { return (longlong) (value+(value > 0 ? 0.5 : -0.5)); } + double val() { DBUG_ASSERT(fixed == 1); return value; } + longlong val_int() + { + DBUG_ASSERT(fixed == 1); + return (longlong) (value+(value > 0 ? 0.5 : -0.5)); + } String* val_str(String *str) { str->set(value, decimals, default_charset()); @@ -943,7 +982,7 @@ public: void store(Item *item); double val(); longlong val_int(); - String* val_str(String *) { return value; } + String* val_str(String *) { DBUG_ASSERT(fixed == 1); return value; } enum Item_result result_type() const { return STRING_RESULT; } CHARSET_INFO *charset() const { return value->charset(); }; }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index ab24b615365..8f55467a23e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -103,6 +103,7 @@ Item_bool_func2* Le_creator::create(Item *a, Item *b) const longlong Item_func_not::val_int() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); null_value=args[0]->null_value; return !null_value && value == 0 ? 1 : 0; @@ -113,7 +114,8 @@ longlong Item_func_not::val_int() */ longlong Item_func_not_all::val_int() -{ +{ + DBUG_ASSERT(fixed == 1); double value= args[0]->val(); if (abort_on_null) { @@ -502,7 +504,6 @@ bool Item_in_optimizer::fix_left(THD *thd, not_null_tables_cache= args[0]->not_null_tables(); with_sum_func= args[0]->with_sum_func; const_item_cache= args[0]->const_item(); - fixed= 1; return 0; } @@ -510,7 +511,8 @@ bool Item_in_optimizer::fix_left(THD *thd, bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables, Item ** ref) { - if (fix_left(thd, tables, ref)) + DBUG_ASSERT(fixed == 0); + if (!args[0]->fixed && fix_left(thd, tables, ref)) return 1; if (args[0]->maybe_null) maybe_null=1; @@ -529,12 +531,14 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables, used_tables_cache|= args[1]->used_tables(); not_null_tables_cache|= args[1]->not_null_tables(); const_item_cache&= args[1]->const_item(); + fixed= 1; return 0; } longlong Item_in_optimizer::val_int() { + DBUG_ASSERT(fixed == 1); cache->store(args[0]); if (cache->null_value) { @@ -573,6 +577,7 @@ bool Item_in_optimizer::is_null() longlong Item_func_eq::val_int() { + DBUG_ASSERT(fixed == 1); int value= cmp.compare(); return value == 0 ? 1 : 0; } @@ -588,11 +593,13 @@ void Item_func_equal::fix_length_and_dec() longlong Item_func_equal::val_int() { + DBUG_ASSERT(fixed == 1); return cmp.compare(); } longlong Item_func_ne::val_int() { + DBUG_ASSERT(fixed == 1); int value= cmp.compare(); return value != 0 && !null_value ? 1 : 0; } @@ -600,6 +607,7 @@ longlong Item_func_ne::val_int() longlong Item_func_ge::val_int() { + DBUG_ASSERT(fixed == 1); int value= cmp.compare(); return value >= 0 ? 1 : 0; } @@ -607,12 +615,14 @@ longlong Item_func_ge::val_int() longlong Item_func_gt::val_int() { + DBUG_ASSERT(fixed == 1); int value= cmp.compare(); return value > 0 ? 1 : 0; } longlong Item_func_le::val_int() { + DBUG_ASSERT(fixed == 1); int value= cmp.compare(); return value <= 0 && !null_value ? 1 : 0; } @@ -620,6 +630,7 @@ longlong Item_func_le::val_int() longlong Item_func_lt::val_int() { + DBUG_ASSERT(fixed == 1); int value= cmp.compare(); return value < 0 && !null_value ? 1 : 0; } @@ -627,6 +638,7 @@ longlong Item_func_lt::val_int() longlong Item_func_strcmp::val_int() { + DBUG_ASSERT(fixed == 1); String *a=args[0]->val_str(&tmp_value1); String *b=args[1]->val_str(&tmp_value2); if (!a || !b) @@ -676,6 +688,7 @@ void Item_func_interval::fix_length_and_dec() longlong Item_func_interval::val_int() { + DBUG_ASSERT(fixed == 1); double value= row->el(0)->val(); uint i; @@ -741,6 +754,7 @@ void Item_func_between::fix_length_and_dec() longlong Item_func_between::val_int() { // ANSI BETWEEN + DBUG_ASSERT(fixed == 1); if (cmp_type == STRING_RESULT) { String *value,*a,*b; @@ -848,6 +862,7 @@ Field *Item_func_ifnull::tmp_table_field(TABLE *table) double Item_func_ifnull::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if (!args[0]->null_value) { @@ -863,6 +878,7 @@ Item_func_ifnull::val() longlong Item_func_ifnull::val_int() { + DBUG_ASSERT(fixed == 1); longlong value=args[0]->val_int(); if (!args[0]->null_value) { @@ -878,6 +894,7 @@ Item_func_ifnull::val_int() String * Item_func_ifnull::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); if (!args[0]->null_value) { @@ -933,6 +950,7 @@ Item_func_if::fix_length_and_dec() double Item_func_if::val() { + DBUG_ASSERT(fixed == 1); Item *arg= args[0]->val_int() ? args[1] : args[2]; double value=arg->val(); null_value=arg->null_value; @@ -942,6 +960,7 @@ Item_func_if::val() longlong Item_func_if::val_int() { + DBUG_ASSERT(fixed == 1); Item *arg= args[0]->val_int() ? args[1] : args[2]; longlong value=arg->val_int(); null_value=arg->null_value; @@ -951,6 +970,7 @@ Item_func_if::val_int() String * Item_func_if::val_str(String *str) { + DBUG_ASSERT(fixed == 1); Item *arg= args[0]->val_int() ? args[1] : args[2]; String *res=arg->val_str(str); if (res) @@ -983,6 +1003,7 @@ Item_func_nullif::fix_length_and_dec() double Item_func_nullif::val() { + DBUG_ASSERT(fixed == 1); double value; if (!cmp.compare()) { @@ -997,6 +1018,7 @@ Item_func_nullif::val() longlong Item_func_nullif::val_int() { + DBUG_ASSERT(fixed == 1); longlong value; if (!cmp.compare()) { @@ -1011,6 +1033,7 @@ Item_func_nullif::val_int() String * Item_func_nullif::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res; if (!cmp.compare()) { @@ -1104,6 +1127,7 @@ Item *Item_func_case::find_item(String *str) String *Item_func_case::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res; Item *item=find_item(str); @@ -1121,6 +1145,7 @@ String *Item_func_case::val_str(String *str) longlong Item_func_case::val_int() { + DBUG_ASSERT(fixed == 1); char buff[MAX_FIELD_WIDTH]; String dummy_str(buff,sizeof(buff),default_charset()); Item *item=find_item(&dummy_str); @@ -1138,6 +1163,7 @@ longlong Item_func_case::val_int() double Item_func_case::val() { + DBUG_ASSERT(fixed == 1); char buff[MAX_FIELD_WIDTH]; String dummy_str(buff,sizeof(buff),default_charset()); Item *item=find_item(&dummy_str); @@ -1243,6 +1269,7 @@ void Item_func_case::print(String *str) String *Item_func_coalesce::val_str(String *str) { + DBUG_ASSERT(fixed == 1); null_value=0; for (uint i=0 ; i < arg_count ; i++) { @@ -1256,6 +1283,7 @@ String *Item_func_coalesce::val_str(String *str) longlong Item_func_coalesce::val_int() { + DBUG_ASSERT(fixed == 1); null_value=0; for (uint i=0 ; i < arg_count ; i++) { @@ -1269,6 +1297,7 @@ longlong Item_func_coalesce::val_int() double Item_func_coalesce::val() { + DBUG_ASSERT(fixed == 1); null_value=0; for (uint i=0 ; i < arg_count ; i++) { @@ -1675,6 +1704,7 @@ void Item_func_in::print(String *str) longlong Item_func_in::val_int() { + DBUG_ASSERT(fixed == 1); if (array) { int tmp=array->find(args[0]); @@ -1698,6 +1728,7 @@ longlong Item_func_in::val_int() longlong Item_func_bit_or::val_int() { + DBUG_ASSERT(fixed == 1); ulonglong arg1= (ulonglong) args[0]->val_int(); if (args[0]->null_value) { @@ -1717,6 +1748,7 @@ longlong Item_func_bit_or::val_int() longlong Item_func_bit_and::val_int() { + DBUG_ASSERT(fixed == 1); ulonglong arg1= (ulonglong) args[0]->val_int(); if (args[0]->null_value) { @@ -1755,6 +1787,7 @@ void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item) bool Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); List_iterator<Item> li(list); Item *item; #ifndef EMBEDDED_LIBRARY @@ -1878,14 +1911,27 @@ void Item_cond::print(String *str) } -void Item_cond::neg_arguments() +void Item_cond::neg_arguments(THD *thd) { List_iterator<Item> li(list); Item *item; while ((item= li++)) /* Apply not transformation to the arguments */ { - Item *new_item= item->neg_transformer(); - VOID(li.replace(new_item ? new_item : new Item_func_not(item))); + Item *new_item= item->neg_transformer(thd); + if (!new_item) + { + new_item= new Item_func_not(item); + /* + We can use 0 as tables list because Item_func_not do not use it + on fix_fields and its arguments are already fixed. + + We do not check results of fix_fields, because there are not way + to return error in this functions interface, thd->net.report_error + will be checked on upper level call. + */ + new_item->fix_fields(thd, 0, &new_item); + } + VOID(li.replace(new_item)); } } @@ -1910,6 +1956,7 @@ void Item_cond::neg_arguments() longlong Item_cond_and::val_int() { + DBUG_ASSERT(fixed == 1); List_iterator_fast<Item> li(list); Item *item; null_value= 0; @@ -1927,6 +1974,7 @@ longlong Item_cond_and::val_int() longlong Item_cond_or::val_int() { + DBUG_ASSERT(fixed == 1); List_iterator_fast<Item> li(list); Item *item; null_value=0; @@ -1988,6 +2036,7 @@ Item *and_expressions(Item *a, Item *b, Item **org_item) longlong Item_func_isnull::val_int() { + DBUG_ASSERT(fixed == 1); /* Handle optimization if the argument can't be null This has to be here because of the test in update_used_tables(). @@ -1999,6 +2048,7 @@ longlong Item_func_isnull::val_int() longlong Item_is_not_null_test::val_int() { + DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_is_not_null_test::val_int"); if (!used_tables_cache) { @@ -2038,6 +2088,7 @@ void Item_is_not_null_test::update_used_tables() longlong Item_func_isnotnull::val_int() { + DBUG_ASSERT(fixed == 1); return args[0]->is_null() ? 0 : 1; } @@ -2052,6 +2103,7 @@ void Item_func_isnotnull::print(String *str) longlong Item_func_like::val_int() { + DBUG_ASSERT(fixed == 1); String* res = args[0]->val_str(&tmp_value1); if (args[0]->null_value) { @@ -2097,6 +2149,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) { + DBUG_ASSERT(fixed == 0); if (Item_bool_func2::fix_fields(thd, tlist, ref)) return 1; @@ -2150,6 +2203,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) bool Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1) || args[1]->fix_fields(thd,tables, args + 1) || args[1]->check_cols(1)) return 1; /* purecov: inspected */ @@ -2197,6 +2251,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) longlong Item_func_regex::val_int() { + DBUG_ASSERT(fixed == 1); char buff[MAX_FIELD_WIDTH]; String *res, tmp(buff,sizeof(buff),&my_charset_bin); @@ -2497,6 +2552,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const longlong Item_cond_xor::val_int() { + DBUG_ASSERT(fixed == 1); List_iterator<Item> li(list); Item *item; int result=0; @@ -2518,6 +2574,7 @@ longlong Item_cond_xor::val_int() SYNPOSIS neg_transformer() + thd thread handler DESCRIPTION Transform the item using next rules: @@ -2541,62 +2598,116 @@ longlong Item_cond_xor::val_int() NULL if we cannot apply NOT transformation (see Item::neg_transformer()). */ -Item *Item_func_not::neg_transformer() /* NOT(x) -> x */ +Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */ { - /* We should apply negation elimination to the argument of the NOT function */ - return eliminate_not_funcs(args[0]); + // We should apply negation elimination to the argument of the NOT function + return eliminate_not_funcs(thd, args[0]); } -Item *Item_func_eq::neg_transformer() /* a = b -> a != b */ + +Item *Item_bool_rowready_func2::neg_transformer(THD *thd) { - return new Item_func_ne(args[0], args[1]); + Item *item= negated_item(); + if (item) + { + /* + We can use 0 as tables list because Item_func* family do not use it + on fix_fields and its arguments are already fixed. + + We do not check results of fix_fields, because there are not way + to return error in this functions interface, thd->net.report_error + will be checked on upper level call. + */ + item->fix_fields(thd, 0, &item); + } + return item; } -Item *Item_func_ne::neg_transformer() /* a != b -> a = b */ + +/* a IS NULL -> a IS NOT NULL */ +Item *Item_func_isnull::neg_transformer(THD *thd) { - return new Item_func_eq(args[0], args[1]); + Item *item= new Item_func_isnotnull(args[0]); + // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer + if (item) + item->fix_fields(thd, 0, &item); + return item; } -Item *Item_func_lt::neg_transformer() /* a < b -> a >= b */ + +/* a IS NOT NULL -> a IS NULL */ +Item *Item_func_isnotnull::neg_transformer(THD *thd) { - return new Item_func_ge(args[0], args[1]); + Item *item= new Item_func_isnull(args[0]); + // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer + if (item) + item->fix_fields(thd, 0, &item); + return item; } -Item *Item_func_ge::neg_transformer() /* a >= b -> a < b */ + +Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */ + /* NOT a OR NOT b OR ... */ { - return new Item_func_lt(args[0], args[1]); + neg_arguments(thd); + Item *item= new Item_cond_or(list); + // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer + if (item) + item->fix_fields(thd, 0, &item); + return item; +} + + +Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */ + /* NOT a AND NOT b AND ... */ +{ + neg_arguments(thd); + Item *item= new Item_cond_and(list); + // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer + if (item) + item->fix_fields(thd, 0, &item); + return item; } -Item *Item_func_gt::neg_transformer() /* a > b -> a <= b */ + +Item *Item_func_eq::negated_item() /* a = b -> a != b */ { - return new Item_func_le(args[0], args[1]); + return new Item_func_ne(args[0], args[1]); } -Item *Item_func_le::neg_transformer() /* a <= b -> a > b */ + +Item *Item_func_ne::negated_item() /* a != b -> a = b */ { - return new Item_func_gt(args[0], args[1]); + return new Item_func_eq(args[0], args[1]); +} + + +Item *Item_func_lt::negated_item() /* a < b -> a >= b */ +{ + return new Item_func_ge(args[0], args[1]); } -Item *Item_func_isnull::neg_transformer() /* a IS NULL -> a IS NOT NULL */ + +Item *Item_func_ge::negated_item() /* a >= b -> a < b */ { - return new Item_func_isnotnull(args[0]); + return new Item_func_lt(args[0], args[1]); } -Item *Item_func_isnotnull::neg_transformer() /* a IS NOT NULL -> a IS NULL */ + +Item *Item_func_gt::negated_item() /* a > b -> a <= b */ { - return new Item_func_isnull(args[0]); + return new Item_func_le(args[0], args[1]); } -Item *Item_cond_and::neg_transformer() /* NOT(a AND b AND ...) -> */ - /* NOT a OR NOT b OR ... */ + +Item *Item_func_le::negated_item() /* a <= b -> a > b */ { - neg_arguments(); - return new Item_cond_or(list); + return new Item_func_gt(args[0], args[1]); } -Item *Item_cond_or::neg_transformer() /* NOT(a OR b OR ...) -> */ - /* NOT a AND NOT b AND ... */ +// just fake method, should never be called +Item *Item_bool_rowready_func2::negated_item() { - neg_arguments(); - return new Item_cond_and(list); + DBUG_ASSERT(0); + return 0; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 9d39ddf4e76..a2587f408b1 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -218,6 +218,8 @@ public: tmp_arg[1]= orig_b; DBUG_VOID_RETURN; } + Item *neg_transformer(THD *thd); + virtual Item *negated_item(); }; class Item_func_not :public Item_bool_func @@ -227,7 +229,7 @@ public: longlong val_int(); enum Functype functype() const { return NOT_FUNC; } const char *func_name() const { return "not"; } - Item *neg_transformer(); + Item *neg_transformer(THD *thd); }; class Item_func_not_all :public Item_func_not @@ -254,7 +256,7 @@ public: enum Functype rev_functype() const { return EQ_FUNC; } cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "="; } - Item *neg_transformer(); + Item *negated_item(); }; class Item_func_equal :public Item_bool_rowready_func2 @@ -267,6 +269,7 @@ public: enum Functype rev_functype() const { return EQUAL_FUNC; } cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "<=>"; } + Item* neg_transformer(THD *thd) { return 0; } }; @@ -279,7 +282,7 @@ public: enum Functype rev_functype() const { return LE_FUNC; } cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return ">="; } - Item *neg_transformer(); + Item *negated_item(); }; @@ -292,7 +295,7 @@ public: enum Functype rev_functype() const { return LT_FUNC; } cond_result eq_cmp_result() const { return COND_FALSE; } const char *func_name() const { return ">"; } - Item *neg_transformer(); + Item *negated_item(); }; @@ -305,7 +308,7 @@ public: enum Functype rev_functype() const { return GE_FUNC; } cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "<="; } - Item *neg_transformer(); + Item *negated_item(); }; @@ -318,7 +321,7 @@ public: enum Functype rev_functype() const { return GT_FUNC; } cond_result eq_cmp_result() const { return COND_FALSE; } const char *func_name() const { return "<"; } - Item *neg_transformer(); + Item *negated_item(); }; @@ -331,7 +334,7 @@ public: cond_result eq_cmp_result() const { return COND_FALSE; } optimize_type select_optimize() const { return OPTIMIZE_KEY; } const char *func_name() const { return "<>"; } - Item *neg_transformer(); + Item *negated_item(); }; @@ -409,6 +412,7 @@ public: enum Item_result result_type () const { return cached_result_type; } bool fix_fields(THD *thd,struct st_table_list *tlist, Item **ref) { + DBUG_ASSERT(fixed == 0); args[0]->top_level_item(); return Item_func::fix_fields(thd, tlist, ref); } @@ -726,6 +730,7 @@ class Item_func_in :public Item_int_func void cleanup() { DBUG_ENTER("Item_func_in::cleanup"); + Item_int_func::cleanup(); delete array; delete in_item; array= 0; @@ -778,7 +783,7 @@ public: } table_map not_null_tables() const { return 0; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } - Item *neg_transformer(); + Item *neg_transformer(THD *thd); CHARSET_INFO *compare_collation() { return args[0]->collation.collation; } }; @@ -812,7 +817,7 @@ public: const char *func_name() const { return "isnotnull"; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } table_map not_null_tables() const { return 0; } - Item *neg_transformer(); + Item *neg_transformer(THD *thd); void print(String *str); CHARSET_INFO *compare_collation() { return args[0]->collation.collation; } }; @@ -920,7 +925,7 @@ public: void top_level_item() { abort_on_null=1; } void copy_andor_arguments(THD *thd, Item_cond *item); bool walk(Item_processor processor, byte *arg); - void neg_arguments(); + void neg_arguments(THD *thd); }; @@ -941,7 +946,7 @@ public: item->copy_andor_arguments(thd, this); return item; } - Item *neg_transformer(); + Item *neg_transformer(THD *thd); }; class Item_cond_or :public Item_cond @@ -962,7 +967,7 @@ public: item->copy_andor_arguments(thd, this); return item; } - Item *neg_transformer(); + Item *neg_transformer(THD *thd); }; @@ -990,9 +995,9 @@ inline Item *and_conds(Item *a,Item *b) { if (!b) return a; if (!a) return b; - Item *cond=new Item_cond_and(a,b); + Item *cond= new Item_cond_and(a,b); if (cond) - cond->update_used_tables(); + cond->fix_fields(current_thd, 0, &cond); return cond; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 04e3452c1f7..be9367ec381 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -199,6 +199,7 @@ Item_func::Item_func(THD *thd, Item_func *item) bool Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); Item **arg,**arg_end; #ifndef EMBEDDED_LIBRARY // Avoid compiler warning char buff[STACK_BUFF_ALLOC]; // Max argument in function @@ -214,8 +215,10 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) { Item *item; - /* We can't yet set item to *arg as fix_fields may change *arg */ - /* We shouldn't call fix_fields() twice, so check 'fixed' field first */ + /* + We can't yet set item to *arg as fix_fields may change *arg + We shouldn't call fix_fields() twice, so check 'fixed' field first + */ if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) || (*arg)->check_cols(allowed_arg_cols)) return 1; /* purecov: inspected */ @@ -381,6 +384,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) String *Item_real_func::val_str(String *str) { + DBUG_ASSERT(fixed == 1); double nr=val(); if (null_value) return 0; /* purecov: inspected */ @@ -391,6 +395,7 @@ String *Item_real_func::val_str(String *str) String *Item_num_func::val_str(String *str) { + DBUG_ASSERT(fixed == 1); if (hybrid_type == INT_RESULT) { longlong nr=val_int(); @@ -423,12 +428,13 @@ void Item_func::fix_num_length_and_dec() Item *Item_func::get_tmp_table_item(THD *thd) { if (!with_sum_func && !const_item()) - return new Item_field(result_field); + return new Item_field(result_field, 1); return copy_or_same(thd); } String *Item_int_func::val_str(String *str) { + DBUG_ASSERT(fixed == 1); longlong nr=val_int(); if (null_value) return 0; @@ -456,6 +462,7 @@ void Item_num_op::find_num_type(void) String *Item_num_op::val_str(String *str) { + DBUG_ASSERT(fixed == 1); if (hybrid_type == INT_RESULT) { longlong nr=val_int(); @@ -497,6 +504,7 @@ void Item_func_unsigned::print(String *str) double Item_func_plus::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val()+args[1]->val(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; @@ -505,6 +513,7 @@ double Item_func_plus::val() longlong Item_func_plus::val_int() { + DBUG_ASSERT(fixed == 1); if (hybrid_type == INT_RESULT) { longlong value=args[0]->val_int()+args[1]->val_int(); @@ -532,6 +541,7 @@ void Item_func_minus::fix_length_and_dec() double Item_func_minus::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val() - args[1]->val(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; @@ -540,6 +550,7 @@ double Item_func_minus::val() longlong Item_func_minus::val_int() { + DBUG_ASSERT(fixed == 1); if (hybrid_type == INT_RESULT) { longlong value=args[0]->val_int() - args[1]->val_int(); @@ -553,6 +564,7 @@ longlong Item_func_minus::val_int() double Item_func_mul::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val()*args[1]->val(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; /* purecov: inspected */ @@ -561,6 +573,7 @@ double Item_func_mul::val() longlong Item_func_mul::val_int() { + DBUG_ASSERT(fixed == 1); if (hybrid_type == INT_RESULT) { longlong value=args[0]->val_int()*args[1]->val_int(); @@ -574,6 +587,7 @@ longlong Item_func_mul::val_int() double Item_func_div::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); double val2=args[1]->val(); if ((null_value= val2 == 0.0 || args[0]->null_value || args[1]->null_value)) @@ -583,6 +597,7 @@ double Item_func_div::val() longlong Item_func_div::val_int() { + DBUG_ASSERT(fixed == 1); if (hybrid_type == INT_RESULT) { longlong value=args[0]->val_int(); @@ -607,6 +622,7 @@ void Item_func_div::fix_length_and_dec() /* Integer division */ longlong Item_func_int_div::val_int() { + DBUG_ASSERT(fixed == 1); longlong value=args[0]->val_int(); longlong val2=args[1]->val_int(); if ((null_value= val2 == 0 || args[0]->null_value || args[1]->null_value)) @@ -627,6 +643,7 @@ void Item_func_int_div::fix_length_and_dec() double Item_func_mod::val() { + DBUG_ASSERT(fixed == 1); double value= floor(args[0]->val()+0.5); double val2=floor(args[1]->val()+0.5); if ((null_value=val2 == 0.0 || args[0]->null_value || args[1]->null_value)) @@ -636,6 +653,7 @@ double Item_func_mod::val() longlong Item_func_mod::val_int() { + DBUG_ASSERT(fixed == 1); longlong value= args[0]->val_int(); longlong val2= args[1]->val_int(); if ((null_value=val2 == 0 || args[0]->null_value || args[1]->null_value)) @@ -654,6 +672,7 @@ void Item_func_mod::fix_length_and_dec() double Item_func_neg::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); null_value=args[0]->null_value; return -value; @@ -662,6 +681,7 @@ double Item_func_neg::val() longlong Item_func_neg::val_int() { + DBUG_ASSERT(fixed == 1); longlong value=args[0]->val_int(); null_value=args[0]->null_value; return -value; @@ -695,6 +715,7 @@ void Item_func_neg::fix_length_and_dec() double Item_func_abs::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); null_value=args[0]->null_value; return fabs(value); @@ -703,6 +724,7 @@ double Item_func_abs::val() longlong Item_func_abs::val_int() { + DBUG_ASSERT(fixed == 1); longlong value=args[0]->val_int(); null_value=args[0]->null_value; return value >= 0 ? value : -value; @@ -725,6 +747,7 @@ void Item_func_abs::fix_length_and_dec() /* Gateway to natural LOG function */ double Item_func_ln::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; @@ -738,6 +761,7 @@ double Item_func_ln::val() */ double Item_func_log::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; @@ -753,6 +777,7 @@ double Item_func_log::val() double Item_func_log2::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; @@ -761,6 +786,7 @@ double Item_func_log2::val() double Item_func_log10::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; /* purecov: inspected */ @@ -769,6 +795,7 @@ double Item_func_log10::val() double Item_func_exp::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=args[0]->null_value)) return 0.0; /* purecov: inspected */ @@ -777,6 +804,7 @@ double Item_func_exp::val() double Item_func_sqrt::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=(args[0]->null_value || value < 0))) return 0.0; /* purecov: inspected */ @@ -785,6 +813,7 @@ double Item_func_sqrt::val() double Item_func_pow::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); double val2=args[1]->val(); if ((null_value=(args[0]->null_value || args[1]->null_value))) @@ -796,6 +825,7 @@ double Item_func_pow::val() double Item_func_acos::val() { + DBUG_ASSERT(fixed == 1); // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) volatile double value=args[0]->val(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) @@ -805,6 +835,7 @@ double Item_func_acos::val() double Item_func_asin::val() { + DBUG_ASSERT(fixed == 1); // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) volatile double value=args[0]->val(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) @@ -814,6 +845,7 @@ double Item_func_asin::val() double Item_func_atan::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=args[0]->null_value)) return 0.0; @@ -829,6 +861,7 @@ double Item_func_atan::val() double Item_func_cos::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=args[0]->null_value)) return 0.0; @@ -837,6 +870,7 @@ double Item_func_cos::val() double Item_func_sin::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=args[0]->null_value)) return 0.0; @@ -845,6 +879,7 @@ double Item_func_sin::val() double Item_func_tan::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=args[0]->null_value)) return 0.0; @@ -857,6 +892,7 @@ double Item_func_tan::val() longlong Item_func_shift_left::val_int() { + DBUG_ASSERT(fixed == 1); uint shift; ulonglong res= ((ulonglong) args[0]->val_int() << (shift=(uint) args[1]->val_int())); @@ -871,6 +907,7 @@ longlong Item_func_shift_left::val_int() longlong Item_func_shift_right::val_int() { + DBUG_ASSERT(fixed == 1); uint shift; ulonglong res= (ulonglong) args[0]->val_int() >> (shift=(uint) args[1]->val_int()); @@ -886,6 +923,7 @@ longlong Item_func_shift_right::val_int() longlong Item_func_bit_neg::val_int() { + DBUG_ASSERT(fixed == 1); ulonglong res= (ulonglong) args[0]->val_int(); if ((null_value=args[0]->null_value)) return 0; @@ -905,6 +943,7 @@ void Item_func_integer::fix_length_and_dec() longlong Item_func_ceiling::val_int() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); null_value=args[0]->null_value; return (longlong) ceil(value); @@ -912,6 +951,7 @@ longlong Item_func_ceiling::val_int() longlong Item_func_floor::val_int() { + DBUG_ASSERT(fixed == 1); // the volatile's for BUG #3051 to calm optimizer down (because of gcc's bug) volatile double value=args[0]->val(); null_value=args[0]->null_value; @@ -934,6 +974,7 @@ void Item_func_round::fix_length_and_dec() double Item_func_round::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); int dec=(int) args[1]->val_int(); uint abs_dec=abs(dec); @@ -1001,11 +1042,13 @@ void Item_func_rand::update_used_tables() double Item_func_rand::val() { + DBUG_ASSERT(fixed == 1); return my_rnd(rand); } longlong Item_func_sign::val_int() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); null_value=args[0]->null_value; return value < 0.0 ? -1 : (value > 0 ? 1 : 0); @@ -1014,6 +1057,7 @@ longlong Item_func_sign::val_int() double Item_func_units::val() { + DBUG_ASSERT(fixed == 1); double value=args[0]->val(); if ((null_value=args[0]->null_value)) return 0; @@ -1045,6 +1089,7 @@ void Item_func_min_max::fix_length_and_dec() String *Item_func_min_max::val_str(String *str) { + DBUG_ASSERT(fixed == 1); switch (cmp_type) { case INT_RESULT: { @@ -1106,6 +1151,7 @@ String *Item_func_min_max::val_str(String *str) double Item_func_min_max::val() { + DBUG_ASSERT(fixed == 1); double value=0.0; null_value=1; for (uint i=0; i < arg_count ; i++) @@ -1128,6 +1174,7 @@ double Item_func_min_max::val() longlong Item_func_min_max::val_int() { + DBUG_ASSERT(fixed == 1); longlong value=0; null_value=1; for (uint i=0; i < arg_count ; i++) @@ -1149,6 +1196,7 @@ longlong Item_func_min_max::val_int() longlong Item_func_length::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); if (!res) { @@ -1162,6 +1210,7 @@ longlong Item_func_length::val_int() longlong Item_func_char_length::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); if (!res) { @@ -1175,6 +1224,7 @@ longlong Item_func_char_length::val_int() longlong Item_func_coercibility::val_int() { + DBUG_ASSERT(fixed == 1); if (args[0]->null_value) { null_value= 1; @@ -1194,6 +1244,7 @@ void Item_func_locate::fix_length_and_dec() longlong Item_func_locate::val_int() { + DBUG_ASSERT(fixed == 1); String *a=args[0]->val_str(&value1); String *b=args[1]->val_str(&value2); if (!a || !b) @@ -1244,6 +1295,7 @@ void Item_func_locate::print(String *str) longlong Item_func_field::val_int() { + DBUG_ASSERT(fixed == 1); if (cmp_type == STRING_RESULT) { String *field; @@ -1291,6 +1343,7 @@ void Item_func_field::fix_length_and_dec() longlong Item_func_ascii::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); if (!res) { @@ -1303,6 +1356,7 @@ longlong Item_func_ascii::val_int() longlong Item_func_ord::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); if (!res) { @@ -1357,6 +1411,7 @@ static const char separator=','; longlong Item_func_find_in_set::val_int() { + DBUG_ASSERT(fixed == 1); if (enum_value) { ulonglong tmp=(ulonglong) args[1]->val_int(); @@ -1410,6 +1465,7 @@ longlong Item_func_find_in_set::val_int() longlong Item_func_bit_count::val_int() { + DBUG_ASSERT(fixed == 1); ulonglong value= (ulonglong) args[0]->val_int(); if (args[0]->null_value) { @@ -1682,6 +1738,7 @@ String *udf_handler::val_str(String *str,String *save_str) double Item_func_udf_float::val() { + DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_udf_float::val"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); @@ -1691,6 +1748,7 @@ double Item_func_udf_float::val() String *Item_func_udf_float::val_str(String *str) { + DBUG_ASSERT(fixed == 1); double nr=val(); if (null_value) return 0; /* purecov: inspected */ @@ -1701,6 +1759,7 @@ String *Item_func_udf_float::val_str(String *str) longlong Item_func_udf_int::val_int() { + DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_udf_int::val_int"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); @@ -1711,6 +1770,7 @@ longlong Item_func_udf_int::val_int() String *Item_func_udf_int::val_str(String *str) { + DBUG_ASSERT(fixed == 1); longlong nr=val_int(); if (null_value) return 0; @@ -1734,6 +1794,7 @@ void Item_func_udf_str::fix_length_and_dec() String *Item_func_udf_str::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res=udf.val_str(str,&str_value); null_value = !res; return res; @@ -1847,6 +1908,7 @@ void item_user_lock_release(User_level_lock *ull) longlong Item_master_pos_wait::val_int() { + DBUG_ASSERT(fixed == 1); THD* thd = current_thd; String *log_name = args[0]->val_str(&value); int event_count= 0; @@ -1948,6 +2010,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) longlong Item_func_get_lock::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); longlong timeout=args[1]->val_int(); struct timespec abstime; @@ -2043,6 +2106,7 @@ longlong Item_func_get_lock::val_int() longlong Item_func_release_lock::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); User_level_lock *ull; longlong result; @@ -2077,6 +2141,7 @@ longlong Item_func_release_lock::val_int() longlong Item_func_set_last_insert_id::val_int() { + DBUG_ASSERT(fixed == 1); longlong value=args[0]->val_int(); current_thd->insert_id(value); null_value=args[0]->null_value; @@ -2087,6 +2152,7 @@ longlong Item_func_set_last_insert_id::val_int() longlong Item_func_benchmark::val_int() { + DBUG_ASSERT(fixed == 1); char buff[MAX_FIELD_WIDTH]; String tmp(buff,sizeof(buff), &my_charset_bin); THD *thd=current_thd; @@ -2179,6 +2245,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */ if (Item_func::fix_fields(thd, tables, ref) || !(entry= get_variable(&thd->user_vars, name, 1))) @@ -2443,6 +2510,7 @@ Item_func_set_user_var::update() double Item_func_set_user_var::val() { + DBUG_ASSERT(fixed == 1); check(); update(); // Store expression return entry->val(&null_value); @@ -2450,6 +2518,7 @@ double Item_func_set_user_var::val() longlong Item_func_set_user_var::val_int() { + DBUG_ASSERT(fixed == 1); check(); update(); // Store expression return entry->val_int(&null_value); @@ -2457,6 +2526,7 @@ longlong Item_func_set_user_var::val_int() String *Item_func_set_user_var::val_str(String *str) { + DBUG_ASSERT(fixed == 1); check(); update(); // Store expression return entry->val_str(&null_value, str, decimals); @@ -2476,6 +2546,7 @@ void Item_func_set_user_var::print(String *str) String * Item_func_get_user_var::val_str(String *str) { + DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_get_user_var::val_str"); if (!var_entry) DBUG_RETURN((String*) 0); // No such variable @@ -2485,6 +2556,7 @@ Item_func_get_user_var::val_str(String *str) double Item_func_get_user_var::val() { + DBUG_ASSERT(fixed == 1); if (!var_entry) return 0.0; // No such variable return (var_entry->val(&null_value)); @@ -2493,6 +2565,7 @@ double Item_func_get_user_var::val() longlong Item_func_get_user_var::val_int() { + DBUG_ASSERT(fixed == 1); if (!var_entry) return LL(0); // No such variable return (var_entry->val_int(&null_value)); @@ -2639,6 +2712,7 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const longlong Item_func_inet_aton::val_int() { + DBUG_ASSERT(fixed == 1); uint byte_result = 0; ulonglong result = 0; // We are ready for 64 bit addresses const char *p,* end; @@ -2706,6 +2780,7 @@ void Item_func_match::init_search(bool no_order) fields.push_back(args[i]); concat=new Item_func_concat_ws(new Item_string(" ",1, cmp_collation.collation), fields); + concat->fix_fields(current_thd, 0, &concat); } if (master) @@ -2748,6 +2823,7 @@ void Item_func_match::init_search(bool no_order) bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { + DBUG_ASSERT(fixed == 0); Item *item; LINT_INIT(item); // Safe as arg_count is > 1 @@ -2892,6 +2968,7 @@ bool Item_func_match::eq(const Item *item, bool binary_cmp) const double Item_func_match::val() { + DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_match::val"); if (ft_handler == NULL) DBUG_RETURN(-1.0); @@ -2934,6 +3011,7 @@ void Item_func_match::print(String *str) longlong Item_func_bit_xor::val_int() { + DBUG_ASSERT(fixed == 1); ulonglong arg1= (ulonglong) args[0]->val_int(); ulonglong arg2= (ulonglong) args[1]->val_int(); if ((null_value= (args[0]->null_value || args[1]->null_value))) @@ -3062,6 +3140,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name, longlong Item_func_is_free_lock::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); THD *thd=current_thd; User_level_lock *ull; @@ -3084,6 +3163,7 @@ longlong Item_func_is_free_lock::val_int() longlong Item_func_is_used_lock::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); THD *thd=current_thd; User_level_lock *ull; diff --git a/sql/item_func.h b/sql/item_func.h index c3fd3a19298..4558c1c6f62 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -155,7 +155,7 @@ public: Item_real_func(Item *a,Item *b) :Item_func(a,b) {} Item_real_func(List<Item> &list) :Item_func(list) {} String *val_str(String*str); - longlong val_int() { return (longlong) val(); } + longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) val(); } enum Item_result result_type () const { return REAL_RESULT; } void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); } }; @@ -169,7 +169,7 @@ public: Item_num_func(Item *a) :Item_func(a),hybrid_type(REAL_RESULT) {} Item_num_func(Item *a,Item *b) :Item_func(a,b),hybrid_type(REAL_RESULT) {} String *val_str(String*str); - longlong val_int() { return (longlong) val(); } + longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) val(); } enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec() { fix_num_length_and_dec(); } bool is_null() { (void) val(); return null_value; } @@ -200,7 +200,7 @@ public: 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) {} - double val() { return (double) val_int(); } + double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() {} @@ -285,7 +285,7 @@ class Item_func_int_div :public Item_num_op public: Item_func_int_div(Item *a,Item *b) :Item_num_op(a,b) { hybrid_type=INT_RESULT; } - double val() { return (double) val_int(); } + double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } longlong val_int(); const char *func_name() const { return "DIV"; } void fix_length_and_dec(); @@ -584,7 +584,8 @@ class Item_func_bit_length :public Item_func_length { public: Item_func_bit_length(Item *a) :Item_func_length(a) {} - longlong val_int() { return Item_func_length::val_int()*8; } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return Item_func_length::val_int()*8; } const char *func_name() const { return "bit_length"; } }; @@ -765,6 +766,7 @@ public: const char *func_name() const { return udf.name(); } bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); bool res= udf.fix_fields(thd, tables, this, arg_count, args); used_tables_cache= udf.used_tables_cache; const_item_cache= udf.const_item_cache; @@ -782,7 +784,8 @@ class Item_func_udf_float :public Item_udf_func Item_func_udf_float(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - longlong val_int() { return (longlong) Item_func_udf_float::val(); } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return (longlong) Item_func_udf_float::val(); } double val(); String *val_str(String *str); void fix_length_and_dec() { fix_num_length_and_dec(); } @@ -833,7 +836,7 @@ class Item_func_udf_float :public Item_real_func public: Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_real_func(list) {} - double val() { return 0.0; } + double val() { DBUG_ASSERT(fixed == 1); return 0.0; } }; @@ -842,7 +845,7 @@ class Item_func_udf_int :public Item_int_func public: Item_func_udf_int(udf_func *udf_arg) :Item_int_func() {} Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_int_func(list) {} - longlong val_int() { return 0; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } }; @@ -851,9 +854,10 @@ class Item_func_udf_str :public Item_func public: Item_func_udf_str(udf_func *udf_arg) :Item_func() {} Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_func(list) {} - String *val_str(String *) { null_value=1; return 0; } - double val() { null_value=1; return 0.0; } - longlong val_int() { null_value=1; return 0; } + String *val_str(String *) + { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } + double val() { 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; } }; @@ -1000,6 +1004,7 @@ public: void cleanup() { DBUG_ENTER("Item_func_match"); + Item_real_func::cleanup(); if (!master && ft_handler) { ft_handler->please->close_search(ft_handler); @@ -1021,7 +1026,7 @@ public: table_map not_null_tables() const { return 0; } bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); bool eq(const Item *, bool binary_cmp) const; - longlong val_int() { return val()!=0.0; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return val()!=0.0; } double val(); void print(String *str); diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 1c9338f5f35..a1305e0b1d9 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -30,6 +30,7 @@ String *Item_func_geometry_from_text::val_str(String *str) { + DBUG_ASSERT(fixed == 1); Geometry_buffer buffer; String arg_val; String *wkt= args[0]->val_str(&arg_val); @@ -61,6 +62,7 @@ void Item_func_geometry_from_text::fix_length_and_dec() String *Item_func_geometry_from_wkb::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String arg_val; String *wkb= args[0]->val_str(&arg_val); Geometry_buffer buffer; @@ -91,6 +93,7 @@ void Item_func_geometry_from_wkb::fix_length_and_dec() String *Item_func_as_wkt::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String arg_val; String *swkb= args[0]->val_str(&arg_val); Geometry_buffer buffer; @@ -119,6 +122,7 @@ void Item_func_as_wkt::fix_length_and_dec() String *Item_func_as_wkb::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String arg_val; String *swkb= args[0]->val_str(&arg_val); Geometry_buffer buffer; @@ -144,6 +148,7 @@ void Item_func_as_wkb::fix_length_and_dec() String *Item_func_geometry_type::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *swkb= args[0]->val_str(str); Geometry_buffer buffer; Geometry *geom= NULL; @@ -163,6 +168,7 @@ String *Item_func_geometry_type::val_str(String *str) String *Item_func_envelope::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String arg_val; String *swkb= args[0]->val_str(&arg_val); Geometry_buffer buffer; @@ -186,6 +192,7 @@ String *Item_func_envelope::val_str(String *str) String *Item_func_centroid::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String arg_val; String *swkb= args[0]->val_str(&arg_val); Geometry_buffer buffer; @@ -213,6 +220,7 @@ String *Item_func_centroid::val_str(String *str) String *Item_func_spatial_decomp::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String arg_val; String *swkb= args[0]->val_str(&arg_val); Geometry_buffer buffer; @@ -259,6 +267,7 @@ err: String *Item_func_spatial_decomp_n::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String arg_val; String *swkb= args[0]->val_str(&arg_val); long n= (long) args[1]->val_int(); @@ -317,6 +326,7 @@ err: String *Item_func_point::val_str(String *str) { + DBUG_ASSERT(fixed == 1); double x= args[0]->val(); double y= args[1]->val(); @@ -346,6 +356,7 @@ String *Item_func_point::val_str(String *str) String *Item_func_spatial_collection::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String arg_value; uint i; @@ -454,6 +465,7 @@ err: longlong Item_func_spatial_rel::val_int() { + DBUG_ASSERT(fixed == 1); String *res1= args[0]->val_str(&tmp_value1); String *res2= args[1]->val_str(&tmp_value2); Geometry_buffer buffer1, buffer2; @@ -500,6 +512,7 @@ longlong Item_func_spatial_rel::val_int() longlong Item_func_isempty::val_int() { + DBUG_ASSERT(fixed == 1); String tmp; null_value=0; return args[0]->null_value ? 1 : 0; @@ -508,6 +521,7 @@ longlong Item_func_isempty::val_int() longlong Item_func_issimple::val_int() { + DBUG_ASSERT(fixed == 1); String tmp; String *wkb=args[0]->val_str(&tmp); @@ -520,6 +534,7 @@ longlong Item_func_issimple::val_int() longlong Item_func_isclosed::val_int() { + DBUG_ASSERT(fixed == 1); String tmp; String *swkb= args[0]->val_str(&tmp); Geometry_buffer buffer; @@ -543,6 +558,7 @@ longlong Item_func_isclosed::val_int() longlong Item_func_dimension::val_int() { + DBUG_ASSERT(fixed == 1); uint32 dim= 0; // In case of error String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; @@ -561,6 +577,7 @@ longlong Item_func_dimension::val_int() longlong Item_func_numinteriorring::val_int() { + DBUG_ASSERT(fixed == 1); uint32 num= 0; // In case of error String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; @@ -577,6 +594,7 @@ longlong Item_func_numinteriorring::val_int() longlong Item_func_numgeometries::val_int() { + DBUG_ASSERT(fixed == 1); uint32 num= 0; // In case of errors String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; @@ -593,6 +611,7 @@ longlong Item_func_numgeometries::val_int() longlong Item_func_numpoints::val_int() { + DBUG_ASSERT(fixed == 1); uint32 num= 0; // In case of errors String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; @@ -610,6 +629,7 @@ longlong Item_func_numpoints::val_int() double Item_func_x::val() { + DBUG_ASSERT(fixed == 1); double res= 0.0; // In case of errors String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; @@ -626,6 +646,7 @@ double Item_func_x::val() double Item_func_y::val() { + DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; @@ -642,6 +663,7 @@ double Item_func_y::val() double Item_func_area::val() { + DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; @@ -658,6 +680,7 @@ double Item_func_area::val() double Item_func_glength::val() { + DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; @@ -673,6 +696,7 @@ double Item_func_glength::val() longlong Item_func_srid::val_int() { + DBUG_ASSERT(fixed == 1); String *swkb= args[0]->val_str(&value); Geometry_buffer buffer; Geometry *geom; diff --git a/sql/item_row.cc b/sql/item_row.cc index 2b0cd38e3c1..c7e4bc0acf4 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -55,6 +55,7 @@ void Item_row::illegal_method_call(const char *method) bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) { + DBUG_ASSERT(fixed == 0); null_value= 0; maybe_null= 0; Item **arg, **arg_end; @@ -78,6 +79,7 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) maybe_null|= item->maybe_null; with_sum_func= with_sum_func || item->with_sum_func; } + fixed= 1; return 0; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 2833e1ca016..008f54ba20f 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -60,6 +60,7 @@ uint nr_of_decimals(const char *str) double Item_str_func::val() { + DBUG_ASSERT(fixed == 1); int err; String *res; res=val_str(&str_value); @@ -69,15 +70,19 @@ double Item_str_func::val() longlong Item_str_func::val_int() { + DBUG_ASSERT(fixed == 1); int err; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,NULL,&err) : (longlong) 0; + return res ? + my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL, &err) : + (longlong) 0; } String *Item_func_md5::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String * sptr= args[0]->val_str(str); if (sptr) { @@ -115,6 +120,7 @@ void Item_func_md5::fix_length_and_dec() String *Item_func_sha::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String * sptr= args[0]->val_str(str); if (sptr) /* If we got value different from NULL */ { @@ -155,6 +161,7 @@ void Item_func_sha::fix_length_and_dec() String *Item_func_aes_encrypt::val_str(String *str) { + DBUG_ASSERT(fixed == 1); char key_buff[80]; String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info); String *sptr= args[0]->val_str(str); // String to encrypt @@ -190,6 +197,7 @@ void Item_func_aes_encrypt::fix_length_and_dec() String *Item_func_aes_decrypt::val_str(String *str) { + DBUG_ASSERT(fixed == 1); char key_buff[80]; String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info); String *sptr, *key; @@ -234,6 +242,7 @@ void Item_func_aes_decrypt::fix_length_and_dec() String *Item_func_concat::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res,*res2,*use_as_buff; uint i; @@ -350,6 +359,7 @@ void Item_func_concat::fix_length_and_dec() String *Item_func_des_encrypt::val_str(String *str) { + DBUG_ASSERT(fixed == 1); #ifdef HAVE_OPENSSL DES_cblock ivec; struct st_des_keyblock keyblock; @@ -432,6 +442,7 @@ error: String *Item_func_des_decrypt::val_str(String *str) { + DBUG_ASSERT(fixed == 1); #ifdef HAVE_OPENSSL DES_key_schedule ks1, ks2, ks3; DES_cblock ivec; @@ -503,6 +514,7 @@ error: String *Item_func_concat_ws::val_str(String *str) { + DBUG_ASSERT(fixed == 1); char tmp_str_buff[10]; String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info), *sep_str, *res, *res2,*use_as_buff; @@ -668,6 +680,7 @@ void Item_func_concat_ws::print(String *str) String *Item_func_reverse::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res = args[0]->val_str(str); char *ptr,*end; @@ -725,6 +738,7 @@ void Item_func_reverse::fix_length_and_dec() String *Item_func_replace::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res,*res2,*res3; int offset; uint from_length,to_length; @@ -845,6 +859,7 @@ void Item_func_replace::fix_length_and_dec() String *Item_func_insert::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res,*res2; uint start,length; @@ -892,6 +907,7 @@ void Item_func_insert::fix_length_and_dec() String *Item_func_lcase::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res; if (!(res=args[0]->val_str(str))) { @@ -907,6 +923,7 @@ String *Item_func_lcase::val_str(String *str) String *Item_func_ucase::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res; if (!(res=args[0]->val_str(str))) { @@ -922,6 +939,7 @@ String *Item_func_ucase::val_str(String *str) String *Item_func_left::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); long length =(long) args[1]->val_int(); @@ -966,6 +984,7 @@ void Item_func_left::fix_length_and_dec() String *Item_func_right::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); long length =(long) args[1]->val_int(); @@ -994,6 +1013,7 @@ void Item_func_right::fix_length_and_dec() String *Item_func_substr::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res = args[0]->val_str(str); int32 start = (int32) args[1]->val_int(); int32 length = arg_count == 3 ? (int32) args[2]->val_int() : INT_MAX32; @@ -1053,6 +1073,7 @@ void Item_func_substr_index::fix_length_and_dec() String *Item_func_substr_index::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); String *delimeter =args[1]->val_str(&tmp_value); int32 count = (int32) args[2]->val_int(); @@ -1164,6 +1185,7 @@ String *Item_func_substr_index::val_str(String *str) String *Item_func_ltrim::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ @@ -1202,6 +1224,7 @@ String *Item_func_ltrim::val_str(String *str) String *Item_func_rtrim::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ @@ -1274,6 +1297,7 @@ String *Item_func_rtrim::val_str(String *str) String *Item_func_trim::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ @@ -1346,6 +1370,7 @@ void Item_func_trim::fix_length_and_dec() String *Item_func_password::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res= args[0]->val_str(str); if ((null_value=args[0]->null_value)) return 0; @@ -1368,6 +1393,7 @@ char *Item_func_password::alloc(THD *thd, const char *password) String *Item_func_old_password::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res= args[0]->val_str(str); if ((null_value=args[0]->null_value)) return 0; @@ -1391,6 +1417,7 @@ char *Item_func_old_password::alloc(THD *thd, const char *password) String *Item_func_encrypt::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); #ifdef HAVE_CRYPT @@ -1435,6 +1462,7 @@ void Item_func_encode::fix_length_and_dec() String *Item_func_encode::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res; if (!(res=args[0]->val_str(str))) { @@ -1450,6 +1478,7 @@ String *Item_func_encode::val_str(String *str) String *Item_func_decode::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res; if (!(res=args[0]->val_str(str))) { @@ -1466,6 +1495,7 @@ String *Item_func_decode::val_str(String *str) String *Item_func_database::val_str(String *str) { + DBUG_ASSERT(fixed == 1); THD *thd= current_thd; if (!thd->db) { @@ -1481,6 +1511,7 @@ String *Item_func_database::val_str(String *str) String *Item_func_user::val_str(String *str) { + DBUG_ASSERT(fixed == 1); THD *thd=current_thd; CHARSET_INFO *cs= system_charset_info; const char *host= thd->host_or_ip; @@ -1531,6 +1562,7 @@ static char get_scode(CHARSET_INFO *cs,char *ptr) String *Item_func_soundex::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); char last_ch,ch; CHARSET_INFO *cs= collation.collation; @@ -1591,6 +1623,7 @@ Item_func_format::Item_func_format(Item *org,int dec) :Item_str_func(org) String *Item_func_format::val_str(String *str) { + DBUG_ASSERT(fixed == 1); double nr =args[0]->val(); uint32 diff,length,str_length; uint dec; @@ -1661,6 +1694,7 @@ void Item_func_elt::fix_length_and_dec() double Item_func_elt::val() { + DBUG_ASSERT(fixed == 1); uint tmp; null_value=1; if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) @@ -1673,6 +1707,7 @@ double Item_func_elt::val() longlong Item_func_elt::val_int() { + DBUG_ASSERT(fixed == 1); uint tmp; null_value=1; if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) @@ -1686,6 +1721,7 @@ longlong Item_func_elt::val_int() String *Item_func_elt::val_str(String *str) { + DBUG_ASSERT(fixed == 1); uint tmp; null_value=1; if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) @@ -1743,6 +1779,7 @@ void Item_func_make_set::update_used_tables() String *Item_func_make_set::val_str(String *str) { + DBUG_ASSERT(fixed == 1); ulonglong bits; bool first_found=0; Item **ptr=args; @@ -1808,6 +1845,7 @@ void Item_func_make_set::print(String *str) String *Item_func_char::val_str(String *str) { + DBUG_ASSERT(fixed == 1); str->length(0); for (uint i=0 ; i < arg_count ; i++) { @@ -1882,6 +1920,7 @@ void Item_func_repeat::fix_length_and_dec() String *Item_func_repeat::val_str(String *str) { + DBUG_ASSERT(fixed == 1); uint length,tot_length; char *to; long count= (long) args[1]->val_int(); @@ -1944,6 +1983,7 @@ void Item_func_rpad::fix_length_and_dec() String *Item_func_rpad::val_str(String *str) { + DBUG_ASSERT(fixed == 1); uint32 res_byte_length,res_char_length,pad_char_length,pad_byte_length; char *to; const char *ptr_pad; @@ -2020,6 +2060,7 @@ void Item_func_lpad::fix_length_and_dec() String *Item_func_lpad::val_str(String *str) { + DBUG_ASSERT(fixed == 1); uint32 res_char_length,pad_char_length; ulong count= (long) args[1]->val_int(), byte_count; String *res= args[0]->val_str(&tmp_value); @@ -2069,6 +2110,7 @@ err: String *Item_func_conv::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res= args[0]->val_str(str); char *endptr,ans[65],*ptr; longlong dec; @@ -2097,6 +2139,7 @@ String *Item_func_conv::val_str(String *str) String *Item_func_conv_charset::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *arg= args[0]->val_str(str); if (!arg) { @@ -2124,6 +2167,7 @@ void Item_func_conv_charset::print(String *str) String *Item_func_set_collation::val_str(String *str) { + DBUG_ASSERT(fixed == 1); str=args[0]->val_str(str); if ((null_value=args[0]->null_value)) return 0; @@ -2183,6 +2227,7 @@ bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const String *Item_func_charset::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res = args[0]->val_str(str); if ((null_value=(args[0]->null_value || !res->charset()))) @@ -2194,6 +2239,7 @@ String *Item_func_charset::val_str(String *str) String *Item_func_collation::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res = args[0]->val_str(str); if ((null_value=(args[0]->null_value || !res->charset()))) @@ -2206,6 +2252,7 @@ String *Item_func_collation::val_str(String *str) String *Item_func_hex::val_str(String *str) { + DBUG_ASSERT(fixed == 1); if (args[0]->result_type() != STRING_RESULT) { /* Return hex of unsigned longlong value */ @@ -2253,6 +2300,7 @@ inline int hexchar_to_int(char c) String *Item_func_unhex::val_str(String *str) { + DBUG_ASSERT(fixed == 1); /* Convert given hex string to a binary string */ String *res= args[0]->val_str(str); const char *from=res->ptr(), *end; @@ -2296,6 +2344,7 @@ void Item_func_binary::print(String *str) String *Item_load_file::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *file_name; File file; MY_STAT stat_info; @@ -2339,6 +2388,7 @@ err: String* Item_func_export_set::val_str(String* str) { + DBUG_ASSERT(fixed == 1); ulonglong the_set = (ulonglong) args[0]->val_int(); String yes_buf, *yes; yes = args[1]->val_str(&yes_buf); @@ -2408,6 +2458,7 @@ void Item_func_export_set::fix_length_and_dec() String* Item_func_inet_ntoa::val_str(String* str) { + DBUG_ASSERT(fixed == 1); uchar buf[8], *p; ulonglong n = (ulonglong) args[0]->val_int(); char num[4]; @@ -2467,6 +2518,7 @@ String* Item_func_inet_ntoa::val_str(String* str) String *Item_func_quote::val_str(String *str) { + DBUG_ASSERT(fixed == 1); /* Bit mask that has 1 for set for the position of the following characters: 0, \, ' and ^Z @@ -2541,6 +2593,7 @@ null: longlong Item_func_uncompressed_length::val_int() { + DBUG_ASSERT(fixed == 1); String *res= args[0]->val_str(&value); if (!res) { @@ -2562,6 +2615,7 @@ longlong Item_func_uncompressed_length::val_int() longlong Item_func_crc32::val_int() { + DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); if (!res) { @@ -2577,6 +2631,7 @@ longlong Item_func_crc32::val_int() String *Item_func_compress::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res= args[0]->val_str(str); if (!res) { @@ -2634,6 +2689,7 @@ String *Item_func_compress::val_str(String *str) String *Item_func_uncompress::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res= args[0]->val_str(str); ulong new_size; int err; @@ -2715,6 +2771,7 @@ static void set_clock_seq_str() String *Item_func_uuid::val_str(String *str) { + DBUG_ASSERT(fixed == 1); char *s; pthread_mutex_lock(&LOCK_uuid_generator); if (! uuid_time) /* first UUID() call. initializing data */ diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 5b9c442b5db..22134733393 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -100,6 +100,7 @@ public: void update_used_tables(); bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { + DBUG_ASSERT(fixed == 0); return (separator->fix_fields(thd, tlist, &separator) || separator->check_cols(1) || Item_func::fix_fields(thd, tlist, ref)); @@ -411,6 +412,7 @@ public: String *val_str(String *str); bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { + DBUG_ASSERT(fixed == 0); return (item->fix_fields(thd, tlist, &item) || item->check_cols(1) || Item_func::fix_fields(thd, tlist, ref)); @@ -545,6 +547,7 @@ public: Item_func_binary(Item *a) :Item_str_func(a) {} String *val_str(String *a) { + DBUG_ASSERT(fixed == 1); String *tmp=args[0]->val_str(a); null_value=args[0]->null_value; if (tmp) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index deb1ebabef9..b0f5e3ba9d4 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -102,6 +102,7 @@ Item_subselect::select_transformer(JOIN *join) bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); engine->set_thd((thd= thd_param)); stmt= thd->current_statement; @@ -125,8 +126,10 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) engine->exclude(); substitution= 0; fixed= 1; - thd->where= "checking transformed subquery"; - int ret= (*ref)->fix_fields(thd, tables, ref); + thd->where= "checking transformed subquery"; + int ret= 0; + if (!(*ref)->fixed) + ret= (*ref)->fix_fields(thd, tables, ref); // We can't substitute aggregate functions (like (SELECT (max(i))) if ((*ref)->with_sum_func) { @@ -201,7 +204,7 @@ bool Item_subselect::const_item() const Item *Item_subselect::get_tmp_table_item(THD *thd) { if (!with_sum_func && !const_item()) - return new Item_field(result_field); + return new Item_field(result_field, 1); return copy_or_same(thd); } @@ -396,6 +399,7 @@ void Item_singlerow_subselect::bring_value() double Item_singlerow_subselect::val() { + DBUG_ASSERT(fixed == 1); if (!exec() && !value->null_value) { null_value= 0; @@ -410,6 +414,7 @@ double Item_singlerow_subselect::val() longlong Item_singlerow_subselect::val_int() { + DBUG_ASSERT(fixed == 1); if (!exec() && !value->null_value) { null_value= 0; @@ -518,6 +523,7 @@ void Item_exists_subselect::fix_length_and_dec() double Item_exists_subselect::val() { + DBUG_ASSERT(fixed == 1); if (exec()) { reset(); @@ -528,6 +534,7 @@ double Item_exists_subselect::val() longlong Item_exists_subselect::val_int() { + DBUG_ASSERT(fixed == 1); if (exec()) { reset(); @@ -538,6 +545,7 @@ longlong Item_exists_subselect::val_int() String *Item_exists_subselect::val_str(String *str) { + DBUG_ASSERT(fixed == 1); if (exec()) { reset(); @@ -549,6 +557,7 @@ String *Item_exists_subselect::val_str(String *str) double Item_in_subselect::val() { + DBUG_ASSERT(fixed == 1); if (exec()) { reset(); @@ -562,6 +571,7 @@ double Item_in_subselect::val() longlong Item_in_subselect::val_int() { + DBUG_ASSERT(fixed == 1); if (exec()) { reset(); @@ -575,6 +585,7 @@ longlong Item_in_subselect::val_int() String *Item_in_subselect::val_str(String *str) { + DBUG_ASSERT(fixed == 1); if (exec()) { reset(); @@ -651,9 +662,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, select_lex->item_list.empty(); select_lex->item_list.push_back(item); - if (item->fix_fields(thd, join->tables_list, - select_lex->item_list.head_ref())) - goto err; + // fix_fields call for 'item' will be made during new subquery fix_fields subs= new Item_singlerow_subselect(select_lex); } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 77a910ae5d6..a8afbbb165e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -113,7 +113,7 @@ Item *Item_sum::get_tmp_table_item(THD *thd) if (arg->type() == Item::FIELD_ITEM) ((Item_field*) arg)->field= result_field_tmp++; else - sum_item->args[i]= new Item_field(result_field_tmp++); + sum_item->args[i]= new Item_field(result_field_tmp++, 1); } } } @@ -137,6 +137,7 @@ bool Item_sum::walk (Item_processor processor, byte *argument) String * Item_sum_num::val_str(String *str) { + DBUG_ASSERT(fixed == 1); double nr=val(); if (null_value) return 0; @@ -148,6 +149,7 @@ Item_sum_num::val_str(String *str) String * Item_sum_int::val_str(String *str) { + DBUG_ASSERT(fixed == 1); longlong nr= val_int(); if (null_value) return 0; @@ -162,6 +164,7 @@ Item_sum_int::val_str(String *str) bool Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); if (!thd->allow_sum_func) { my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); @@ -191,6 +194,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) bool Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); Item *item= args[0]; if (!thd->allow_sum_func) { @@ -265,6 +269,7 @@ bool Item_sum_sum::add() double Item_sum_sum::val() { + DBUG_ASSERT(fixed == 1); return sum; } @@ -296,6 +301,7 @@ bool Item_sum_count::add() longlong Item_sum_count::val_int() { + DBUG_ASSERT(fixed == 1); return (longlong) count; } @@ -328,6 +334,7 @@ bool Item_sum_avg::add() double Item_sum_avg::val() { + DBUG_ASSERT(fixed == 1); if (!count) { null_value=1; @@ -344,6 +351,7 @@ double Item_sum_avg::val() double Item_sum_std::val() { + DBUG_ASSERT(fixed == 1); double tmp= Item_sum_variance::val(); return tmp <= 0.0 ? 0.0 : sqrt(tmp); } @@ -384,6 +392,7 @@ bool Item_sum_variance::add() double Item_sum_variance::val() { + DBUG_ASSERT(fixed == 1); if (!count) { null_value=1; @@ -439,6 +448,7 @@ void Item_sum_variance::update_field() double Item_sum_hybrid::val() { + DBUG_ASSERT(fixed == 1); int err; if (null_value) return 0.0; @@ -464,6 +474,7 @@ double Item_sum_hybrid::val() longlong Item_sum_hybrid::val_int() { + DBUG_ASSERT(fixed == 1); if (null_value) return 0; if (hybrid_type == INT_RESULT) @@ -475,6 +486,7 @@ longlong Item_sum_hybrid::val_int() String * Item_sum_hybrid::val_str(String *str) { + DBUG_ASSERT(fixed == 1); if (null_value) return 0; switch (hybrid_type) { @@ -609,6 +621,7 @@ bool Item_sum_max::add() longlong Item_sum_bit::val_int() { + DBUG_ASSERT(fixed == 1); return (longlong) bits; } @@ -942,6 +955,7 @@ Item_avg_field::Item_avg_field(Item_sum_avg *item) double Item_avg_field::val() { + // fix_fields() never calls for this Item double nr; longlong count; float8get(nr,field->ptr); @@ -959,6 +973,7 @@ double Item_avg_field::val() String *Item_avg_field::val_str(String *str) { + // fix_fields() never calls for this Item double nr=Item_avg_field::val(); if (null_value) return 0; @@ -973,6 +988,7 @@ Item_std_field::Item_std_field(Item_sum_std *item) double Item_std_field::val() { + // fix_fields() never calls for this Item double tmp= Item_variance_field::val(); return tmp <= 0.0 ? 0.0 : sqrt(tmp); } @@ -988,6 +1004,7 @@ Item_variance_field::Item_variance_field(Item_sum_variance *item) double Item_variance_field::val() { + // fix_fields() never calls for this Item double sum,sum_sqr; longlong count; float8get(sum,field->ptr); @@ -1007,6 +1024,7 @@ double Item_variance_field::val() String *Item_variance_field::val_str(String *str) { + // fix_fields() never calls for this Item double nr=val(); if (null_value) return 0; @@ -1116,6 +1134,7 @@ void Item_sum_count_distinct::cleanup() bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); if (Item_sum_num::fix_fields(thd, tables, ref)) return 1; return 0; @@ -1353,6 +1372,7 @@ bool Item_sum_count_distinct::add() longlong Item_sum_count_distinct::val_int() { + DBUG_ASSERT(fixed == 1); if (!table) // Empty query return LL(0); if (use_tree) @@ -1399,6 +1419,7 @@ Item *Item_sum_udf_float::copy_or_same(THD* thd) double Item_sum_udf_float::val() { + DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_sum_udf_float::val"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); @@ -1407,6 +1428,7 @@ double Item_sum_udf_float::val() String *Item_sum_udf_float::val_str(String *str) { + DBUG_ASSERT(fixed == 1); double nr=val(); if (null_value) return 0; /* purecov: inspected */ @@ -1423,6 +1445,7 @@ Item *Item_sum_udf_int::copy_or_same(THD* thd) longlong Item_sum_udf_int::val_int() { + DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_sum_udf_int::val_int"); DBUG_PRINT("info",("result_type: %d arg_count: %d", args[0]->result_type(), arg_count)); @@ -1432,6 +1455,7 @@ longlong Item_sum_udf_int::val_int() String *Item_sum_udf_int::val_str(String *str) { + DBUG_ASSERT(fixed == 1); longlong nr=val_int(); if (null_value) return 0; @@ -1459,6 +1483,7 @@ Item *Item_sum_udf_str::copy_or_same(THD* thd) String *Item_sum_udf_str::val_str(String *str) { + DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_sum_udf_str::str"); String *res=udf.val_str(str,&str_value); null_value = !res; @@ -1679,6 +1704,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, void Item_func_group_concat::cleanup() { DBUG_ENTER("Item_func_group_concat::cleanup"); + Item_sum::cleanup(); /* Free table and tree if they belong to this item (if item have not pointer to original item from which was made copy => it own its objects ) @@ -1794,6 +1820,7 @@ void Item_func_group_concat::reset_field() bool Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); uint i; /* for loop variable */ if (!thd->allow_sum_func) @@ -1961,6 +1988,7 @@ void Item_func_group_concat::make_unique() String* Item_func_group_concat::val_str(String* str) { + DBUG_ASSERT(fixed == 1); if (null_value) return 0; if (tree_mode) diff --git a/sql/item_sum.h b/sql/item_sum.h index 11c95100db5..397d853aa78 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -88,7 +88,7 @@ public: virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } virtual const char *func_name() const { return "?"; } virtual Item *result_item(Field *field) - { return new Item_field(field);} + { return new Item_field(field, 1);} table_map used_tables() const { return ~(table_map) 0; } /* Not used */ bool const_item() const { return 0; } bool is_null() { return null_value; } @@ -114,7 +114,8 @@ public: Item_sum_num(List<Item> &list) :Item_sum(list) {} Item_sum_num(THD *thd, Item_sum_num *item) :Item_sum(thd, item) {} bool fix_fields(THD *, TABLE_LIST *, Item **); - longlong val_int() { return (longlong) val(); } /* Real as default */ + longlong val_int() + { DBUG_ASSERT(fixed == 1); return (longlong) val(); } /* Real as default */ String *val_str(String*str); void reset_field(); }; @@ -126,7 +127,7 @@ public: Item_sum_int(Item *item_par) :Item_sum_num(item_par) {} Item_sum_int(List<Item> &list) :Item_sum_num(list) {} Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {} - double val() { return (double) val_int(); } + double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() @@ -270,7 +271,7 @@ public: Item_avg_field(Item_sum_avg *item); enum Type type() const { return FIELD_AVG_ITEM; } double val(); - longlong val_int() { return (longlong) val(); } + longlong val_int() { /* can't be fix_fields()ed */ return (longlong) val(); } bool is_null() { (void) val_int(); return null_value; } String *val_str(String*); enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } @@ -310,7 +311,7 @@ public: Item_variance_field(Item_sum_variance *item); enum Type type() const {return FIELD_VARIANCE_ITEM; } double val(); - longlong val_int() { return (longlong) val(); } + longlong val_int() { /* can't be fix_fields()ed */ return (longlong) val(); } String *val_str(String*); bool is_null() { (void) val_int(); return null_value; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } @@ -533,6 +534,7 @@ public: const char *func_name() const { return udf.name(); } bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + DBUG_ASSERT(fixed == 0); fixed= 1; return udf.fix_fields(thd,tables,this,this->arg_count,this->args); } @@ -554,7 +556,8 @@ class Item_sum_udf_float :public Item_udf_sum :Item_udf_sum(udf_arg,list) {} Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) :Item_udf_sum(thd, item) {} - longlong val_int() { return (longlong) Item_sum_udf_float::val(); } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return (longlong) Item_sum_udf_float::val(); } double val(); String *val_str(String*str); void fix_length_and_dec() { fix_num_length_and_dec(); } @@ -571,7 +574,8 @@ public: Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) :Item_udf_sum(thd, item) {} longlong val_int(); - double val() { return (double) Item_sum_udf_int::val_int(); } + double val() + { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() { decimals=0; max_length=21; } @@ -616,7 +620,7 @@ class Item_sum_udf_float :public Item_sum_num Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) :Item_sum_num(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } - double val() { return 0.0; } + double val() { DBUG_ASSERT(fixed == 1); return 0.0; } void clear() {} bool add() { return 0; } void update_field() {} @@ -631,8 +635,8 @@ public: Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) :Item_sum_num(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } - longlong val_int() { return 0; } - double val() { return 0; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } + double val() { DBUG_ASSERT(fixed == 1); return 0; } void clear() {} bool add() { return 0; } void update_field() {} @@ -646,9 +650,10 @@ public: Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) :Item_sum_num(thd, item) {} - String *val_str(String *) { null_value=1; return 0; } - double val() { null_value=1; return 0.0; } - longlong val_int() { null_value=1; return 0; } + String *val_str(String *) + { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } + double val() { 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; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index d0674411fcf..1ac04cd9ff0 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -672,6 +672,7 @@ bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, longlong Item_func_period_add::val_int() { + DBUG_ASSERT(fixed == 1); ulong period=(ulong) args[0]->val_int(); int months=(int) args[1]->val_int(); @@ -686,6 +687,7 @@ longlong Item_func_period_add::val_int() longlong Item_func_period_diff::val_int() { + DBUG_ASSERT(fixed == 1); ulong period1=(ulong) args[0]->val_int(); ulong period2=(ulong) args[1]->val_int(); @@ -699,6 +701,7 @@ longlong Item_func_period_diff::val_int() longlong Item_func_to_days::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; if (get_arg0_date(<ime,0)) return 0; @@ -707,6 +710,7 @@ longlong Item_func_to_days::val_int() longlong Item_func_dayofyear::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; if (get_arg0_date(<ime,0)) return 0; @@ -716,6 +720,7 @@ longlong Item_func_dayofyear::val_int() longlong Item_func_dayofmonth::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; (void) get_arg0_date(<ime,1); return (longlong) ltime.day; @@ -723,6 +728,7 @@ longlong Item_func_dayofmonth::val_int() longlong Item_func_month::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; (void) get_arg0_date(<ime,1); return (longlong) ltime.month; @@ -731,6 +737,7 @@ longlong Item_func_month::val_int() String* Item_func_monthname::val_str(String* str) { + DBUG_ASSERT(fixed == 1); const char *month_name; uint month=(uint) Item_func_month::val_int(); @@ -750,6 +757,7 @@ String* Item_func_monthname::val_str(String* str) longlong Item_func_quarter::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; (void) get_arg0_date(<ime,1); return (longlong) ((ltime.month+2)/3); @@ -757,6 +765,7 @@ longlong Item_func_quarter::val_int() longlong Item_func_hour::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; (void) get_arg0_time(<ime); return ltime.hour; @@ -764,6 +773,7 @@ longlong Item_func_hour::val_int() longlong Item_func_minute::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; (void) get_arg0_time(<ime); return ltime.minute; @@ -772,6 +782,7 @@ longlong Item_func_minute::val_int() longlong Item_func_second::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; (void) get_arg0_time(<ime); return ltime.second; @@ -817,6 +828,7 @@ uint week_mode(uint mode) longlong Item_func_week::val_int() { + DBUG_ASSERT(fixed == 1); uint year; TIME ltime; if (get_arg0_date(<ime,0)) @@ -829,6 +841,7 @@ longlong Item_func_week::val_int() longlong Item_func_yearweek::val_int() { + DBUG_ASSERT(fixed == 1); uint year,week; TIME ltime; if (get_arg0_date(<ime,0)) @@ -844,6 +857,7 @@ longlong Item_func_yearweek::val_int() longlong Item_func_weekday::val_int() { + DBUG_ASSERT(fixed == 1); ulong tmp_value=(ulong) args[0]->val_int(); if ((null_value=(args[0]->null_value || !tmp_value))) return 0; /* purecov: inspected */ @@ -854,6 +868,7 @@ longlong Item_func_weekday::val_int() String* Item_func_dayname::val_str(String* str) { + DBUG_ASSERT(fixed == 1); uint weekday=(uint) val_int(); // Always Item_func_daynr() const char *name; @@ -868,6 +883,7 @@ String* Item_func_dayname::val_str(String* str) longlong Item_func_year::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; (void) get_arg0_date(<ime,1); return (longlong) ltime.year; @@ -876,6 +892,7 @@ longlong Item_func_year::val_int() longlong Item_func_unix_timestamp::val_int() { + DBUG_ASSERT(fixed == 1); if (arg_count == 0) return (longlong) current_thd->query_start(); if (args[0]->type() == FIELD_ITEM) @@ -895,6 +912,7 @@ longlong Item_func_unix_timestamp::val_int() longlong Item_func_time_to_sec::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; longlong seconds; (void) get_arg0_time(<ime); @@ -1056,6 +1074,7 @@ static bool get_interval_value(Item *args,interval_type int_type, String *Item_date::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME ltime; if (get_date(<ime, TIME_FUZZY_DATE)) return (String *) 0; @@ -1082,6 +1101,7 @@ int Item_date::save_in_field(Field *field, bool no_conversions) longlong Item_date::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; if (get_date(<ime, TIME_FUZZY_DATE)) return 0; @@ -1127,6 +1147,7 @@ void Item_func_curdate::fix_length_and_dec() String *Item_func_curdate::val_str(String *str) { + DBUG_ASSERT(fixed == 1); if (str->alloc(11)) { null_value= 1; @@ -1165,7 +1186,8 @@ void Item_func_curdate_utc::store_now_in_tm(time_t now, struct tm *now_tm) String *Item_func_curtime::val_str(String *str) -{ +{ + DBUG_ASSERT(fixed == 1); str_value.set(buff, buff_length, &my_charset_bin); return &str_value; } @@ -1215,6 +1237,7 @@ void Item_func_curtime_utc::store_now_in_tm(time_t now, struct tm *now_tm) String *Item_func_now::val_str(String *str) { + DBUG_ASSERT(fixed == 1); str_value.set(buff,buff_length, &my_charset_bin); return &str_value; } @@ -1290,6 +1313,7 @@ void Item_func_now_utc::store_now_in_tm(time_t now, struct tm *now_tm) String *Item_func_sec_to_time::val_str(String *str) { + DBUG_ASSERT(fixed == 1); longlong seconds=(longlong) args[0]->val_int(); uint sec; TIME ltime; @@ -1320,6 +1344,7 @@ String *Item_func_sec_to_time::val_str(String *str) longlong Item_func_sec_to_time::val_int() { + DBUG_ASSERT(fixed == 1); longlong seconds=args[0]->val_int(); longlong sign=1; if ((null_value=args[0]->null_value)) @@ -1428,6 +1453,7 @@ uint Item_func_date_format::format_length(const String *format) String *Item_func_date_format::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *format; TIME l_time; uint size; @@ -1477,6 +1503,7 @@ null_date: String *Item_func_from_unixtime::val_str(String *str) { + DBUG_ASSERT(fixed == 1); struct tm tm_tmp,*start; time_t tmp=(time_t) args[0]->val_int(); TIME ltime; @@ -1509,6 +1536,7 @@ null_date: longlong Item_func_from_unixtime::val_int() { + DBUG_ASSERT(fixed == 1); time_t tmp=(time_t) (ulong) args[0]->val_int(); if ((null_value=args[0]->null_value)) return 0; @@ -1685,6 +1713,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date) String *Item_date_add_interval::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME ltime; enum date_time_format_types format; @@ -1708,6 +1737,7 @@ String *Item_date_add_interval::val_str(String *str) longlong Item_date_add_interval::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; longlong date; if (Item_date_add_interval::get_date(<ime,0)) @@ -1777,6 +1807,7 @@ void Item_extract::fix_length_and_dec() longlong Item_extract::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; long neg; if (date_value) @@ -1888,6 +1919,7 @@ void Item_char_typecast::print(String *str) String *Item_char_typecast::val_str(String *str) { + DBUG_ASSERT(fixed == 1); String *res, *res1; uint32 length; @@ -1944,6 +1976,7 @@ void Item_char_typecast::fix_length_and_dec() String *Item_datetime_typecast::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME ltime; if (!get_arg0_date(<ime,1) && !make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME, @@ -1965,6 +1998,7 @@ bool Item_time_typecast::get_time(TIME *ltime) String *Item_time_typecast::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME ltime; if (!get_arg0_time(<ime) && @@ -1987,6 +2021,7 @@ bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date) String *Item_date_typecast::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME ltime; if (!get_arg0_date(<ime,1) && !str->alloc(11)) @@ -2007,6 +2042,7 @@ String *Item_date_typecast::val_str(String *str) String *Item_func_makedate::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME l_time; long daynr= (long) args[1]->val_int(); long yearnr= (long) args[0]->val_int(); @@ -2072,6 +2108,7 @@ void Item_func_add_time::fix_length_and_dec() String *Item_func_add_time::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME l_time1, l_time2, l_time3; bool is_time= 0; long microseconds, seconds, days= 0; @@ -2193,6 +2230,7 @@ void Item_func_add_time::print(String *str) String *Item_func_timediff::val_str(String *str) { + DBUG_ASSERT(fixed == 1); longlong seconds; long microseconds; long days; @@ -2263,6 +2301,7 @@ null_date: String *Item_func_maketime::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME ltime; long hour= (long) args[0]->val_int(); @@ -2301,6 +2340,7 @@ String *Item_func_maketime::val_str(String *str) longlong Item_func_microsecond::val_int() { + DBUG_ASSERT(fixed == 1); TIME ltime; if (!get_arg0_time(<ime)) return ltime.second_part; @@ -2310,6 +2350,7 @@ longlong Item_func_microsecond::val_int() String *Item_func_get_format::val_str(String *str) { + DBUG_ASSERT(fixed == 1); const char *format_name; KNOWN_DATE_TIME_FORMAT *format; String *val= args[0]->val_str(str); @@ -2499,6 +2540,7 @@ null_date: String *Item_func_str_to_date::val_str(String *str) { + DBUG_ASSERT(fixed == 1); TIME ltime; if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE)) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 1b044b49fb1..bfe7795500e 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -88,7 +88,8 @@ class Item_func_month :public Item_func public: Item_func_month(Item *a) :Item_func(a) {} longlong val_int(); - double val() { return (double) Item_func_month::val_int(); } + double val() + { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); } String *val_str(String *str) { str->set(val_int(), &my_charset_bin); @@ -249,9 +250,10 @@ public: Item_func_weekday(Item *a,bool type_arg) :Item_func(a), odbc_type(type_arg) {} longlong val_int(); - double val() { return (double) val_int(); } + double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String *str) - { + { + DBUG_ASSERT(fixed == 1); str->set(val_int(), &my_charset_bin); return null_value ? 0 : str; } @@ -324,7 +326,7 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_DATE; } String *val_str(String *str); longlong val_int(); - double val() { return (double) val_int(); } + double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } const char *func_name() const { return "date"; } void fix_length_and_dec() { @@ -366,8 +368,8 @@ public: Item_func_curtime(Item *a) :Item_func(a) {} enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } - double val() { return (double) value; } - longlong val_int() { return value; } + double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } String *val_str(String *str); void fix_length_and_dec(); Field *tmp_table_field(TABLE *t_arg) @@ -412,7 +414,7 @@ class Item_func_curdate :public Item_date public: Item_func_curdate() :Item_date() {} void set_result_from_tm(struct tm *now); - longlong val_int() { return (value) ; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return (value) ; } String *val_str(String *str); void fix_length_and_dec(); bool get_date(TIME *res, uint fuzzy_date); @@ -450,8 +452,8 @@ public: Item_func_now() :Item_date_func() {} Item_func_now(Item *a) :Item_date_func(a) {} enum Item_result result_type () const { return STRING_RESULT; } - double val() { return (double) value; } - longlong val_int() { return value; } + double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } int save_in_field(Field *to, bool no_conversions); String *val_str(String *str); void fix_length_and_dec(); @@ -508,7 +510,11 @@ class Item_func_from_unixtime :public Item_date_func { public: Item_func_from_unixtime(Item *a) :Item_date_func(a) {} - double val() { return (double) Item_func_from_unixtime::val_int(); } + double val() + { + DBUG_ASSERT(fixed == 1); + return (double) Item_func_from_unixtime::val_int(); + } longlong val_int(); String *val_str(String *str); const char *func_name() const { return "from_unixtime"; } @@ -526,7 +532,11 @@ class Item_func_sec_to_time :public Item_str_func { public: Item_func_sec_to_time(Item *item) :Item_str_func(item) {} - double val() { return (double) Item_func_sec_to_time::val_int(); } + double val() + { + DBUG_ASSERT(fixed == 1); + return (double) Item_func_sec_to_time::val_int(); + } longlong val_int(); String *val_str(String *); void fix_length_and_dec() @@ -572,7 +582,7 @@ public: const char *func_name() const { return "date_add_interval"; } void fix_length_and_dec(); enum_field_types field_type() const { return cached_field_type; } - double val() { return (double) val_int(); } + double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } longlong val_int(); bool get_date(TIME *res, uint fuzzy_date); void print(String *str); @@ -601,6 +611,7 @@ public: Item_typecast(Item *a) :Item_str_func(a) {} String *val_str(String *a) { + DBUG_ASSERT(fixed == 1); String *tmp=args[0]->val_str(a); null_value=args[0]->null_value; if (tmp) diff --git a/sql/item_uniq.h b/sql/item_uniq.h index 47f967b52c6..5582537bdbb 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -27,7 +27,7 @@ class Item_func_unique_users :public Item_real_func public: Item_func_unique_users(Item *name_arg,int start,int end,List<Item> &list) :Item_real_func(list) {} - double val() { return 0.0; } + double val() { DBUG_ASSERT(fixed == 1); return 0.0; } void fix_length_and_dec() { decimals=0; max_length=6; } void print(String *str) { str->append("0.0", 3); } }; @@ -40,7 +40,7 @@ public: :Item_sum_num(item_arg) {} Item_sum_unique_users(THD *thd, Item_sum_unique_users *item) :Item_sum_num(thd, item) {} - double val() { return 0.0; } + double val() { DBUG_ASSERT(fixed == 1); return 0.0; } enum Sumfunctype sum_func () const {return UNIQUE_USERS_FUNC;} void clear() {} bool add() { return 0; } @@ -48,6 +48,7 @@ public: void update_field() {} bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { + DBUG_ASSERT(fixed == 0); fixed= 1; return 0; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1766063c5ec..22249f93320 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2154,7 +2154,7 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, Item **ref= ref_pointer_array; while ((item= it++)) { - if (item->fix_fields(thd, tables, it.ref()) || + if (!item->fixed && item->fix_fields(thd, tables, it.ref()) || (item= *(it.ref()))->check_cols(1)) DBUG_RETURN(-1); /* purecov: inspected */ if (ref) @@ -2293,7 +2293,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, thd->used_tables|=table->map; while ((field = *ptr++)) { - Item_field *item= new Item_field(field); + Item_field *item= new Item_field(field, 0); if (!found++) (void) it->replace(item); // Replace '*' else @@ -2336,7 +2336,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) if (*conds) { thd->where="where clause"; - if ((*conds)->fix_fields(thd, tables, conds) || (*conds)->check_cols(1)) + if (!(*conds)->fixed && (*conds)->fix_fields(thd, tables, conds) || + (*conds)->check_cols(1)) DBUG_RETURN(1); not_null_tables= (*conds)->not_null_tables(); } @@ -2348,7 +2349,9 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) { /* Make a join an a expression */ thd->where="on clause"; - if (table->on_expr->fix_fields(thd, tables, &table->on_expr) || + + if (!table->on_expr->fixed && + table->on_expr->fix_fields(thd, tables, &table->on_expr) || table->on_expr->check_cols(1)) DBUG_RETURN(1); thd->lex->current_select->cond_count++; @@ -2387,12 +2390,12 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) t1->field[i]->field_name, t2->field[j]->field_name)) { - Item_func_eq *tmp=new Item_func_eq(new Item_field(t1->field[i]), - new Item_field(t2->field[j])); + // fix_fields() call will be made for tmp by cond_and->fix_fields + Item_func_eq *tmp=new Item_func_eq(new Item_field(t1->field[i], 1), + new Item_field(t2->field[j], + 1)); if (!tmp) DBUG_RETURN(1); - tmp->fix_length_and_dec(); // Update cmp_type - tmp->const_item_cache=0; /* Mark field used for table cache */ t1->field[i]->query_id=t2->field[j]->query_id=thd->query_id; cond_and->list.push_back(tmp); @@ -2402,8 +2405,11 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) } } } - cond_and->used_tables_cache= t1->map | t2->map; + //cond_and->used_tables_cache= t1->map | t2->map; thd->lex->current_select->cond_count+= cond_and->list.elements; + if (cond_and->fix_fields(thd, tables, (Item**)&cond_and) || + cond_and->check_cols(1)) + DBUG_RETURN(1); if (!table->outer_join) // Not left join { if (!(*conds=and_conds(*conds, cond_and))) diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 0e04316a2e7..4bfb8cdfe3c 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -151,7 +151,11 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, if (is_union) - res= mysql_union(thd, lex, derived_result, unit); + { + // execute union without clean up + if (!(res= unit->prepare(thd, derived_result, SELECT_NO_UNLOCK))) + res= unit->exec(); + } else { unit->offset_limit_cnt= first_select->offset_limit; diff --git a/sql/sql_help.cc b/sql/sql_help.cc index e12dde68266..f3d5775133c 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -624,7 +624,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen, TABLE_LIST *tables, TABLE *table, Field *pfname, int *error) { - Item *cond= new Item_func_like(new Item_field(pfname), + Item *cond= new Item_func_like(new Item_field(pfname, 1), new Item_string(mask,mlen,pfname->charset()), (char*) "\\"); if (thd->is_fatal_error) @@ -743,15 +743,18 @@ int mysqld_help(THD *thd, const char *mask) else { Field *topic_cat_id= used_fields[help_topic_help_category_id].field; - Item *cond_topic_by_cat= new Item_func_equal(new Item_field(topic_cat_id), - new Item_int((int32)category_id)); - Item *cond_cat_by_cat= new Item_func_equal(new Item_field(cat_cat_id), - new Item_int((int32)category_id)); + Item *cond_topic_by_cat= + new Item_func_equal(new Item_field(topic_cat_id, 1), + new Item_int((int32)category_id)); + Item *cond_cat_by_cat= + new Item_func_equal(new Item_field(cat_cat_id, 1), + new Item_int((int32)category_id)); if (!(select_topics_by_cat= prepare_simple_select(thd,cond_topic_by_cat, tables,tables[0].table, &error)) || - !(select_cat_by_cat= prepare_simple_select(thd,cond_cat_by_cat,tables, - tables[1].table,&error))) + !(select_cat_by_cat= + prepare_simple_select(thd,cond_cat_by_cat,tables, + tables[1].table,&error))) { res= -1; goto end; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 58a9b9c588d..1ae93f2b1a0 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -122,7 +122,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { Field **field; for (field=table->field; *field ; field++) - fields.push_back(new Item_field(*field)); + fields.push_back(new Item_field(*field, 1)); } else { // Part field list diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7e6d0ca2434..a33f15a1177 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4031,6 +4031,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (default_value) { + if (default_value->fix_fields(thd, 0, &default_value)) + { + DBUG_RETURN(1); + } /* We allow specifying value for first TIMESTAMP column altough it is silently ignored. This should be fixed in 4.1 diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 769e2646a19..171421c1796 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -70,8 +70,10 @@ static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables, uint select_options, const char *info, Item *having, Procedure *proc, SELECT_LEX_UNIT *unit); -static COND *optimize_cond(COND *conds,Item::cond_result *cond_value); -static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value); +static COND *optimize_cond(THD *thd, COND *conds, + Item::cond_result *cond_value); +static COND *remove_eq_conds(THD *thd, COND *cond, + Item::cond_result *cond_value); static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); static bool open_tmp_table(TABLE *table); static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, @@ -286,6 +288,10 @@ JOIN::prepare(Item ***rref_pointer_array, { DBUG_ENTER("JOIN::prepare"); + // to prevent double initialization on EXPLAIN + if (optimized) + DBUG_RETURN(0); + conds= conds_init; order= order_init; group_list= group_init; @@ -315,8 +321,9 @@ JOIN::prepare(Item ***rref_pointer_array, thd->where="having clause"; thd->allow_sum_func=1; select_lex->having_fix_field= 1; - bool having_fix_rc= (having->fix_fields(thd, tables_list, &having) || - having->check_cols(1)); + bool having_fix_rc= !having->fixed && + (having->fix_fields(thd, tables_list, &having) || + having->check_cols(1)); select_lex->having_fix_field= 0; if (having_fix_rc || thd->net.report_error) DBUG_RETURN(-1); /* purecov: inspected */ @@ -518,7 +525,7 @@ JOIN::optimize() } #endif - conds= optimize_cond(conds,&cond_value); + conds= optimize_cond(thd, conds,&cond_value); if (thd->net.report_error) { error= 1; @@ -1421,9 +1428,14 @@ JOIN::exec() if (!curr_table->select->cond) curr_table->select->cond= sort_table_cond; else // This should never happen + { if (!(curr_table->select->cond= - new Item_cond_and(curr_table->select->cond, sort_table_cond))) + new Item_cond_and(curr_table->select->cond, + sort_table_cond)) || + curr_table->select->cond->fix_fields(thd, tables_list, + &curr_table->select->cond)) DBUG_VOID_RETURN; + } curr_table->select_cond= curr_table->select->cond; curr_table->select_cond->top_level_item(); DBUG_EXECUTE("where",print_where(curr_table->select->cond, @@ -4341,6 +4353,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father, SYNPOSIS eliminate_not_funcs() + thd thread handler cond condition tree DESCRIPTION @@ -4357,7 +4370,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father, New condition tree */ -COND *eliminate_not_funcs(COND *cond) +COND *eliminate_not_funcs(THD *thd, COND *cond) { if (!cond) return cond; @@ -4367,7 +4380,7 @@ COND *eliminate_not_funcs(COND *cond) Item *item; while ((item= li++)) { - Item *new_item= eliminate_not_funcs(item); + Item *new_item= eliminate_not_funcs(thd, item); if (item != new_item) VOID(li.replace(new_item)); /* replace item with a new condition */ } @@ -4375,14 +4388,13 @@ COND *eliminate_not_funcs(COND *cond) else if (cond->type() == Item::FUNC_ITEM && /* 'NOT' operation? */ ((Item_func*) cond)->functype() == Item_func::NOT_FUNC) { - COND *new_cond= ((Item_func*) cond)->arguments()[0]->neg_transformer(); + COND *new_cond= ((Item_func*) cond)->arguments()[0]->neg_transformer(thd); if (new_cond) { /* Here we can delete the NOT function. Something like: delete cond; But we don't need to do it. All items will be deleted later at once. */ - new_cond->fix_fields(current_thd, 0, &new_cond); cond= new_cond; } } @@ -4391,7 +4403,7 @@ COND *eliminate_not_funcs(COND *cond) static COND * -optimize_cond(COND *conds,Item::cond_result *cond_value) +optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) { DBUG_ENTER("optimize_cond"); if (!conds) @@ -4401,7 +4413,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value) } DBUG_EXECUTE("where",print_where(conds,"original");); /* eliminate NOT operators */ - conds= eliminate_not_funcs(conds); + conds= eliminate_not_funcs(thd, conds); DBUG_EXECUTE("where", print_where(conds, "after negation elimination");); /* change field = field to field = const for each found field = const */ propagate_cond_constants((I_List<COND_CMP> *) 0,conds,conds); @@ -4410,7 +4422,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value) Remove all and-levels where CONST item != CONST item */ DBUG_EXECUTE("where",print_where(conds,"after const change");); - conds=remove_eq_conds(conds,cond_value) ; + conds= remove_eq_conds(thd, conds, cond_value) ; DBUG_EXECUTE("info",print_where(conds,"after remove");); DBUG_RETURN(conds); } @@ -4425,7 +4437,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value) */ static COND * -remove_eq_conds(COND *cond,Item::cond_result *cond_value) +remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) { if (cond->type() == Item::COND_ITEM) { @@ -4439,7 +4451,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value) Item *item; while ((item=li++)) { - Item *new_item=remove_eq_conds(item,&tmp_cond_value); + Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value); if (!new_item) li.remove(); else if (item != new_item) @@ -4473,7 +4485,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value) } } if (should_fix_fields) - cond->fix_fields(current_thd,0, &cond); + cond->update_used_tables(); if (!((Item_cond*) cond)->argument_list()->elements || *cond_value != Item::COND_OK) @@ -4500,7 +4512,6 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value) Item_func_isnull *func=(Item_func_isnull*) cond; Item **args= func->arguments(); - THD *thd=current_thd; if (args[0]->type() == Item::FIELD_ITEM) { Field *field=((Item_field*) args[0])->field; @@ -5005,7 +5016,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, *blob_field++= new_field; blob_count++; } - ((Item_sum*) item)->args[i]= new Item_field(new_field); + ((Item_sum*) item)->args[i]= new Item_field(new_field, 1); } } } @@ -6761,7 +6772,7 @@ static bool test_if_ref(Item_field *left_item,Item *right_item) static COND * -make_cond_for_table(COND *cond,table_map tables,table_map used_table) +make_cond_for_table(COND *cond, table_map tables, table_map used_table) { if (used_table && !(cond->used_tables() & used_table)) return (COND*) 0; // Already checked @@ -6787,8 +6798,8 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table) case 1: return new_cond->argument_list()->head(); default: - new_cond->used_tables_cache=((Item_cond*) cond)->used_tables_cache & - tables; + if (new_cond->fix_fields(current_thd, 0, (Item**)&new_cond)) + return (COND*) 0; return new_cond; } } @@ -6806,7 +6817,8 @@ make_cond_for_table(COND *cond,table_map tables,table_map used_table) return (COND*) 0; // Always true new_cond->argument_list()->push_back(fix); } - new_cond->used_tables_cache=((Item_cond_or*) cond)->used_tables_cache; + if (new_cond->fix_fields(current_thd, 0, (Item**)&new_cond)) + return (COND*) 0; new_cond->top_level_item(); return new_cond; } @@ -7310,8 +7322,10 @@ static bool fix_having(JOIN *join, Item **having) if (!table->select->cond) table->select->cond=sort_table_cond; else // This should never happen - if (!(table->select->cond=new Item_cond_and(table->select->cond, - sort_table_cond))) + if (!(table->select->cond= new Item_cond_and(table->select->cond, + sort_table_cond)) || + table->select->cond->fix_fields(join->thd, join->tanles_list, + &table->select->cond)) return 1; table->select_cond=table->select->cond; table->select_cond->top_level_item(); @@ -7930,10 +7944,15 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, } order->in_field_list=0; Item *it= *order->item; - if (it->fix_fields(thd, tables, order->item) || - //'it' ressigned because fix_field can change it - (it= *order->item)->check_cols(1) || - thd->is_fatal_error) + /* + we check it->fixed because Item_func_group_concat can put + arguments for which fix_fields already was called + */ + if (!it->fixed && + (it->fix_fields(thd, tables, order->item) || + //'it' ressigned because fix_field can change it + (it= *order->item)->check_cols(1) || + thd->is_fatal_error)) return 1; // Wrong field uint el= all_fields.elements; all_fields.push_front(it); // Add new field to field list @@ -8584,7 +8603,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, if (item->type() == Item::SUM_FUNC_ITEM && field->table->group) item_field= ((Item_sum*) item)->result_item(field); else - item_field= (Item*) new Item_field(field); + item_field= (Item*) new Item_field(field, 1); if (!item_field) return TRUE; // Fatal error item_field->name= item->name; /*lint -e613 */ @@ -8759,7 +8778,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i]. fieldnr-1]; Item *value=join_tab->ref.items[i]; - cond->add(new Item_func_equal(new Item_field(field),value)); + cond->add(new Item_func_equal(new Item_field(field, 1), value)); } if (thd->is_fatal_error) DBUG_RETURN(TRUE); diff --git a/sql/sql_select.h b/sql/sql_select.h index 36526bee066..fea3f7c6b80 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -432,4 +432,4 @@ bool cp_buffer_from_ref(TABLE_REF *ref); bool error_if_full_join(JOIN *join); int report_error(TABLE *table, int error); int safe_index_read(JOIN_TAB *tab); -COND *eliminate_not_funcs(COND *cond); +COND *eliminate_not_funcs(THD *thd, COND *cond); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d68db2cb3bc..2a94c66ac1a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1050,7 +1050,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) { if (!wild || !wild[0] || !wild_case_compare(system_charset_info, field->field_name,wild)) - field_list.push_back(new Item_field(field)); + field_list.push_back(new Item_field(field, 1)); } restore_record(table,default_values); // Get empty record if (thd->protocol->send_fields(&field_list,2)) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index a05fa44cfc9..bb5996919e3 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -203,6 +203,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, } } + item_list.empty(); + // it is not single select if (first_select->next_select()) { union_result->tmp_table_param.field_count= types.elements; @@ -222,14 +224,17 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, result_table_list.table= table; union_result->set_table(table); - item_list.empty(); thd_arg->lex->current_select= lex_select_save; { Field **field; for (field= table->field; *field; field++) { - if (item_list.push_back(new Item_field(*field))) + Item_field *item= new Item_field(*field, 1); + if (item_list.push_back(item)) DBUG_RETURN(-1); +#ifndef DBUG_OFF + item->double_fix= 0; +#endif } } } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index ef953eb734d..42dd0895132 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -713,7 +713,7 @@ multi_update::initialize_tables(JOIN *join) /* ok to be on stack as this is not referenced outside of this func */ Field_string offset(table->file->ref_length, 0, "offset", table, &my_charset_bin); - if (!(If=new Item_field(((Field *) &offset)))) + if (!(If= new Item_field(((Field *) &offset), 1))) DBUG_RETURN(1); If->maybe_null=0; if (temp_fields.push_front(If)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c87de8a5cd5..e2c33584bdf 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4348,6 +4348,11 @@ purge_option: YYABORT; } Item *tmp= new Item_func_unix_timestamp($2); + /* + it is OK olny emulate fix_fieds, because we need only + value of constant + */ + tmp->Item::fix_fields(0,0,0); Lex->sql_command = SQLCOM_PURGE_BEFORE; Lex->purge_time= (ulong) tmp->val_int(); } @@ -4482,7 +4487,13 @@ text_string: | HEX_NUM { Item *tmp = new Item_varbinary($1.str,$1.length); - $$= tmp ? tmp->val_str((String*) 0) : (String*) 0; + /* + it is OK olny emulate fix_fieds, because we need only + value of constant + */ + $$= tmp ? + tmp->Item::fix_fields(0,0,0), tmp->val_str((String*) 0) : + (String*) 0; } ; @@ -4512,7 +4523,11 @@ param_marker: signed_literal: literal { $$ = $1; } | '+' NUM_literal { $$ = $2; } - | '-' NUM_literal { $$ = new Item_func_neg($2); } + | '-' NUM_literal + { + /* $2 it's Item_int -> we can get value without fix_fields call */ + $$= new Item_int(-$2->val_int(), $2->max_length+1); + } ; @@ -4525,7 +4540,13 @@ literal: | UNDERSCORE_CHARSET HEX_NUM { Item *tmp= new Item_varbinary($2.str,$2.length); - String *str= tmp ? tmp->val_str((String*) 0) : (String*) 0; + /* + it is OK olny emulate fix_fieds, because we need only + value of constant + */ + String *str= tmp ? + tmp->Item::fix_fields(0,0,0), tmp->val_str((String*) 0) : + (String*) 0; $$= new Item_string(str ? str->ptr() : "", str ? str->length() : 0, Lex->charset); |