summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2018-04-18 19:34:12 +0200
committerSergei Golubchik <serg@mariadb.org>2019-03-12 13:10:48 +0100
commit83123412f00d9b69f1c5ea39b160d1d27be701a9 (patch)
treed9192c723230a21c504930504ebcb15bf78670a7
parent01c49e66b559d311725ff4c0d86592c3c9eaa58d (diff)
downloadmariadb-git-83123412f00d9b69f1c5ea39b160d1d27be701a9.tar.gz
MDEV-11975: SQLCOM_PREPARE of EXPLAIN & ANALYZE statement do not return correct metadata info
Added metadate info after prepare EXPLAIN/ANALYZE.
-rw-r--r--sql/sql_class.cc29
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_prepare.cc24
3 files changed, 45 insertions, 10 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 0971d4fdaaa..628dcee0570 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2405,18 +2405,31 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
}
-int THD::send_explain_fields(select_result *result, uint8 explain_flags, bool is_analyze)
+void THD::prepare_explain_fields(select_result *result,
+ List<Item> *field_list,
+ uint8 explain_flags,
+ bool is_analyze)
{
- List<Item> field_list;
if (lex->explain_json)
- make_explain_json_field_list(field_list, is_analyze);
+ make_explain_json_field_list(*field_list, is_analyze);
else
- make_explain_field_list(field_list, explain_flags, is_analyze);
+ make_explain_field_list(*field_list, explain_flags, is_analyze);
+
+ result->prepare(*field_list, NULL);
+}
- result->prepare(field_list, NULL);
- return (result->send_result_set_metadata(field_list,
- Protocol::SEND_NUM_ROWS |
- Protocol::SEND_EOF));
+
+int THD::send_explain_fields(select_result *result,
+ uint8 explain_flags,
+ bool is_analyze)
+{
+ List<Item> field_list;
+ int rc;
+ prepare_explain_fields(result, &field_list, explain_flags, is_analyze);
+ rc= result->send_result_set_metadata(field_list,
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF);
+ return(rc);
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 8dde68b7fba..e93bd00eec0 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3331,6 +3331,8 @@ public:
void add_changed_table(TABLE *table);
void add_changed_table(const char *key, long key_length);
CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length);
+ void prepare_explain_fields(select_result *result, List<Item> *field_list,
+ uint8 explain_flags, bool is_analyze);
int send_explain_fields(select_result *result, uint8 explain_flags,
bool is_analyze);
void make_explain_field_list(List<Item> &field_list, uint8 explain_flags,
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 455d6b3cb86..89b7e490cb9 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2475,8 +2475,28 @@ static bool check_prepared_statement(Prepared_statement *stmt)
break;
}
if (res == 0)
- DBUG_RETURN(stmt->is_sql_prepare() ?
- FALSE : (send_prep_stmt(stmt, 0) || thd->protocol->flush()));
+ {
+ if (!stmt->is_sql_prepare())
+ {
+ if (lex->describe || lex->analyze_stmt)
+ {
+ if (!lex->result &&
+ !(lex->result= new (stmt->mem_root) select_send(thd)))
+ DBUG_RETURN(TRUE);
+ List<Item> field_list;
+ thd->prepare_explain_fields(lex->result, &field_list,
+ lex->describe, lex->analyze_stmt);
+ res= send_prep_stmt(stmt, lex->result->field_count(field_list)) ||
+ lex->result->send_result_set_metadata(field_list,
+ Protocol::SEND_EOF);
+ }
+ else
+ res= send_prep_stmt(stmt, 0);
+ if (!res)
+ thd->protocol->flush();
+ }
+ DBUG_RETURN(FALSE);
+ }
error:
DBUG_RETURN(TRUE);
}