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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
5485e447
Commit
5485e447
authored
Oct 01, 2009
by
Alexander Nozdrin
Browse files
Options
Browse Files
Download
Plain Diff
Merge from mysql-next-mr.
parents
de0285a2
3f7624fc
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1660 additions
and
922 deletions
+1660
-922
mysql-test/mysql-test-run.pl
mysql-test/mysql-test-run.pl
+0
-1
mysql-test/r/bench_count_distinct.result
mysql-test/r/bench_count_distinct.result
+1
-1
mysql-test/r/group_min_max.result
mysql-test/r/group_min_max.result
+262
-8
mysql-test/t/group_min_max.test
mysql-test/t/group_min_max.test
+123
-2
sql/field.h
sql/field.h
+6
-3
sql/item_sum.cc
sql/item_sum.cc
+637
-646
sql/item_sum.h
sql/item_sum.h
+335
-198
sql/opt_range.cc
sql/opt_range.cc
+137
-51
sql/opt_range.h
sql/opt_range.h
+15
-2
sql/opt_sum.cc
sql/opt_sum.cc
+8
-2
sql/sql_class.h
sql/sql_class.h
+1
-0
sql/sql_select.cc
sql/sql_select.cc
+125
-5
sql/sql_select.h
sql/sql_select.h
+7
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+3
-3
No files found.
mysql-test/mysql-test-run.pl
View file @
5485e447
...
...
@@ -5085,7 +5085,6 @@ sub valgrind_arguments {
else
{
mtr_add_arg
(
$args
,
"
--tool=memcheck
");
# From >= 2.1.2 needs this option
mtr_add_arg
(
$args
,
"
--alignment=8
");
mtr_add_arg
(
$args
,
"
--leak-check=yes
");
mtr_add_arg
(
$args
,
"
--num-callers=16
");
mtr_add_arg
(
$args
,
"
--suppressions=%s/valgrind.supp
",
$glob_mysql_test_dir
)
...
...
mysql-test/r/bench_count_distinct.result
View file @
5485e447
...
...
@@ -5,7 +5,7 @@ count(distinct n)
100
explain extended select count(distinct n) from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1
index NULL n 4 NULL 200 100.00 Using index
1 SIMPLE t1
range NULL n 4 NULL 10 100.00 Using index for group-by
Warnings:
Note 1003 select count(distinct `test`.`t1`.`n`) AS `count(distinct n)` from `test`.`t1`
drop table t1;
mysql-test/r/group_min_max.result
View file @
5485e447
This diff is collapsed.
Click to expand it.
mysql-test/t/group_min_max.test
View file @
5485e447
...
...
@@ -570,13 +570,13 @@ explain select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a');
explain
select
count
(
distinct
a1
,
a2
,
b
,
c
)
from
t1
where
(
a2
>=
'b'
)
and
(
b
=
'a'
)
and
(
c
=
'i121'
);
explain
extended
select
count
(
distinct
a1
,
a2
,
b
)
from
t1
where
(
a1
>
'a'
)
and
(
a2
>
'a'
)
and
(
b
=
'c'
);
explain
select
count
(
distinct
b
)
from
t1
where
(
a2
>=
'b'
)
and
(
b
=
'a'
);
explain
extended
select
ord
(
a1
)
+
count
(
distinct
a1
,
a2
,
b
)
from
t1
where
(
a1
>
'a'
)
and
(
a2
>
'a'
);
explain
extended
select
98
+
count
(
distinct
a1
,
a2
,
b
)
from
t1
where
(
a1
>
'a'
)
and
(
a2
>
'a'
);
select
count
(
distinct
a1
,
a2
,
b
)
from
t1
where
(
a2
>=
'b'
)
and
(
b
=
'a'
);
select
count
(
distinct
a1
,
a2
,
b
,
c
)
from
t1
where
(
a2
>=
'b'
)
and
(
b
=
'a'
)
and
(
c
=
'i121'
);
select
count
(
distinct
a1
,
a2
,
b
)
from
t1
where
(
a1
>
'a'
)
and
(
a2
>
'a'
)
and
(
b
=
'c'
);
select
count
(
distinct
b
)
from
t1
where
(
a2
>=
'b'
)
and
(
b
=
'a'
);
select
ord
(
a1
)
+
count
(
distinct
a1
,
a2
,
b
)
from
t1
where
(
a1
>
'a'
)
and
(
a2
>
'a'
);
select
98
+
count
(
distinct
a1
,
a2
,
b
)
from
t1
where
(
a1
>
'a'
)
and
(
a2
>
'a'
);
#
# Queries with expressions in the select clause
...
...
@@ -1033,3 +1033,124 @@ SELECT a, MAX(b) FROM t WHERE b GROUP BY a;
DROP
TABLE
t
;
--
echo
End
of
5.1
tests
--
echo
#
--
echo
# WL#3220 (Loose index scan for COUNT DISTINCT)
--
echo
#
CREATE
TABLE
t1
(
a
INT
,
b
INT
,
c
INT
,
KEY
(
a
,
b
));
INSERT
INTO
t1
VALUES
(
1
,
1
,
1
),
(
1
,
2
,
1
),
(
1
,
3
,
1
),
(
1
,
4
,
1
);
INSERT
INTO
t1
SELECT
a
,
b
+
4
,
1
FROM
t1
;
INSERT
INTO
t1
SELECT
a
+
1
,
b
,
1
FROM
t1
;
CREATE
TABLE
t2
(
a
INT
,
b
INT
,
c
INT
,
d
INT
,
e
INT
,
f
INT
,
KEY
(
a
,
b
,
c
));
INSERT
INTO
t2
VALUES
(
1
,
1
,
1
,
1
,
1
,
1
),
(
1
,
2
,
1
,
1
,
1
,
1
),
(
1
,
3
,
1
,
1
,
1
,
1
),
(
1
,
4
,
1
,
1
,
1
,
1
);
INSERT
INTO
t2
SELECT
a
,
b
+
4
,
c
,
d
,
e
,
f
FROM
t2
;
INSERT
INTO
t2
SELECT
a
+
1
,
b
,
c
,
d
,
e
,
f
FROM
t2
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
;
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
,
b
)
FROM
t1
;
SELECT
COUNT
(
DISTINCT
a
,
b
)
FROM
t1
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
b
,
a
)
FROM
t1
;
SELECT
COUNT
(
DISTINCT
b
,
a
)
FROM
t1
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
b
)
FROM
t1
;
SELECT
COUNT
(
DISTINCT
b
)
FROM
t1
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
GROUP
BY
a
;
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
GROUP
BY
a
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
b
)
FROM
t1
GROUP
BY
a
;
SELECT
COUNT
(
DISTINCT
b
)
FROM
t1
GROUP
BY
a
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
GROUP
BY
b
;
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
GROUP
BY
b
;
EXPLAIN
SELECT
DISTINCT
COUNT
(
DISTINCT
a
)
FROM
t1
;
SELECT
DISTINCT
COUNT
(
DISTINCT
a
)
FROM
t1
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
,
b
+
0
)
FROM
t1
;
SELECT
COUNT
(
DISTINCT
a
,
b
+
0
)
FROM
t1
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
HAVING
COUNT
(
DISTINCT
b
)
<
10
;
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
HAVING
COUNT
(
DISTINCT
b
)
<
10
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
HAVING
COUNT
(
DISTINCT
c
)
<
10
;
SELECT
COUNT
(
DISTINCT
a
)
FROM
t1
HAVING
COUNT
(
DISTINCT
c
)
<
10
;
EXPLAIN
SELECT
1
FROM
t1
HAVING
COUNT
(
DISTINCT
a
)
<
10
;
SELECT
1
FROM
t1
HAVING
COUNT
(
DISTINCT
a
)
<
10
;
EXPLAIN
SELECT
1
FROM
t1
GROUP
BY
a
HAVING
COUNT
(
DISTINCT
b
)
>
1
;
SELECT
1
FROM
t1
GROUP
BY
a
HAVING
COUNT
(
DISTINCT
b
)
>
1
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
t1_1
.
a
)
FROM
t1
t1_1
,
t1
t1_2
GROUP
BY
t1_1
.
a
;
SELECT
COUNT
(
DISTINCT
t1_1
.
a
)
FROM
t1
t1_1
,
t1
t1_2
GROUP
BY
t1_1
.
a
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
),
12
FROM
t1
;
SELECT
COUNT
(
DISTINCT
a
),
12
FROM
t1
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
,
b
,
c
)
FROM
t2
;
SELECT
COUNT
(
DISTINCT
a
,
b
,
c
)
FROM
t2
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
),
SUM
(
DISTINCT
a
),
AVG
(
DISTINCT
a
)
FROM
t2
;
SELECT
COUNT
(
DISTINCT
a
),
SUM
(
DISTINCT
a
),
AVG
(
DISTINCT
a
)
FROM
t2
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
),
SUM
(
DISTINCT
a
),
AVG
(
DISTINCT
f
)
FROM
t2
;
SELECT
COUNT
(
DISTINCT
a
),
SUM
(
DISTINCT
a
),
AVG
(
DISTINCT
f
)
FROM
t2
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
,
b
),
COUNT
(
DISTINCT
b
,
a
)
FROM
t2
;
SELECT
COUNT
(
DISTINCT
a
,
b
),
COUNT
(
DISTINCT
b
,
a
)
FROM
t2
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
,
b
),
COUNT
(
DISTINCT
b
,
f
)
FROM
t2
;
SELECT
COUNT
(
DISTINCT
a
,
b
),
COUNT
(
DISTINCT
b
,
f
)
FROM
t2
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
,
b
),
COUNT
(
DISTINCT
b
,
d
)
FROM
t2
;
SELECT
COUNT
(
DISTINCT
a
,
b
),
COUNT
(
DISTINCT
b
,
d
)
FROM
t2
;
EXPLAIN
SELECT
a
,
c
,
COUNT
(
DISTINCT
c
,
a
,
b
)
FROM
t2
GROUP
BY
a
,
b
,
c
;
SELECT
a
,
c
,
COUNT
(
DISTINCT
c
,
a
,
b
)
FROM
t2
GROUP
BY
a
,
b
,
c
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
c
,
a
,
b
)
FROM
t2
WHERE
a
>
5
AND
b
BETWEEN
10
AND
20
GROUP
BY
a
,
b
,
c
;
SELECT
COUNT
(
DISTINCT
c
,
a
,
b
)
FROM
t2
WHERE
a
>
5
AND
b
BETWEEN
10
AND
20
GROUP
BY
a
,
b
,
c
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
b
),
SUM
(
DISTINCT
b
)
FROM
t2
WHERE
a
=
5
GROUP
BY
b
;
SELECT
COUNT
(
DISTINCT
b
),
SUM
(
DISTINCT
b
)
FROM
t2
WHERE
a
=
5
GROUP
BY
b
;
EXPLAIN
SELECT
a
,
COUNT
(
DISTINCT
b
),
SUM
(
DISTINCT
b
)
FROM
t2
GROUP
BY
a
;
SELECT
a
,
COUNT
(
DISTINCT
b
),
SUM
(
DISTINCT
b
)
FROM
t2
GROUP
BY
a
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
b
),
SUM
(
DISTINCT
b
)
FROM
t2
GROUP
BY
a
;
SELECT
COUNT
(
DISTINCT
b
),
SUM
(
DISTINCT
b
)
FROM
t2
GROUP
BY
a
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
,
b
)
FROM
t2
WHERE
c
=
13
AND
d
=
42
;
SELECT
COUNT
(
DISTINCT
a
,
b
)
FROM
t2
WHERE
c
=
13
AND
d
=
42
;
EXPLAIN
SELECT
a
,
COUNT
(
DISTINCT
a
),
SUM
(
DISTINCT
a
)
FROM
t2
WHERE
b
=
13
AND
c
=
42
GROUP
BY
a
;
SELECT
a
,
COUNT
(
DISTINCT
a
),
SUM
(
DISTINCT
a
)
FROM
t2
WHERE
b
=
13
AND
c
=
42
GROUP
BY
a
;
EXPLAIN
SELECT
COUNT
(
DISTINCT
a
,
b
),
SUM
(
DISTINCT
a
)
FROM
t2
WHERE
b
=
42
;
SELECT
COUNT
(
DISTINCT
a
,
b
),
SUM
(
DISTINCT
a
)
FROM
t2
WHERE
b
=
42
;
EXPLAIN
SELECT
SUM
(
DISTINCT
a
),
MAX
(
b
)
FROM
t2
GROUP
BY
a
;
SELECT
SUM
(
DISTINCT
a
),
MAX
(
b
)
FROM
t2
GROUP
BY
a
;
EXPLAIN
SELECT
42
*
(
a
+
c
+
COUNT
(
DISTINCT
c
,
a
,
b
))
FROM
t2
GROUP
BY
a
,
b
,
c
;
SELECT
42
*
(
a
+
c
+
COUNT
(
DISTINCT
c
,
a
,
b
))
FROM
t2
GROUP
BY
a
,
b
,
c
;
EXPLAIN
SELECT
(
SUM
(
DISTINCT
a
)
+
MAX
(
b
))
FROM
t2
GROUP
BY
a
;
SELECT
(
SUM
(
DISTINCT
a
)
+
MAX
(
b
))
FROM
t2
GROUP
BY
a
;
DROP
TABLE
t1
,
t2
;
--
echo
# end of WL#3220 tests
sql/field.h
View file @
5485e447
...
...
@@ -1934,9 +1934,12 @@ public:
virtual
bool
str_needs_quotes
()
{
return
TRUE
;
}
my_decimal
*
val_decimal
(
my_decimal
*
);
int
cmp
(
const
uchar
*
a
,
const
uchar
*
b
)
{
DBUG_ASSERT
(
ptr
==
a
);
return
Field_bit
::
key_cmp
(
b
,
bytes_in_rec
+
test
(
bit_len
));
{
DBUG_ASSERT
(
ptr
==
a
||
ptr
==
b
);
if
(
ptr
==
a
)
return
Field_bit
::
key_cmp
(
b
,
bytes_in_rec
+
test
(
bit_len
));
else
return
Field_bit
::
key_cmp
(
a
,
bytes_in_rec
+
test
(
bit_len
))
*
-
1
;
}
int
cmp_binary_offset
(
uint
row_offset
)
{
return
cmp_offset
(
row_offset
);
}
...
...
sql/item_sum.cc
View file @
5485e447
This diff is collapsed.
Click to expand it.
sql/item_sum.h
View file @
5485e447
This diff is collapsed.
Click to expand it.
sql/opt_range.cc
View file @
5485e447
This diff is collapsed.
Click to expand it.
sql/opt_range.h
View file @
5485e447
...
...
@@ -616,6 +616,7 @@ private:
uchar
*
last_prefix
;
/* Prefix of the last group for detecting EOF. */
bool
have_min
;
/* Specify whether we are computing */
bool
have_max
;
/* a MIN, a MAX, or both. */
bool
have_agg_distinct
;
/* aggregate_function(DISTINCT ...). */
bool
seen_first_key
;
/* Denotes whether the first key was retrieved.*/
KEY_PART_INFO
*
min_max_arg_part
;
/* The keypart of the only argument field */
/* of all MIN/MAX functions. */
...
...
@@ -629,6 +630,11 @@ private:
List
<
Item_sum
>
*
max_functions
;
List_iterator
<
Item_sum
>
*
min_functions_it
;
List_iterator
<
Item_sum
>
*
max_functions_it
;
/*
Use index scan to get the next different key instead of jumping into it
through index read
*/
bool
is_index_scan
;
public:
/*
The following two members are public to allow easy access from
...
...
@@ -646,12 +652,13 @@ private:
void
update_max_result
();
public:
QUICK_GROUP_MIN_MAX_SELECT
(
TABLE
*
table
,
JOIN
*
join
,
bool
have_min
,
bool
have_max
,
KEY_PART_INFO
*
min_max_arg_part
,
bool
have_max
,
bool
have_agg_distinct
,
KEY_PART_INFO
*
min_max_arg_part
,
uint
group_prefix_len
,
uint
group_key_parts
,
uint
used_key_parts
,
KEY
*
index_info
,
uint
use_index
,
double
read_cost
,
ha_rows
records
,
uint
key_infix_len
,
uchar
*
key_infix
,
MEM_ROOT
*
parent_alloc
);
*
parent_alloc
,
bool
is_index_scan
);
~
QUICK_GROUP_MIN_MAX_SELECT
();
bool
add_range
(
SEL_ARG
*
sel_range
);
void
update_key_stat
();
...
...
@@ -667,6 +674,12 @@ public:
#ifndef DBUG_OFF
void
dbug_dump
(
int
indent
,
bool
verbose
);
#endif
bool
is_agg_distinct
()
{
return
have_agg_distinct
;
}
virtual
void
append_loose_scan_type
(
String
*
str
)
{
if
(
is_index_scan
)
str
->
append
(
STRING_WITH_LEN
(
" (scanning)"
));
}
};
...
...
sql/opt_sum.cc
View file @
5485e447
...
...
@@ -355,10 +355,13 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result
=
0
;
break
;
}
item_sum
->
set_aggregator
(
item_sum
->
with_distinct
?
Aggregator
::
DISTINCT_AGGREGATOR
:
Aggregator
::
SIMPLE_AGGREGATOR
);
if
(
!
count
)
{
/* If count == 0, then we know that is_exact_count == TRUE. */
((
Item_sum_min
*
)
item_sum
)
->
clear
();
/* Set to NULL. */
((
Item_sum_min
*
)
item_sum
)
->
aggregator_
clear
();
/* Set to NULL. */
}
else
((
Item_sum_min
*
)
item_sum
)
->
reset
();
/* Set to the constant value. */
...
...
@@ -443,10 +446,13 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result
=
0
;
break
;
}
item_sum
->
set_aggregator
(
item_sum
->
with_distinct
?
Aggregator
::
DISTINCT_AGGREGATOR
:
Aggregator
::
SIMPLE_AGGREGATOR
);
if
(
!
count
)
{
/* If count != 1, then we know that is_exact_count == TRUE. */
((
Item_sum_max
*
)
item_sum
)
->
clear
();
/* Set to NULL. */
((
Item_sum_max
*
)
item_sum
)
->
aggregator_
clear
();
/* Set to NULL. */
}
else
((
Item_sum_max
*
)
item_sum
)
->
reset
();
/* Set to the constant value. */
...
...
sql/sql_class.h
View file @
5485e447
...
...
@@ -54,6 +54,7 @@
class
Reprepare_observer
{
public:
Reprepare_observer
()
{}
/**
Check if a change of metadata is OK. In future
the signature of this method may be extended to accept the old
...
...
sql/sql_select.cc
View file @
5485e447
...
...
@@ -222,6 +222,7 @@ static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table);
static
void
copy_sum_funcs
(
Item_sum
**
func_ptr
,
Item_sum
**
end
);
static
bool
add_ref_to_table_cond
(
THD
*
thd
,
JOIN_TAB
*
join_tab
);
static
bool
setup_sum_funcs
(
THD
*
thd
,
Item_sum
**
func_ptr
);
static
bool
prepare_sum_aggregators
(
Item_sum
**
func_ptr
,
bool
need_distinct
);
static
bool
init_sum_functions
(
Item_sum
**
func
,
Item_sum
**
end
);
static
bool
update_sum_func
(
Item_sum
**
func
);
static
void
select_describe
(
JOIN
*
join
,
bool
need_tmp_table
,
bool
need_order
,
...
...
@@ -1232,7 +1233,11 @@ JOIN::optimize()
if
(
test_if_subpart
(
group_list
,
order
)
||
(
!
group_list
&&
tmp_table_param
.
sum_func_count
))
{
order
=
0
;
if
(
is_indexed_agg_distinct
(
this
,
NULL
))
sort_and_group
=
0
;
}
// Can't use sort on head table if using row cache
if
(
full_join
)
...
...
@@ -1410,8 +1415,16 @@ JOIN::optimize()
single table queries, thus it is sufficient to test only the first
join_tab element of the plan for its access method.
*/
bool
need_distinct
=
TRUE
;
if
(
join_tab
->
is_using_loose_index_scan
())
{
tmp_table_param
.
precomputed_group_by
=
TRUE
;
if
(
join_tab
->
is_using_agg_loose_index_scan
())
{
need_distinct
=
FALSE
;
tmp_table_param
.
precomputed_group_by
=
FALSE
;
}
}
/* Create a tmp table if distinct or if the sort is too complicated */
if
(
need_tmp
)
...
...
@@ -1472,6 +1485,7 @@ JOIN::optimize()
HA_POS_ERROR
,
HA_POS_ERROR
,
FALSE
)
||
alloc_group_fields
(
this
,
group_list
)
||
make_sum_func_list
(
all_fields
,
fields_list
,
1
)
||
prepare_sum_aggregators
(
sum_funcs
,
need_distinct
)
||
setup_sum_funcs
(
thd
,
sum_funcs
))
{
DBUG_RETURN
(
1
);
...
...
@@ -1481,6 +1495,7 @@ JOIN::optimize()
else
{
if
(
make_sum_func_list
(
all_fields
,
fields_list
,
0
)
||
prepare_sum_aggregators
(
sum_funcs
,
need_distinct
)
||
setup_sum_funcs
(
thd
,
sum_funcs
))
{
DBUG_RETURN
(
1
);
...
...
@@ -1953,7 +1968,9 @@ JOIN::exec()
}
}
if
(
curr_join
->
make_sum_func_list
(
*
curr_all_fields
,
*
curr_fields_list
,
1
,
TRUE
))
1
,
TRUE
)
||
prepare_sum_aggregators
(
curr_join
->
sum_funcs
,
!
curr_join
->
join_tab
->
is_using_agg_loose_index_scan
()))
DBUG_VOID_RETURN
;
curr_join
->
group_list
=
0
;
if
(
!
curr_join
->
sort_and_group
&&
...
...
@@ -2056,6 +2073,8 @@ JOIN::exec()
if
(
curr_join
->
make_sum_func_list
(
*
curr_all_fields
,
*
curr_fields_list
,
1
,
TRUE
)
||
prepare_sum_aggregators
(
curr_join
->
sum_funcs
,
!
curr_join
->
join_tab
||
!
curr_join
->
join_tab
->
is_using_agg_loose_index_scan
())
||
setup_sum_funcs
(
curr_join
->
thd
,
curr_join
->
sum_funcs
)
||
thd
->
is_fatal_error
)
DBUG_VOID_RETURN
;
...
...
@@ -3937,6 +3956,82 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
}
/**
Check for the presence of AGGFN(DISTINCT a) queries that may be subject
to loose index scan.
Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
(QUICK_GROUP_MIN_MAX_SELECT).
Optionally (if out_args is supplied) will push the arguments of
AGGFN(DISTINCT) to the list
@param join the join to check
@param[out] out_args list of aggregate function arguments
@return does the query qualify for indexed AGGFN(DISTINCT)
@retval true it does
@retval false AGGFN(DISTINCT) must apply distinct in it.
*/
bool
is_indexed_agg_distinct
(
JOIN
*
join
,
List
<
Item_field
>
*
out_args
)
{
Item_sum
**
sum_item_ptr
;
bool
result
=
false
;
if
(
join
->
tables
!=
1
||
/* reference more than 1 table */
join
->
select_distinct
||
/* or a DISTINCT */
join
->
select_lex
->
olap
==
ROLLUP_TYPE
)
/* Check (B3) for ROLLUP */
return
false
;
if
(
join
->
make_sum_func_list
(
join
->
all_fields
,
join
->
fields_list
,
1
))
return
false
;
for
(
sum_item_ptr
=
join
->
sum_funcs
;
*
sum_item_ptr
;
sum_item_ptr
++
)
{
Item_sum
*
sum_item
=
*
sum_item_ptr
;
Item
*
expr
;
/* aggregate is not AGGFN(DISTINCT) or more than 1 argument to it */
switch
(
sum_item
->
sum_func
())
{
case
Item_sum
:
:
MIN_FUNC
:
case
Item_sum
:
:
MAX_FUNC
:
continue
;
case
Item_sum
:
:
COUNT_DISTINCT_FUNC
:
break
;
case
Item_sum
:
:
AVG_DISTINCT_FUNC
:
case
Item_sum
:
:
SUM_DISTINCT_FUNC
:
if
(
sum_item
->
get_arg_count
()
==
1
)
break
;
/* fall through */
default:
return
false
;
}
/*
We arrive here for every COUNT(DISTINCT),AVG(DISTINCT) or SUM(DISTINCT).
Collect the arguments of the aggregate functions to a list.
We don't worry about duplicates as these will be sorted out later in
get_best_group_min_max
*/
for
(
uint
i
=
0
;
i
<
sum_item
->
get_arg_count
();
i
++
)
{
expr
=
sum_item
->
get_arg
(
i
);
/* The AGGFN(DISTINCT) arg is not an attribute? */
if
(
expr
->
real_item
()
->
type
()
!=
Item
::
FIELD_ITEM
)
return
false
;
/*
If we came to this point the AGGFN(DISTINCT) loose index scan
optimization is applicable
*/
if
(
out_args
)
out_args
->
push_back
((
Item_field
*
)
expr
);
result
=
true
;
}
}
return
result
;
}
/**
Discover the indexes that can be used for GROUP BY or DISTINCT queries.
...
...
@@ -3979,6 +4074,10 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
item
->
walk
(
&
Item
::
collect_item_field_processor
,
0
,
(
uchar
*
)
&
indexed_fields
);
}
else
if
(
is_indexed_agg_distinct
(
join
,
&
indexed_fields
))
{
join
->
sort_and_group
=
1
;
}
else
return
;
...
...
@@ -10377,6 +10476,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
bzero
(
share
,
sizeof
(
*
share
));
table
->
field
=
field
;
table
->
s
=
share
;
table
->
temp_pool_slot
=
MY_BIT_NONE
;
share
->
blob_field
=
blob_field
;
share
->
fields
=
field_count
;
share
->
blob_ptr_size
=
portable_sizeof_char_ptr
;
...
...
@@ -14532,7 +14632,7 @@ setup_new_fields(THD *thd, List<Item> &fields,
optimize away 'order by'.
*/
static
ORDER
*
ORDER
*
create_distinct_group
(
THD
*
thd
,
Item
**
ref_pointer_array
,
ORDER
*
order_list
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
all_fields
,
...
...
@@ -15334,7 +15434,22 @@ static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
DBUG_ENTER
(
"setup_sum_funcs"
);
while
((
func
=
*
(
func_ptr
++
)))
{
if
(
func
->
setup
(
thd
))
if
(
func
->
aggregator_setup
(
thd
))
DBUG_RETURN
(
TRUE
);
}
DBUG_RETURN
(
FALSE
);
}
static
bool
prepare_sum_aggregators
(
Item_sum
**
func_ptr
,
bool
need_distinct
)
{
Item_sum
*
func
;
DBUG_ENTER
(
"setup_sum_funcs"
);
while
((
func
=
*
(
func_ptr
++
)))
{
if
(
func
->
set_aggregator
(
need_distinct
&&
func
->
with_distinct
?
Aggregator
::
DISTINCT_AGGREGATOR
:
Aggregator
::
SIMPLE_AGGREGATOR
))
DBUG_RETURN
(
TRUE
);
}
DBUG_RETURN
(
FALSE
);
...
...
@@ -15384,7 +15499,7 @@ init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr)
/* If rollup, calculate the upper sum levels */
for
(
;
*
func_ptr
;
func_ptr
++
)
{
if
((
*
func_ptr
)
->
add
())
if
((
*
func_ptr
)
->
a
ggregator_a
dd
())
return
1
;
}
return
0
;
...
...
@@ -15396,7 +15511,7 @@ update_sum_func(Item_sum **func_ptr)
{
Item_sum
*
func
;
for
(;
(
func
=
(
Item_sum
*
)
*
func_ptr
)
;
func_ptr
++
)
if
(
func
->
add
())
if
(
func
->
a
ggregator_a
dd
())
return
1
;
return
0
;
}
...
...
@@ -16313,7 +16428,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if
(
key_read
)
{
if
(
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_GROUP_MIN_MAX
)
{
QUICK_GROUP_MIN_MAX_SELECT
*
qgs
=
(
QUICK_GROUP_MIN_MAX_SELECT
*
)
tab
->
select
->
quick
;
extra
.
append
(
STRING_WITH_LEN
(
"; Using index for group-by"
));
qgs
->
append_loose_scan_type
(
&
extra
);
}
else
extra
.
append
(
STRING_WITH_LEN
(
"; Using index"
));
}
...
...
sql/sql_select.h
View file @
5485e447
...
...
@@ -218,6 +218,11 @@ typedef struct st_join_table {
(
select
->
quick
->
get_type
()
==
QUICK_SELECT_I
::
QS_TYPE_GROUP_MIN_MAX
));
}
bool
is_using_agg_loose_index_scan
()
{
return
(
is_using_loose_index_scan
()
&&
((
QUICK_GROUP_MIN_MAX_SELECT
*
)
select
->
quick
)
->
is_agg_distinct
());
}
}
JOIN_TAB
;
enum_nested_loop_state
sub_select_cache
(
JOIN
*
join
,
JOIN_TAB
*
join_tab
,
bool
...
...
@@ -564,6 +569,8 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field,
const
char
*
name
,
TABLE
*
table
,
Item_field
*
item
,
uint
convert_blob_length
);
bool
is_indexed_agg_distinct
(
JOIN
*
join
,
List
<
Item_field
>
*
out_args
);
/* functions from opt_sum.cc */
bool
simple_pred
(
Item_func
*
func_item
,
Item
**
args
,
bool
*
inv_order
);
int
opt_sum_query
(
TABLE_LIST
*
tables
,
List
<
Item
>
&
all_fields
,
COND
*
conds
);
...
...
sql/sql_yacc.yy
View file @
5485e447
...
...
@@ -8182,7 +8182,7 @@ sum_expr:
}
| AVG_SYM '(' DISTINCT in_sum_expr ')'
{
$$= new (YYTHD->mem_root) Item_sum_avg
_distinct($4
);
$$= new (YYTHD->mem_root) Item_sum_avg
($4, TRUE
);
if ($$ == NULL)
MYSQL_YYABORT;
}
...
...
@@ -8225,7 +8225,7 @@ sum_expr:
{ Select->in_sum_expr--; }
')'
{
$$= new (YYTHD->mem_root) Item_sum_count
_distinct
(* $5);
$$= new (YYTHD->mem_root) Item_sum_count(* $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
...
...
@@ -8290,7 +8290,7 @@ sum_expr:
}
| SUM_SYM '(' DISTINCT in_sum_expr ')'
{
$$= new (YYTHD->mem_root) Item_sum_sum
_distinct($4
);
$$= new (YYTHD->mem_root) Item_sum_sum
($4, TRUE
);
if ($$ == NULL)
MYSQL_YYABORT;
}
...
...
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