Commit cb2c799b authored by Alexander Barkov's avatar Alexander Barkov

MDEV-8860 Wrong result for WHERE 2016 < SOME (SELECT CAST(time_column AS DATETIME) FROM t1)

MDEV-8875 Wrong metadata for MAX(CAST(time_column AS DATETIME))
parent cc9cfeca
......@@ -1726,7 +1726,7 @@ select 1 from t1 where 1 < some (select cast(a as datetime) from t1);
1
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: '2001-01-01 00:01:00'
Warning 1292 Incorrect datetime value: '1'
drop table t1;
SET timestamp=DEFAULT;
select time('10:10:10') > 10;
......
......@@ -1096,5 +1096,48 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (coalesce(`test`.`t1`.`a`) = TIMESTAMP'2001-01-01 00:00:00')
DROP TABLE t1;
#
# MDEV-8875 Wrong metadata for MAX(CAST(time_column AS DATETIME))
#
SET timestamp=UNIX_TIMESTAMP('2015-01-01 00:00:00');
CREATE TABLE t1 (a TIME);
INSERT INTO t1 VALUES ('00:00:00'),('00:01:00');
SELECT MAX(CAST(a AS DATETIME)) FROM t1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def MAX(CAST(a AS DATETIME)) 12 19 19 Y 128 0 63
MAX(CAST(a AS DATETIME))
2015-01-01 00:01:00
CREATE TABLE t2 AS SELECT MAX(CAST(a AS DATETIME)) FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`MAX(CAST(a AS DATETIME))` datetime DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t1;
SET timestamp=DEFAULT;
#
# MDEV-8860 Wrong result for WHERE 2016 < SOME (SELECT CAST(time_column AS DATETIME) FROM t1)
#
SET timestamp=UNIX_TIMESTAMP('2015-01-01 00:00:00');
CREATE TABLE t1 (a TIME);
INSERT INTO t1 VALUES ('00:00:00'),('00:01:00');
SELECT 1 FROM t1 WHERE 2016 > SOME (SELECT CAST(a AS DATETIME) FROM t1);
1
Warnings:
Warning 1292 Incorrect datetime value: '2016'
SELECT * FROM t1 WHERE 2016 > CAST(a AS DATETIME);
a
Warnings:
Warning 1292 Incorrect datetime value: '2016'
SELECT 1 FROM t1 WHERE 20160101 > SOME (SELECT CAST(a AS DATETIME) FROM t1);
1
1
1
SELECT * FROM t1 WHERE 20160101 > CAST(a AS DATETIME);
a
00:00:00
00:01:00
DROP TABLE t1;
#
# End of 10.1 tests
#
......@@ -663,6 +663,35 @@ INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-02 00:00:00');
EXPLAIN EXTENDED SELECT * FROM t1 WHERE COALESCE(a)=TIMESTAMP'2001-01-01 00:00:00' AND COALESCE(a)>=TIMESTAMP'2001-01-01 00:00:00';
DROP TABLE t1;
--echo #
--echo # MDEV-8875 Wrong metadata for MAX(CAST(time_column AS DATETIME))
--echo #
SET timestamp=UNIX_TIMESTAMP('2015-01-01 00:00:00');
CREATE TABLE t1 (a TIME);
INSERT INTO t1 VALUES ('00:00:00'),('00:01:00');
--disable_ps_protocol
--enable_metadata
SELECT MAX(CAST(a AS DATETIME)) FROM t1;
--disable_metadata
--enable_ps_protocol
CREATE TABLE t2 AS SELECT MAX(CAST(a AS DATETIME)) FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
--echo # MDEV-8860 Wrong result for WHERE 2016 < SOME (SELECT CAST(time_column AS DATETIME) FROM t1)
--echo #
SET timestamp=UNIX_TIMESTAMP('2015-01-01 00:00:00');
CREATE TABLE t1 (a TIME);
INSERT INTO t1 VALUES ('00:00:00'),('00:01:00');
SELECT 1 FROM t1 WHERE 2016 > SOME (SELECT CAST(a AS DATETIME) FROM t1);
SELECT * FROM t1 WHERE 2016 > CAST(a AS DATETIME);
SELECT 1 FROM t1 WHERE 20160101 > SOME (SELECT CAST(a AS DATETIME) FROM t1);
SELECT * FROM t1 WHERE 20160101 > CAST(a AS DATETIME);
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #
......@@ -1190,7 +1190,15 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
decimals=item->decimals;
with_subselect= args[0]->with_subselect;
switch (hybrid_type= item->result_type()) {
Item *item2= item->real_item();
if (item2->type() == Item::FIELD_ITEM)
set_handler_by_field_type(((Item_field*) item2)->field->type());
else if (item->cmp_type() == TIME_RESULT)
set_handler_by_field_type(item2->field_type());
else
set_handler_by_result_type(item2->result_type());
switch (Item_sum_hybrid::result_type()) {
case INT_RESULT:
case DECIMAL_RESULT:
case STRING_RESULT:
......@@ -1210,11 +1218,6 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
result_field=0;
null_value=1;
fix_length_and_dec();
item= item->real_item();
if (item->type() == Item::FIELD_ITEM)
hybrid_field_type= ((Item_field*) item)->field->type();
else
hybrid_field_type= Item::field_type();
if (check_sum_func(thd, ref))
return TRUE;
......@@ -2235,7 +2238,7 @@ void Item_sum_num::reset_field()
void Item_sum_hybrid::reset_field()
{
switch(hybrid_type) {
switch(Item_sum_hybrid::result_type()) {
case STRING_RESULT:
{
char buff[MAX_FIELD_WIDTH];
......@@ -2507,7 +2510,7 @@ Item *Item_sum_avg::result_item(THD *thd, Field *field)
void Item_sum_hybrid::update_field()
{
switch (hybrid_type) {
switch (Item_sum_hybrid::result_type()) {
case STRING_RESULT:
min_max_update_str_field();
break;
......
......@@ -1027,26 +1027,26 @@ class Item_sum_std :public Item_sum_variance
// This class is a string or number function depending on num_func
class Arg_comparator;
class Item_cache;
class Item_sum_hybrid :public Item_sum
class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type
{
protected:
Item_cache *value, *arg_cache;
Arg_comparator *cmp;
Item_result hybrid_type;
enum_field_types hybrid_field_type;
int cmp_sign;
bool was_values; // Set if we have found at least one row (for max/min only)
bool was_null_value;
public:
Item_sum_hybrid(THD *thd, Item *item_par,int sign):
Item_sum(thd, item_par), value(0), arg_cache(0), cmp(0),
hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG),
Item_sum(thd, item_par),
Type_handler_hybrid_field_type(MYSQL_TYPE_LONGLONG),
value(0), arg_cache(0), cmp(0),
cmp_sign(sign), was_values(TRUE)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
:Item_sum(thd, item), value(item->value), arg_cache(0),
hybrid_type(item->hybrid_type), hybrid_field_type(item->hybrid_field_type),
:Item_sum(thd, item),
Type_handler_hybrid_field_type(item),
value(item->value), arg_cache(0),
cmp_sign(item->cmp_sign), was_values(item->was_values)
{ }
bool fix_fields(THD *, Item **);
......@@ -1058,8 +1058,12 @@ protected:
void reset_field();
String *val_str(String *);
bool keep_field_type(void) const { return 1; }
enum Item_result result_type () const { return hybrid_type; }
enum enum_field_types field_type() const { return hybrid_field_type; }
enum Item_result result_type () const
{ return Type_handler_hybrid_field_type::result_type(); }
enum Item_result cmp_type () const
{ return Type_handler_hybrid_field_type::cmp_type(); }
enum enum_field_types field_type() const
{ return Type_handler_hybrid_field_type::field_type(); }
void update_field();
void min_max_update_str_field();
void min_max_update_real_field();
......
......@@ -270,6 +270,12 @@ class Type_handler_hybrid_field_type: public Type_handler
const Type_handler *get_handler_by_field_type(enum_field_types type) const;
public:
Type_handler_hybrid_field_type();
Type_handler_hybrid_field_type(enum_field_types type)
:m_type_handler(get_handler_by_field_type(type))
{ }
Type_handler_hybrid_field_type(const Type_handler_hybrid_field_type *other)
:m_type_handler(other->m_type_handler)
{ }
enum_field_types field_type() const { return m_type_handler->field_type(); }
Item_result result_type() const { return m_type_handler->result_type(); }
Item_result cmp_type() const { return m_type_handler->cmp_type(); }
......
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