Commit e8875833 authored by Sergei Petrunia's avatar Sergei Petrunia

Make window functions computation step show up in EXPLAIN FORMAT=JSON output

parent 44fdb56c
...@@ -1401,3 +1401,76 @@ pk c CNT ...@@ -1401,3 +1401,76 @@ pk c CNT
9 2 4 9 2 4
10 2 3 10 2 3
drop table t0,t1; drop table t0,t1;
#
# EXPLAIN FORMAT=JSON support for window functions
#
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
explain format=json select rank() over (order by a) from t0;
EXPLAIN
{
"query_block": {
"select_id": 1,
"window_functions_computation": {
"temporary_table": {
"table": {
"table_name": "t0",
"access_type": "ALL",
"rows": 10,
"filtered": 100
}
}
}
}
}
create table t1 (a int, b int, c int);
insert into t1 select a,a,a from t0;
explain format=json
select
a,
rank() over (order by sum(b))
from t1
group by a;
EXPLAIN
{
"query_block": {
"select_id": 1,
"filesort": {
"window_functions_computation": {
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 10,
"filtered": 100
}
}
}
}
}
}
explain format=json
select
a,
rank() over (order by sum(b))
from t1
group by a
order by null;
EXPLAIN
{
"query_block": {
"select_id": 1,
"window_functions_computation": {
"temporary_table": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 10,
"filtered": 100
}
}
}
}
}
drop table t1;
drop table t0;
...@@ -924,8 +924,33 @@ execute stmt; ...@@ -924,8 +924,33 @@ execute stmt;
drop table t0,t1; drop table t0,t1;
--echo #
--echo # EXPLAIN FORMAT=JSON support for window functions
--echo #
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
explain format=json select rank() over (order by a) from t0;
create table t1 (a int, b int, c int);
insert into t1 select a,a,a from t0;
explain format=json
select
a,
rank() over (order by sum(b))
from t1
group by a;
explain format=json
select
a,
rank() over (order by sum(b))
from t1
group by a
order by null;
drop table t1;
drop table t0;
...@@ -878,6 +878,9 @@ void Explain_select::print_explain_json(Explain_query *query, ...@@ -878,6 +878,9 @@ void Explain_select::print_explain_json(Explain_query *query,
case AGGR_OP_REMOVE_DUPLICATES: case AGGR_OP_REMOVE_DUPLICATES:
writer->add_member("duplicate_removal").start_object(); writer->add_member("duplicate_removal").start_object();
break; break;
case AGGR_OP_WINDOW_FUNCS:
writer->add_member("window_functions_computation").start_object();
break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
......
...@@ -264,7 +264,8 @@ typedef enum ...@@ -264,7 +264,8 @@ typedef enum
AGGR_OP_TEMP_TABLE, AGGR_OP_TEMP_TABLE,
AGGR_OP_FILESORT, AGGR_OP_FILESORT,
//AGGR_OP_READ_SORTED_FILE, // need this? //AGGR_OP_READ_SORTED_FILE, // need this?
AGGR_OP_REMOVE_DUPLICATES AGGR_OP_REMOVE_DUPLICATES,
AGGR_OP_WINDOW_FUNCS
//AGGR_OP_JOIN // Need this? //AGGR_OP_JOIN // Need this?
} enum_explain_aggr_node_type; } enum_explain_aggr_node_type;
...@@ -296,6 +297,11 @@ class Explain_aggr_remove_dups : public Explain_aggr_node ...@@ -296,6 +297,11 @@ class Explain_aggr_remove_dups : public Explain_aggr_node
enum_explain_aggr_node_type get_type() { return AGGR_OP_REMOVE_DUPLICATES; } enum_explain_aggr_node_type get_type() { return AGGR_OP_REMOVE_DUPLICATES; }
}; };
class Explain_aggr_window_funcs : public Explain_aggr_node
{
public:
enum_explain_aggr_node_type get_type() { return AGGR_OP_WINDOW_FUNCS; }
};
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
......
...@@ -2135,7 +2135,6 @@ bool JOIN::make_aggr_tables_info() ...@@ -2135,7 +2135,6 @@ bool JOIN::make_aggr_tables_info()
All optimization is done. Check if we can use the storage engines All optimization is done. Check if we can use the storage engines
group by handler to evaluate the group by group by handler to evaluate the group by
*/ */
group_by_handler *gbh= NULL;
if (tables_list && (tmp_table_param.sum_func_count || group_list) && if (tables_list && (tmp_table_param.sum_func_count || group_list) &&
!procedure) !procedure)
{ {
...@@ -2337,8 +2336,8 @@ bool JOIN::make_aggr_tables_info() ...@@ -2337,8 +2336,8 @@ bool JOIN::make_aggr_tables_info()
// psergey-todo: this is probably an incorrect place: // psergey-todo: this is probably an incorrect place:
if (select_lex->window_funcs.elements) if (select_lex->window_funcs.elements)
{ {
curr_tab->window_funcs= new Window_funcs_computation; curr_tab->window_funcs_step= new Window_funcs_computation;
if (curr_tab->window_funcs->setup(thd, &select_lex->window_funcs)) if (curr_tab->window_funcs_step->setup(thd, &select_lex->window_funcs))
DBUG_RETURN(true); DBUG_RETURN(true);
} }
...@@ -19137,7 +19136,10 @@ bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab) ...@@ -19137,7 +19136,10 @@ bool test_if_use_dynamic_range_scan(JOIN_TAB *join_tab)
int join_init_read_record(JOIN_TAB *tab) int join_init_read_record(JOIN_TAB *tab)
{ {
int error; int error;
/*
Note: the query plan tree for the below operations is constructed in
save_agg_explain_data.
*/
if (tab->distinct && tab->remove_duplicates()) // Remove duplicates. if (tab->distinct && tab->remove_duplicates()) // Remove duplicates.
return 1; return 1;
if (tab->filesort && tab->sort_table()) // Sort table. if (tab->filesort && tab->sort_table()) // Sort table.
...@@ -24158,6 +24160,14 @@ void save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) ...@@ -24158,6 +24160,14 @@ void save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
node= new Explain_aggr_tmp_table; node= new Explain_aggr_tmp_table;
node->child= prev_node; node->child= prev_node;
if (join_tab->window_funcs_step)
{
prev_node=node;
node= new Explain_aggr_window_funcs;
node->child= prev_node;
}
/* The below matches execution in join_init_read_record() */
if (join_tab->distinct) if (join_tab->distinct)
{ {
prev_node= node; prev_node= node;
...@@ -25919,9 +25929,10 @@ AGGR_OP::end_send() ...@@ -25919,9 +25929,10 @@ AGGR_OP::end_send()
// Update ref array // Update ref array
join_tab->join->set_items_ref_array(*join_tab->ref_array); join_tab->join->set_items_ref_array(*join_tab->ref_array);
if (join_tab->window_funcs) if (join_tab->window_funcs_step)
{ {
join_tab->window_funcs->exec(join); if (join_tab->window_funcs_step->exec(join))
return NESTED_LOOP_ERROR;
} }
table->reginfo.lock_type= TL_UNLOCK; table->reginfo.lock_type= TL_UNLOCK;
......
...@@ -428,7 +428,7 @@ typedef struct st_join_table { ...@@ -428,7 +428,7 @@ typedef struct st_join_table {
Non-NULL value means this join_tab must do window function computation Non-NULL value means this join_tab must do window function computation
before reading. before reading.
*/ */
Window_funcs_computation* window_funcs; Window_funcs_computation* window_funcs_step;
/** /**
List of topmost expressions in the select list. The *next* JOIN TAB List of topmost expressions in the select list. The *next* JOIN TAB
......
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