diff options
-rw-r--r-- | sql/item.cc | 24 | ||||
-rw-r--r-- | sql/item.h | 109 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 70 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 4 | ||||
-rw-r--r-- | sql/item_create.cc | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 41 | ||||
-rw-r--r-- | sql/item_func.h | 2 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 128 | ||||
-rw-r--r-- | sql/item_strfunc.h | 10 | ||||
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 3 |
11 files changed, 212 insertions, 183 deletions
diff --git a/sql/item.cc b/sql/item.cc index d74b9d7454f..4c7b30b0410 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -39,8 +39,7 @@ Item::Item(): { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; - collation= &my_charset_bin; - coercibility= COER_COERCIBLE; + set_charset(&my_charset_bin, DERIVATION_COERCIBLE); name= 0; decimals= 0; max_length= 0; THD *thd= current_thd; @@ -68,8 +67,7 @@ Item::Item(THD *thd, Item &item): unsigned_flag(item.unsigned_flag), with_sum_func(item.with_sum_func), fixed(item.fixed), - collation(item.collation), - coercibility(item.coercibility) + collation(item.collation) { next=thd->free_list; // Put in free list thd->free_list= this; @@ -185,12 +183,12 @@ CHARSET_INFO * Item::default_charset() const return current_thd->variables.collation_connection; } -bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, - CHARSET_INFO *cs2, enum coercion co2) +bool Item::set_charset(CHARSET_INFO *cs1, Derivation co1, + CHARSET_INFO *cs2, Derivation co2) { if (cs1 == &my_charset_bin || cs2 == &my_charset_bin) { - set_charset(&my_charset_bin, COER_NOCOLL); + set_charset(&my_charset_bin, DERIVATION_NONE); return 0; } @@ -209,7 +207,7 @@ bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, { if (cs1 != cs2) { - if (co1 == COER_EXPLICIT) + if (co1 == DERIVATION_EXPLICIT) { return 1; } @@ -218,7 +216,7 @@ bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, CHARSET_INFO *bin= get_charset_by_csname(cs1->csname, MY_CS_BINSORT,MYF(0)); if (!bin) return 1; - set_charset(bin, COER_NOCOLL); + set_charset(bin, DERIVATION_NONE); } } else @@ -230,7 +228,7 @@ bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1, Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) { set_field(f); - coercibility= COER_IMPLICIT; + set_charset(DERIVATION_IMPLICIT); fixed= 1; // This item is not needed in fix_fields } @@ -239,7 +237,7 @@ Item_field::Item_field(THD *thd, Item_field &item): Item_ident(thd, item), field(item.field), result_field(item.result_field) -{ coercibility= COER_IMPLICIT; } +{ set_charset(DERIVATION_IMPLICIT); } void Item_field::set_field(Field *field_par) { @@ -251,7 +249,7 @@ void Item_field::set_field(Field *field_par) field_name=field_par->field_name; db_name=field_par->table->table_cache_key; unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); - set_charset(field_par->charset(), COER_IMPLICIT); + set_charset(field_par->charset(), DERIVATION_IMPLICIT); } const char *Item_ident::full_name() const @@ -1102,7 +1100,7 @@ Item_varbinary::Item_varbinary(const char *str, uint str_length) str+=2; } *ptr=0; // Keep purify happy - coercibility= COER_COERCIBLE; + set_charset(&my_charset_bin, DERIVATION_COERCIBLE); } longlong Item_varbinary::val_int() diff --git a/sql/item.h b/sql/item.h index df9ada72ce5..ce79e70e5d6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -23,6 +23,63 @@ class Protocol; struct st_table_list; void item_init(void); /* Init item functions */ + +/* + "Declared Type Collation" + A combination of collation and its deriviation. +*/ + +enum Derivation +{ + DERIVATION_COERCIBLE= 3, + DERIVATION_IMPLICIT= 2, + DERIVATION_NONE= 1, + DERIVATION_EXPLICIT= 0 +}; + +class DTCollation { +public: + CHARSET_INFO *collation; + enum Derivation derivation; + + DTCollation() + { + collation= &my_charset_bin; + derivation= DERIVATION_NONE; + } + DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg) + { + collation= collation_arg; + derivation= derivation_arg; + } + void set(DTCollation *dt) + { + collation= dt->collation; + derivation= dt->derivation; + } + void set(CHARSET_INFO *collation_arg, Derivation derivation_arg) + { + collation= collation_arg; + derivation= derivation_arg; + } + void set(CHARSET_INFO *collation_arg) + { collation= collation_arg; } + void set(Derivation derivation_arg) + { derivation= derivation_arg; } + bool aggregate(DTCollation *dt); + const char *derivation_name() const + { + switch(derivation) + { + case DERIVATION_COERCIBLE: return "COERCIBLE"; + case DERIVATION_IMPLICIT: return "IMPLICIT"; + case DERIVATION_EXPLICIT: return "EXPLICIT"; + case DERIVATION_NONE: return "NONE"; + default: return "UNKNOWN"; + } + } +}; + class Item { uint loop_id; /* Used to find selfrefering loops */ Item(const Item &); /* Prevent use of these */ @@ -41,19 +98,6 @@ public: SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM}; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; - enum coercion { COER_COERCIBLE=3, COER_IMPLICIT=2, - COER_NOCOLL=1, COER_EXPLICIT=0 }; - const char *coercion_name(enum coercion coer) const - { - switch(coer) - { - case COER_COERCIBLE: return "COERCIBLE"; - case COER_IMPLICIT: return "IMPLICIT"; - case COER_EXPLICIT: return "EXPLICIT"; - case COER_NOCOLL: return "NO COLLATION"; - default: return "UNKNOWN"; - } - } String str_value; /* used to store value */ my_string name; /* Name from select */ @@ -65,9 +109,8 @@ public: my_bool unsigned_flag; my_bool with_sum_func; my_bool fixed; /* If item fixed with fix_fields */ - CHARSET_INFO *collation; /* character set && collation */ - enum coercion coercibility; /* Precedence order of collation */ - + DTCollation collation; + // alloc & destruct is done as start of select using sql_alloc Item(); /* @@ -125,13 +168,23 @@ public: virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); } CHARSET_INFO *default_charset() const; - CHARSET_INFO *charset() const { return collation; }; + Derivation derivation() const { return collation.derivation; } + CHARSET_INFO *charset() const { return collation.collation; } void set_charset(CHARSET_INFO *cs) - { collation= cs; } - void set_charset(CHARSET_INFO *cs, enum coercion coer) - { collation= cs; coercibility= coer; } - bool set_charset(CHARSET_INFO *cs1, enum coercion co1, - CHARSET_INFO *cs2, enum coercion co2); + { collation.collation= cs; } + void set_charset(Derivation dv) + { collation.derivation= dv; } + void set_charset(CHARSET_INFO *cs, Derivation dv) + { collation.collation= cs; collation.derivation= dv; } + void set_charset(Item &item) + { collation= item.collation; } + void set_charset(DTCollation *collation_arg) + { + collation.collation= collation_arg->collation; + collation.derivation= collation_arg->derivation; + } + bool set_charset(CHARSET_INFO *cs1, Derivation dv1, + CHARSET_INFO *cs2, Derivation dv2); bool binary() const { return charset()->state & MY_CS_BINSORT ? 1 : 0 ; } @@ -180,7 +233,7 @@ public: 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) - { coercibility= COER_IMPLICIT; } + { set_charset(DERIVATION_IMPLICIT); } // Constructor need to process subselect with temporary tables (see Item) Item_field(THD *thd, Item_field &item); Item_field(Field *field); @@ -381,21 +434,19 @@ class Item_string :public Item { public: Item_string(const char *str,uint length, - CHARSET_INFO *cs, enum coercion coer= COER_COERCIBLE) + CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE) { - set_charset(cs); + set_charset(cs, dv); str_value.set(str,length,cs); - coercibility= coer; max_length=length; set_name(str, length, cs); decimals=NOT_FIXED_DEC; } Item_string(const char *name_par, const char *str, uint length, - CHARSET_INFO *cs, enum coercion coer= COER_COERCIBLE) + CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE) { - set_charset(cs); + set_charset(cs, dv); str_value.set(str,length,cs); - coercibility= coer; max_length=length; set_name(name_par,0,cs); decimals=NOT_FIXED_DEC; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5c2b9ed4682..035f85a45ba 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -23,6 +23,15 @@ #include "mysql_priv.h" #include <m_ctype.h> + +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +{ + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); +} + Item_bool_func2* Item_bool_func2::eq_creator(Item *a, Item *b) { return new Item_func_eq(a, b); @@ -87,13 +96,13 @@ static bool convert_constant_item(Field *field, Item **item) return 0; } -bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, - CHARSET_INFO *cs2, enum coercion co2) +bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, Derivation co1, + CHARSET_INFO *cs2, Derivation co2) { if (cs1 == &my_charset_bin || cs2 == &my_charset_bin) { cmp_charset= &my_charset_bin; - coercibility= co1 > co2 ? co1 : co2; + //coercibility= co1 > co2 ? co1 : co2; return 0; } @@ -106,42 +115,42 @@ bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, if ((co1 <= co2) && (cs1==&my_charset_bin)) { cmp_charset= cs1; - coercibility= co1; + //coercibility= co1; } else if ((co2 <= co1) && (cs2==&my_charset_bin)) { cmp_charset= cs2; - coercibility= co2; + //coercibility= co2; } else { cmp_charset= 0; - coercibility= COER_NOCOLL; + //coercibility= DERIVATION_NOCOLL; return 1; } } else if (co1 < co2) { cmp_charset= cs1; - coercibility= co1; + //coercibility= co1; } else if (co2 < co1) { cmp_charset= cs2; - coercibility= co1; + //coercibility= co1; } else { if (cs1 == cs2) { cmp_charset= cs1; - coercibility= co1; + //coercibility= co1; } else { - coercibility= COER_NOCOLL; + //coercibility= DERIVATION_NOCOLL; cmp_charset= 0; - return (co1 == COER_EXPLICIT) ? 1 : 0; + return (co1 == DERIVATION_EXPLICIT) ? 1 : 0; } } return 0; @@ -171,13 +180,13 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, uint strong= 0; uint weak= 0; - if ((args[0]->coercibility < args[1]->coercibility) && + if ((args[0]->derivation() < args[1]->derivation()) && !my_charset_same(args[0]->charset(), args[1]->charset()) && (args[0]->charset()->state & MY_CS_UNICODE)) { weak= 1; } - else if ((args[1]->coercibility < args[0]->coercibility) && + else if ((args[1]->derivation() < args[0]->derivation()) && !my_charset_same(args[0]->charset(), args[1]->charset()) && (args[1]->charset()->state & MY_CS_UNICODE)) { @@ -194,26 +203,23 @@ bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), args[strong]->charset()); conv= new Item_string(cstr.ptr(),cstr.length(),cstr.charset(), - args[weak]->coercibility); + args[weak]->derivation()); ((Item_string*)conv)->str_value.copy(); } else { conv= new Item_func_conv_charset(args[weak],args[strong]->charset()); - conv->coercibility= args[weak]->coercibility; + //conv->coercibility= args[weak]->derivation(); } args[weak]= conv ? conv : args[weak]; - set_cmp_charset(args[0]->charset(), args[0]->coercibility, - args[1]->charset(), args[1]->coercibility); + set_cmp_charset(args[0]->charset(), args[0]->derivation(), + args[1]->charset(), args[1]->derivation()); } } if (!cmp_charset) { /* set_cmp_charset() failed */ - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[1]->charset()->name,coercion_name(args[1]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); return 1; } return 0; @@ -266,8 +272,8 @@ void Item_bool_func2::fix_length_and_dec() We must set cmp_charset here as we may be called from for an automatic generated item, like in natural join */ - set_cmp_charset(args[0]->charset(), args[0]->coercibility, - args[1]->charset(), args[1]->coercibility); + set_cmp_charset(args[0]->charset(), args[0]->derivation(), + args[1]->charset(), args[1]->derivation()); } @@ -744,12 +750,9 @@ Item_func_ifnull::fix_length_and_dec() args[1]->result_type())) != REAL_RESULT) decimals= 0; - if (set_charset(args[0]->charset(),args[0]->coercibility, - args[1]->charset(),args[1]->coercibility)) - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[1]->charset()->name,coercion_name(args[1]->coercibility), - func_name()); + if (set_charset(args[0]->charset(),args[0]->derivation(), + args[1]->charset(),args[1]->derivation())) + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); } @@ -825,13 +828,10 @@ Item_func_if::fix_length_and_dec() else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT) { cached_result_type = STRING_RESULT; - if (set_charset(args[1]->charset(), args[1]->coercibility, - args[2]->charset(), args[2]->coercibility)) + if (set_charset(args[1]->charset(), args[1]->derivation(), + args[2]->charset(), args[2]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[1]->charset()->name,coercion_name(args[1]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); return; } } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 549839b4f96..b38248d87e1 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -123,8 +123,8 @@ public: { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1); } - bool set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1, - CHARSET_INFO *cs2, enum coercion co2); + bool set_cmp_charset(CHARSET_INFO *cs1, Derivation co1, + CHARSET_INFO *cs2, Derivation co2); optimize_type select_optimize() const { return OPTIMIZE_OP; } virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; } bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } diff --git a/sql/item_create.cc b/sql/item_create.cc index 6956582a8ca..90f42cee959 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -450,7 +450,7 @@ Item *create_func_version(void) { return new Item_string(NullS,server_version, (uint) strlen(server_version), - system_charset_info, Item::COER_IMPLICIT); + system_charset_info, DERIVATION_IMPLICIT); } Item *create_func_weekday(Item* a) diff --git a/sql/item_func.cc b/sql/item_func.cc index 6482d81f484..170260c6819 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -31,6 +31,14 @@ #include <zlib.h> #endif +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +{ + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); +} + /* return TRUE if item is a constant */ bool @@ -859,14 +867,11 @@ void Item_func_min_max::fix_length_and_dec() maybe_null=0; cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); if (i==0) - set_charset(args[i]->charset(), args[i]->coercibility); - else if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + set_charset(*args[i]); + else if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -1038,7 +1043,7 @@ longlong Item_func_coercibility::val_int() return 0; } null_value= 0; - return (longlong) args[0]->coercibility; + return (longlong) args[0]->derivation(); } longlong Item_func_locate::val_int() @@ -2000,7 +2005,7 @@ Item_func_set_user_var::fix_length_and_dec() void Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type, CHARSET_INFO *cs, - enum coercion coercibility) + Derivation dv) { if ((null_value=args[0]->null_value)) { @@ -2009,8 +2014,7 @@ void Item_func_set_user_var::update_hash(void *ptr, uint length, my_free(entry->value,MYF(0)); entry->value=0; entry->length=0; - entry->var_charset=cs; - entry->var_coercibility= coercibility; + collation.set(cs, dv); } else { @@ -2041,8 +2045,7 @@ void Item_func_set_user_var::update_hash(void *ptr, uint length, memcpy(entry->value,ptr,length); entry->length= length; entry->type=type; - entry->var_charset=cs; - entry->var_coercibility= coercibility; + entry->collation.set(cs, dv); } return; @@ -2085,7 +2088,7 @@ Item_func_set_user_var::val() { double value=args[0]->val(); update_hash((void*) &value,sizeof(value), REAL_RESULT, - &my_charset_bin, COER_NOCOLL); + &my_charset_bin, DERIVATION_NONE); return value; } @@ -2094,7 +2097,7 @@ Item_func_set_user_var::val_int() { longlong value=args[0]->val_int(); update_hash((void*) &value, sizeof(longlong), INT_RESULT, - &my_charset_bin, COER_NOCOLL); + &my_charset_bin, DERIVATION_NONE); return value; } @@ -2103,10 +2106,10 @@ Item_func_set_user_var::val_str(String *str) { String *res=args[0]->val_str(str); if (!res) // Null value - update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin, COER_NOCOLL); + update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin, DERIVATION_NONE); else update_hash((void*) res->ptr(), res->length(), STRING_RESULT, - res->charset(), args[0]->coercibility); + res->charset(), args[0]->derivation()); return res; } @@ -2147,7 +2150,7 @@ Item_func_get_user_var::val_str(String *str) str->set(*(longlong*) entry->value, &my_charset_bin); break; case STRING_RESULT: - if (str->copy(entry->value, entry->length, entry->var_charset)) + if (str->copy(entry->value, entry->length, entry->collation.collation)) { null_value=1; return NULL; @@ -2236,7 +2239,7 @@ void Item_func_get_user_var::fix_length_and_dec() ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)); user_var_event->user_var_event= var_entry; user_var_event->type= var_entry->type; - user_var_event->charset_number= var_entry->var_charset->number; + user_var_event->charset_number= var_entry->collation.collation->number; if (!var_entry->value) { /* NULL value*/ diff --git a/sql/item_func.h b/sql/item_func.h index 8ef2b85de52..4e39833c467 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -943,7 +943,7 @@ public: longlong val_int(); String *val_str(String *str); void update_hash(void *ptr, uint length, enum Item_result type, - CHARSET_INFO *cs, enum coercion coercibility); + CHARSET_INFO *cs, Derivation dv); bool update(); enum Item_result result_type () const { return cached_result_type; } bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 3cc5ac218e3..23df49c81be 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -36,6 +36,14 @@ String empty_string("",default_charset_info); +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +{ + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); +} + uint nr_of_decimals(const char *str) { if ((str=strchr(str,'.'))) @@ -316,17 +324,14 @@ void Item_func_concat::fix_length_and_dec() bool first_coll= 1; max_length=0; - set_charset(args[0]->charset(),args[0]->coercibility); + set_charset(*args[0]); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -622,18 +627,15 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array, void Item_func_concat_ws::fix_length_and_dec() { - set_charset(separator->charset(),separator->coercibility); + set_charset(*separator); max_length=separator->max_length*(arg_count-1); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -702,7 +704,7 @@ String *Item_func_reverse::val_str(String *str) void Item_func_reverse::fix_length_and_dec() { - set_charset(args[0]->charset(),args[0]->coercibility); + set_charset(*args[0]); max_length = args[0]->max_length; } @@ -826,17 +828,14 @@ void Item_func_replace::fix_length_and_dec() max_length=MAX_BLOB_WIDTH; maybe_null=1; } - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); for (i=1; i<3; i++) { - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -876,13 +875,10 @@ null: void Item_func_insert::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->coercibility, - args[3]->charset(), args[3]->coercibility)) + if (set_charset(args[0]->charset(), args[0]->derivation(), + args[3]->charset(), args[3]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[3]->charset()->name,coercion_name(args[3]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[3]->collation, func_name()); } max_length=args[0]->max_length+args[3]->max_length; if (max_length > MAX_BLOB_WIDTH) @@ -963,7 +959,7 @@ void Item_str_func::left_right_max_length() void Item_func_left::fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); left_right_max_length(); } @@ -990,7 +986,7 @@ String *Item_func_right::val_str(String *str) void Item_func_right::fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); left_right_max_length(); } @@ -1024,7 +1020,7 @@ void Item_func_substr::fix_length_and_dec() { max_length=args[0]->max_length; - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); if (args[1]->const_item()) { int32 start=(int32) args[1]->val_int()-1; @@ -1320,18 +1316,15 @@ void Item_func_trim::fix_length_and_dec() max_length= args[0]->max_length; if (arg_count == 1) { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); remove.set_charset(charset()); remove.set_ascii(" ",1); } else - if (set_charset(args[1]->charset(), args[1]->coercibility, - args[0]->charset(), args[0]->coercibility)) + if (set_charset(args[1]->charset(), args[1]->derivation(), + args[0]->charset(), args[0]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[1]->charset()->name,coercion_name(args[1]->coercibility), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - func_name()); + my_coll_agg_error(args[1]->collation, args[0]->collation, func_name()); } } @@ -1545,7 +1538,7 @@ String *Item_func_user::val_str(String *str) void Item_func_soundex::fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); max_length=args[0]->max_length; set_if_bigger(max_length,4); } @@ -1675,16 +1668,13 @@ void Item_func_elt::fix_length_and_dec() set_if_bigger(max_length,args[i]->max_length); set_if_bigger(decimals,args[i]->decimals); if (i == 0) - set_charset(args[i]->charset(),args[i]->coercibility); + set_charset(*args[0]); else { - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -1780,17 +1770,14 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, void Item_func_make_set::fix_length_and_dec() { max_length=arg_count-1; - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); for (uint i=0 ; i < arg_count ; i++) { max_length+=args[i]->max_length; - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } @@ -1916,7 +1903,7 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value, void Item_func_repeat::fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); if (args[1]->const_item()) { max_length=(long) (args[0]->max_length * args[1]->val_int()); @@ -1976,13 +1963,10 @@ err: void Item_func_rpad::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->coercibility, - args[2]->charset(), args[2]->coercibility)) + if (set_charset(args[0]->charset(), args[0]->derivation(), + args[2]->charset(), args[2]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[2]->charset()->name,coercion_name(args[2]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[2]->collation, func_name()); } if (args[1]->const_item()) @@ -2045,13 +2029,10 @@ String *Item_func_rpad::val_str(String *str) void Item_func_lpad::fix_length_and_dec() { - if (set_charset(args[0]->charset(), args[0]->coercibility, - args[2]->charset(), args[2]->coercibility)) + if (set_charset(args[0]->charset(), args[0]->derivation(), + args[2]->charset(), args[2]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - args[0]->charset()->name,coercion_name(args[0]->coercibility), - args[2]->charset()->name,coercion_name(args[2]->coercibility), - func_name()); + my_coll_agg_error(args[0]->collation, args[2]->collation, func_name()); } if (args[1]->const_item()) @@ -2173,7 +2154,7 @@ void Item_func_conv_charset::fix_length_and_dec() { set_charset(conv_charset); max_length = args[0]->max_length*conv_charset->mbmaxlen; - set_charset(conv_charset, COER_IMPLICIT); + set_charset(conv_charset, DERIVATION_IMPLICIT); } @@ -2277,7 +2258,7 @@ void Item_func_set_collation::fix_length_and_dec() colname,args[0]->charset()->csname); return; } - set_charset(set_collation, COER_EXPLICIT); + set_charset(set_collation, DERIVATION_EXPLICIT); max_length= args[0]->max_length; } @@ -2468,16 +2449,13 @@ void Item_func_export_set::fix_length_and_dec() uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); max_length=length*64+sep_length*63; - set_charset(args[1]->charset(), args[1]->coercibility); + set_charset(*args[1]); for (i=2 ; i < 4 && i < arg_count ; i++) { - if (set_charset(charset(), coercibility, - args[i]->charset(), args[i]->coercibility)) + if (set_charset(charset(), derivation(), + args[i]->charset(), args[i]->derivation())) { - my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), - charset()->name,coercion_name(coercibility), - args[i]->charset()->name,coercion_name(args[i]->coercibility), - func_name()); + my_coll_agg_error(collation, args[i]->collation, func_name()); break; } } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 6bb1c510013..3f2860f4b2b 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -153,7 +153,7 @@ public: Item_str_conv(Item *item) :Item_str_func(item) {} void fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); max_length = args[0]->max_length; } }; @@ -335,7 +335,7 @@ public: class Item_func_database :public Item_str_func { public: - Item_func_database() { coercibility= COER_IMPLICIT; } + Item_func_database() { set_charset(DERIVATION_IMPLICIT); } String *val_str(String *); void fix_length_and_dec() { @@ -348,7 +348,7 @@ public: class Item_func_user :public Item_str_func { public: - Item_func_user() { coercibility= COER_IMPLICIT; } + Item_func_user() { set_charset(DERIVATION_IMPLICIT); } String *val_str(String *); void fix_length_and_dec() { @@ -549,7 +549,7 @@ public: const char *func_name() const { return "load_file"; } void fix_length_and_dec() { - set_charset(&my_charset_bin, COER_COERCIBLE); + set_charset(&my_charset_bin, DERIVATION_COERCIBLE); maybe_null=1; max_length=MAX_BLOB_WIDTH; } @@ -586,7 +586,7 @@ public: String *val_str(String *); void fix_length_and_dec() { - set_charset(args[0]->charset(), args[0]->coercibility); + set_charset(*args[0]); max_length= args[0]->max_length * 2 + 2; } }; diff --git a/sql/log_event.cc b/sql/log_event.cc index 98a877616e0..749732384c7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2230,7 +2230,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli) } Item_func_set_user_var e(user_var_name, it); e.fix_fields(thd, 0, 0); - e.update_hash(val, val_len, type, charset, Item::COER_NOCOLL); + e.update_hash(val, val_len, type, charset, DERIVATION_NONE); free_root(&thd->mem_root,0); rli->inc_event_relay_log_pos(get_event_len()); diff --git a/sql/sql_class.h b/sql/sql_class.h index 33767bc4226..db99fb443c8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -975,8 +975,7 @@ class user_var_entry char *value; ulong length, update_query_id, used_query_id; Item_result type; - CHARSET_INFO *var_charset; - enum Item::coercion var_coercibility; + DTCollation collation; }; /* Class for unique (removing of duplicates) */ |