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
|
4 2001-01-04 2001-01-04
|
||||||
DROP TABLE t1;
|
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
|
# 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;
|
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id;
|
||||||
DROP TABLE t1;
|
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 #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@@ -1261,7 +1261,7 @@ bool Field::can_optimize_keypart_ref(const Item_func *cond,
|
|||||||
/*
|
/*
|
||||||
This handles all numeric and BIT data types.
|
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
|
const Item *const_item) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(cmp_type() != STRING_RESULT);
|
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
|
const Item *const_item) const
|
||||||
{
|
{
|
||||||
return true; // Field is of TIME_RESULT, which supersedes everything else.
|
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
|
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;
|
||||||
class Column_statistics_collected;
|
class Column_statistics_collected;
|
||||||
class Item_func;
|
class Item_func;
|
||||||
class Item_bool_func2;
|
class Item_bool_func;
|
||||||
|
|
||||||
enum enum_check_fields
|
enum enum_check_fields
|
||||||
{
|
{
|
||||||
@@ -986,7 +986,7 @@ public:
|
|||||||
{
|
{
|
||||||
return can_optimize_keypart_ref(cond, item);
|
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;
|
const Item *const_item) const;
|
||||||
bool can_optimize_outer_join_table_elimination(const Item_func *cond,
|
bool can_optimize_outer_join_table_elimination(const Item_func *cond,
|
||||||
const Item *item) const
|
const Item *item) const
|
||||||
@@ -1191,7 +1191,7 @@ public:
|
|||||||
bool match_collation_to_optimize_range() const { return true; }
|
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_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_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;
|
const Item *const_item) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1625,7 +1625,7 @@ public:
|
|||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
return false;
|
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
|
const Item *const_item) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
@@ -1664,7 +1664,7 @@ public:
|
|||||||
return pos_in_interval_val_real(min, max);
|
return pos_in_interval_val_real(min, max);
|
||||||
}
|
}
|
||||||
bool can_optimize_keypart_ref(const Item_func *cond, const Item *item) const;
|
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;
|
const Item *const_item) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2721,7 +2721,7 @@ public:
|
|||||||
const uchar *from_end, uint param_data);
|
const uchar *from_end, uint param_data);
|
||||||
|
|
||||||
bool can_optimize_keypart_ref(const Item_func *cond, const Item *item) const;
|
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
|
const Item *const_item) const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@@ -136,11 +136,6 @@ public:
|
|||||||
bool is_bool_type() { return true; }
|
bool is_bool_type() { return true; }
|
||||||
void fix_length_and_dec() { decimals=0; max_length=1; }
|
void fix_length_and_dec() { decimals=0; max_length=1; }
|
||||||
uint decimal_precision() const { return 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();
|
Item_bool_func2::cleanup();
|
||||||
cmp.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,
|
void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
|
||||||
uint *and_level, table_map usable_tables,
|
uint *and_level, table_map usable_tables,
|
||||||
SARGABLE_PARAM **sargables)
|
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))
|
if (!simple_pred(pred, args, &inv))
|
||||||
DBUG_RETURN(FALSE);
|
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());
|
DBUG_ASSERT(pred->is_bool_type());
|
||||||
Item_bool_func *bool_func= (Item_bool_func*) pred;
|
Item_bool_func *bool_func= (Item_bool_func*) pred;
|
||||||
if (!bool_func->can_optimize_group_min_max(min_max_arg_item,
|
Field *field= min_max_arg_item->field;
|
||||||
args[1]))
|
if (!args[2]) // this is a binary function
|
||||||
DBUG_RETURN(FALSE);
|
{
|
||||||
|
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
|
else
|
||||||
|
Reference in New Issue
Block a user