Commit 42bc08b3 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-8229 GROUP_MIN_MAX is erroneously applied for BETWEEN in some cases

parent 1f4a89b1
......@@ -3779,5 +3779,95 @@ id MIN(a) MAX(a)
4 2001-01-04 2001-01-04
DROP TABLE t1;
#
# MDEV-8229 GROUP_MIN_MAX is erroneously applied for BETWEEN in some cases
#
SET NAMES latin1;
CREATE TABLE t1 (id INT NOT NULL, a VARCHAR(20)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,'2001-01-01');
INSERT INTO t1 VALUES (1,'2001-01-02');
INSERT INTO t1 VALUES (1,'2001-01-03');
INSERT INTO t1 VALUES (1,' 2001-01-04');
INSERT INTO t1 VALUES (2,'2001-01-01');
INSERT INTO t1 VALUES (2,'2001-01-02');
INSERT INTO t1 VALUES (2,'2001-01-03');
INSERT INTO t1 VALUES (2,' 2001-01-04');
INSERT INTO t1 VALUES (3,'2001-01-01');
INSERT INTO t1 VALUES (3,'2001-01-02');
INSERT INTO t1 VALUES (3,'2001-01-03');
INSERT INTO t1 VALUES (3,' 2001-01-04');
INSERT INTO t1 VALUES (4,'2001-01-01');
INSERT INTO t1 VALUES (4,'2001-01-02');
INSERT INTO t1 VALUES (4,'2001-01-03');
INSERT INTO t1 VALUES (4,' 2001-01-04');
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
1 2001-01-04 2001-01-03
2 2001-01-04 2001-01-03
3 2001-01-04 2001-01-03
4 2001-01-04 2001-01-03
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND '2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
1 2001-01-04 2001-01-04
2 2001-01-04 2001-01-04
3 2001-01-04 2001-01-04
4 2001-01-04 2001-01-04
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND '2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
1 2001-01-04 2001-01-04
2 2001-01-04 2001-01-04
3 2001-01-04 2001-01-04
4 2001-01-04 2001-01-04
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND DATE'2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
1 2001-01-04 2001-01-04
2 2001-01-04 2001-01-04
3 2001-01-04 2001-01-04
4 2001-01-04 2001-01-04
ALTER TABLE t1 ADD KEY(id,a);
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
1 2001-01-04 2001-01-03
2 2001-01-04 2001-01-03
3 2001-01-04 2001-01-03
4 2001-01-04 2001-01-03
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND '2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
1 2001-01-04 2001-01-04
2 2001-01-04 2001-01-04
3 2001-01-04 2001-01-04
4 2001-01-04 2001-01-04
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND '2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
1 2001-01-04 2001-01-04
2 2001-01-04 2001-01-04
3 2001-01-04 2001-01-04
4 2001-01-04 2001-01-04
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND DATE'2001-01-05' GROUP BY id;
id MIN(a) MAX(a)
1 2001-01-04 2001-01-04
2 2001-01-04 2001-01-04
3 2001-01-04 2001-01-04
4 2001-01-04 2001-01-04
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL id 27 NULL 9 Using where; Using index for group-by
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND '2001-01-05' GROUP BY id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL id 27 NULL 9 Using where; Using index for group-by
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL id 27 NULL 16 Using where; Using index
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND '2001-01-05' GROUP BY id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL id 27 NULL 16 Using where; Using index
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND DATE'2001-01-05' GROUP BY id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL id 27 NULL 16 Using where; Using index
DROP TABLE t1;
#
# End of 10.1 tests
#
......@@ -1557,6 +1557,46 @@ SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104.0 GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id;
DROP TABLE t1;
--echo #
--echo # MDEV-8229 GROUP_MIN_MAX is erroneously applied for BETWEEN in some cases
--echo #
SET NAMES latin1;
CREATE TABLE t1 (id INT NOT NULL, a VARCHAR(20)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,'2001-01-01');
INSERT INTO t1 VALUES (1,'2001-01-02');
INSERT INTO t1 VALUES (1,'2001-01-03');
INSERT INTO t1 VALUES (1,' 2001-01-04');
INSERT INTO t1 VALUES (2,'2001-01-01');
INSERT INTO t1 VALUES (2,'2001-01-02');
INSERT INTO t1 VALUES (2,'2001-01-03');
INSERT INTO t1 VALUES (2,' 2001-01-04');
INSERT INTO t1 VALUES (3,'2001-01-01');
INSERT INTO t1 VALUES (3,'2001-01-02');
INSERT INTO t1 VALUES (3,'2001-01-03');
INSERT INTO t1 VALUES (3,' 2001-01-04');
INSERT INTO t1 VALUES (4,'2001-01-01');
INSERT INTO t1 VALUES (4,'2001-01-02');
INSERT INTO t1 VALUES (4,'2001-01-03');
INSERT INTO t1 VALUES (4,' 2001-01-04');
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND '2001-01-05' GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND '2001-01-05' GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND DATE'2001-01-05' GROUP BY id;
ALTER TABLE t1 ADD KEY(id,a);
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND '2001-01-05' GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND '2001-01-05' GROUP BY id;
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND DATE'2001-01-05' GROUP BY id;
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN ' 2001-01-04' AND '2001-01-05' GROUP BY id;
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND '2001-01-05' GROUP BY id;
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND DATE'2001-01-05' GROUP BY id;
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN DATE'2001-01-04' AND '2001-01-05' GROUP BY id;
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a BETWEEN '2001-01-04' AND DATE'2001-01-05' GROUP BY id;
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #
......@@ -1261,7 +1261,7 @@ bool Field::can_optimize_keypart_ref(const Item_func *cond,
/*
This handles all numeric and BIT data types.
*/
bool Field::can_optimize_group_min_max(const Item_bool_func2 *cond,
bool Field::can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const
{
DBUG_ASSERT(cmp_type() != STRING_RESULT);
......@@ -5289,7 +5289,7 @@ bool Field_temporal::can_optimize_keypart_ref(const Item_func *cond,
}
bool Field_temporal::can_optimize_group_min_max(const Item_bool_func2 *cond,
bool Field_temporal::can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const
{
return true; // Field is of TIME_RESULT, which supersedes everything else.
......@@ -6506,7 +6506,7 @@ bool Field_longstr::can_optimize_hash_join(const Item_func *cond,
}
bool Field_longstr::can_optimize_group_min_max(const Item_bool_func2 *cond,
bool Field_longstr::can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const
{
/*
......
......@@ -40,7 +40,7 @@ class Field;
class Column_statistics;
class Column_statistics_collected;
class Item_func;
class Item_bool_func2;
class Item_bool_func;
enum enum_check_fields
{
......@@ -986,7 +986,7 @@ public:
{
return can_optimize_keypart_ref(cond, item);
}
virtual bool can_optimize_group_min_max(const Item_bool_func2 *cond,
virtual bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const;
bool can_optimize_outer_join_table_elimination(const Item_func *cond,
const Item *item) const
......@@ -1191,7 +1191,7 @@ public:
bool match_collation_to_optimize_range() const { return true; }
bool can_optimize_keypart_ref(const Item_func *cond, const Item *item) const;
bool can_optimize_hash_join(const Item_func *cond, const Item *item) const;
bool can_optimize_group_min_max(const Item_bool_func2 *cond,
bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const;
};
......@@ -1625,7 +1625,7 @@ public:
DBUG_ASSERT(0);
return false;
}
bool can_optimize_group_min_max(const Item_bool_func2 *cond,
bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const
{
DBUG_ASSERT(0);
......@@ -1664,7 +1664,7 @@ public:
return pos_in_interval_val_real(min, max);
}
bool can_optimize_keypart_ref(const Item_func *cond, const Item *item) const;
bool can_optimize_group_min_max(const Item_bool_func2 *cond,
bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const;
};
......@@ -2721,7 +2721,7 @@ public:
const uchar *from_end, uint param_data);
bool can_optimize_keypart_ref(const Item_func *cond, const Item *item) const;
bool can_optimize_group_min_max(const Item_bool_func2 *cond,
bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const
{
/*
......
......@@ -136,11 +136,6 @@ public:
bool is_bool_type() { return true; }
void fix_length_and_dec() { decimals=0; max_length=1; }
uint decimal_precision() const { return 1; }
virtual bool can_optimize_group_min_max(Item_field *min_max_arg_item,
const Item *const_item) const
{
return false;
}
};
......@@ -338,12 +333,6 @@ public:
Item_bool_func2::cleanup();
cmp.cleanup();
}
bool can_optimize_group_min_max(Item_field *min_max_arg_item,
const Item *const_item) const
{
return min_max_arg_item->field->can_optimize_group_min_max(this,
const_item);
}
void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
uint *and_level, table_map usable_tables,
SARGABLE_PARAM **sargables)
......
......@@ -13455,14 +13455,23 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
if (!simple_pred(pred, args, &inv))
DBUG_RETURN(FALSE);
if (args[0] && args[1] && !args[2]) // this is a binary function
if (args[0] && args[1]) // this is a binary function or BETWEEN
{
DBUG_ASSERT(pred->is_bool_type());
Item_bool_func *bool_func= (Item_bool_func*) pred;
if (!bool_func->can_optimize_group_min_max(min_max_arg_item,
args[1]))
Field *field= min_max_arg_item->field;
if (!args[2]) // this is a binary function
{
if (!field->can_optimize_group_min_max(bool_func, args[1]))
DBUG_RETURN(FALSE);
}
else // this is BETWEEN
{
if (!field->can_optimize_group_min_max(bool_func, args[1]) ||
!field->can_optimize_group_min_max(bool_func, args[2]))
DBUG_RETURN(FALSE);
}
}
}
else
has_other= true;
......
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