mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-8229 GROUP_MIN_MAX is erroneously applied for BETWEEN in some cases
This commit is contained in:
@@ -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
|
||||
{
|
||||
/*
|
||||
|
12
sql/field.h
12
sql/field.h
@@ -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,13 +13455,22 @@ 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]))
|
||||
DBUG_RETURN(FALSE);
|
||||
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
|
||||
|
Reference in New Issue
Block a user