diff options
author | Sergei Petrunia <psergey@askmonty.org> | 2014-12-06 20:33:25 +0300 |
---|---|---|
committer | Sergei Petrunia <psergey@askmonty.org> | 2014-12-06 20:33:25 +0300 |
commit | 913b7672c5fe2db750a382685f0810d383b43faa (patch) | |
tree | 98f8456628e218820a1e4bfd35b72d457682f7d1 | |
parent | db21fddc3740dfa48f3443751c48282467afac5e (diff) | |
parent | eeef80d09f8045d99963a2bf2fa92595c55bb26d (diff) | |
download | mariadb-git-913b7672c5fe2db750a382685f0810d383b43faa.tar.gz |
Merge bb-10.1-explain-json into 10.1
-rw-r--r-- | mysql-test/r/explain_json.result | 54 | ||||
-rw-r--r-- | mysql-test/r/explain_json_innodb.result | 57 | ||||
-rw-r--r-- | mysql-test/t/explain_json.test | 20 | ||||
-rw-r--r-- | mysql-test/t/explain_json_innodb.test | 28 | ||||
-rw-r--r-- | sql/my_json_writer.cc | 6 | ||||
-rw-r--r-- | sql/sql_explain.cc | 29 | ||||
-rw-r--r-- | sql/sql_explain.h | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 |
8 files changed, 195 insertions, 7 deletions
diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result index d0a0b8f5be3..5998912e0c5 100644 --- a/mysql-test/r/explain_json.result +++ b/mysql-test/r/explain_json.result @@ -1,4 +1,4 @@ -drop table if exists t0,t1; +drop table if exists t0,t1,t2; create table t0(a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); explain format=json select * from t0; @@ -551,6 +551,7 @@ EXPLAIN { "query_block": { "select_id": 1, + "const_condition": "1", "table": { "table_name": "t1", "access_type": "ALL", @@ -813,3 +814,54 @@ EXPLAIN } } DROP TABLE t1, t2; +# +# Join's constant expression +# +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1(a int, b int); +insert into t1 select tbl1.a+10*tbl2.a, 1234 from t0 tbl1, t0 tbl2; +explain format=json +select * from t0 +where +20000 > all (select max(tbl1.a + tbl2.a) +from t1 tbl1, t1 tbl2 where tbl1.b=tbl2.b); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "const_condition": "<not>(<in_optimizer>(20000,(<max>(subquery#2) >= 20000)))", + "table": { + "table_name": "t0", + "access_type": "ALL", + "rows": 10, + "filtered": 100 + }, + "subqueries": [ + { + "query_block": { + "select_id": 2, + "table": { + "table_name": "tbl1", + "access_type": "ALL", + "rows": 100, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "tbl2", + "access_type": "ALL", + "rows": 100, + "filtered": 100 + }, + "buffer_type": "flat", + "join_type": "BNL", + "attached_condition": "(tbl2.b = tbl1.b)" + } + } + } + ] + } +} +drop table t1; +drop table t0; diff --git a/mysql-test/r/explain_json_innodb.result b/mysql-test/r/explain_json_innodb.result new file mode 100644 index 00000000000..cc389c63bda --- /dev/null +++ b/mysql-test/r/explain_json_innodb.result @@ -0,0 +1,57 @@ +drop table if exists t0,t1,t2; +# +# MDEV-7266: Assertion `!element_started' failed in Json_writer& Json_writer::add_member +# +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (column_name_1 INT, column_name_2 VARCHAR(52)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (3,'United States'); +CREATE TABLE t3 (b INT, c VARCHAR(3), PRIMARY KEY (c,b)) ENGINE=InnoDB; +INSERT INTO t3 VALUES (4,'USA'),(5,'CAN'); +EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE 0 < ALL ( +SELECT tbl_alias1.column_name_1 FROM t2 AS tbl_alias1, t3 AS tbl_alias2 +WHERE tbl_alias2.b = tbl_alias1.column_name_1 AND tbl_alias2.c = tbl_alias1.column_name_2 +); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 2, + "filtered": 100 + }, + "subqueries": [ + { + "query_block": { + "select_id": 2, + "table": { + "table_name": "tbl_alias1", + "access_type": "ALL", + "rows": 1, + "filtered": 100, + "attached_condition": "((tbl_alias1.column_name_2 is not null) and (tbl_alias1.column_name_1 is not null))" + }, + "table": { + "table_name": "tbl_alias2", + "access_type": "eq_ref", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "9", + "used_key_parts": ["c", "b"], + "ref": [ + "test.tbl_alias1.column_name_2", + "test.tbl_alias1.column_name_1" + ], + "rows": 1, + "filtered": 100, + "attached_condition": "(tbl_alias2.c = tbl_alias1.column_name_2)", + "using_index": true + } + } + } + ] + } +} +drop table t1,t2,t3; diff --git a/mysql-test/t/explain_json.test b/mysql-test/t/explain_json.test index b4f90392c53..a94833f86fc 100644 --- a/mysql-test/t/explain_json.test +++ b/mysql-test/t/explain_json.test @@ -2,7 +2,7 @@ # EXPLAIN FORMAT=JSON tests. These are tests developed for MariaDB. # --disable_warnings -drop table if exists t0,t1; +drop table if exists t0,t1,t2; --enable_warnings create table t0(a int); @@ -167,6 +167,24 @@ EXPLAIN FORMAT=JSON SELECT * FROM t1 AS outer_t1 WHERE a <> ALL ( SELECT a FROM DROP TABLE t1,t2; +--echo # +--echo # Join's constant expression +--echo # +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1(a int, b int); +insert into t1 select tbl1.a+10*tbl2.a, 1234 from t0 tbl1, t0 tbl2; + +explain format=json +select * from t0 +where + 20000 > all (select max(tbl1.a + tbl2.a) + from t1 tbl1, t1 tbl2 where tbl1.b=tbl2.b); + +drop table t1; +drop table t0; + --echo # --echo # MDEV-7264: Assertion `0' failed in subselect_engine::get_identifier() on EXPLAIN JSON --echo # diff --git a/mysql-test/t/explain_json_innodb.test b/mysql-test/t/explain_json_innodb.test new file mode 100644 index 00000000000..f70df5d5349 --- /dev/null +++ b/mysql-test/t/explain_json_innodb.test @@ -0,0 +1,28 @@ +# +# MariaDB's EXPLAIN FORMAT=JSON tests that require InnoDB. +# +--source include/have_innodb.inc + +--disable_warnings +drop table if exists t0,t1,t2; +--enable_warnings + +--echo # +--echo # MDEV-7266: Assertion `!element_started' failed in Json_writer& Json_writer::add_member +--echo # + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (column_name_1 INT, column_name_2 VARCHAR(52)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (3,'United States'); + +CREATE TABLE t3 (b INT, c VARCHAR(3), PRIMARY KEY (c,b)) ENGINE=InnoDB; +INSERT INTO t3 VALUES (4,'USA'),(5,'CAN'); + +EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE 0 < ALL ( + SELECT tbl_alias1.column_name_1 FROM t2 AS tbl_alias1, t3 AS tbl_alias2 + WHERE tbl_alias2.b = tbl_alias1.column_name_1 AND tbl_alias2.c = tbl_alias1.column_name_2 +); + +drop table t1,t2,t3; diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index 4f933583347..7a3dc776093 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -218,7 +218,8 @@ bool Single_line_formatting_helper::on_start_array() } else { - state= INACTIVE; + if (state != DISABLED) + state= INACTIVE; // TODO: what if we have accumulated some stuff already? shouldn't we // flush it? return false; // not handled @@ -313,6 +314,9 @@ void Single_line_formatting_helper::flush_on_one_line() void Single_line_formatting_helper::disable_and_flush() { + if (state == DISABLED) + return; + bool start_array= (state == IN_ARRAY); state= DISABLED; // deactivate ourselves and flush all accumulated calls. diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 800f2ce309b..c68f86ce72c 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -27,6 +27,8 @@ const char * STR_DELETING_ALL_ROWS= "Deleting all rows"; const char * STR_IMPOSSIBLE_WHERE= "Impossible WHERE"; const char * STR_NO_ROWS_AFTER_PRUNING= "No matching rows after partition pruning"; +static void write_item(Json_writer *writer, Item *item); + Explain_query::Explain_query(THD *thd_arg, MEM_ROOT *root) : mem_root(root), upd_del_plan(NULL), insert_plan(NULL), unions(root), selects(root), thd(thd_arg), apc_enabled(false), @@ -732,7 +734,17 @@ void Explain_select::print_explain_json(Explain_query *query, Explain_basic_join does not have ORDER/GROUP. A: factor out join tab printing loop into a common func. */ - Explain_basic_join::print_explain_json(query, writer, is_analyze); + writer->add_member("query_block").start_object(); + writer->add_member("select_id").add_ll(select_id); + + if (exec_const_cond) + { + writer->add_member("const_condition"); + write_item(writer, exec_const_cond); + } + + Explain_basic_join::print_explain_json_interns(query, writer, is_analyze); + writer->end_object(); } } @@ -742,10 +754,20 @@ void Explain_basic_join::print_explain_json(Explain_query *query, Json_writer *writer, bool is_analyze) { - Json_writer_nesting_guard guard(writer); - writer->add_member("query_block").start_object(); writer->add_member("select_id").add_ll(select_id); + + print_explain_json_interns(query, writer, is_analyze); + + writer->end_object(); +} + + +void Explain_basic_join::print_explain_json_interns(Explain_query *query, + Json_writer *writer, + bool is_analyze) +{ + Json_writer_nesting_guard guard(writer); for (uint i=0; i< n_join_tabs; i++) { if (join_tabs[i]->start_dups_weedout) @@ -757,7 +779,6 @@ void Explain_basic_join::print_explain_json(Explain_query *query, writer->end_object(); } print_explain_json_for_children(query, writer, is_analyze); - writer->end_object(); } diff --git a/sql/sql_explain.h b/sql/sql_explain.h index a7ef0beb649..c4bfa4d09bf 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -175,6 +175,9 @@ public: void print_explain_json(Explain_query *query, Json_writer *writer, bool is_analyze); + void print_explain_json_interns(Explain_query *query, Json_writer *writer, + bool is_analyze); + /* A flat array of Explain structs for tables. */ Explain_table_access** join_tabs; uint n_join_tabs; @@ -222,6 +225,9 @@ public: */ const char *message; + /* Expensive constant condition */ + Item *exec_const_cond; + /* Global join attributes. In tabular form, they are printed on the first row */ bool using_temporary; bool using_filesort; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a1231152254..cbb5868623c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -23768,6 +23768,8 @@ int JOIN::save_explain_data_intern(Explain_query *output, bool need_tmp_table, if (need_order) xpl_sel->using_filesort= true; + xpl_sel->exec_const_cond= exec_const_cond; + JOIN_TAB* const first_top_tab= first_breadth_first_tab(join, WALK_OPTIMIZATION_TABS); JOIN_TAB* prev_bush_root_tab= NULL; |