Commit 1ec91803 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10317 EXCTACT(MINUTE_MICROSECOND) truncates data

parent 3ccf8218
This diff is collapsed.
...@@ -1712,3 +1712,77 @@ SELECT ...@@ -1712,3 +1712,77 @@ SELECT
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
--echo # --echo #
--echo #
--echo # Start of 10.1 tests
--echo #
--echo #
--echo # MDEV-10317 EXCTACT(MINUTE_MICROSECOND) truncates data
--echo #
let $query=
SELECT
a,
EXTRACT(YEAR FROM a),
EXTRACT(YEAR_MONTH FROM a),
EXTRACT(QUARTER FROM a),
EXTRACT(MONTH FROM a),
EXTRACT(WEEK FROM a),
EXTRACT(DAY FROM a),
EXTRACT(DAY_HOUR FROM a),
EXTRACT(DAY_MINUTE FROM a),
EXTRACT(DAY_SECOND FROM a),
EXTRACT(HOUR FROM a),
EXTRACT(HOUR_MINUTE FROM a),
EXTRACT(HOUR_SECOND FROM a),
EXTRACT(MINUTE FROM a),
EXTRACT(MINUTE_SECOND FROM a),
EXTRACT(SECOND FROM a),
EXTRACT(MICROSECOND FROM a),
EXTRACT(DAY_MICROSECOND FROM a),
EXTRACT(HOUR_MICROSECOND FROM a),
EXTRACT(MINUTE_MICROSECOND FROM a),
EXTRACT(SECOND_MICROSECOND FROM a)
FROM t1;
CREATE TABLE t1 (a DATETIME(6));
INSERT INTO t1 VALUES ('1999-12-31 23:59:59.999999');
--vertical_results
--enable_metadata
--disable_ps_protocol
--eval $query
--enable_ps_protocol
--disable_metadata
--horizontal_results
--eval CREATE TABLE t2 AS $query
--vertical_results
SELECT * FROM t2;
--horizontal_results
SHOW CREATE TABLE t2;
DROP TABLE t1,t2;
CREATE TABLE t1 (a TIME(6));
INSERT INTO t1 VALUES ('-838:59:59.999999'),('838:59:59.999999');
--vertical_results
--enable_metadata
--disable_ps_protocol
--eval $query
--enable_ps_protocol
--disable_metadata
--horizontal_results
--eval CREATE TABLE t2 AS $query
--vertical_results
SELECT * FROM t2;
--horizontal_results
SHOW CREATE TABLE t2;
DROP TABLE t1,t2;
--echo #
--echo # End of 10.1 tests
--echo #
...@@ -2192,26 +2192,26 @@ void Item_extract::fix_length_and_dec() ...@@ -2192,26 +2192,26 @@ void Item_extract::fix_length_and_dec()
{ {
maybe_null=1; // If wrong date maybe_null=1; // If wrong date
switch (int_type) { switch (int_type) {
case INTERVAL_YEAR: max_length=4; date_value=1; break; case INTERVAL_YEAR: set_date_length(4); break; // YYYY
case INTERVAL_YEAR_MONTH: max_length=6; date_value=1; break; case INTERVAL_YEAR_MONTH: set_date_length(6); break; // YYYYMM
case INTERVAL_QUARTER: max_length=2; date_value=1; break; case INTERVAL_QUARTER: set_date_length(2); break; // 1..4
case INTERVAL_MONTH: max_length=2; date_value=1; break; case INTERVAL_MONTH: set_date_length(2); break; // MM
case INTERVAL_WEEK: max_length=2; date_value=1; break; case INTERVAL_WEEK: set_date_length(2); break; // 0..52
case INTERVAL_DAY: max_length=2; date_value=1; break; case INTERVAL_DAY: set_date_length(2); break; // DD
case INTERVAL_DAY_HOUR: max_length=9; date_value=0; break; case INTERVAL_DAY_HOUR: set_time_length(4); break; // DDhh
case INTERVAL_DAY_MINUTE: max_length=11; date_value=0; break; case INTERVAL_DAY_MINUTE: set_time_length(6); break; // DDhhmm
case INTERVAL_DAY_SECOND: max_length=13; date_value=0; break; case INTERVAL_DAY_SECOND: set_time_length(8); break; // DDhhmmss
case INTERVAL_HOUR: max_length=2; date_value=0; break; case INTERVAL_HOUR: set_time_length(2); break; // hh
case INTERVAL_HOUR_MINUTE: max_length=4; date_value=0; break; case INTERVAL_HOUR_MINUTE: set_time_length(4); break; // hhmm
case INTERVAL_HOUR_SECOND: max_length=6; date_value=0; break; case INTERVAL_HOUR_SECOND: set_time_length(6); break; // hhmmss
case INTERVAL_MINUTE: max_length=2; date_value=0; break; case INTERVAL_MINUTE: set_time_length(2); break; // mm
case INTERVAL_MINUTE_SECOND: max_length=4; date_value=0; break; case INTERVAL_MINUTE_SECOND: set_time_length(4); break; // mmss
case INTERVAL_SECOND: max_length=2; date_value=0; break; case INTERVAL_SECOND: set_time_length(2); break; // ss
case INTERVAL_MICROSECOND: max_length=2; date_value=0; break; case INTERVAL_MICROSECOND: set_time_length(6); break; // ffffff
case INTERVAL_DAY_MICROSECOND: max_length=20; date_value=0; break; case INTERVAL_DAY_MICROSECOND: set_time_length(14); break; // DDhhmmssffffff
case INTERVAL_HOUR_MICROSECOND: max_length=13; date_value=0; break; case INTERVAL_HOUR_MICROSECOND: set_time_length(12); break; // hhmmssffffff
case INTERVAL_MINUTE_MICROSECOND: max_length=11; date_value=0; break; case INTERVAL_MINUTE_MICROSECOND: set_time_length(10); break; // mmssffffff
case INTERVAL_SECOND_MICROSECOND: max_length=9; date_value=0; break; case INTERVAL_SECOND_MICROSECOND: set_time_length(8); break; // ssffffff
case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */ case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
} }
} }
......
...@@ -835,10 +835,57 @@ class Item_date_add_interval :public Item_temporal_hybrid_func ...@@ -835,10 +835,57 @@ class Item_date_add_interval :public Item_temporal_hybrid_func
class Item_extract :public Item_int_func class Item_extract :public Item_int_func
{ {
bool date_value; bool date_value;
void set_date_length(uint32 length)
{
/*
Although DATE components (e.g. YEAR, YEAR_MONTH, QUARTER, MONTH, WEEK)
cannot have a sign, we should probably still add +1,
because all around the code we assume that max_length is sign inclusive.
Another options is to set unsigned_flag to "true".
*/
max_length= length; //QQ: see above
date_value= true;
}
void set_time_length(uint32 length)
{
max_length= length + 1/*sign*/;
date_value= false;
}
public: public:
const interval_type int_type; // keep it public const interval_type int_type; // keep it public
Item_extract(THD *thd, interval_type type_arg, Item *a): Item_extract(THD *thd, interval_type type_arg, Item *a):
Item_int_func(thd, a), int_type(type_arg) {} Item_int_func(thd, a), int_type(type_arg) {}
enum_field_types field_type() const
{
switch (int_type) {
case INTERVAL_YEAR:
case INTERVAL_YEAR_MONTH:
case INTERVAL_QUARTER:
case INTERVAL_MONTH:
case INTERVAL_WEEK:
case INTERVAL_DAY:
case INTERVAL_DAY_HOUR:
case INTERVAL_DAY_MINUTE:
case INTERVAL_DAY_SECOND:
case INTERVAL_HOUR:
case INTERVAL_HOUR_MINUTE:
case INTERVAL_HOUR_SECOND:
case INTERVAL_MINUTE:
case INTERVAL_MINUTE_SECOND:
case INTERVAL_SECOND:
case INTERVAL_MICROSECOND:
case INTERVAL_SECOND_MICROSECOND:
return MYSQL_TYPE_LONG;
case INTERVAL_DAY_MICROSECOND:
case INTERVAL_HOUR_MICROSECOND:
case INTERVAL_MINUTE_MICROSECOND:
return MYSQL_TYPE_LONGLONG;
case INTERVAL_LAST:
break;
}
DBUG_ASSERT(0);
return MYSQL_TYPE_LONGLONG;
}
longlong val_int(); longlong val_int();
enum Functype functype() const { return EXTRACT_FUNC; } enum Functype functype() const { return EXTRACT_FUNC; }
const char *func_name() const { return "extract"; } const char *func_name() const { return "extract"; }
...@@ -883,6 +930,8 @@ class Item_extract :public Item_int_func ...@@ -883,6 +930,8 @@ class Item_extract :public Item_int_func
} }
return true; return true;
} }
Field *create_field_for_create_select(TABLE *table)
{ return tmp_table_field_from_field_type(table, false, false); }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment