summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.h
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-03-01 13:24:36 +0100
committerSergei Golubchik <sergii@pisem.net>2011-03-01 13:24:36 +0100
commita8a757c6bb32bbf291afdf33df861127489889ab (patch)
treecee7858869789964ad21b2b90b420f1128d9a10d /sql/item_timefunc.h
parent7e0e4b00c971b81b5ffd18db4f1ea977233e98be (diff)
downloadmariadb-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.h407
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);
};