summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mysql.com>2010-02-11 08:17:25 +0400
committerAlexander Barkov <bar@mysql.com>2010-02-11 08:17:25 +0400
commit702166bcdec5705dd90d8567a88056893433c719 (patch)
treed6306efc9e4d7e6bc6bf4ae5a58bd6aec40420e9 /sql/item_timefunc.h
parent6dd93757263fd219fcbd3d1ed100a681ecbc7c92 (diff)
downloadmariadb-git-702166bcdec5705dd90d8567a88056893433c719.tar.gz
WL#2649 Number-to-string conversions
added: include/ctype_numconv.inc mysql-test/include/ctype_numconv.inc mysql-test/r/ctype_binary.result mysql-test/t/ctype_binary.test Adding tests modified: mysql-test/r/bigint.result mysql-test/r/case.result mysql-test/r/create.result mysql-test/r/ctype_cp1251.result mysql-test/r/ctype_latin1.result mysql-test/r/ctype_ucs.result mysql-test/r/func_gconcat.result mysql-test/r/func_str.result mysql-test/r/metadata.result mysql-test/r/ps_1general.result mysql-test/r/ps_2myisam.result mysql-test/r/ps_3innodb.result mysql-test/r/ps_4heap.result mysql-test/r/ps_5merge.result mysql-test/r/show_check.result mysql-test/r/type_datetime.result mysql-test/r/type_ranges.result mysql-test/r/union.result mysql-test/suite/ndb/r/ps_7ndb.result mysql-test/t/ctype_cp1251.test mysql-test/t/ctype_latin1.test mysql-test/t/ctype_ucs.test mysql-test/t/func_str.test Fixing tests @ sql/field.cc - Return str result using my_charset_numeric. - Using real multi-byte aware str_to_XXX functions to handle tricky charset values propely (e.g. UCS2) @ sql/field.h - Changing derivation of non-string field types to DERIVATION_NUMERIC. - Changing binary() for numeric/datetime fields to always return TRUE even if charset is not my_charset_bin. We need this to keep ha_base_keytype() return HA_KEYTYPE_BINARY. - Adding BINARY_FLAG into some fields, because it's not being set automatically anymore with "my_charset_bin to my_charset_numeric" change. - Changing derivation for numeric/datetime datatypes to a weaker value, to make "SELECT concat('string', field)" use character set of the string literal for the result of the function. @ sql/item.cc - Implementing generic val_str_ascii(). - Using max_char_length() instead of direct read of max_length to make "tricky" charsets like UCS2 work. NOTE: in the future we'll possibly remove all direct reads of max_length - Fixing Item_num::safe_charset_converter(). Previously it alligned binary string to character string (for example by adding leading 0x00 when doing binary->UCS2 conversion). Now it just converts from my_charset_numbner to "tocs". - Using val_str_ascii() in Item::get_time() to make UCS2 arguments work. - Other misc changes @ sql/item.h - Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to bit operations instead of hard-coded bit masks. - Addding new method DTCollation.set_numeric(). - Adding new methods to Item. - Adding helper functions to make code look nicer: agg_item_charsets_for_string_result() agg_item_charsets_for_comparison() - Changing charset for Item_num-derived items from my_charset_bin to my_charset_numeric (which is an alias for latin1). @ sql/item_cmpfunc.cc - Using new helper functions - Other misc changes @ sql/item_cmpfunc.h - Fixing strcmp() to return max_length=2. Previously it returned 1, which was wrong, because it did not fit '-1'. @ sql/item_func.cc - Using new helper functions - Other minor changes @ sql/item_func.h - Removing unused functions - Adding helper functions agg_arg_charsets_for_string_result() agg_arg_charsets_for_comparison() - Adding set_numeric() into constructors of numeric items. - Using fix_length_and_charset() and fix_char_length() instead of direct write to max_length. @ sql/item_geofunc.cc - Changing class for Item_func_geometry_type and Item_func_as_wkt from Item_str_func to Item_str_ascii_func, to make them return UCS2 result properly (when character_set_connection=ucs2). @ sql/item_geofunc.h - Changing class for Item_func_geometry_type and Item_func_as_wkt from Item_str_func to Item_str_ascii_func, to make them return UCS2 result properly (when @@character_set_connection=ucs2). @ sql/item_strfunc.cc - Implementing Item_str_func::val_str(). - Renaming val_str to val_str_ascii for some items, to make them work with UCS2 properly. - Using new helper functions - All single-argument functions that expect string result now call this method: agg_arg_charsets_for_string_result(collation, args, 1); This enables character set conversion to @@character_set_connection in case of pure numeric input. @ sql/item_strfunc.h - Introducing Item_str_ascii_func - for functions which return pure ASCII data, for performance purposes, as well as for the cases when the old implementation of val_str() was heavily 8-bit oriented and implementing a UCS2-aware version is tricky. @ sql/item_sum.cc - Using new helper functions. @ sql/item_timefunc.cc - Using my_charset_numeric instead of my_charset_bin. - Using fix_char_length(), fix_length_and_charset() and fix_length_and_charset_datetime() instead of direct write to max_length. - Using tricky-charset aware function str_to_time_with_warn() @ sql/item_timefunc.h - Using new helper functions for charset and length initialization. - Changing base class for Item_func_get_format() to make it return UCS2 properly (when character_set_connection=ucs2). @ sql/item_xmlfunc.cc - Using new helper function @ sql/my_decimal.cc - Adding a new DECIMAL to CHAR converter with real multibyte support (e.g. UCS2) @ sql/mysql_priv.h - Introducing a new derivation level for numeric/datetime data types. - Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC. - Adding prototypes for str_set_decimal() - Adding prototypes for character-set aware str_to_xxx() functions. @ sql/protocol.cc - Changing charsetnr to "binary" client-side metadata for numeric/datetime data types. @ sql/time.cc - Adding to_ascii() helper function, to convert a string in any character set to ascii representation. In the future can be extended to understand digits written in various non-Latin word scripts. - Adding real multy-byte character set aware versions for str_to_XXXX, to make these these type of queries work correct: INSERT INTO t1 SET datetime_column=ucs2_expression; @ strings/ctype-ucs2.c - endptr was not calculated correctly. INSERTing of UCS2 values into numeric columns returned warnings about truncated wrong data.
Diffstat (limited to 'sql/item_timefunc.h')
-rw-r--r--sql/item_timefunc.h73
1 files changed, 33 insertions, 40 deletions
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 860bd983184..20e4d6488d6 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -122,23 +122,22 @@ public:
class Item_func_month :public Item_func
{
public:
- Item_func_month(Item *a) :Item_func(a) {}
+ Item_func_month(Item *a) :Item_func(a) { collation.set_numeric(); }
longlong val_int();
double val_real()
{ DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); }
String *val_str(String *str)
{
- str->set(val_int(), &my_charset_bin);
+ str->set(val_int(), collation.collation);
return null_value ? 0 : str;
}
const char *func_name() const { return "month"; }
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ decimals= 0;
+ fix_char_length(2);
+ maybe_null= 1;
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
};
@@ -165,9 +164,9 @@ public:
const char *func_name() const { return "dayofyear"; }
void fix_length_and_dec()
{
- decimals=0;
- max_length=3*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ decimals= 0;
+ fix_char_length(3);
+ maybe_null= 1;
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
};
@@ -290,7 +289,7 @@ class Item_func_weekday :public Item_func
bool odbc_type;
public:
Item_func_weekday(Item *a,bool type_arg)
- :Item_func(a), odbc_type(type_arg) {}
+ :Item_func(a), odbc_type(type_arg) { collation.set_numeric(); }
longlong val_int();
double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
String *val_str(String *str)
@@ -306,10 +305,9 @@ public:
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ decimals= 0;
+ fix_char_length(1);
+ maybe_null= 1;
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
};
@@ -379,15 +377,15 @@ public:
Item_date(Item *a) :Item_func(a) {}
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
String *val_str(String *str);
longlong val_int();
double val_real() { return val_real_from_decimal(); }
const char *func_name() const { return "date"; }
void fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
+ decimals= 0;
+ fix_length_and_charset_datetime(MAX_DATE_WIDTH);
}
Field *tmp_table_field(TABLE *table)
{
@@ -414,6 +412,7 @@ public:
Item_date_func(Item *a,Item *b) :Item_str_func(a,b) {}
Item_date_func(Item *a,Item *b, Item *c) :Item_str_func(a,b,c) {}
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
@@ -440,10 +439,11 @@ public:
Item_str_timefunc(Item *a,Item *b) :Item_str_func(a,b) {}
Item_str_timefunc(Item *a, Item *b, Item *c) :Item_str_func(a, b ,c) {}
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
void fix_length_and_dec()
{
decimals= DATETIME_DEC;
- max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
+ fix_length_and_charset_datetime(MAX_TIME_WIDTH);
}
Field *tmp_table_field(TABLE *table)
{
@@ -701,7 +701,6 @@ public:
void fix_length_and_dec()
{
Item_str_timefunc::fix_length_and_dec();
- collation.set(&my_charset_bin);
maybe_null=1;
}
const char *func_name() const { return "sec_to_time"; }
@@ -774,13 +773,7 @@ public:
class Item_typecast_maybe_null :public Item_typecast
{
public:
- Item_typecast_maybe_null(Item *a) :Item_typecast(a) {}
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- max_length=args[0]->max_length;
- maybe_null= 1;
- }
+ Item_typecast_maybe_null(Item *a) :Item_typecast(a) { maybe_null= 1; }
};
@@ -813,16 +806,12 @@ public:
bool get_time(MYSQL_TIME *ltime);
const char *cast_type() const { return "date"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
- }
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- max_length= 10;
- maybe_null= 1;
}
+ void fix_length_and_dec() { fix_length_and_charset_datetime(10); }
bool result_as_longlong() { return TRUE; }
longlong val_int();
double val_real() { return (double) val_int(); }
@@ -847,6 +836,7 @@ public:
bool get_time(MYSQL_TIME *ltime);
const char *cast_type() const { return "time"; }
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
@@ -863,6 +853,8 @@ public:
{
return save_time_in_field(field);
}
+ void fix_length_and_dec()
+ { fix_length_and_charset_datetime(args[0]->max_char_length()); }
};
@@ -874,15 +866,14 @@ public:
String *val_str(String *str);
const char *cast_type() const { return "datetime"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
}
void fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- maybe_null= 1;
- max_length= MAX_DATETIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
+ fix_length_and_charset_datetime(MAX_DATETIME_FULL_WIDTH);
decimals= DATETIME_DEC;
}
bool result_as_longlong() { return TRUE; }
@@ -907,10 +898,11 @@ public:
String *val_str(String *str);
const char *func_name() const { return "makedate"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
void fix_length_and_dec()
{
decimals=0;
- max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
+ fix_length_and_charset_datetime(MAX_DATE_WIDTH);
maybe_null= 1;
}
longlong val_int();
@@ -929,6 +921,7 @@ public:
String *val_str(String *str);
enum_field_types field_type() const { return cached_field_type; }
void fix_length_and_dec();
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
@@ -1019,20 +1012,20 @@ enum date_time_format
USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT
};
-class Item_func_get_format :public Item_str_func
+class Item_func_get_format :public Item_str_ascii_func
{
public:
const timestamp_type type; // keep it public
Item_func_get_format(timestamp_type type_arg, Item *a)
- :Item_str_func(a), type(type_arg)
+ :Item_str_ascii_func(a), type(type_arg)
{}
- String *val_str(String *str);
+ String *val_str_ascii(String *str);
const char *func_name() const { return "get_format"; }
void fix_length_and_dec()
{
maybe_null= 1;
decimals=0;
- max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
+ fix_length_and_charset(17, default_charset());
}
virtual void print(String *str, enum_query_type query_type);
};