Commit ae616467 authored by unknown's avatar unknown

Merge sinisa@bk-internal.mysql.com:/home/bk/mysql-4.1

into sinisa.nasamreza.org:/mnt/work/mysql-4.1


sql/item.cc:
  Auto merged
parents 7ac3e484 c5badac9
...@@ -2401,7 +2401,11 @@ done ...@@ -2401,7 +2401,11 @@ done
dnl Always compile latin1 dnl Always compile latin1
AC_DEFINE(HAVE_CHARSET_latin1) AC_DEFINE(HAVE_CHARSET_latin1)
dnl Always compile utf8
AC_DEFINE(HAVE_CHARSET_utf8)
use_mb=yes
if test "$use_mb" = "yes" if test "$use_mb" = "yes"
then then
AC_DEFINE(USE_MB) AC_DEFINE(USE_MB)
......
...@@ -523,7 +523,7 @@ Variable_name Value ...@@ -523,7 +523,7 @@ Variable_name Value
client_collation latin1 client_collation latin1
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A' charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1 2 1 latin1 latin1 3 1
SET NAMES latin1 COLLATE latin1_bin; SET NAMES latin1 COLLATE latin1_bin;
SHOW VARIABLES LIKE 'client_collation'; SHOW VARIABLES LIKE 'client_collation';
Variable_name Value Variable_name Value
...@@ -538,35 +538,35 @@ Variable_name Value ...@@ -538,35 +538,35 @@ Variable_name Value
client_collation latin1_bin client_collation latin1_bin
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A' charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1_bin 2 0 latin1 latin1_bin 3 0
SET NAMES koi8r; SET NAMES koi8r;
SHOW VARIABLES LIKE 'client_collation'; SHOW VARIABLES LIKE 'client_collation';
Variable_name Value Variable_name Value
client_collation koi8r client_collation koi8r
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A' charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1 2 1 latin1 latin1 3 1
SET COLLATION koi8r_bin; SET COLLATION koi8r_bin;
SHOW VARIABLES LIKE 'client_collation'; SHOW VARIABLES LIKE 'client_collation';
Variable_name Value Variable_name Value
client_collation koi8r_bin client_collation koi8r_bin
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A' charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1 2 1 latin1 latin1 3 1
SET COLLATION DEFAULT; SET COLLATION DEFAULT;
SHOW VARIABLES LIKE 'client_collation'; SHOW VARIABLES LIKE 'client_collation';
Variable_name Value Variable_name Value
client_collation koi8r client_collation koi8r
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A' charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1 2 1 latin1 latin1 3 1
SET NAMES DEFAULT; SET NAMES DEFAULT;
SHOW VARIABLES LIKE 'client_collation'; SHOW VARIABLES LIKE 'client_collation';
Variable_name Value Variable_name Value
client_collation latin1 client_collation latin1
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A' charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1 2 1 latin1 latin1 3 1
SET NAMES latin1 COLLATE koi8r; SET NAMES latin1 COLLATE koi8r;
COLLATION 'koi8r' is not valid for CHARACTER SET 'latin1' COLLATION 'koi8r' is not valid for CHARACTER SET 'latin1'
SET NAMES 'DEFAULT'; SET NAMES 'DEFAULT';
......
select database(),user() like "%@%"; select database(),user() like "%@%";
database() user() like "%@%" database() user() like "%@%"
test 1 test 1
select version()>="3.23.29"; select version()>=_utf8"3.23.29";
version()>="3.23.29" version()>=_utf8"3.23.29"
1 1
select TRUE,FALSE,NULL; select TRUE,FALSE,NULL;
TRUE FALSE NULL TRUE FALSE NULL
......
...@@ -194,10 +194,10 @@ INSERT INTO t1 (ucs2_f,comment) VALUES (0x0566,'ARMENIAN SMALL ZA'); ...@@ -194,10 +194,10 @@ INSERT INTO t1 (ucs2_f,comment) VALUES (0x0566,'ARMENIAN SMALL ZA');
ALTER TABLE t1 ADD armscii8_f CHAR(32) CHARACTER SET armscii8 NOT NULL; ALTER TABLE t1 ADD armscii8_f CHAR(32) CHARACTER SET armscii8 NOT NULL;
ALTER TABLE t1 ADD greek_f CHAR(32) CHARACTER SET greek NOT NULL; ALTER TABLE t1 ADD greek_f CHAR(32) CHARACTER SET greek NOT NULL;
UPDATE t1 SET greek_f=CONVERT(ucs2_f USING greek) WHERE comment LIKE 'GRE%'; UPDATE t1 SET greek_f=CONVERT(ucs2_f USING greek) WHERE comment LIKE _latin2'GRE%';
UPDATE t1 SET armscii8_f=CONVERT(ucs2_f USING armscii8) WHERE comment LIKE 'ARM%'; UPDATE t1 SET armscii8_f=CONVERT(ucs2_f USING armscii8) WHERE comment LIKE _latin2'ARM%';
UPDATE t1 SET utf8_f=CONVERT(ucs2_f USING utf8) WHERE utf8_f=''; UPDATE t1 SET utf8_f=CONVERT(ucs2_f USING utf8) WHERE utf8_f=_utf8'';
UPDATE t1 SET ucs2_f=CONVERT(utf8_f USING ucs2) WHERE ucs2_f=''; UPDATE t1 SET ucs2_f=CONVERT(utf8_f USING ucs2) WHERE ucs2_f=_ucs2'';
SELECT * FROM t1; SELECT * FROM t1;
SET NAMES 'binary'; SET NAMES 'binary';
SELECT * FROM t1; SELECT * FROM t1;
......
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
# #
select database(),user() like "%@%"; select database(),user() like "%@%";
select version()>="3.23.29"; select version()>=_utf8"3.23.29";
select TRUE,FALSE,NULL; select TRUE,FALSE,NULL;
...@@ -39,7 +39,7 @@ Item::Item(): ...@@ -39,7 +39,7 @@ Item::Item():
{ {
marker= 0; marker= 0;
maybe_null=null_value=with_sum_func=unsigned_flag=0; maybe_null=null_value=with_sum_func=unsigned_flag=0;
coercibility=COER_NOCOLL; coercibility=COER_IMPLICIT;
name= 0; name= 0;
decimals= 0; max_length= 0; decimals= 0; max_length= 0;
THD *thd= current_thd; THD *thd= current_thd;
...@@ -172,6 +172,41 @@ CHARSET_INFO * Item::default_charset() const ...@@ -172,6 +172,41 @@ CHARSET_INFO * Item::default_charset() const
return current_thd->db_charset; return current_thd->db_charset;
} }
bool Item::set_charset(CHARSET_INFO *cs1, enum coercion co1,
CHARSET_INFO *cs2, enum coercion co2)
{
if (cs1 == &my_charset_bin || cs2 == &my_charset_bin)
{
set_charset(&my_charset_bin, COER_NOCOLL);
return 0;
}
if (!my_charset_same(cs1,cs2))
return 1;
if (co1 < co2)
{
set_charset(cs1, co1);
}
else if (co2 < co1)
{
set_charset(cs2, co2);
}
else // co2 == co1
{
if (cs1 != cs2)
{
CHARSET_INFO *bin= get_charset_by_csname(cs1->csname, MY_CS_BINSORT,MYF(0));
if (!bin)
return 1;
set_charset(bin, COER_NOCOLL);
}
else
set_charset(cs2, co2);
}
return 0;
}
Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name)
{ {
set_field(f); set_field(f);
...@@ -195,8 +230,7 @@ void Item_field::set_field(Field *field_par) ...@@ -195,8 +230,7 @@ void Item_field::set_field(Field *field_par)
table_name=field_par->table_name; table_name=field_par->table_name;
field_name=field_par->field_name; field_name=field_par->field_name;
unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
set_charset(field_par->charset()); set_charset(field_par->charset(), COER_IMPLICIT);
coercibility= COER_IMPLICIT;
} }
const char *Item_ident::full_name() const const char *Item_ident::full_name() const
......
...@@ -39,8 +39,8 @@ class Item { ...@@ -39,8 +39,8 @@ class Item {
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM}; SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
enum coercion { COER_NOCOLL=3, COER_COERCIBLE=2, enum coercion { COER_COERCIBLE=3, COER_IMPLICIT=2,
COER_IMPLICIT=1, COER_EXPLICIT=0 }; COER_NOCOLL=1, COER_EXPLICIT=0 };
String str_value; /* used to store value */ String str_value; /* used to store value */
my_string name; /* Name from select */ my_string name; /* Name from select */
...@@ -113,6 +113,13 @@ class Item { ...@@ -113,6 +113,13 @@ class Item {
CHARSET_INFO *default_charset() const; CHARSET_INFO *default_charset() const;
CHARSET_INFO *charset() const { return str_value.charset(); }; CHARSET_INFO *charset() const { return str_value.charset(); };
void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); } void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); }
void set_charset(CHARSET_INFO *cs, enum coercion coer)
{
str_value.set_charset(cs);
coercibility= coer;
}
bool set_charset(CHARSET_INFO *cs1, enum coercion co1,
CHARSET_INFO *cs2, enum coercion co2);
virtual void set_outer_resolving() {} virtual void set_outer_resolving() {}
// Row emulation // Row emulation
......
...@@ -87,6 +87,35 @@ static bool convert_constant_item(Field *field, Item **item) ...@@ -87,6 +87,35 @@ static bool convert_constant_item(Field *field, Item **item)
return 0; return 0;
} }
bool Item_bool_func2::set_cmp_charset(CHARSET_INFO *cs1, enum coercion co1,
CHARSET_INFO *cs2, enum coercion co2)
{
if((cs1 == &my_charset_bin) || (cs2 == &my_charset_bin))
{
cmp_charset= &my_charset_bin;
return 0;
}
if ((co1 == COER_NOCOLL) || (co2 == COER_NOCOLL))
return 1;
if (!my_charset_same(cs1,cs2))
return 1;
if (co1 < co2)
cmp_charset= cs1;
else if (co2 < co1)
cmp_charset= cs2;
else // co1==co2
{
if (cs1 == cs2)
cmp_charset= cs1;
else
return 1;
}
return 0;
}
void Item_bool_func2::fix_length_and_dec() void Item_bool_func2::fix_length_and_dec()
{ {
max_length= 1; // Function returns 0 or 1 max_length= 1; // Function returns 0 or 1
...@@ -124,9 +153,12 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -124,9 +153,12 @@ void Item_bool_func2::fix_length_and_dec()
} }
} }
} }
/* QQ: COERCIBILITY */ if (set_cmp_charset(args[0]->charset(), args[0]->coercibility,
cmp_charset= (args[0]->binary() || args[1]->binary()) ? args[1]->charset(), args[1]->coercibility))
&my_charset_bin : args[0]->charset(); {
my_error(ER_WRONG_ARGUMENTS,MYF(0),func_name());
return;
}
set_cmp_func(); set_cmp_func();
} }
......
...@@ -122,6 +122,8 @@ class Item_bool_func2 :public Item_int_func ...@@ -122,6 +122,8 @@ class Item_bool_func2 :public Item_int_func
{ {
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1); 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);
optimize_type select_optimize() const { return OPTIMIZE_OP; } optimize_type select_optimize() const { return OPTIMIZE_OP; }
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; } virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
......
...@@ -433,7 +433,7 @@ Item *create_func_version(void) ...@@ -433,7 +433,7 @@ Item *create_func_version(void)
{ {
return new Item_string(NullS,server_version, return new Item_string(NullS,server_version,
(uint) strlen(server_version), (uint) strlen(server_version),
default_charset_info); system_charset_info);
} }
Item *create_func_weekday(Item* a) Item *create_func_weekday(Item* a)
......
...@@ -107,7 +107,6 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -107,7 +107,6 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0; // Fatal error if flag is set! return 0; // Fatal error if flag is set!
if (arg_count) if (arg_count)
{ // Print purify happy { // Print purify happy
bool first_coll= 1;
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{ {
if ((*arg)->fix_fields(thd, tables, arg) || if ((*arg)->fix_fields(thd, tables, arg) ||
...@@ -116,38 +115,6 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -116,38 +115,6 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
if ((*arg)->maybe_null) if ((*arg)->maybe_null)
maybe_null=1; maybe_null=1;
if ((*arg)->result_type() == STRING_RESULT)
{
/*
Set return character set to first argument if we are returning a
string.
*/
if (first_coll)
{
set_charset((*arg)->charset());
coercibility= (*args)->coercibility;
first_coll= 0;
}
else if ((*arg)->charset() == &my_charset_bin ||
charset() == &my_charset_bin)
{
set_charset(&my_charset_bin);
coercibility= COER_NOCOLL;
}
else if ((*arg)->coercibility < coercibility)
{
if (!my_charset_same(charset(),(*arg)->charset()))
{
set_charset(&my_charset_bin);
coercibility= COER_NOCOLL;
}
else
{
coercibility= (*arg)->coercibility;
set_charset((*arg)->charset());
}
}
}
with_sum_func= with_sum_func || (*arg)->with_sum_func; with_sum_func= with_sum_func || (*arg)->with_sum_func;
used_tables_cache|=(*arg)->used_tables(); used_tables_cache|=(*arg)->used_tables();
const_item_cache&= (*arg)->const_item(); const_item_cache&= (*arg)->const_item();
......
...@@ -321,9 +321,21 @@ String *Item_func_concat::val_str(String *str) ...@@ -321,9 +321,21 @@ String *Item_func_concat::val_str(String *str)
void Item_func_concat::fix_length_and_dec() void Item_func_concat::fix_length_and_dec()
{ {
bool first_coll= 1;
max_length=0; max_length=0;
set_charset(args[0]->charset(),args[0]->coercibility);
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{
max_length+=args[i]->max_length; max_length+=args[i]->max_length;
if (set_charset(charset(), coercibility,
args[i]->charset(), args[i]->coercibility))
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),func_name());
break;
}
}
if (max_length > MAX_BLOB_WIDTH) if (max_length > MAX_BLOB_WIDTH)
{ {
max_length=MAX_BLOB_WIDTH; max_length=MAX_BLOB_WIDTH;
...@@ -978,6 +990,7 @@ void Item_func_substr::fix_length_and_dec() ...@@ -978,6 +990,7 @@ void Item_func_substr::fix_length_and_dec()
{ {
max_length=args[0]->max_length; max_length=args[0]->max_length;
set_charset(args[0]->charset(), args[0]->coercibility);
if (args[1]->const_item()) if (args[1]->const_item())
{ {
int32 start=(int32) args[1]->val_int()-1; int32 start=(int32) args[1]->val_int()-1;
...@@ -1791,6 +1804,7 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value, ...@@ -1791,6 +1804,7 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value,
void Item_func_repeat::fix_length_and_dec() void Item_func_repeat::fix_length_and_dec()
{ {
set_charset(args[0]->charset(), args[0]->coercibility);
if (args[1]->const_item()) if (args[1]->const_item())
{ {
max_length=(long) (args[0]->max_length * args[1]->val_int()); max_length=(long) (args[0]->max_length * args[1]->val_int());
...@@ -2028,8 +2042,7 @@ String *Item_func_conv_charset::val_str(String *str) ...@@ -2028,8 +2042,7 @@ String *Item_func_conv_charset::val_str(String *str)
void Item_func_conv_charset::fix_length_and_dec() void Item_func_conv_charset::fix_length_and_dec()
{ {
max_length = args[0]->max_length*conv_charset->mbmaxlen; max_length = args[0]->max_length*conv_charset->mbmaxlen;
coercibility= COER_IMPLICIT; set_charset(conv_charset, COER_IMPLICIT);
set_charset(conv_charset);
} }
...@@ -2171,9 +2184,7 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, ...@@ -2171,9 +2184,7 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables,
set_collation->name,args[0]->charset()->csname); set_collation->name,args[0]->charset()->csname);
return 1; return 1;
} }
set_charset(set_collation); set_charset(set_collation, COER_EXPLICIT);
coercibility= COER_EXPLICIT;
with_sum_func= with_sum_func || args[0]->with_sum_func; with_sum_func= with_sum_func || args[0]->with_sum_func;
used_tables_cache=args[0]->used_tables(); used_tables_cache=args[0]->used_tables();
const_item_cache=args[0]->const_item(); const_item_cache=args[0]->const_item();
......
...@@ -151,7 +151,11 @@ class Item_str_conv :public Item_str_func ...@@ -151,7 +151,11 @@ class Item_str_conv :public Item_str_func
{ {
public: public:
Item_str_conv(Item *item) :Item_str_func(item) {} Item_str_conv(Item *item) :Item_str_func(item) {}
void fix_length_and_dec() { max_length = args[0]->max_length; } void fix_length_and_dec()
{
set_charset(args[0]->charset(), args[0]->coercibility);
max_length = args[0]->max_length;
}
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment