#At file:///home/mikael/mysql_clones/mysql-next-wl3352/
2920 Mikael Ronstrom 2009-11-02
Fixed a few bugs in hex string generation, in call to val_str for partition expressions, also made code reusable for DEFAULT handling to fix BUG#48464 by introducing function get_cs_converted_string_value, added partition_utf8 test case for UTF8 outputs
added:
mysql-test/r/partition_utf8.result
mysql-test/t/partition_utf8.test
modified:
BUILD/build_mccge.sh
mysql-test/r/partition_column.result
mysql-test/t/partition_column.test
sql/mysql_priv.h
sql/sql_partition.cc
sql/sql_partition.h
sql/sql_show.cc
=== modified file 'BUILD/build_mccge.sh'
--- a/BUILD/build_mccge.sh 2009-10-28 17:22:36 +0000
+++ b/BUILD/build_mccge.sh 2009-11-02 13:49:26 +0000
@@ -1274,7 +1274,7 @@ set_bsd_configs()
if test "x$fast_flag" != "xno" ; then
compiler_flags="$compiler_flags -O3"
else
- compiler_flags="$compiler_flags -O"
+ compiler_flags="$compiler_flags -O0"
fi
set_cc_and_cxx_for_gcc
}
@@ -1305,7 +1305,7 @@ set_linux_configs()
if test "x$fast_flag" != "xno" ; then
compiler_flags="$compiler_flags -O2"
else
- compiler_flags="$compiler_flags -O"
+ compiler_flags="$compiler_flags -O0"
fi
# configure will set proper compiler flags for gcc on Linux
elif test "x$compiler" = "xicc" ; then
@@ -1375,8 +1375,8 @@ set_solaris_configs()
LDFLAGS="$LDFLAGS -O2"
compiler_flags="$compiler_flags -O2"
else
- LDFLAGS="$LDFLAGS -O"
- compiler_flags="$compiler_flags -O"
+ LDFLAGS="$LDFLAGS -O0"
+ compiler_flags="$compiler_flags -O0"
fi
fi
else
@@ -1407,7 +1407,7 @@ set_solaris_configs()
elif test "x$fast_flag" = "xgeneric" ; then
compiler_flags="$compiler_flags -xO2"
else
- compiler_flags="$compiler_flags -xO"
+ compiler_flags="$compiler_flags -xO0"
fi
else
#Using SPARC cpu with SunStudio (Forte) compiler
@@ -1421,7 +1421,7 @@ set_solaris_configs()
elif test "x$fast_flag" = "xgeneric" ; then
compiler_flags="$compiler_flags -xO2"
else
- compiler_flags="$compiler_flags -xO"
+ compiler_flags="$compiler_flags -xO0"
fi
fi
fi
@@ -1452,7 +1452,7 @@ set_macosx_configs()
if test "x$fast_flag" != "xno" ; then
compiler_flags="$compiler_flags -Os"
else
- compiler_flags="$compiler_flags -O"
+ compiler_flags="$compiler_flags -O0"
fi
set_cc_and_cxx_for_gcc
}
=== modified file 'mysql-test/r/partition_column.result'
--- a/mysql-test/r/partition_column.result 2009-11-02 10:03:40 +0000
+++ b/mysql-test/r/partition_column.result 2009-11-02 13:49:26 +0000
@@ -1,18 +1,18 @@
drop table if exists t1;
-create table t1 (a varchar(1500), b varchar(1570))
-partition by list columns(a,b)
-( partition p0 values in (('a','b')));
-ERROR HY000: The total length of the partitioning fields is too large
-create table t1 (a varchar(1023) character set utf8 collate utf8_spanish2_ci)
-partition by range columns(a)
-( partition p0 values less than ('CZ'),
-partition p1 values less than ('CH'),
-partition p2 values less than ('D'));
-insert into t1 values ('czz'),('chi'),('ci'),('cg');
-select * from t1 where a between 'cg' AND 'ci';
-a
-ci
-cg
+create table t1 (a varchar(5))
+partition by list columns(a)
+( partition p0 values in ('\''),
+ partition p1 values in ('\\'),
+ partition p2 values in ('\0'));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(5) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST COLUMNS(a)
+(PARTITION p0 VALUES IN ('''') ENGINE = MyISAM,
+ PARTITION p1 VALUES IN ('\\') ENGINE = MyISAM,
+ PARTITION p2 VALUES IN ('\0') ENGINE = MyISAM) */
drop table t1;
set @@sql_mode=allow_invalid_dates;
create table t1 (a char, b char, c date)
@@ -24,22 +24,6 @@ partition by range columns (a,b,c)
( partition p0 values less than (0,0,'3000-11-31'));
ERROR HY000: Partition column values of incorrect type
set @@sql_mode='';
-create table t1 (a varchar(2) character set ucs2)
-partition by list columns (a)
-(partition p0 values in (0x2020),
-partition p1 values in (''));
-set names utf8;
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` varchar(2) CHARACTER SET ucs2 DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-/*!50100 PARTITION BY LIST COLUMNS(a)
-(PARTITION p0 VALUES IN ('†') ENGINE = MyISAM,
- PARTITION p1 VALUES IN ('') ENGINE = MyISAM) */
-insert into t1 values ('');
-insert into t1 values (_ucs2 0x2020);
-drop table t1;
create table t1 (a int, b char(10), c varchar(25), d datetime)
partition by range columns(a,b,c,d)
subpartition by hash (to_seconds(d))
=== added file 'mysql-test/r/partition_utf8.result'
--- a/mysql-test/r/partition_utf8.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/partition_utf8.result 2009-11-02 13:49:26 +0000
@@ -0,0 +1,53 @@
+set names utf8;
+create table t1 (a varchar(2) character set cp1250)
+partition by list columns (a)
+( partition p0 values in (0x81));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(2) CHARACTER SET cp1250 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST COLUMNS(a)
+(PARTITION p0 VALUES IN (_cp1250 0x81) ENGINE = MyISAM) */
+drop table t1;
+create table t1 (a varchar(2) character set cp1250)
+partition by list columns (a)
+( partition p0 values in (0x80));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(2) CHARACTER SET cp1250 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST COLUMNS(a)
+(PARTITION p0 VALUES IN ('€') ENGINE = MyISAM) */
+drop table t1;
+create table t1 (a varchar(1500), b varchar(1570))
+partition by list columns(a,b)
+( partition p0 values in (('a','b')));
+ERROR HY000: The total length of the partitioning fields is too large
+create table t1 (a varchar(1023) character set utf8 collate utf8_spanish2_ci)
+partition by range columns(a)
+( partition p0 values less than ('CZ'),
+partition p1 values less than ('CH'),
+partition p2 values less than ('D'));
+insert into t1 values ('czz'),('chi'),('ci'),('cg');
+select * from t1 where a between 'cg' AND 'ci';
+a
+ci
+cg
+drop table t1;
+create table t1 (a varchar(2) character set ucs2)
+partition by list columns (a)
+(partition p0 values in (0x2020),
+partition p1 values in (''));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` varchar(2) CHARACTER SET ucs2 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST COLUMNS(a)
+(PARTITION p0 VALUES IN ('†') ENGINE = MyISAM,
+ PARTITION p1 VALUES IN ('') ENGINE = MyISAM) */
+insert into t1 values ('');
+insert into t1 values (_ucs2 0x2020);
+drop table t1;
=== modified file 'mysql-test/t/partition_column.test'
--- a/mysql-test/t/partition_column.test 2009-11-02 10:03:40 +0000
+++ b/mysql-test/t/partition_column.test 2009-11-02 13:49:26 +0000
@@ -8,21 +8,12 @@
drop table if exists t1;
--enable_warnings
-#
-# BUG#48164, too long partition fields causes crash
-#
---error ER_PARTITION_FIELDS_TOO_LONG
-create table t1 (a varchar(1500), b varchar(1570))
-partition by list columns(a,b)
-( partition p0 values in (('a','b')));
-
-create table t1 (a varchar(1023) character set utf8 collate utf8_spanish2_ci)
-partition by range columns(a)
-( partition p0 values less than ('CZ'),
- partition p1 values less than ('CH'),
- partition p2 values less than ('D'));
-insert into t1 values ('czz'),('chi'),('ci'),('cg');
-select * from t1 where a between 'cg' AND 'ci';
+create table t1 (a varchar(5))
+partition by list columns(a)
+( partition p0 values in ('\''),
+ partition p1 values in ('\\'),
+ partition p2 values in ('\0'));
+show create table t1;
drop table t1;
#
@@ -40,19 +31,6 @@ partition by range columns (a,b,c)
( partition p0 values less than (0,0,'3000-11-31'));
set @@sql_mode='';
-#
-# BUG#48163, Dagger in UCS2 not working as partition value
-#
-create table t1 (a varchar(2) character set ucs2)
-partition by list columns (a)
-(partition p0 values in (0x2020),
- partition p1 values in (''));
-set names utf8;
-show create table t1;
-insert into t1 values ('');
-insert into t1 values (_ucs2 0x2020);
-drop table t1;
-
--error ER_WRONG_TYPE_COLUMN_VALUE_ERROR
create table t1 (a int, b char(10), c varchar(25), d datetime)
partition by range columns(a,b,c,d)
=== added file 'mysql-test/t/partition_utf8.test'
--- a/mysql-test/t/partition_utf8.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/partition_utf8.test 2009-11-02 13:49:26 +0000
@@ -0,0 +1,42 @@
+# Tests for Column list which requires utf8 output
+--source include/have_partition.inc
+set names utf8;
+create table t1 (a varchar(2) character set cp1250)
+partition by list columns (a)
+( partition p0 values in (0x81));
+show create table t1;
+drop table t1;
+create table t1 (a varchar(2) character set cp1250)
+partition by list columns (a)
+( partition p0 values in (0x80));
+show create table t1;
+drop table t1;
+
+#
+# BUG#48164, too long partition fields causes crash
+#
+--error ER_PARTITION_FIELDS_TOO_LONG
+create table t1 (a varchar(1500), b varchar(1570))
+partition by list columns(a,b)
+( partition p0 values in (('a','b')));
+
+create table t1 (a varchar(1023) character set utf8 collate utf8_spanish2_ci)
+partition by range columns(a)
+( partition p0 values less than ('CZ'),
+ partition p1 values less than ('CH'),
+ partition p2 values less than ('D'));
+insert into t1 values ('czz'),('chi'),('ci'),('cg');
+select * from t1 where a between 'cg' AND 'ci';
+drop table t1;
+
+#
+# BUG#48163, Dagger in UCS2 not working as partition value
+#
+create table t1 (a varchar(2) character set ucs2)
+partition by list columns (a)
+(partition p0 values in (0x2020),
+ partition p1 values in (''));
+show create table t1;
+insert into t1 values ('');
+insert into t1 values (_ucs2 0x2020);
+drop table t1;
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2009-11-02 10:09:15 +0000
+++ b/sql/mysql_priv.h 2009-11-02 13:49:26 +0000
@@ -1326,7 +1326,6 @@ void remove_status_vars(SHOW_VAR *list);
void init_status_vars();
void free_status_vars();
void reset_status_vars();
-
/* information schema */
extern LEX_STRING INFORMATION_SCHEMA_NAME;
/* log tables */
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2009-10-30 21:35:20 +0000
+++ b/sql/sql_partition.cc 2009-11-02 13:49:26 +0000
@@ -2132,92 +2132,6 @@ static Create_field* get_sql_field(char
}
-/*
- Convert a string in a given character set to a string which can be
- used for FRM file storage in which case use_hex is TRUE and we store
- the character constants as hex strings in the character set encoding
- their field have. In the case of SHOW CREATE TABLE and the
- PARTITIONS information schema table we instead provide utf8 strings
- to the user and convert to the utf8 character set.
-
- SYNOPSIS
- get_converted_part_value_from_string()
- item Item from which constant comes
- res String as provided by val_str after
- conversion to character set
- field_cs Character set string is encoded in
- NULL for INT_RESULT's here
- val_conv Out value: The string created
- use_hex TRUE => hex string created
- FALSE => utf8 constant string created
- RETURN VALUES
- TRUE Error
- FALSE Ok
-*/
-
-int get_converted_part_value_from_string(Item *item,
- String *res,
- CHARSET_INFO *field_cs,
- String *val_conv,
- bool use_hex)
-{
- String val;
- uint dummy_errors;
- uint len, high, low, i;
- const char *ptr;
- char buf[3];
-
- if (item->result_type() == INT_RESULT)
- {
- longlong value= item->val_int();
- val_conv->set(value, system_charset_info);
- return FALSE;
- }
- if (!res)
- {
- my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
- return TRUE;
- }
- val_conv->length(0);
- if (!field_cs || res->length() == 0)
- {
- val_conv->append("'");
- if (res->length() != 0)
- val_conv->append(*res);
- val_conv->append("'");
- return FALSE;
- }
- if (field_cs && use_hex)
- {
- val_conv->append("_");
- val_conv->append(field_cs->csname);
- val_conv->append(" ");
- }
- if (use_hex)
- {
- val_conv->append("0x");
- len= res->length();
- ptr= res->ptr();
- for (i= 0; i < len; i++)
- {
- high= (*ptr) >> 4;
- low= (*ptr) & 0x0F;
- buf[0]= _dig_vec_upper[high];
- buf[1]= _dig_vec_upper[low];
- buf[2]= 0;
- val_conv->append((const char*)buf);
- ptr++;
- }
- }
- else
- {
- val.copy(res->ptr(), res->length(), field_cs,
- system_charset_info, &dummy_errors);
- append_unescaped(val_conv, val.ptr(), val.length());
- }
- return FALSE;
-}
-
static int add_column_list_values(File fptr, partition_info *part_info,
part_elem_value *list_value,
HA_CREATE_INFO *create_info,
@@ -2311,9 +2225,11 @@ static int add_column_list_values(File f
}
{
String val_conv;
+ val_conv.set_charset(system_charset_info);
res= item_expr->val_str(&str);
- if (get_converted_part_value_from_string(item_expr, res,
- field_cs, &val_conv,
+ if (get_cs_converted_part_value_from_string(current_thd,
+ item_expr, res,
+ &val_conv, field_cs,
(bool)(alter_info != NULL)))
return 1;
err+= add_string_object(fptr, &val_conv);
=== modified file 'sql/sql_partition.h'
--- a/sql/sql_partition.h 2009-10-30 20:08:34 +0000
+++ b/sql/sql_partition.h 2009-11-02 13:49:26 +0000
@@ -75,11 +75,12 @@ void get_partition_set(const TABLE *tabl
const key_range *key_spec,
part_id_range *part_spec);
uint get_partition_field_store_length(Field *field);
-int get_converted_part_value_from_string(Item *item,
- String *res,
- CHARSET_INFO *cs,
- String *val_conv,
- bool use_hex);
+int get_cs_converted_part_value_from_string(THD *thd,
+ Item *item,
+ String *input_str,
+ String *output_str,
+ CHARSET_INFO *cs,
+ bool use_hex);
void get_full_part_id_from_key(const TABLE *table, uchar *buf,
KEY *key_info,
const key_range *key_spec,
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2009-11-02 10:09:15 +0000
+++ b/sql/sql_show.cc 2009-11-02 13:49:26 +0000
@@ -78,6 +78,12 @@ static TYPELIB grant_types = { sizeof(gr
static void store_key_options(THD *thd, String *packet, TABLE *table,
KEY *key_info);
+static void get_cs_converted_string_value(THD *thd,
+ String *input_str,
+ String *output_str,
+ CHARSET_INFO *cs,
+ bool use_hex);
+
static void
append_algorithm(TABLE_LIST *table, String *buff);
@@ -4795,6 +4801,57 @@ static void collect_partition_expr(List<
}
return;
}
+
+
+/*
+ Convert a string in a given character set to a string which can be
+ used for FRM file storage in which case use_hex is TRUE and we store
+ the character constants as hex strings in the character set encoding
+ their field have. In the case of SHOW CREATE TABLE and the
+ PARTITIONS information schema table we instead provide utf8 strings
+ to the user and convert to the utf8 character set.
+
+ SYNOPSIS
+ get_cs_converted_part_value_from_string()
+ item Item from which constant comes
+ input_str String as provided by val_str after
+ conversion to character set
+ output_str Out value: The string created
+ cs Character set string is encoded in
+ NULL for INT_RESULT's here
+ use_hex TRUE => hex string created
+ FALSE => utf8 constant string created
+
+ RETURN VALUES
+ TRUE Error
+ FALSE Ok
+*/
+
+int get_cs_converted_part_value_from_string(THD *thd,
+ Item *item,
+ String *input_str,
+ String *output_str,
+ CHARSET_INFO *cs,
+ bool use_hex)
+{
+ if (item->result_type() == INT_RESULT)
+ {
+ longlong value= item->val_int();
+ output_str->set(value, system_charset_info);
+ return FALSE;
+ }
+ if (!input_str)
+ {
+ my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+ return TRUE;
+ }
+ get_cs_converted_string_value(thd,
+ input_str,
+ output_str,
+ cs,
+ use_hex);
+ return FALSE;
+}
#endif
@@ -4877,7 +4934,8 @@ static void store_schema_partitions_reco
}
static int
-get_partition_column_description(partition_info *part_info,
+get_partition_column_description(THD *thd,
+ partition_info *part_info,
part_elem_value *list_value,
String &tmp_str)
{
@@ -4905,9 +4963,9 @@ get_partition_column_description(partiti
DBUG_RETURN(1);
}
String *res= item->val_str(&str);
- if (get_converted_part_value_from_string(item, res,
+ if (get_cs_converted_part_value_from_string(thd, item, res, &val_conv,
part_info->part_field_array[i]->charset(),
- &val_conv, FALSE))
+ FALSE))
{
DBUG_RETURN(1);
}
@@ -5055,7 +5113,8 @@ static int get_schema_partitions_record(
List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
part_elem_value *list_value= list_val_it++;
tmp_str.length(0);
- if (get_partition_column_description(part_info,
+ if (get_partition_column_description(thd,
+ part_info,
list_value,
tmp_str))
{
@@ -5092,7 +5151,8 @@ static int get_schema_partitions_record(
{
if (part_info->part_field_list.elements > 1U)
tmp_str.append("(");
- if (get_partition_column_description(part_info,
+ if (get_partition_column_description(thd,
+ part_info,
list_value,
tmp_str))
{
@@ -7231,3 +7291,95 @@ bool show_create_trigger(THD *thd, const
status and client connection will be closed.
*/
}
+
+/*
+ Convert a string in character set in column character set format
+ to utf8 character set if possible, the utf8 character set string
+ will later possibly be converted to character set used by client.
+ Thus we attempt conversion from column character set to both
+ utf8 and to character set client.
+
+ Examples of strings that should fail conversion to utf8 are unassigned
+ characters as e.g. 0x81 in cp1250 (Windows character set for for countries
+ like Czech and Poland). Example of string that should fail conversion to
+ character set on client (e.g. if this is latin1) is 0x2020 (daggger) in
+ ucs2.
+
+ If the conversion fails we will as a fall back convert the string to
+ hex encoded format. The caller of the function can also ask for hex
+ encoded format of output string unconditionally.
+
+ SYNOPSIS
+ get_cs_converted_string_value()
+ thd Thread object
+ input_str Input string in cs character set
+ output_str Output string to be produced in utf8
+ cs Character set of input string
+ use_hex Use hex string unconditionally
+
+
+ RETURN VALUES
+ No return value
+*/
+
+static void get_cs_converted_string_value(THD *thd,
+ String *input_str,
+ String *output_str,
+ CHARSET_INFO *cs,
+ bool use_hex)
+{
+
+ output_str->length(0);
+ if (input_str->length() == 0)
+ {
+ output_str->append("''");
+ return;
+ }
+ if (!use_hex)
+ {
+ String try_val;
+ uint try_conv_error= 0;
+
+ try_val.copy(input_str->ptr(), input_str->length(), cs,
+ thd->variables.character_set_client, &try_conv_error);
+ if (!try_conv_error)
+ {
+ String val;
+ uint conv_error= 0;
+
+ val.copy(input_str->ptr(), input_str->length(), cs,
+ system_charset_info, &conv_error);
+ if (!conv_error)
+ {
+ append_unescaped(output_str, val.ptr(), val.length());
+ return;
+ }
+ }
+ /* We had a conversion error, use hex encoded string for safety */
+ }
+ {
+ const uchar *ptr;
+ uint i, len;
+ char buf[3];
+
+ output_str->append("_");
+ output_str->append(cs->csname);
+ output_str->append(" ");
+ output_str->append("0x");
+ len= input_str->length();
+ ptr= (uchar*)input_str->ptr();
+ for (i= 0; i < len; i++)
+ {
+ uint high, low;
+
+ high= (*ptr) >> 4;
+ low= (*ptr) & 0x0F;
+ buf[0]= _dig_vec_upper[high];
+ buf[1]= _dig_vec_upper[low];
+ buf[2]= 0;
+ output_str->append((const char*)buf);
+ ptr++;
+ }
+ }
+ return;
+}
| Thread |
|---|
| • bzr commit into mysql-5.5-next-mr branch (mikael:2920) Bug#48464 | Mikael Ronstrom | 2 Nov |