diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-03-01 13:24:36 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-03-01 13:24:36 +0100 |
commit | a8a757c6bb32bbf291afdf33df861127489889ab (patch) | |
tree | cee7858869789964ad21b2b90b420f1128d9a10d /sql/item_timefunc.h | |
parent | 7e0e4b00c971b81b5ffd18db4f1ea977233e98be (diff) | |
download | mariadb-git-a8a757c6bb32bbf291afdf33df861127489889ab.tar.gz |
wl#173 - temporal types with sub-second resolution
and collateral changes.
* introduce my_hrtime_t, my_timediff_t, and conversion macros
* inroduce TIME_RESULT, but it can only be returned from Item::cmp_type(),
never from Item::result_type()
* pack_time/unpack_time function for "packed" representation of
MYSQL_TIME in a longlong that can be compared
* ADDTIME()/SUBTIME()/+- INTERVAL now work with TIME values
* numbers aren't quoted in EXPLAIN EXTENDED
* new column I_S.COLUMNS.DATETIME_PRECISION
* date/time values are compares to anything as date/time, not as strings or numbers.
* old timestamp(X) is no longer supported
* MYSQL_TIME to string conversion functions take precision as an argument
* unified the warnings from Field_timestamp/datetime/time/date/newdate store methods
* Field_timestamp_hires, Field_datetime_hires, Field_time_hires
* Field_temporal
* Lazy_string class to pass a value (string, number, time) polymorphically down the stack
* make_truncated_value_warning and Field::set_datetime_warning use Lazy_string as an argument, removed char*/int/double variants
* removed Field::can_be_compared_as_longlong(). Use Field::cmp_type() == INT_RESULT instead
* introduced Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
* in many cases date/time types are treated like other types, not as special cases
* greatly simplified Arg_comparator (regarding date/time/year code)
* SEC_TO_TIME is real function, not integer.
* microsecond precision in NOW, CURTIME, etc
* Item_temporal. All items derived from it only provide get_date, but no val* methods
* replication of NOW(6)
* Protocol::store(time) now takes the precision as an argument
* @@TIMESTAMP is a double
client/mysqlbinlog.cc:
remove unneded casts
include/my_sys.h:
introduce my_hrtime_t, my_timediff_t, and conversion macros
include/my_time.h:
pack_time/unpack_time, etc.
convenience functions to work with MYSQL_TIME::second_part
libmysql/libmysql.c:
str_to_time() is gone. str_to_datetime() does it now.
my_TIME_to_str() takes the precision as an argument
mysql-test/include/ps_conv.inc:
time is not equal to datetime anymore
mysql-test/r/distinct.result:
a test for an old MySQL bug
mysql-test/r/explain.result:
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/func_default.result:
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/func_sapdb.result:
when decimals=NOT_FIXED_DEC it means "not fixed" indeed
mysql-test/r/func_test.result:
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/func_time.result:
ADDTIME()/SUBTIME()/+- INTERVAL now work with TIME values
mysql-test/r/having.result:
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/information_schema.result:
new column I_S.COLUMNS.DATETIME_PRECISION
mysql-test/r/join_outer.result:
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/metadata.result:
TIMESTAMP no longer has zerofill flag
mysql-test/r/range.result:
invalid datetime is not compared with as a string
mysql-test/r/select.result:
NO_ZERO_IN_DATE, etc only affect storage - according to the manual
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/subselect.result:
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/sysdate_is_now.result:
when decimals=NOT_FIXED_DEC it means "not fixed" indeed
mysql-test/r/type_blob.result:
TIMESTAMP(N) is not deprecated
mysql-test/r/type_timestamp.result:
old TIMESTAMP(X) semantics is not supported anymore
mysql-test/r/union.result:
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/r/varbinary.result:
numbers aren't quoted in EXPLAIN EXTENDED
mysql-test/t/distinct.test:
test for an old MySQL bug
mysql-test/t/func_time.test:
+- INTERVAL now works with TIME values
mysql-test/t/select.test:
typo
mysql-test/t/subselect.test:
only one error per statement, please
mysql-test/t/system_mysql_db_fix40123.test:
old timestamp(X) is no longer supported
mysql-test/t/system_mysql_db_fix50030.test:
old timestamp(X) is no longer supported
mysql-test/t/system_mysql_db_fix50117.test:
old timestamp(X) is no longer supported
mysql-test/t/type_blob.test:
old timestamp(X) is no longer supported
mysql-test/t/type_timestamp.test:
old timestamp(X) is no longer supported
mysys/my_getsystime.c:
functions to get the time with microsecond precision
mysys/my_init.c:
move the my_getsystime.c initialization code to my_getsystime.c
mysys/my_static.c:
no need to make these variables extern
mysys/my_static.h:
no need to make these variables extern
scripts/mysql_system_tables.sql:
old timestamp(X) is no longer supported
scripts/mysql_system_tables_fix.sql:
old timestamp(X) is no longer supported
scripts/mysqlhotcopy.sh:
old timestamp(X) is no longer supported
sql-common/my_time.c:
* call str_to_time from str_to_datetime, as appropriate
* date/time to string conversions take precision as an argument
* number_to_time()
* TIME_to_double()
* pack_time() and unpack_time()
sql/event_data_objects.cc:
cast is not needed
my_datetime_to_str() takes precision as an argument
sql/event_db_repository.cc:
avoid dangerous downcast (because the pointer is
not always Field_timestamp, see events_1.test)
sql/event_queue.cc:
avoid silly double-work for cond_wait
(having an endpoint of wait, subtract the current time to get the timeout,
and use set_timespec() macro to fill in struct timespec, by adding the current
time to the timeout)
sql/field.cc:
* remove virtual Field::get_time(), everyone should use only Field::get_date()
* remove lots of #ifdef WORDS_BIGENDIAN
* unified the warnings from Field_timestamp/datetime/time/date/newdate store methods
* Field_timestamp_hires, Field_datetime_hires, Field_time_hires
* Field_temporal
* make_truncated_value_warning and Field::set_datetime_warning use Lazy_string as an argument, removed char*/int/double variants
sql/field.h:
* remove virtual Field::get_time(), everyone should use only Field::get_date()
* remove lots of #ifdef WORDS_BIGENDIAN
* unified the warnings from Field_timestamp/datetime/time/date/newdate store methods
* Field_timestamp_hires, Field_datetime_hires, Field_time_hires
* Field_temporal
* make_truncated_value_warning and Field::set_datetime_warning use Lazy_string as an argument, removed char*/int/double variants
* removed Field::can_be_compared_as_longlong(). Use Field::cmp_type() == INT_RESULT instead
sql/filesort.cc:
TIME_RESULT, cmp_time()
sql/item.cc:
* numbers aren't quoted in EXPLAIN EXTENDED
* Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
* virtual Item::get_time() is gone
* Item_param::field_type() is set correctly
* Item_datetime, for a datetime constant
* time to anything is compared as a time
* Item_cache::print() prints the value is available
* bug fixed in Item_cache_int::val_str()
sql/item.h:
* Item::print_value(), to be used from Item_xxx::print() when needed
* Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
* virtual Item::get_time() is gone
* Item_datetime, for a datetime constant
* better default for cast_to_int_type()
* Item_cache objects now *always* have the field_type() set
sql/item_cmpfunc.cc:
* get_year_value, get_time_value are gone. get_datetime_value does it all
* get_value_a_func, get_value_b_func are gone
* can_compare_as_dates() is gone too, TIME_RESULT is used instead
* cmp_type() instead or result_type() when doing a comparison
* compare_datetime and compate_e_datetime in the comparator_matrix, is_nulls_eq is gone
* Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
sql/item_cmpfunc.h:
greatly simplified Arg_comparator
sql/item_create.cc:
* fix a bug in error messages in CAST
sql/item_func.cc:
Item::cmp_result() instead of Item::is_datetime() and Item::result_as_longlong()
mention all possibitiles in switch over Item_result values, or use default:
sql/item_row.h:
overwrite the default cmp_type() for Item_row,
as no MYSQL_TYPE_xxx value corresponds to ROW_RESULT
sql/item_timefunc.cc:
rewrite make_datetime to support precision argument
SEC_TO_TIME is real function, not integer.
many functions that returned temporal values had duplicate code in val_* methods,
some of them did not have get_date() which resulted in unnecessary date->str->date conversions.
Now they all are derived from Item_temporal_func and *only* provide get_date, not val* methods.
many fixes to set decimals (datetime precision) correctly.
sql/item_timefunc.h:
SEC_TO_TIME is real function, not integer.
many functions that returned temporal values had duplicate code in val_* methods,
some of them did not have get_date() which resulted in unnecessary date->str->date conversions.
Now they all are derived from Item_temporal_func and *only* provide get_date, not val* methods.
many fixes to set decimals (datetime precision) correctly.
sql/log_event.cc:
replication of NOW(6)
sql/log_event.h:
replication of NOW(6)
sql/mysql_priv.h:
Lazy_string class to pass a value (string, number, time) polymorphically down the stack.
make_truncated_value_warning() that uses it.
sql/mysqld.cc:
datetime in Arg_comparator::comparator_matrix
sql/opt_range.cc:
cleanup: don't disable warnings before calling save_in_field_no_warnings()
sql/protocol.cc:
Protocol::store(time) now takes the precision as an argument
sql/protocol.h:
Protocol::store(time) now takes the precision as an argument
sql/rpl_rli.cc:
small cleanup
sql/set_var.cc:
SET TIMESTAMP=double
sql/set_var.h:
@@TIMESTAMP is a double
sql/share/errmsg.txt:
precision and scale are unsigned
sql/slave.cc:
replication of NOW(6)
sql/sp_head.cc:
cleanup
sql/sql_class.cc:
support for NOW(6)
sql/sql_class.h:
support for NOW(6)
sql/sql_insert.cc:
support for NOW(6)
sql/sql_select.cc:
use item->cmp_type().
move a comment where it belongs
sql/sql_show.cc:
new column I_S.COLUMNS.DATETIME_PRECISION
sql/sql_yacc.yy:
TIME(X), DATETIME(X), cast, NOW(X), CURTIME(X), etc
sql/time.cc:
fix date_add_interval() to support MYSQL_TIMESTAMP_TIME argument
storage/myisam/ha_myisam.cc:
TIMESTAMP no longer carries ZEROFIELD flag, still we keep MYI file compatible.
strings/my_vsnprintf.c:
warnings
tests/mysql_client_test.c:
old timestamp(X) does not work anymore
datetime is no longer equal to time
Diffstat (limited to 'sql/item_timefunc.h')
-rw-r--r-- | sql/item_timefunc.h | 407 |
1 files changed, 116 insertions, 291 deletions
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 47bb9509582..e2e65142902 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -323,147 +323,100 @@ public: }; -class Item_func_time_to_sec :public Item_int_func +class Item_func_time_to_sec :public Item_real_func { public: - Item_func_time_to_sec(Item *item) :Item_int_func(item) {} - longlong val_int(); + Item_func_time_to_sec(Item *item) :Item_real_func(item) {} const char *func_name() const { return "time_to_sec"; } + double val_real(); void fix_length_and_dec() { maybe_null= TRUE; - decimals=0; - max_length=10*MY_CHARSET_BIN_MB_MAXLEN; + decimals=args[0]->decimals; + max_length=17; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} }; -/* - This can't be a Item_str_func, because the val_real() functions are special -*/ - -class Item_date :public Item_func +class Item_temporal_func: public Item_func { public: - Item_date() :Item_func() {} - Item_date(Item *a) :Item_func(a) {} + Item_temporal_func() :Item_func() {} + Item_temporal_func(Item *a) :Item_func(a) {} + Item_temporal_func(Item *a, Item *b) :Item_func(a,b) {} + Item_temporal_func(Item *a, Item *b, Item *c) :Item_func(a,b,c) {} enum Item_result result_type () const { return STRING_RESULT; } - enum_field_types field_type() const { return MYSQL_TYPE_DATE; } + enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } 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; - } - Field *tmp_table_field(TABLE *table) - { - return tmp_table_field_from_field_type(table, 0); - } - bool result_as_longlong() { return TRUE; } + double val_real(); + bool get_date(MYSQL_TIME *res, uint fuzzy_date) { DBUG_ASSERT(0); return 1; } my_decimal *val_decimal(my_decimal *decimal_value) - { - DBUG_ASSERT(fixed == 1); - return val_decimal_from_date(decimal_value); - } + { return val_decimal_from_date(decimal_value); } + Field *tmp_table_field(TABLE *table) + { return tmp_table_field_from_field_type(table, 0); } int save_in_field(Field *field, bool no_conversions) - { - return save_date_in_field(field); - } + { return save_date_in_field(field); } }; - -class Item_date_func :public Item_str_func +class Item_datefunc :public Item_temporal_func { public: - Item_date_func() :Item_str_func() {} - Item_date_func(Item *a) :Item_str_func(a) {} - 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; } - Field *tmp_table_field(TABLE *table) - { - return tmp_table_field_from_field_type(table, 0); - } - bool result_as_longlong() { return TRUE; } - double val_real() { return (double) val_int(); } - my_decimal *val_decimal(my_decimal *decimal_value) - { - DBUG_ASSERT(fixed == 1); - return val_decimal_from_date(decimal_value); - } - int save_in_field(Field *field, bool no_conversions) - { - return save_date_in_field(field); + Item_datefunc() :Item_temporal_func() {} + Item_datefunc(Item *a) :Item_temporal_func(a) {} + enum_field_types field_type() const { return MYSQL_TYPE_DATE; } + const char *func_name() const { return "date"; } + bool get_date(MYSQL_TIME *res, uint fuzzy_date) + { return get_arg0_date(res, fuzzy_date); } + void fix_length_and_dec() + { + collation.set(&my_charset_bin); + decimals=0; + max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } }; -class Item_str_timefunc :public Item_str_func +class Item_timefunc :public Item_temporal_func { public: - Item_str_timefunc() :Item_str_func() {} - Item_str_timefunc(Item *a) :Item_str_func(a) {} - 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) {} + Item_timefunc() :Item_temporal_func() {} + Item_timefunc(Item *a) :Item_temporal_func(a) {} + Item_timefunc(Item *a,Item *b) :Item_temporal_func(a,b) {} + Item_timefunc(Item *a, Item *b, Item *c) :Item_temporal_func(a, b ,c) {} enum_field_types field_type() const { return MYSQL_TYPE_TIME; } void fix_length_and_dec() { - decimals= DATETIME_DEC; - max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; - } - Field *tmp_table_field(TABLE *table) - { - return tmp_table_field_from_field_type(table, 0); + max_length= MAX_TIME_WIDTH + + (decimals ? min(decimals, MAX_SEC_PART_DIGITS)+1 : 0); } - double val_real() { return val_real_from_decimal(); } - my_decimal *val_decimal(my_decimal *decimal_value) - { - DBUG_ASSERT(fixed == 1); - return val_decimal_from_time(decimal_value); - } - int save_in_field(Field *field, bool no_conversions) - { - return save_time_in_field(field); - } - longlong val_int() { return val_int_from_decimal(); } - bool result_as_longlong() { return TRUE; } }; /* Abstract CURTIME function. Children should define what time zone is used */ -class Item_func_curtime :public Item_str_timefunc +class Item_func_curtime :public Item_timefunc { - longlong value; - char buff[9*2+32]; - uint buff_length; + MYSQL_TIME ltime; public: - Item_func_curtime() :Item_str_timefunc() {} - Item_func_curtime(Item *a) :Item_str_timefunc(a) {} - double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } - longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } - String *val_str(String *str); + Item_func_curtime(uint dec) :Item_timefunc() { decimals= dec; } + bool fix_fields(THD *, Item **); void fix_length_and_dec(); + bool get_date(MYSQL_TIME *res, uint fuzzy_date); /* Abstract method that defines which time zone is used for conversion. Converts time current time in my_time_t representation to broken-down MYSQL_TIME representation using UTC-SYSTEM or per-thread time zone. */ virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; - bool result_as_longlong() { return TRUE; } }; class Item_func_curtime_local :public Item_func_curtime { public: - Item_func_curtime_local() :Item_func_curtime() {} - Item_func_curtime_local(Item *a) :Item_func_curtime(a) {} + Item_func_curtime_local(uint dec) :Item_func_curtime(dec) {} const char *func_name() const { return "curtime"; } virtual void store_now_in_TIME(MYSQL_TIME *now_time); }; @@ -472,8 +425,7 @@ public: class Item_func_curtime_utc :public Item_func_curtime { public: - Item_func_curtime_utc() :Item_func_curtime() {} - Item_func_curtime_utc(Item *a) :Item_func_curtime(a) {} + Item_func_curtime_utc(uint dec) :Item_func_curtime(dec) {} const char *func_name() const { return "utc_time"; } virtual void store_now_in_TIME(MYSQL_TIME *now_time); }; @@ -481,14 +433,11 @@ public: /* Abstract CURDATE function. See also Item_func_curtime. */ -class Item_func_curdate :public Item_date +class Item_func_curdate :public Item_datefunc { - longlong value; MYSQL_TIME ltime; public: - Item_func_curdate() :Item_date() {} - longlong val_int() { DBUG_ASSERT(fixed == 1); return (value) ; } - String *val_str(String *str); + Item_func_curdate() :Item_datefunc() {} void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; @@ -515,20 +464,12 @@ public: /* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */ -class Item_func_now :public Item_date_func +class Item_func_now :public Item_temporal_func { -protected: - longlong value; - char buff[20*2+32]; // +32 to make my_snprintf_{8bit|ucs2} happy - uint buff_length; MYSQL_TIME ltime; public: - Item_func_now() :Item_date_func() {} - Item_func_now(Item *a) :Item_date_func(a) {} - enum Item_result result_type () const { return STRING_RESULT; } - longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } - int save_in_field(Field *to, bool no_conversions); - String *val_str(String *str); + Item_func_now(uint dec) :Item_temporal_func() { decimals= dec; } + bool fix_fields(THD *, Item **); void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; @@ -538,8 +479,7 @@ public: class Item_func_now_local :public Item_func_now { public: - Item_func_now_local() :Item_func_now() {} - Item_func_now_local(Item *a) :Item_func_now(a) {} + Item_func_now_local(uint dec) :Item_func_now(dec) {} const char *func_name() const { return "now"; } virtual void store_now_in_TIME(MYSQL_TIME *now_time); virtual enum Functype functype() const { return NOW_FUNC; } @@ -549,8 +489,7 @@ public: class Item_func_now_utc :public Item_func_now { public: - Item_func_now_utc() :Item_func_now() {} - Item_func_now_utc(Item *a) :Item_func_now(a) {} + Item_func_now_utc(uint dec) :Item_func_now(dec) {} const char *func_name() const { return "utc_timestamp"; } virtual void store_now_in_TIME(MYSQL_TIME *now_time); }; @@ -563,16 +502,10 @@ public: class Item_func_sysdate_local :public Item_func_now { public: - Item_func_sysdate_local() :Item_func_now() {} - Item_func_sysdate_local(Item *a) :Item_func_now(a) {} + Item_func_sysdate_local(uint dec) :Item_func_now(dec) {} bool const_item() const { return 0; } const char *func_name() const { return "sysdate"; } void store_now_in_TIME(MYSQL_TIME *now_time); - double val_real(); - longlong val_int(); - int save_in_field(Field *to, bool no_conversions); - String *val_str(String *str); - void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); void update_used_tables() { @@ -582,10 +515,10 @@ public: }; -class Item_func_from_days :public Item_date +class Item_func_from_days :public Item_datefunc { public: - Item_func_from_days(Item *a) :Item_date(a) {} + Item_func_from_days(Item *a) :Item_datefunc(a) {} const char *func_name() const { return "from_days"; } bool get_date(MYSQL_TIME *res, uint fuzzy_date); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} @@ -609,13 +542,11 @@ public: }; -class Item_func_from_unixtime :public Item_date_func +class Item_func_from_unixtime :public Item_temporal_func { THD *thd; public: - Item_func_from_unixtime(Item *a) :Item_date_func(a) {} - longlong val_int(); - String *val_str(String *str); + Item_func_from_unixtime(Item *a) :Item_temporal_func(a) {} const char *func_name() const { return "from_unixtime"; } void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); @@ -636,7 +567,7 @@ class Time_zone; tables can be used during this function calculation for loading time zone descriptions. */ -class Item_func_convert_tz :public Item_date_func +class Item_func_convert_tz :public Item_temporal_func { /* If time zone parameters are constants we are caching objects that @@ -648,9 +579,7 @@ class Item_func_convert_tz :public Item_date_func Time_zone *from_tz, *to_tz; public: Item_func_convert_tz(Item *a, Item *b, Item *c): - Item_date_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {} - longlong val_int(); - String *val_str(String *str); + Item_temporal_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {} const char *func_name() const { return "convert_tz"; } void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); @@ -658,29 +587,25 @@ class Item_func_convert_tz :public Item_date_func }; -class Item_func_sec_to_time :public Item_str_timefunc +class Item_func_sec_to_time :public Item_timefunc { public: - Item_func_sec_to_time(Item *item) :Item_str_timefunc(item) {} - double val_real() - { - DBUG_ASSERT(fixed == 1); - return (double) Item_func_sec_to_time::val_int(); - } - longlong val_int(); - String *val_str(String *); + Item_func_sec_to_time(Item *item) :Item_timefunc(item) {} + bool get_date(MYSQL_TIME *res, uint fuzzy_date); void fix_length_and_dec() { - Item_str_timefunc::fix_length_and_dec(); collation.set(&my_charset_bin); maybe_null=1; + decimals= args[0]->decimals; + if (decimals != NOT_FIXED_DEC && decimals > MAX_SEC_PART_DIGITS) + decimals= MAX_SEC_PART_DIGITS; + Item_timefunc::fix_length_and_dec(); } const char *func_name() const { return "sec_to_time"; } - bool result_as_longlong() { return TRUE; } }; -class Item_date_add_interval :public Item_date_func +class Item_date_add_interval :public Item_temporal_func { String value; enum_field_types cached_field_type; @@ -689,12 +614,10 @@ public: const interval_type int_type; // keep it public const bool date_sub_interval; // keep it public Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg) - :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {} - String *val_str(String *); + :Item_temporal_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {} const char *func_name() const { return "date_add_interval"; } void fix_length_and_dec(); enum_field_types field_type() const { return cached_field_type; } - longlong val_int(); bool get_date(MYSQL_TIME *res, uint fuzzy_date); bool eq(const Item *item, bool binary_cmp) const; virtual void print(String *str, enum_query_type query_type); @@ -718,43 +641,7 @@ class Item_extract :public Item_int_func }; -class Item_typecast :public Item_str_func -{ -public: - Item_typecast(Item *a) :Item_str_func(a) {} - String *val_str(String *a) - { - DBUG_ASSERT(fixed == 1); - String *tmp=args[0]->val_str(a); - null_value=args[0]->null_value; - if (tmp) - tmp->set_charset(collation.collation); - return tmp; - } - void fix_length_and_dec() - { - collation.set(&my_charset_bin); - max_length=args[0]->max_length; - } - virtual const char* cast_type() const= 0; - virtual void print(String *str, enum_query_type query_type); -}; - - -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; - } -}; - - -class Item_char_typecast :public Item_typecast +class Item_char_typecast :public Item_str_func { int cast_length; CHARSET_INFO *cast_cs, *from_cs; @@ -762,119 +649,85 @@ class Item_char_typecast :public Item_typecast String tmp_value; public: Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg) - :Item_typecast(a), cast_length(length_arg), cast_cs(cs_arg) {} + :Item_str_func(a), cast_length(length_arg), cast_cs(cs_arg) {} enum Functype functype() const { return CHAR_TYPECAST_FUNC; } bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "cast_as_char"; } - const char* cast_type() const { return "char"; }; String *val_str(String *a); void fix_length_and_dec(); - virtual void print(String *str, enum_query_type query_type); + void print(String *str, enum_query_type query_type); }; -class Item_date_typecast :public Item_typecast_maybe_null +class Item_temporal_typecast: public Item_temporal_func { public: - Item_date_typecast(Item *a) :Item_typecast_maybe_null(a) {} + Item_temporal_typecast(Item *a) :Item_temporal_func(a) {} + virtual const char *cast_type() const = 0; + void print(String *str, enum_query_type query_type); +}; + +class Item_date_typecast :public Item_temporal_typecast +{ +public: + Item_date_typecast(Item *a) :Item_temporal_typecast(a) {} const char *func_name() const { return "cast_as_date"; } - String *val_str(String *str); bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); - bool get_time(MYSQL_TIME *ltime); const char *cast_type() const { return "date"; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; } - 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; + decimals= 0; + max_length= MAX_DATE_WIDTH; maybe_null= 1; } - bool result_as_longlong() { return TRUE; } - longlong val_int(); - double val_real() { return (double) val_int(); } - my_decimal *val_decimal(my_decimal *decimal_value) - { - DBUG_ASSERT(fixed == 1); - return val_decimal_from_date(decimal_value); - } - int save_in_field(Field *field, bool no_conversions) - { - return save_date_in_field(field); - } }; -class Item_time_typecast :public Item_typecast_maybe_null +class Item_time_typecast :public Item_temporal_typecast { public: - Item_time_typecast(Item *a) :Item_typecast_maybe_null(a) {} + Item_time_typecast(Item *a, uint dec_arg) + :Item_temporal_typecast(a) { decimals= dec_arg; } const char *func_name() const { return "cast_as_time"; } - String *val_str(String *str); - bool get_time(MYSQL_TIME *ltime); + bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); const char *cast_type() const { return "time"; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } - Field *tmp_table_field(TABLE *table) - { - return tmp_table_field_from_field_type(table, 0); - } - bool result_as_longlong() { return TRUE; } - longlong val_int(); - double val_real() { return val_real_from_decimal(); } - my_decimal *val_decimal(my_decimal *decimal_value) - { - DBUG_ASSERT(fixed == 1); - return val_decimal_from_time(decimal_value); - } - int save_in_field(Field *field, bool no_conversions) + void fix_length_and_dec() { - return save_time_in_field(field); + collation.set(&my_charset_bin); + maybe_null= 1; + max_length= MAX_TIME_WIDTH; + if (decimals && decimals != NOT_FIXED_DEC) + max_length+= min(decimals, MAX_SEC_PART_DIGITS) + 1; } }; -class Item_datetime_typecast :public Item_typecast_maybe_null +class Item_datetime_typecast :public Item_temporal_typecast { public: - Item_datetime_typecast(Item *a) :Item_typecast_maybe_null(a) {} + Item_datetime_typecast(Item *a, uint dec_arg) + :Item_temporal_typecast(a) { decimals= dec_arg; } const char *func_name() const { return "cast_as_datetime"; } - String *val_str(String *str); const char *cast_type() const { return "datetime"; } enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } - Field *tmp_table_field(TABLE *table) - { - return tmp_table_field_from_field_type(table, 0); - } + bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); void fix_length_and_dec() { collation.set(&my_charset_bin); maybe_null= 1; - max_length= MAX_DATETIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN; - decimals= DATETIME_DEC; - } - bool result_as_longlong() { return TRUE; } - longlong val_int(); - double val_real() { return val_real_from_decimal(); } - double val() { return (double) val_int(); } - my_decimal *val_decimal(my_decimal *decimal_value) - { - DBUG_ASSERT(fixed == 1); - return val_decimal_from_date(decimal_value); - } - int save_in_field(Field *field, bool no_conversions) - { - return save_date_in_field(field); + max_length= MAX_DATETIME_WIDTH; + if (decimals && decimals != NOT_FIXED_DEC) + max_length+= min(decimals, MAX_SEC_PART_DIGITS) + 1; } }; -class Item_func_makedate :public Item_date_func +class Item_func_makedate :public Item_temporal_func { public: - Item_func_makedate(Item *a,Item *b) :Item_date_func(a,b) {} - String *val_str(String *str); + Item_func_makedate(Item *a,Item *b) :Item_temporal_func(a,b) {} const char *func_name() const { return "makedate"; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; } void fix_length_and_dec() @@ -884,11 +737,11 @@ public: /* It returns NULL when the second argument is less or equal to 0 */ maybe_null= 1; } - longlong val_int(); + bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); }; -class Item_func_add_time :public Item_str_func +class Item_func_add_time :public Item_temporal_func { const bool is_date; int sign; @@ -896,61 +749,39 @@ class Item_func_add_time :public Item_str_func public: Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg) - :Item_str_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; } - String *val_str(String *str); + :Item_temporal_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; } enum_field_types field_type() const { return cached_field_type; } void fix_length_and_dec(); - - Field *tmp_table_field(TABLE *table) - { - return tmp_table_field_from_field_type(table, 0); - } + bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); virtual void print(String *str, enum_query_type query_type); const char *func_name() const { return "add_time"; } - double val_real() { return val_real_from_decimal(); } - my_decimal *val_decimal(my_decimal *decimal_value) - { - DBUG_ASSERT(fixed == 1); - if (cached_field_type == MYSQL_TYPE_TIME) - return val_decimal_from_time(decimal_value); - if (cached_field_type == MYSQL_TYPE_DATETIME) - return val_decimal_from_date(decimal_value); - return Item_str_func::val_decimal(decimal_value); - } - int save_in_field(Field *field, bool no_conversions) - { - if (cached_field_type == MYSQL_TYPE_TIME) - return save_time_in_field(field); - if (cached_field_type == MYSQL_TYPE_DATETIME) - return save_date_in_field(field); - return Item_str_func::save_in_field(field, no_conversions); - } }; -class Item_func_timediff :public Item_str_timefunc +class Item_func_timediff :public Item_timefunc { public: Item_func_timediff(Item *a, Item *b) - :Item_str_timefunc(a, b) {} - String *val_str(String *str); + :Item_timefunc(a, b) {} const char *func_name() const { return "timediff"; } void fix_length_and_dec() { - Item_str_timefunc::fix_length_and_dec(); + decimals= NOT_FIXED_DEC; + Item_timefunc::fix_length_and_dec(); maybe_null= 1; } + bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); }; -class Item_func_maketime :public Item_str_timefunc +class Item_func_maketime :public Item_timefunc { public: Item_func_maketime(Item *a, Item *b, Item *c) - :Item_str_timefunc(a, b, c) + :Item_timefunc(a, b, c) { maybe_null= TRUE; } - String *val_str(String *str); const char *func_name() const { return "maketime"; } + bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); }; class Item_func_microsecond :public Item_int_func @@ -1009,32 +840,26 @@ public: }; -class Item_func_str_to_date :public Item_str_func +class Item_func_str_to_date :public Item_temporal_func { enum_field_types cached_field_type; - date_time_format_types cached_format_type; timestamp_type cached_timestamp_type; bool const_item; public: Item_func_str_to_date(Item *a, Item *b) - :Item_str_func(a, b), const_item(false) + :Item_temporal_func(a, b), const_item(false) {} - String *val_str(String *str); bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); const char *func_name() const { return "str_to_date"; } enum_field_types field_type() const { return cached_field_type; } void fix_length_and_dec(); - Field *tmp_table_field(TABLE *table) - { - return tmp_table_field_from_field_type(table, 1); - } }; -class Item_func_last_day :public Item_date +class Item_func_last_day :public Item_datefunc { public: - Item_func_last_day(Item *a) :Item_date(a) {} + Item_func_last_day(Item *a) :Item_datefunc(a) {} const char *func_name() const { return "last_day"; } bool get_date(MYSQL_TIME *res, uint fuzzy_date); }; |