Commit 31657edc authored by bell@laptop.sanja.is.com.ua's avatar bell@laptop.sanja.is.com.ua

Merge laptop.sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1

into laptop.sanja.is.com.ua:/home/bell/mysql/bk/work-collation-4.1
parents 63fc15ce 5b28d4a9
...@@ -210,7 +210,6 @@ CHARACTER_SET=latin1 ...@@ -210,7 +210,6 @@ CHARACTER_SET=latin1
DBUSER="" DBUSER=""
START_WAIT_TIMEOUT=10 START_WAIT_TIMEOUT=10
STOP_WAIT_TIMEOUT=10 STOP_WAIT_TIMEOUT=10
TEST_REPLICATION=0
MYSQL_TEST_SSL_OPTS="" MYSQL_TEST_SSL_OPTS=""
while test $# -gt 0; do while test $# -gt 0; do
...@@ -288,9 +287,6 @@ while test $# -gt 0; do ...@@ -288,9 +287,6 @@ while test $# -gt 0; do
--user-test=*) --user-test=*)
USER_TEST=`$ECHO "$1" | $SED -e "s;--user-test=;;"` USER_TEST=`$ECHO "$1" | $SED -e "s;--user-test=;;"`
;; ;;
--rpl)
TEST_REPLICATION=1
;;
--mysqld=*) --mysqld=*)
TMP=`$ECHO "$1" | $SED -e "s;--mysqld=;;"` TMP=`$ECHO "$1" | $SED -e "s;--mysqld=;;"`
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT $TMP" EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT $TMP"
...@@ -1406,18 +1402,11 @@ if [ -z "$1" ] ; ...@@ -1406,18 +1402,11 @@ if [ -z "$1" ] ;
then then
if [ x$RECORD = x1 ]; then if [ x$RECORD = x1 ]; then
$ECHO "Will not run in record mode without a specific test case." $ECHO "Will not run in record mode without a specific test case."
else
if [ x$TEST_REPLICATION = x1 ]; then
for tf in `ls -1 $TESTDIR/*.$TESTSUFFIX | $SORT`
do
run_testcase $tf
done
else else
for tf in $TESTDIR/*.$TESTSUFFIX for tf in $TESTDIR/*.$TESTSUFFIX
do do
run_testcase $tf run_testcase $tf
done done
fi
$RM -f $TIMEFILE # Remove for full test $RM -f $TIMEFILE # Remove for full test
fi fi
else else
......
...@@ -42,6 +42,60 @@ t1 CREATE TABLE `t1` ( ...@@ -42,6 +42,60 @@ t1 CREATE TABLE `t1` (
`t` char(4) character set cp1251 NOT NULL default '' `t` char(4) character set cp1251 NOT NULL default ''
) TYPE=MyISAM CHARSET=latin1 ) TYPE=MyISAM CHARSET=latin1
drop table t1; drop table t1;
select
cast(_latin1'ab' AS char) as c1,
cast(_latin1'a ' AS char) as c2,
cast(_latin1'abc' AS char(2)) as c3,
cast(_latin1'a ' AS char(2)) as c4,
cast(_latin1'a' AS char(2)) as c5;
c1 c2 c3 c4 c5
ab a ab a a
create table t1 select
cast(_latin1'ab' AS char) as c1,
cast(_latin1'a ' AS char) as c2,
cast(_latin1'abc' AS char(2)) as c3,
cast(_latin1'a ' AS char(2)) as c4,
cast(_latin1'a' AS char(2)) as c5;
select * from t1;
c1 c2 c3 c4 c5
ab a ab a a
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` char(2) binary NOT NULL default '',
`c2` char(2) binary NOT NULL default '',
`c3` char(2) binary NOT NULL default '',
`c4` char(2) binary NOT NULL default '',
`c5` char(2) binary NOT NULL default ''
) TYPE=MyISAM CHARSET=latin1
drop table t1;
select
cast(_koi8r'' AS nchar) as c1,
cast(_koi8r' ' AS nchar) as c2,
cast(_koi8r'' AS nchar(2)) as c3,
cast(_koi8r' ' AS nchar(2)) as c4,
cast(_koi8r'' AS nchar(2)) as c5;
c1 c2 c3 c4 c5
фг ф фг ф ф
create table t1 select
cast(_koi8r'' AS nchar) as c1,
cast(_koi8r' ' AS nchar) as c2,
cast(_koi8r'' AS nchar(2)) as c3,
cast(_koi8r' ' AS nchar(2)) as c4,
cast(_koi8r'' AS nchar(2)) as c5;
select * from t1;
c1 c2 c3 c4 c5
фг ф фг ф ф
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` char(2) character set utf8 NOT NULL default '',
`c2` char(2) character set utf8 NOT NULL default '',
`c3` char(2) character set utf8 NOT NULL default '',
`c4` char(2) character set utf8 NOT NULL default '',
`c5` char(2) character set utf8 NOT NULL default ''
) TYPE=MyISAM CHARSET=latin1
drop table t1;
select cast("2001-1-1" as date) = "2001-01-01"; select cast("2001-1-1" as date) = "2001-01-01";
cast("2001-1-1" as date) = "2001-01-01" cast("2001-1-1" as date) = "2001-01-01"
1 1
......
...@@ -23,6 +23,47 @@ create table t1 select cast(_koi8r' ...@@ -23,6 +23,47 @@ create table t1 select cast(_koi8r'
show create table t1; show create table t1;
drop table t1; drop table t1;
#
# CAST to CHAR with/without length
#
select
cast(_latin1'ab' AS char) as c1,
cast(_latin1'a ' AS char) as c2,
cast(_latin1'abc' AS char(2)) as c3,
cast(_latin1'a ' AS char(2)) as c4,
cast(_latin1'a' AS char(2)) as c5;
create table t1 select
cast(_latin1'ab' AS char) as c1,
cast(_latin1'a ' AS char) as c2,
cast(_latin1'abc' AS char(2)) as c3,
cast(_latin1'a ' AS char(2)) as c4,
cast(_latin1'a' AS char(2)) as c5;
select * from t1;
show create table t1;
drop table t1;
#
# CAST to NCHAR with/without length
#
select
cast(_koi8r'' AS nchar) as c1,
cast(_koi8r' ' AS nchar) as c2,
cast(_koi8r'' AS nchar(2)) as c3,
cast(_koi8r' ' AS nchar(2)) as c4,
cast(_koi8r'' AS nchar(2)) as c5;
create table t1 select
cast(_koi8r'' AS nchar) as c1,
cast(_koi8r' ' AS nchar) as c2,
cast(_koi8r'' AS nchar(2)) as c3,
cast(_koi8r' ' AS nchar(2)) as c4,
cast(_koi8r'' AS nchar(2)) as c5;
select * from t1;
show create table t1;
drop table t1;
# #
# The following should be fixed in 4.1 # The following should be fixed in 4.1
# #
......
...@@ -470,21 +470,21 @@ Item *create_load_file(Item* a) ...@@ -470,21 +470,21 @@ Item *create_load_file(Item* a)
} }
Item *create_func_cast(Item *a, Cast_target cast_type, CHARSET_INFO *cs) Item *create_func_cast(Item *a, Cast_target cast_type, int len, CHARSET_INFO *cs)
{ {
Item *res; Item *res;
LINT_INIT(res); LINT_INIT(res);
switch (cast_type) { switch (cast_type) {
case ITEM_CAST_BINARY: res= new Item_func_binary(a); break; case ITEM_CAST_BINARY: res= new Item_func_binary(a); break;
case ITEM_CAST_CHAR:
res= (cs == NULL) ? (Item*) new Item_char_typecast(a) :
(Item*) new Item_func_conv_charset(a,cs);
break;
case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break; case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break;
case ITEM_CAST_UNSIGNED_INT: res= new Item_func_unsigned(a); break; case ITEM_CAST_UNSIGNED_INT: res= new Item_func_unsigned(a); break;
case ITEM_CAST_DATE: res= new Item_date_typecast(a); break; case ITEM_CAST_DATE: res= new Item_date_typecast(a); break;
case ITEM_CAST_TIME: res= new Item_time_typecast(a); break; case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break; case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
case ITEM_CAST_CHAR:
res= new Item_char_typecast(a, len, cs ? cs :
current_thd->variables.collation_connection);
break;
} }
return res; return res;
} }
......
...@@ -28,7 +28,7 @@ Item *create_func_bit_length(Item* a); ...@@ -28,7 +28,7 @@ Item *create_func_bit_length(Item* a);
Item *create_func_coercibility(Item* a); Item *create_func_coercibility(Item* a);
Item *create_func_ceiling(Item* a); Item *create_func_ceiling(Item* a);
Item *create_func_char_length(Item* a); Item *create_func_char_length(Item* a);
Item *create_func_cast(Item *a, Cast_target cast_type, CHARSET_INFO *cs); Item *create_func_cast(Item *a, Cast_target cast_type, int len, CHARSET_INFO *cs);
Item *create_func_connection_id(void); Item *create_func_connection_id(void);
Item *create_func_conv(Item* a, Item *b, Item *c); Item *create_func_conv(Item* a, Item *b, Item *c);
Item *create_func_cos(Item* a); Item *create_func_cos(Item* a);
......
...@@ -1474,6 +1474,59 @@ void Item_typecast::print(String *str) ...@@ -1474,6 +1474,59 @@ void Item_typecast::print(String *str)
str->append(')'); str->append(')');
} }
String *Item_char_typecast::val_str(String *str)
{
String *res, *res1;
uint32 length;
if (!charset_conversion && !(res= args[0]->val_str(str)))
{
null_value= 1;
return 0;
}
else
{
// Convert character set if differ
if (!(res1= args[0]->val_str(&tmp_value)) ||
str->copy(res1->ptr(), res1->length(),res1->charset(), cast_cs))
{
null_value= 1;
return 0;
}
res= str;
}
/*
Cut the tail if cast with length
and the result is longer than cast length, e.g.
CAST('string' AS CHAR(1))
*/
if (cast_length >= 0 &&
(res->length() > (length= (uint32) res->charpos(cast_length))))
{ // Safe even if const arg
if (!res->alloced_length())
{ // Don't change const str
str_value= *res; // Not malloced string
res= &str_value;
}
res->length((uint) length);
}
null_value= 0;
return res;
}
void Item_char_typecast::fix_length_and_dec()
{
uint32 char_length;
charset_conversion= !my_charset_same(args[0]->collation.collation, cast_cs) &&
args[0]->collation.collation != &my_charset_bin &&
cast_cs != &my_charset_bin;
collation.set(cast_cs, DERIVATION_IMPLICIT);
char_length= (cast_length >= 0) ? cast_length :
args[0]->max_length/args[0]->collation.collation->mbmaxlen;
max_length= char_length * cast_cs->mbmaxlen;
}
String *Item_datetime_typecast::val_str(String *str) String *Item_datetime_typecast::val_str(String *str)
{ {
TIME ltime; TIME ltime;
......
...@@ -614,13 +614,15 @@ public: ...@@ -614,13 +614,15 @@ public:
class Item_char_typecast :public Item_typecast class Item_char_typecast :public Item_typecast
{ {
public: int cast_length;
Item_char_typecast(Item *a) :Item_typecast(a) {} CHARSET_INFO *cast_cs;
void fix_length_and_dec() bool charset_conversion;
{ String tmp_value;
collation.set(default_charset()); public:
max_length=args[0]->max_length; Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg)
} :Item_typecast(a), cast_length(length_arg), cast_cs(cs_arg) {}
String *val_str(String *a);
void fix_length_and_dec();
}; };
......
...@@ -642,7 +642,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -642,7 +642,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <ha_rkey_mode> handler_rkey_mode %type <ha_rkey_mode> handler_rkey_mode
%type <cast_type> cast_type %type <cast_type> cast_type cast_type_finalize
%type <udf_type> udf_func_type %type <udf_type> udf_func_type
...@@ -2355,11 +2355,19 @@ simple_expr: ...@@ -2355,11 +2355,19 @@ simple_expr:
6, &my_charset_latin1)); 6, &my_charset_latin1));
} }
| CAST_SYM '(' expr AS cast_type ')' | CAST_SYM '(' expr AS cast_type ')'
{ $$= create_func_cast($3, $5, Lex->charset); } {
$$= create_func_cast($3, $5,
Lex->length ? atoi(Lex->length) : -1,
Lex->charset);
}
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END | CASE_SYM opt_expr WHEN_SYM when_list opt_else END
{ $$= new Item_func_case(* $4, $2, $5 ); } { $$= new Item_func_case(* $4, $2, $5 ); }
| CONVERT_SYM '(' expr ',' cast_type ')' | CONVERT_SYM '(' expr ',' cast_type ')'
{ $$= create_func_cast($3, $5, Lex->charset); } {
$$= create_func_cast($3, $5,
Lex->length ? atoi(Lex->length) : -1,
Lex->charset);
}
| CONVERT_SYM '(' expr USING charset_name ')' | CONVERT_SYM '(' expr USING charset_name ')'
{ $$= new Item_func_conv_charset($3,$5); } { $$= new Item_func_conv_charset($3,$5); }
| CONVERT_SYM '(' expr ',' expr ',' expr ')' | CONVERT_SYM '(' expr ',' expr ',' expr ')'
...@@ -2800,16 +2808,25 @@ in_sum_expr: ...@@ -2800,16 +2808,25 @@ in_sum_expr:
$$= $3; $$= $3;
}; };
cast_type_init:
{ Lex->charset= NULL; Lex->length= (char*)0; }
;
cast_type_finalize:
BINARY { $$=ITEM_CAST_BINARY; }
| CHAR_SYM opt_len opt_binary { $$=ITEM_CAST_CHAR; }
| NCHAR_SYM opt_len { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; }
| SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; }
| SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; }
| UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; }
| UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; }
| DATE_SYM { $$=ITEM_CAST_DATE; }
| TIME_SYM { $$=ITEM_CAST_TIME; }
| DATETIME { $$=ITEM_CAST_DATETIME; }
;
cast_type: cast_type:
BINARY { $$=ITEM_CAST_BINARY; Lex->charset= NULL; } cast_type_init cast_type_finalize { $$= $2; }
| CHAR_SYM opt_binary { $$=ITEM_CAST_CHAR; }
| SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; }
| SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; }
| UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; }
| UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; }
| DATE_SYM { $$=ITEM_CAST_DATE; Lex->charset= NULL; }
| TIME_SYM { $$=ITEM_CAST_TIME; Lex->charset= NULL; }
| DATETIME { $$=ITEM_CAST_DATETIME; Lex->charset= NULL; }
; ;
expr_list: expr_list:
......
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