From eeef80d09f8045d99963a2bf2fa92595c55bb26d Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Sat, 6 Dec 2014 20:13:38 +0300 Subject: [PATCH] EXPLAIN FORMAT=JSON : Fix MDEV-7266, bug in pretty-printer - Single_line_formatting_helper should not accidentally exit the DISABLED state. No JSON construct should be able to move the Single_line_formatting_helper from DISABLED state. --- mysql-test/r/explain_json.result | 2 +- mysql-test/r/explain_json_innodb.result | 57 +++++++++++++++++++++++++ mysql-test/t/explain_json_innodb.test | 28 ++++++++++++ sql/my_json_writer.cc | 6 ++- 4 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/explain_json_innodb.result create mode 100644 mysql-test/t/explain_json_innodb.test diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result index e1135298924..94a8d822d72 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; 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_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.