summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2014-12-06 20:33:25 +0300
committerSergei Petrunia <psergey@askmonty.org>2014-12-06 20:33:25 +0300
commit913b7672c5fe2db750a382685f0810d383b43faa (patch)
tree98f8456628e218820a1e4bfd35b72d457682f7d1
parentdb21fddc3740dfa48f3443751c48282467afac5e (diff)
parenteeef80d09f8045d99963a2bf2fa92595c55bb26d (diff)
downloadmariadb-git-913b7672c5fe2db750a382685f0810d383b43faa.tar.gz
Merge bb-10.1-explain-json into 10.1
-rw-r--r--mysql-test/r/explain_json.result54
-rw-r--r--mysql-test/r/explain_json_innodb.result57
-rw-r--r--mysql-test/t/explain_json.test20
-rw-r--r--mysql-test/t/explain_json_innodb.test28
-rw-r--r--sql/my_json_writer.cc6
-rw-r--r--sql/sql_explain.cc29
-rw-r--r--sql/sql_explain.h6
-rw-r--r--sql/sql_select.cc2
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;