Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
bb3115b2
Commit
bb3115b2
authored
Mar 12, 2015
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-6990 GROUP_MIN_MAX optimization is not applied in some cases when it could
parent
129c82bb
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
163 additions
and
30 deletions
+163
-30
mysql-test/r/group_min_max.result
mysql-test/r/group_min_max.result
+54
-0
mysql-test/t/group_min_max.test
mysql-test/t/group_min_max.test
+36
-0
sql/field.cc
sql/field.cc
+32
-0
sql/field.h
sql/field.h
+26
-0
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+11
-0
sql/opt_range.cc
sql/opt_range.cc
+4
-30
No files found.
mysql-test/r/group_min_max.result
View file @
bb3115b2
...
@@ -3727,3 +3727,57 @@ DROP TABLE t1;
...
@@ -3727,3 +3727,57 @@ DROP TABLE t1;
#
#
# End of 10.0 tests
# End of 10.0 tests
#
#
#
# Start of 10.1 tests
#
#
# MDEV-6990 GROUP_MIN_MAX optimization is not applied in some cases when it could
#
CREATE TABLE t1 (id INT NOT NULL, a DATE, KEY(id,a)) 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');
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>='2001-01-04' GROUP BY id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL id 8 NULL 9 Using where; Using index for group-by
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104.0 GROUP BY id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL id 8 NULL 9 Using where; Using index for group-by
EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL id 8 NULL 9 Using where; Using index for group-by
SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>='2001-01-04' 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>=20010104.0 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>=20010104e0 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
DROP TABLE t1;
#
# End of 10.1 tests
#
mysql-test/t/group_min_max.test
View file @
bb3115b2
...
@@ -1524,3 +1524,39 @@ DROP TABLE t1;
...
@@ -1524,3 +1524,39 @@ DROP TABLE t1;
--
echo
# End of 10.0 tests
--
echo
# End of 10.0 tests
--
echo
#
--
echo
#
--
echo
#
--
echo
# Start of 10.1 tests
--
echo
#
--
echo
#
--
echo
# MDEV-6990 GROUP_MIN_MAX optimization is not applied in some cases when it could
--
echo
#
CREATE
TABLE
t1
(
id
INT
NOT
NULL
,
a
DATE
,
KEY
(
id
,
a
))
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'
);
EXPLAIN
SELECT
id
,
MIN
(
a
),
MAX
(
a
)
FROM
t1
WHERE
a
>=
'2001-01-04'
GROUP
BY
id
;
EXPLAIN
SELECT
id
,
MIN
(
a
),
MAX
(
a
)
FROM
t1
WHERE
a
>=
20010104.0
GROUP
BY
id
;
EXPLAIN
SELECT
id
,
MIN
(
a
),
MAX
(
a
)
FROM
t1
WHERE
a
>=
20010104
e0
GROUP
BY
id
;
SELECT
id
,
MIN
(
a
),
MAX
(
a
)
FROM
t1
WHERE
a
>=
'2001-01-04'
GROUP
BY
id
;
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
>=
20010104
e0
GROUP
BY
id
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# End of 10.1 tests
--
echo
#
sql/field.cc
View file @
bb3115b2
...
@@ -1246,6 +1246,18 @@ double Field::pos_in_interval_val_str(Field *min, Field *max, uint data_offset)
...
@@ -1246,6 +1246,18 @@ double Field::pos_in_interval_val_str(Field *min, Field *max, uint data_offset)
}
}
/*
This handles all numeric and BIT data types.
*/
bool
Field
::
can_optimize_group_min_max
(
const
Item_bool_func2
*
cond
,
const
Item
*
const_item
)
{
DBUG_ASSERT
(
cmp_type
()
!=
STRING_RESULT
);
DBUG_ASSERT
(
cmp_type
()
!=
TIME_RESULT
);
return
const_item
->
cmp_type
()
!=
TIME_RESULT
;
}
/**
/**
Numeric fields base class constructor.
Numeric fields base class constructor.
*/
*/
...
@@ -5257,6 +5269,14 @@ my_decimal *Field_temporal::val_decimal(my_decimal *d)
...
@@ -5257,6 +5269,14 @@ my_decimal *Field_temporal::val_decimal(my_decimal *d)
return
TIME_to_my_decimal
(
&
ltime
,
d
);
return
TIME_to_my_decimal
(
&
ltime
,
d
);
}
}
bool
Field_temporal
::
can_optimize_group_min_max
(
const
Item_bool_func2
*
cond
,
const
Item
*
const_item
)
{
return
true
;
// Field is of TIME_RESULT, which supersedes everything else.
}
/****************************************************************************
/****************************************************************************
** time type
** time type
** In string context: HH:MM:SS
** In string context: HH:MM:SS
...
@@ -6448,6 +6468,18 @@ uint32 Field_longstr::max_data_length() const
...
@@ -6448,6 +6468,18 @@ uint32 Field_longstr::max_data_length() const
}
}
bool
Field_longstr
::
can_optimize_group_min_max
(
const
Item_bool_func2
*
cond
,
const
Item
*
const_item
)
{
// Can't use indexes when comparing a string to a number or a date
if
(
const_item
->
cmp_type
()
!=
STRING_RESULT
)
return
false
;
// Don't use an index when comparing strings of different collations.
return
charset
()
==
((
Item_bool_func2
*
)
cond
)
->
compare_collation
();
}
double
Field_string
::
val_real
(
void
)
double
Field_string
::
val_real
(
void
)
{
{
ASSERT_COLUMN_MARKED_FOR_READ
;
ASSERT_COLUMN_MARKED_FOR_READ
;
...
...
sql/field.h
View file @
bb3115b2
...
@@ -39,6 +39,7 @@ class Relay_log_info;
...
@@ -39,6 +39,7 @@ class Relay_log_info;
class
Field
;
class
Field
;
class
Column_statistics
;
class
Column_statistics
;
class
Column_statistics_collected
;
class
Column_statistics_collected
;
class
Item_bool_func2
;
enum
enum_check_fields
enum
enum_check_fields
{
{
...
@@ -963,6 +964,9 @@ class Field
...
@@ -963,6 +964,9 @@ class Field
return
(
double
)
0.5
;
return
(
double
)
0.5
;
}
}
virtual
bool
can_optimize_group_min_max
(
const
Item_bool_func2
*
cond
,
const
Item
*
const_item
);
friend
int
cre_myisam
(
char
*
name
,
register
TABLE
*
form
,
uint
options
,
friend
int
cre_myisam
(
char
*
name
,
register
TABLE
*
form
,
uint
options
,
ulonglong
auto_increment_value
);
ulonglong
auto_increment_value
);
friend
class
Copy_field
;
friend
class
Copy_field
;
...
@@ -1154,6 +1158,8 @@ class Field_longstr :public Field_str
...
@@ -1154,6 +1158,8 @@ class Field_longstr :public Field_str
int
store_decimal
(
const
my_decimal
*
d
);
int
store_decimal
(
const
my_decimal
*
d
);
uint32
max_data_length
()
const
;
uint32
max_data_length
()
const
;
bool
match_collation_to_optimize_range
()
const
{
return
true
;
}
bool
match_collation_to_optimize_range
()
const
{
return
true
;
}
bool
can_optimize_group_min_max
(
const
Item_bool_func2
*
cond
,
const
Item
*
const_item
);
};
};
/* base class for float and double and decimal (old one) */
/* base class for float and double and decimal (old one) */
...
@@ -1581,6 +1587,12 @@ class Field_null :public Field_str {
...
@@ -1581,6 +1587,12 @@ class Field_null :public Field_str {
uint
size_of
()
const
{
return
sizeof
(
*
this
);
}
uint
size_of
()
const
{
return
sizeof
(
*
this
);
}
uint32
max_display_length
()
{
return
4
;
}
uint32
max_display_length
()
{
return
4
;
}
void
move_field_offset
(
my_ptrdiff_t
ptr_diff
)
{}
void
move_field_offset
(
my_ptrdiff_t
ptr_diff
)
{}
bool
can_optimize_group_min_max
(
const
Item_bool_func2
*
cond
,
const
Item
*
const_item
)
{
DBUG_ASSERT
(
0
);
return
false
;
}
};
};
...
@@ -1613,6 +1625,8 @@ class Field_temporal: public Field {
...
@@ -1613,6 +1625,8 @@ class Field_temporal: public Field {
{
{
return
pos_in_interval_val_real
(
min
,
max
);
return
pos_in_interval_val_real
(
min
,
max
);
}
}
bool
can_optimize_group_min_max
(
const
Item_bool_func2
*
cond
,
const
Item
*
const_item
);
};
};
...
@@ -2650,6 +2664,18 @@ class Field_enum :public Field_str {
...
@@ -2650,6 +2664,18 @@ class Field_enum :public Field_str {
virtual
const
uchar
*
unpack
(
uchar
*
to
,
const
uchar
*
from
,
virtual
const
uchar
*
unpack
(
uchar
*
to
,
const
uchar
*
from
,
const
uchar
*
from_end
,
uint
param_data
);
const
uchar
*
from_end
,
uint
param_data
);
bool
can_optimize_group_min_max
(
const
Item_bool_func2
*
cond
,
const
Item
*
const_item
)
{
/*
Can't use GROUP_MIN_MAX optimization for ENUM and SET,
because the values are stored as numbers in index,
while MIN() and MAX() work as strings.
It would return the records with min and max enum numeric indexes.
"Bug#45300 MAX() and ENUM type" should be fixed first.
*/
return
false
;
}
private:
private:
int
do_save_field_metadata
(
uchar
*
first_byte
);
int
do_save_field_metadata
(
uchar
*
first_byte
);
uint
is_equal
(
Create_field
*
new_field
);
uint
is_equal
(
Create_field
*
new_field
);
...
...
sql/item_cmpfunc.h
View file @
bb3115b2
...
@@ -131,6 +131,11 @@ class Item_bool_func :public Item_int_func
...
@@ -131,6 +131,11 @@ class Item_bool_func :public Item_int_func
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
;
}
};
};
...
@@ -419,6 +424,12 @@ class Item_bool_rowready_func2 :public Item_bool_func2
...
@@ -419,6 +424,12 @@ class Item_bool_rowready_func2 :public Item_bool_func2
{
{
return
(
*
arg
!=
NULL
);
return
(
*
arg
!=
NULL
);
}
}
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
);
}
};
};
/**
/**
...
...
sql/opt_range.cc
View file @
bb3115b2
...
@@ -13412,39 +13412,13 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
...
@@ -13412,39 +13412,13 @@ 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
);
/* Check for compatible string comparisons - similar to get_mm_leaf. */
if
(
args
[
0
]
&&
args
[
1
]
&&
!
args
[
2
])
// this is a binary function
if
(
args
[
0
]
&&
args
[
1
]
&&
!
args
[
2
])
// this is a binary function
{
{
if
(
args
[
1
]
->
cmp_type
()
==
TIME_RESULT
&&
DBUG_ASSERT
(
pred
->
is_bool_type
());
min_max_arg_item
->
field
->
cmp_type
()
!=
TIME_RESULT
)
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
);
DBUG_RETURN
(
FALSE
);
/*
Can't use GROUP_MIN_MAX optimization for ENUM and SET,
because the values are stored as numbers in index,
while MIN() and MAX() work as strings.
It would return the records with min and max enum numeric indexes.
"Bug#45300 MAX() and ENUM type" should be fixed first.
*/
if
(
min_max_arg_item
->
field
->
real_type
()
==
MYSQL_TYPE_ENUM
||
min_max_arg_item
->
field
->
real_type
()
==
MYSQL_TYPE_SET
)
DBUG_RETURN
(
FALSE
);
if
(
min_max_arg_item
->
result_type
()
==
STRING_RESULT
&&
/*
Don't use an index when comparing strings of different collations.
*/
((
args
[
1
]
->
result_type
()
==
STRING_RESULT
&&
image_type
==
Field
::
itRAW
&&
min_max_arg_item
->
field
->
charset
()
!=
pred
->
compare_collation
())
||
/*
We can't always use indexes when comparing a string index to a
number.
*/
(
args
[
1
]
->
result_type
()
!=
STRING_RESULT
&&
min_max_arg_item
->
field
->
cmp_type
()
!=
args
[
1
]
->
result_type
())))
DBUG_RETURN
(
FALSE
);
}
}
}
}
else
else
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment