Skip to content

Commit 39fa518

Browse files
authored
Merge pull request cmu-db#1108 from pranavk/explain_gh
Support for EXPLAIN statement
2 parents 3451aef + 2f2a34c commit 39fa518

10 files changed

+115
-5
lines changed

src/common/internal_types.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,9 @@ std::string StatementTypeToString(StatementType type) {
471471
case StatementType::VARIABLE_SET: {
472472
return "SET";
473473
}
474+
case StatementType::EXPLAIN: {
475+
return "EXPLAIN";
476+
}
474477
default: {
475478
throw ConversionException(StringUtil::Format(
476479
"No string conversion for StatementType value '%d'",
@@ -572,6 +575,8 @@ std::string QueryTypeToString(QueryType query_type) {
572575
return "EXECUTE";
573576
case QueryType::QUERY_SELECT:
574577
return "SELECT";
578+
case QueryType::QUERY_EXPLAIN:
579+
return "EXPLAIN";
575580
case QueryType::QUERY_OTHER:
576581
default:
577582
return "OTHER";
@@ -630,6 +635,7 @@ QueryType StatementTypeToQueryType(StatementType stmt_type,
630635
{StatementType::DROP, QueryType::QUERY_DROP},
631636
{StatementType::SELECT, QueryType::QUERY_SELECT},
632637
{StatementType::VARIABLE_SET, QueryType::QUERY_SET},
638+
{StatementType::EXPLAIN, QueryType::QUERY_EXPLAIN}
633639
};
634640
QueryType query_type = QueryType::QUERY_OTHER;
635641
std::unordered_map<StatementType, QueryType,

src/include/common/internal_types.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ enum class StatementType {
671671
ANALYZE = 15, // analyze type
672672
VARIABLE_SET = 16, // variable set statement type
673673
CREATE_FUNC = 17, // create func statement type
674+
EXPLAIN = 18 // explain statement type
674675
};
675676
std::string StatementTypeToString(StatementType type);
676677
StatementType StringToStatementType(const std::string &str);
@@ -704,7 +705,8 @@ enum class QueryType {
704705
QUERY_INVALID = 20,
705706
QUERY_CREATE_TRIGGER = 21,
706707
QUERY_CREATE_SCHEMA = 22,
707-
QUERY_CREATE_VIEW = 23
708+
QUERY_CREATE_VIEW = 23,
709+
QUERY_EXPLAIN = 24
708710
};
709711
std::string QueryTypeToString(QueryType query_type);
710712
QueryType StringToQueryType(std::string str);
@@ -1416,4 +1418,4 @@ enum class SSLLevel {
14161418
SSL_VERIIFY = 2,
14171419
};
14181420

1419-
} // namespace peloton
1421+
} // namespace peloton

src/include/common/sql_node_visitor.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class CreateFunctionStatement;
2121
class InsertStatement;
2222
class DeleteStatement;
2323
class DropStatement;
24+
class ExplainStatement;
2425
class PrepareStatement;
2526
class ExecuteStatement;
2627
class TransactionStatement;
@@ -80,6 +81,7 @@ class SqlNodeVisitor {
8081
virtual void Visit(parser::UpdateStatement *) {}
8182
virtual void Visit(parser::CopyStatement *) {}
8283
virtual void Visit(parser::AnalyzeStatement *){};
84+
virtual void Visit(parser::ExplainStatement *){};
8385

8486
virtual void Visit(expression::ComparisonExpression *expr);
8587
virtual void Visit(expression::AggregateExpression *expr);
@@ -93,8 +95,6 @@ class SqlNodeVisitor {
9395
virtual void Visit(expression::StarExpression *expr);
9496
virtual void Visit(expression::TupleValueExpression *expr);
9597
virtual void Visit(expression::SubqueryExpression *expr);
96-
97-
9898
};
9999

100100
} // namespace peloton

src/include/network/postgres_protocol_handler.h

+8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131

3232
namespace peloton {
3333

34+
namespace parser {
35+
class ExplainStatement;
36+
} // namespace parser
37+
3438
namespace network {
3539

3640
typedef std::vector<std::unique_ptr<OutputPacket>> ResponseBuffer;
@@ -161,6 +165,10 @@ class PostgresProtocolHandler : public ProtocolHandler {
161165
/* Execute a Simple query protocol message */
162166
ProcessResult ExecQueryMessage(InputPacket *pkt, const size_t thread_id);
163167

168+
/* Execute a EXPLAIN query message */
169+
ResultType ExecQueryExplain(const std::string &query,
170+
parser::ExplainStatement &explain_stmt);
171+
164172
/* Process the PARSE message of the extended query protocol */
165173
void ExecParseMessage(InputPacket *pkt);
166174

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Peloton
4+
//
5+
// explain_statement.h
6+
//
7+
// Identification: src/include/parser/explain_statement.h
8+
//
9+
// Copyright (c) 2015-2018, Carnegie Mellon University Database Group
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#pragma once
14+
15+
#include "parser/sql_statement.h"
16+
17+
namespace peloton {
18+
namespace parser {
19+
20+
/**
21+
* @class ExplainStatement
22+
* @brief Represents "EXPLAIN <query>"
23+
*/
24+
class ExplainStatement : public SQLStatement {
25+
public:
26+
ExplainStatement() : SQLStatement(StatementType::EXPLAIN) {}
27+
virtual ~ExplainStatement() {}
28+
29+
void Accept(SqlNodeVisitor *v) override { v->Visit(this); }
30+
31+
std::unique_ptr<parser::SQLStatement> real_sql_stmt;
32+
};
33+
34+
} // namespace parser
35+
} // namespace peloton

src/include/parser/parsenodes.h

+13
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,19 @@ typedef struct SelectStmt {
326326
/* Eventually add fields for CORRESPONDING spec here */
327327
} SelectStmt;
328328

329+
/*
330+
* Explain Statement
331+
*
332+
* The "query" field is initially a raw parse tree, and is converted to a
333+
* Query node during parse analysis. Note that rewriting and planning
334+
* of the query are always postponed until execution.
335+
*/
336+
typedef struct ExplainStmt {
337+
NodeTag type;
338+
Node *query; /* the query (see comments above) */
339+
List *options; /* list of DefElem nodes */
340+
} ExplainStmt;
341+
329342
typedef struct TypeName {
330343
NodeTag type;
331344
List *names; /* qualified name (list of Value strings) */

src/include/parser/postgresparser.h

+3
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ class PostgresParser {
217217
// transform helper for select statements
218218
static parser::SelectStatement *SelectTransform(SelectStmt *root);
219219

220+
// transform helper for explain statements
221+
static parser::SQLStatement *ExplainTransform(ExplainStmt *root);
222+
220223
// transform helper for delete statements
221224
static parser::SQLStatement *DeleteTransform(DeleteStmt *root);
222225

src/include/parser/statements.h

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "delete_statement.h"
2222
#include "drop_statement.h"
2323
#include "execute_statement.h"
24+
#include "explain_statement.h"
2425
#include "insert_statement.h"
2526
#include "prepare_statement.h"
2627
#include "select_statement.h"

src/network/postgres_protocol_handler.cpp

+34-1
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@
2323
#include "network/postgres_protocol_handler.h"
2424
#include "network/peloton_server.h"
2525
#include "parser/postgresparser.h"
26+
#include "parser/statements.h"
2627
#include "planner/abstract_plan.h"
2728
#include "planner/delete_plan.h"
2829
#include "planner/insert_plan.h"
30+
#include "planner/plan_util.h"
2931
#include "planner/update_plan.h"
3032
#include "settings/settings_manager.h"
3133
#include "traffic_cop/traffic_cop.h"
3234
#include "type/value.h"
3335
#include "type/value_factory.h"
36+
#include "util/string_util.h"
3437

3538
#define SSL_MESSAGE_VERNO 80877103
3639
#define PROTO_MAJOR_VERSION(x) (x >> 16)
@@ -219,6 +222,12 @@ ProcessResult PostgresProtocolHandler::ExecQueryMessage(
219222
ExecQueryMessageGetResult(status);
220223
return ProcessResult::COMPLETE;
221224
};
225+
case QueryType::QUERY_EXPLAIN: {
226+
auto status = ExecQueryExplain(
227+
query, static_cast<parser::ExplainStatement &>(*sql_stmt));
228+
ExecQueryMessageGetResult(status);
229+
return ProcessResult::COMPLETE;
230+
}
222231
default: {
223232
std::string stmt_name = "unamed";
224233
std::unique_ptr<parser::SQLStatementList> unnamed_sql_stmt_list(
@@ -248,6 +257,30 @@ ProcessResult PostgresProtocolHandler::ExecQueryMessage(
248257
}
249258
}
250259

260+
ResultType PostgresProtocolHandler::ExecQueryExplain(
261+
const std::string &query, parser::ExplainStatement &explain_stmt) {
262+
std::unique_ptr<parser::SQLStatementList> unnamed_sql_stmt_list(
263+
new parser::SQLStatementList());
264+
unnamed_sql_stmt_list->PassInStatement(std::move(explain_stmt.real_sql_stmt));
265+
auto stmt = traffic_cop_->PrepareStatement(
266+
"explain", query, std::move(unnamed_sql_stmt_list));
267+
ResultType status = ResultType::UNKNOWN;
268+
if (stmt != nullptr) {
269+
traffic_cop_->SetStatement(stmt);
270+
std::vector<std::string> plan_info = StringUtil::Split(
271+
planner::PlanUtil::GetInfo(stmt->GetPlanTree().get()), '\n');
272+
const std::vector<FieldInfo> tuple_descriptor = {
273+
traffic_cop_->GetColumnFieldForValueType("Query plan",
274+
type::TypeId::VARCHAR)};
275+
stmt->SetTupleDescriptor(tuple_descriptor);
276+
traffic_cop_->SetResult(plan_info);
277+
status = ResultType::SUCCESS;
278+
} else {
279+
status = ResultType::FAILURE;
280+
}
281+
return status;
282+
}
283+
251284
void PostgresProtocolHandler::ExecQueryMessageGetResult(ResultType status) {
252285
std::vector<FieldInfo> tuple_descriptor;
253286
if (status == ResultType::SUCCESS) {
@@ -826,7 +859,7 @@ void PostgresProtocolHandler::ExecExecuteMessageGetResult(ResultType status) {
826859
return;
827860
}
828861
}
829-
} // namespace network
862+
}
830863

831864
void PostgresProtocolHandler::GetResult() {
832865
traffic_cop_->ExecuteStatementPlanGetResult();

src/parser/postgresparser.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,12 @@ parser::SelectStatement *PostgresParser::SelectTransform(SelectStmt *root) {
16861686
return result;
16871687
}
16881688

1689+
parser::SQLStatement *PostgresParser::ExplainTransform(ExplainStmt *root) {
1690+
parser::ExplainStatement *result = new parser::ExplainStatement();
1691+
result->real_sql_stmt.reset(NodeTransform(root->query));
1692+
return result;
1693+
}
1694+
16891695
// This function takes in a Postgres DeleteStmt parsenode
16901696
// and transfers into a Peloton DeleteStatement parsenode.
16911697
// Please refer to parser/parsenode.h for the definition of
@@ -1787,6 +1793,9 @@ parser::SQLStatement *PostgresParser::NodeTransform(Node *stmt) {
17871793
case T_VariableSetStmt:
17881794
result = VariableSetTransform((VariableSetStmt*)stmt);
17891795
break;
1796+
case T_ExplainStmt:
1797+
result = ExplainTransform(reinterpret_cast<ExplainStmt *>(stmt));
1798+
break;
17901799
default: {
17911800
throw NotImplementedException(StringUtil::Format(
17921801
"Statement of type %d not supported yet...\n", stmt->type));

0 commit comments

Comments
 (0)