MDEV-4859 Wrong value and data type of "SELECT MAX(time_column) + 1 FROM t1"
Fixed.
This commit is contained in:
parent
f8a6ee59ac
commit
2394fa67d4
@ -958,10 +958,10 @@ sec_to_time(1) + 0, from_unixtime(1) + 0;
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`now() - now()` decimal(20,0) NOT NULL DEFAULT '0',
|
`now() - now()` bigint(21) NOT NULL DEFAULT '0',
|
||||||
`curtime() - curtime()` decimal(11,0) NOT NULL DEFAULT '0',
|
`curtime() - curtime()` bigint(12) NOT NULL DEFAULT '0',
|
||||||
`sec_to_time(1) + 0` decimal(11,0) DEFAULT NULL,
|
`sec_to_time(1) + 0` bigint(12) DEFAULT NULL,
|
||||||
`from_unixtime(1) + 0` decimal(20,0) DEFAULT NULL
|
`from_unixtime(1) + 0` bigint(21) DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
SELECT SEC_TO_TIME(3300000);
|
SELECT SEC_TO_TIME(3300000);
|
||||||
|
@ -191,5 +191,112 @@ SELECT CONCAT(GREATEST(TIME('32 00:00:01'),TIME('00:00:00')));
|
|||||||
CONCAT(GREATEST(TIME('32 00:00:01'),TIME('00:00:00')))
|
CONCAT(GREATEST(TIME('32 00:00:01'),TIME('00:00:00')))
|
||||||
768:00:01
|
768:00:01
|
||||||
#
|
#
|
||||||
|
# MDEV-4859 Wrong value and data type of "SELECT MAX(time_column) + 1 FROM t1"
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (t0 TIME);
|
||||||
|
INSERT INTO t1 VALUES ('10:10:10');
|
||||||
|
SELECT MAX(t0)+1 FROM t1;
|
||||||
|
MAX(t0)+1
|
||||||
|
101011
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
MAX(t0)+1
|
||||||
|
101011
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
MAX(t0)+1 bigint(12) YES NULL
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
CREATE TABLE t1 (t0 TIME);
|
||||||
|
INSERT INTO t1 VALUES ('10:10:10');
|
||||||
|
SELECT MAX(t0)+1.1 FROM t1;
|
||||||
|
MAX(t0)+1.1
|
||||||
|
101011.1
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1.1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
MAX(t0)+1.1
|
||||||
|
101011.1
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
MAX(t0)+1.1 decimal(12,1) YES NULL
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
CREATE TABLE t1 (t0 TIME);
|
||||||
|
INSERT INTO t1 VALUES ('10:10:10');
|
||||||
|
SELECT MAX(t0)+1e0 FROM t1;
|
||||||
|
MAX(t0)+1e0
|
||||||
|
101011
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1e0 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
MAX(t0)+1e0
|
||||||
|
101011
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
MAX(t0)+1e0 double YES NULL
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
CREATE TABLE t1 (t1 TIME(1));
|
||||||
|
INSERT INTO t1 VALUES ('10:10:10');
|
||||||
|
SELECT MAX(t1)+1 FROM t1;
|
||||||
|
MAX(t1)+1
|
||||||
|
101011.0
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t1)+1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
MAX(t1)+1
|
||||||
|
101011.0
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
MAX(t1)+1 decimal(13,1) YES NULL
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
CREATE TABLE t1 (t0 DATETIME);
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
|
||||||
|
SELECT MAX(t0)+1 FROM t1;
|
||||||
|
MAX(t0)+1
|
||||||
|
20010101101011
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
MAX(t0)+1
|
||||||
|
20010101101011
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
MAX(t0)+1 bigint(21) YES NULL
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
CREATE TABLE t1 (t0 DATETIME);
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
|
||||||
|
SELECT MAX(t0)+1.1 FROM t1;
|
||||||
|
MAX(t0)+1.1
|
||||||
|
20010101101011.1
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1.1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
MAX(t0)+1.1
|
||||||
|
20010101101011.1
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
MAX(t0)+1.1 decimal(21,1) YES NULL
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
CREATE TABLE t1 (t0 DATETIME);
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
|
||||||
|
SELECT MAX(t0)+1e0 FROM t1;
|
||||||
|
MAX(t0)+1e0
|
||||||
|
20010101101011
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1e0 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
MAX(t0)+1e0
|
||||||
|
20010101101011
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
MAX(t0)+1e0 double YES NULL
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
CREATE TABLE t1 (t1 DATETIME(1));
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
|
||||||
|
SELECT MAX(t1)+1 FROM t1;
|
||||||
|
MAX(t1)+1
|
||||||
|
20010101101011.0
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t1)+1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
MAX(t1)+1
|
||||||
|
20010101101011.0
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
MAX(t1)+1 decimal(22,1) YES NULL
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
#
|
||||||
# End of 5.3 tests
|
# End of 5.3 tests
|
||||||
#
|
#
|
||||||
|
@ -134,6 +134,74 @@ SELECT CONVERT_TZ(GREATEST(TIME('00:00:00'),TIME('00:00:00')),'+00:00','+7:5');
|
|||||||
SELECT CONCAT(GREATEST(TIME('00:00:01'),TIME('00:00:00')));
|
SELECT CONCAT(GREATEST(TIME('00:00:01'),TIME('00:00:00')));
|
||||||
SELECT CONCAT(GREATEST(TIME('32 00:00:01'),TIME('00:00:00')));
|
SELECT CONCAT(GREATEST(TIME('32 00:00:01'),TIME('00:00:00')));
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-4859 Wrong value and data type of "SELECT MAX(time_column) + 1 FROM t1"
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (t0 TIME);
|
||||||
|
INSERT INTO t1 VALUES ('10:10:10');
|
||||||
|
SELECT MAX(t0)+1 FROM t1;
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (t0 TIME);
|
||||||
|
INSERT INTO t1 VALUES ('10:10:10');
|
||||||
|
SELECT MAX(t0)+1.1 FROM t1;
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1.1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (t0 TIME);
|
||||||
|
INSERT INTO t1 VALUES ('10:10:10');
|
||||||
|
SELECT MAX(t0)+1e0 FROM t1;
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1e0 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (t1 TIME(1));
|
||||||
|
INSERT INTO t1 VALUES ('10:10:10');
|
||||||
|
SELECT MAX(t1)+1 FROM t1;
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t1)+1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (t0 DATETIME);
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
|
||||||
|
SELECT MAX(t0)+1 FROM t1;
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (t0 DATETIME);
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
|
||||||
|
SELECT MAX(t0)+1.1 FROM t1;
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1.1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (t0 DATETIME);
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
|
||||||
|
SELECT MAX(t0)+1e0 FROM t1;
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t0)+1e0 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (t1 DATETIME(1));
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
|
||||||
|
SELECT MAX(t1)+1 FROM t1;
|
||||||
|
CREATE TABLE t2 AS SELECT MAX(t1)+1 FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SHOW COLUMNS FROM t2;
|
||||||
|
DROP TABLE t2,t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 5.3 tests
|
--echo # End of 5.3 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
69
sql/item.cc
69
sql/item.cc
@ -350,6 +350,27 @@ my_decimal *Item::val_decimal_from_time(my_decimal *decimal_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
longlong Item::val_int_from_date()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
if (get_date(<ime, 0))
|
||||||
|
return 0;
|
||||||
|
longlong v= TIME_to_ulonglong(<ime);
|
||||||
|
return ltime.neg ? -v : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double Item::val_real_from_date()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
if (get_date(<ime, 0))
|
||||||
|
return 0;
|
||||||
|
return TIME_to_double(<ime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
double Item::val_real_from_decimal()
|
double Item::val_real_from_decimal()
|
||||||
{
|
{
|
||||||
/* Note that fix_fields may not be called for Item_avg_field items */
|
/* Note that fix_fields may not be called for Item_avg_field items */
|
||||||
@ -8381,6 +8402,18 @@ int Item_cache_int::save_in_field(Field *field, bool no_conversions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
longlong Item_cache_temporal::val_temporal_packed()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
if ((!value_cached && !cache_value()) || null_value)
|
||||||
|
{
|
||||||
|
null_value= TRUE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String *Item_cache_temporal::val_str(String *str)
|
String *Item_cache_temporal::val_str(String *str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
@ -8393,6 +8426,42 @@ String *Item_cache_temporal::val_str(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_decimal *Item_cache_temporal::val_decimal(my_decimal *decimal_value)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
if ((!value_cached && !cache_value()) || null_value)
|
||||||
|
{
|
||||||
|
null_value= true;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return val_decimal_from_date(decimal_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
longlong Item_cache_temporal::val_int()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
if ((!value_cached && !cache_value()) || null_value)
|
||||||
|
{
|
||||||
|
null_value= true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return val_int_from_date();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double Item_cache_temporal::val_real()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
if ((!value_cached && !cache_value()) || null_value)
|
||||||
|
{
|
||||||
|
null_value= true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return val_real_from_date();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_cache_temporal::cache_value()
|
bool Item_cache_temporal::cache_value()
|
||||||
{
|
{
|
||||||
if (!example)
|
if (!example)
|
||||||
|
@ -847,7 +847,9 @@ public:
|
|||||||
my_decimal *val_decimal_from_date(my_decimal *decimal_value);
|
my_decimal *val_decimal_from_date(my_decimal *decimal_value);
|
||||||
my_decimal *val_decimal_from_time(my_decimal *decimal_value);
|
my_decimal *val_decimal_from_time(my_decimal *decimal_value);
|
||||||
longlong val_int_from_decimal();
|
longlong val_int_from_decimal();
|
||||||
|
longlong val_int_from_date();
|
||||||
double val_real_from_decimal();
|
double val_real_from_decimal();
|
||||||
|
double val_real_from_date();
|
||||||
|
|
||||||
int save_time_in_field(Field *field);
|
int save_time_in_field(Field *field);
|
||||||
int save_date_in_field(Field *field);
|
int save_date_in_field(Field *field);
|
||||||
@ -3830,6 +3832,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
String* val_str(String *str);
|
String* val_str(String *str);
|
||||||
|
my_decimal *val_decimal(my_decimal *);
|
||||||
|
longlong val_int();
|
||||||
|
longlong val_temporal_packed();
|
||||||
|
double val_real();
|
||||||
bool cache_value();
|
bool cache_value();
|
||||||
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
|
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
|
||||||
int save_in_field(Field *field, bool no_conversions);
|
int save_in_field(Field *field, bool no_conversions);
|
||||||
|
@ -877,10 +877,13 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
|
|||||||
enum_field_types f_type= item->cmp_type() == TIME_RESULT ?
|
enum_field_types f_type= item->cmp_type() == TIME_RESULT ?
|
||||||
item->field_type() : warn_item->field_type();
|
item->field_type() : warn_item->field_type();
|
||||||
|
|
||||||
if (item->result_type() == INT_RESULT && item->cmp_type() == TIME_RESULT)
|
if (item->result_type() == INT_RESULT &&
|
||||||
|
item->cmp_type() == TIME_RESULT &&
|
||||||
|
item->type() == Item::CACHE_ITEM)
|
||||||
{
|
{
|
||||||
/* it's our Item_cache_int, as created below */
|
/* it's our Item_cache_temporal, as created below */
|
||||||
value= item->val_int();
|
DBUG_ASSERT(is_temporal_type(((Item_cache *) item)->field_type()));
|
||||||
|
value= ((Item_cache_temporal*) item)->val_temporal_packed();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -798,6 +798,8 @@ void Item_num_op::find_num_type(void)
|
|||||||
cached_result_type= DECIMAL_RESULT;
|
cached_result_type= DECIMAL_RESULT;
|
||||||
result_precision();
|
result_precision();
|
||||||
fix_decimals();
|
fix_decimals();
|
||||||
|
if ((r0 == TIME_RESULT || r1 == TIME_RESULT) && decimals == 0)
|
||||||
|
cached_result_type= INT_RESULT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -687,7 +687,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
|
|||||||
|
|
||||||
void Item_sum_hybrid::setup_hybrid(Item *item, Item *value_arg)
|
void Item_sum_hybrid::setup_hybrid(Item *item, Item *value_arg)
|
||||||
{
|
{
|
||||||
if (!(value= Item_cache::get_cache(item)))
|
if (!(value= Item_cache::get_cache(item, item->cmp_type())))
|
||||||
return;
|
return;
|
||||||
value->setup(item);
|
value->setup(item);
|
||||||
value->store(value_arg);
|
value->store(value_arg);
|
||||||
|
@ -1362,27 +1362,6 @@ String *Item_temporal_func::val_str(String *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
longlong Item_temporal_func::val_int()
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(fixed == 1);
|
|
||||||
MYSQL_TIME ltime;
|
|
||||||
if (get_date(<ime, 0))
|
|
||||||
return 0;
|
|
||||||
longlong v= TIME_to_ulonglong(<ime);
|
|
||||||
return ltime.neg ? -v : v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
double Item_temporal_func::val_real()
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(fixed == 1);
|
|
||||||
MYSQL_TIME ltime;
|
|
||||||
if (get_date(<ime, 0))
|
|
||||||
return 0;
|
|
||||||
return TIME_to_double(<ime);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
|
bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
|
||||||
{
|
{
|
||||||
longlong value=args[0]->val_int();
|
longlong value=args[0]->val_int();
|
||||||
|
@ -448,8 +448,8 @@ public:
|
|||||||
enum Item_result result_type () const { return STRING_RESULT; }
|
enum Item_result result_type () const { return STRING_RESULT; }
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
longlong val_int();
|
longlong val_int() { return val_int_from_date(); }
|
||||||
double val_real();
|
double val_real() { return val_real_from_date(); }
|
||||||
bool get_date(MYSQL_TIME *res, uint fuzzy_date) { DBUG_ASSERT(0); return 1; }
|
bool get_date(MYSQL_TIME *res, uint fuzzy_date) { DBUG_ASSERT(0); return 1; }
|
||||||
my_decimal *val_decimal(my_decimal *decimal_value)
|
my_decimal *val_decimal(my_decimal *decimal_value)
|
||||||
{ return val_decimal_from_date(decimal_value); }
|
{ return val_decimal_from_date(decimal_value); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user