summaryrefslogtreecommitdiff
path: root/sql-common/my_time.c
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2018-02-14 22:58:34 +0400
committerAlexander Barkov <bar@mariadb.org>2018-02-14 22:58:34 +0400
commitc17a06abf8f7418091b87abd5e1fa7c6522c7591 (patch)
tree9f8aa80599830631f6210d3a961f113e544e45c1 /sql-common/my_time.c
parent1fe9092d0684bd8fb2985093f341c54204d280b1 (diff)
downloadmariadb-git-c17a06abf8f7418091b87abd5e1fa7c6522c7591.tar.gz
MDEV-15310 Range optimizer does not work well for "WHERE temporal_column NOT IN (const_list)"
There were two problems related to the bug report: 1. Item_datetime::get_date() was not implemented. So execution went through val_int() followed by int-to-datetime or int-to-time conversion. This was the reason why the optimizer did not work well on data with fractional seconds. 2. Item_datetime::set() did not have a TIME specific code to mix months and days to hours after unpack_time(). This is why the optimizer did not work well with negative TIME values, as well as huge time values. Changes: 1. Overriding Item_datetime::get_date(), to return ltime. This fixes the problem N1. 2. Cleanup: Moving pack_time() and unpack_time() from sql-common/my_time.c and include/my_time.h to sql/sql_time.cc and sql/sql_time.h, as they are not needed on the client side. 3. Adding a new "enum_mysql_timestamp_type ts_type" parameter to unpack_time() and moving the TIME specific code to mix months and days with hours inside unpack_time(). Adding a new "ts_type" parameter to Item_datetime::set(), to pass it from the caller down to unpack_time(). So now the TIME specific code is automatically called from Item_datetime::set(). This fixes the problem N2. This change also helped to get rid of duplicate TIME specific code from other three places, where mixing month/days to hours was done immediately after unpack_time(). Moving the DATE specific code to zero hhmmssff from Item_func_min_max::get_date_native to inside unpack_time(), for symmetry. 4. Removing the virtual method in_vector::result_type(), adding in_vector::type_handler() instead. This helps to get result_type(), field_type(), mysql_timestamp_type() of an in_vector easier. Passing type_handler()->mysql_timestamp_type() as a new parameter to Item_datetime::set() inside in_temporal::value_to_item(). 5. Cleaup: Removing separate implementations of in_datetime::get_value() and in_time::get_value(). Adding a single implementation in_temporal::get_value() instead. Passing type_handler()->field_type() to get_value_internal().
Diffstat (limited to 'sql-common/my_time.c')
-rw-r--r--sql-common/my_time.c28
1 files changed, 0 insertions, 28 deletions
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index d7953fe36bf..0fa5e5ff1bb 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -1425,31 +1425,3 @@ double TIME_to_double(const MYSQL_TIME *my_time)
d+= my_time->second_part/(double)TIME_SECOND_PART_FACTOR;
return my_time->neg ? -d : d;
}
-
-longlong pack_time(const MYSQL_TIME *my_time)
-{
- return ((((((my_time->year * 13ULL +
- my_time->month) * 32ULL +
- my_time->day) * 24ULL +
- my_time->hour) * 60ULL +
- my_time->minute) * 60ULL +
- my_time->second) * 1000000ULL +
- my_time->second_part) * (my_time->neg ? -1 : 1);
-}
-
-#define get_one(WHERE, FACTOR) WHERE= (ulong)(packed % FACTOR); packed/= FACTOR
-
-MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time)
-{
- if ((my_time->neg= packed < 0))
- packed= -packed;
- get_one(my_time->second_part, 1000000ULL);
- get_one(my_time->second, 60U);
- get_one(my_time->minute, 60U);
- get_one(my_time->hour, 24U);
- get_one(my_time->day, 32U);
- get_one(my_time->month, 13U);
- my_time->year= (uint)packed;
- my_time->time_type= MYSQL_TIMESTAMP_DATETIME;
- return my_time;
-}