diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-09-18 13:07:31 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-09-18 13:07:31 +0200 |
commit | 4ec2e9d7eda78d409d1b017ef4d8928fe9055438 (patch) | |
tree | 6c3a74a740d3c1c5f3a7d1f8154d8a791b435b3f /sql/item_timefunc.cc | |
parent | 1a2a9d74fe1256554eceb09bbc6752a6376df87d (diff) | |
parent | 197bdbae4db78ba65f3668803bebd3c4a4509ae5 (diff) | |
download | mariadb-git-4ec2e9d7eda78d409d1b017ef4d8928fe9055438.tar.gz |
5.5 merge and fixes for compiler/test errors
Diffstat (limited to 'sql/item_timefunc.cc')
-rw-r--r-- | sql/item_timefunc.cc | 65 |
1 files changed, 50 insertions, 15 deletions
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index c82fb3dd0f2..b8421eaee94 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1290,7 +1290,19 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval) String str_value(buf, sizeof(buf), &my_charset_bin); bzero((char*) interval,sizeof(*interval)); - if ((int) int_type <= INTERVAL_MICROSECOND) + if (int_type == INTERVAL_SECOND && args->decimals) + { + my_decimal decimal_value, *val; + ulonglong second; + ulong second_part; + if (!(val= args->val_decimal(&decimal_value))) + return true; + interval->neg= my_decimal2seconds(val, &second, &second_part); + interval->second= second; + interval->second_part= second_part; + return false; + } + else if ((int) int_type <= INTERVAL_MICROSECOND) { value= args->val_int(); if (args->null_value) @@ -1435,12 +1447,12 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval) void Item_temporal_func::fix_length_and_dec() { - static const uint max_time_type_width[5]= - { MAX_DATETIME_WIDTH, MAX_DATETIME_WIDTH, MAX_DATE_WIDTH, - MAX_DATETIME_WIDTH, MIN_TIME_WIDTH }; - + /* + We set maybe_null to 1 as default as any bad argument with date or + time can get us to return NULL. + */ set_persist_maybe_null(1); - max_length= max_time_type_width[mysql_type_to_time_type(field_type())+2]; + max_length= mysql_temporal_int_part_length(field_type()); if (decimals) { if (decimals == NOT_FIXED_DEC) @@ -1929,7 +1941,7 @@ bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime, void Item_func_convert_tz::fix_length_and_dec() { - decimals= args[0]->decimals; + decimals= args[0]->temporal_precision(MYSQL_TYPE_DATETIME); Item_temporal_func::fix_length_and_dec(); } @@ -2000,28 +2012,40 @@ void Item_date_add_interval::fix_length_and_dec() */ cached_field_type= MYSQL_TYPE_STRING; arg0_field_type= args[0]->field_type(); + uint interval_dec= 0; + if (int_type == INTERVAL_MICROSECOND || + (int_type >= INTERVAL_DAY_MICROSECOND && + int_type <= INTERVAL_SECOND_MICROSECOND)) + interval_dec= TIME_SECOND_PART_DIGITS; + else if (int_type == INTERVAL_SECOND && args[1]->decimals > 0) + interval_dec= min(args[1]->decimals, TIME_SECOND_PART_DIGITS); + if (arg0_field_type == MYSQL_TYPE_DATETIME || arg0_field_type == MYSQL_TYPE_TIMESTAMP) + { + decimals= max(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec); cached_field_type= MYSQL_TYPE_DATETIME; + } else if (arg0_field_type == MYSQL_TYPE_DATE) { if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH) cached_field_type= arg0_field_type; else + { + decimals= interval_dec; cached_field_type= MYSQL_TYPE_DATETIME; + } } else if (arg0_field_type == MYSQL_TYPE_TIME) { + decimals= max(args[0]->temporal_precision(MYSQL_TYPE_TIME), interval_dec); if (int_type >= INTERVAL_DAY && int_type != INTERVAL_YEAR_MONTH) cached_field_type= arg0_field_type; else cached_field_type= MYSQL_TYPE_DATETIME; } - if (int_type == INTERVAL_MICROSECOND || int_type >= INTERVAL_DAY_MICROSECOND) - decimals= 6; else - decimals= args[0]->decimals; - + decimals= max(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec); Item_temporal_func::fix_length_and_dec(); } @@ -2534,10 +2558,19 @@ void Item_func_add_time::fix_length_and_dec() arg0_field_type= args[0]->field_type(); if (arg0_field_type == MYSQL_TYPE_DATE || arg0_field_type == MYSQL_TYPE_DATETIME || - arg0_field_type == MYSQL_TYPE_TIMESTAMP) + arg0_field_type == MYSQL_TYPE_TIMESTAMP || + is_date) + { cached_field_type= MYSQL_TYPE_DATETIME; + decimals= max(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), + args[1]->temporal_precision(MYSQL_TYPE_TIME)); + } else if (arg0_field_type == MYSQL_TYPE_TIME) + { cached_field_type= MYSQL_TYPE_TIME; + decimals= max(args[0]->temporal_precision(MYSQL_TYPE_TIME), + args[1]->temporal_precision(MYSQL_TYPE_TIME)); + } Item_temporal_func::fix_length_and_dec(); } @@ -2718,13 +2751,14 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { DBUG_ASSERT(fixed == 1); bool overflow= 0; - longlong hour= args[0]->val_int(); longlong minute= args[1]->val_int(); - longlong second= args[2]->val_int(); + ulonglong second; + ulong microsecond; + bool neg= args[2]->get_seconds(&second, µsecond); if (args[0]->null_value || args[1]->null_value || args[2]->null_value || - minute < 0 || minute > 59 || second < 0 || second > 59) + minute < 0 || minute > 59 || neg || second > 59) return (null_value= 1); bzero(ltime, sizeof(*ltime)); @@ -2746,6 +2780,7 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) ltime->hour= (uint) ((hour < 0 ? -hour : hour)); ltime->minute= (uint) minute; ltime->second= (uint) second; + ltime->second_part= microsecond; } else { |