Added actions setting for Explain query.

This commit is contained in:
Nikolai Kochetov 2020-06-23 19:06:56 +03:00
parent 4ed499c6f0
commit d88e19b69d
11 changed files with 144 additions and 0 deletions

View File

@ -0,0 +1,80 @@
#include <Interpreters/AggregateDescription.h>
#include <Common/FieldVisitors.h>
namespace DB
{
Strings AggregateDescription::explain() const
{
Strings res;
String arguments_pos_str;
for (auto arg : arguments)
{
if (!arguments_pos_str.empty())
arguments_pos_str += ", ";
arguments_pos_str += std::to_string(arg);
}
if (arguments_pos_str.empty())
arguments_pos_str = "none";
res.emplace_back("argument positions: " + arguments_pos_str);
String arguments_names_str;
for (const auto & arg : argument_names)
{
if (!arguments_names_str.empty())
arguments_names_str += ", ";
arguments_names_str += arg;
}
if (arguments_names_str.empty())
arguments_names_str = "none";
res.emplace_back("arguments: " + arguments_names_str);
res.emplace_back("column_name: " + column_name);
auto get_params_string = [](const Array & arr)
{
String params_str;
for (const auto & param : arr)
{
if (!params_str.empty())
params_str += ", ";
params_str += applyVisitor(FieldVisitorToString(), param);
}
return params_str;
};
if (function)
{
String types_str;
for (const auto & type : function->getArgumentTypes())
{
if (!types_str.empty())
types_str += ", ";
types_str += type->getName();
}
auto params_str = get_params_string(function->getParameters());
if (!params_str.empty())
params_str = "(" + params_str + ")";
res.emplace_back("function: " + function->getName() + params_str + '(' + types_str + ") -> " +
function->getReturnType()->getName());
}
else
res.emplace_back("function: nullptr");
if (!parameters.empty())
res.emplace_back("parameters: " + get_params_string(parameters));
return res;
}
}

View File

@ -15,6 +15,8 @@ struct AggregateDescription
ColumnNumbers arguments; ColumnNumbers arguments;
Names argument_names; /// used if no `arguments` are specified. Names argument_names; /// used if no `arguments` are specified.
String column_name; /// What name to use for a column with aggregate function values String column_name; /// What name to use for a column with aggregate function values
Strings explain() const; /// Get description for EXPLAIN query.
}; };
using AggregateDescriptions = std::vector<AggregateDescription>; using AggregateDescriptions = std::vector<AggregateDescription>;

View File

@ -150,6 +150,33 @@ Block Aggregator::Params::getHeader(
return materializeBlock(res); return materializeBlock(res);
} }
Strings Aggregator::Params::explain() const
{
Strings res;
const auto & header = src_header ? src_header
: intermediate_header;
String keys_str;
for (auto key : keys)
{
if (keys_str.empty())
keys_str += ", ";
if (key >= header.columns())
keys_str += "unknown position " + std::to_string(key);
else
keys_str += src_header.getByPosition(key).name;
}
res.emplace_back("keys: " + std::move(keys_str));
for (const auto & aggregate : aggregates)
{
auto aggregate_strings = aggregate.explain();
res.insert(res.end(), aggregate_strings.begin(), aggregate_strings.end());
}
return res;
}
Aggregator::Aggregator(const Params & params_) Aggregator::Aggregator(const Params & params_)
: params(params_), : params(params_),

View File

@ -923,6 +923,9 @@ public:
{ {
return getHeader(src_header, intermediate_header, keys, aggregates, final); return getHeader(src_header, intermediate_header, keys, aggregates, final);
} }
/// Returns keys and aggregated for EXPLAIN query
Strings explain() const;
}; };
Aggregator(const Params & params_); Aggregator(const Params & params_);

View File

@ -120,6 +120,7 @@ struct ExplainSettings
{ {
{"header", query_plan_options.header}, {"header", query_plan_options.header},
{"description", query_plan_options.description}, {"description", query_plan_options.description},
{"actions", query_plan_options.actions}
}; };
bool has(const std::string & name) const bool has(const std::string & name) const

View File

@ -18,6 +18,7 @@ SRCS(
ActionsVisitor.cpp ActionsVisitor.cpp
addMissingDefaults.cpp addMissingDefaults.cpp
addTypeConversionToAST.cpp addTypeConversionToAST.cpp
AggregateDescription.cpp
Aggregator.cpp Aggregator.cpp
AnyInputOptimize.cpp AnyInputOptimize.cpp
ArithmeticOperationsInAgrFuncOptimize.cpp ArithmeticOperationsInAgrFuncOptimize.cpp

View File

@ -139,4 +139,9 @@ void AggregatingStep::transformPipeline(QueryPipeline & pipeline)
pipeline.enableQuotaForCurrentStreams(); pipeline.enableQuotaForCurrentStreams();
} }
Strings AggregatingStep::describeActions() const
{
return params.explain();
}
} }

View File

@ -28,6 +28,8 @@ public:
void transformPipeline(QueryPipeline & pipeline) override; void transformPipeline(QueryPipeline & pipeline) override;
Strings describeActions() const override;
private: private:
Aggregator::Params params; Aggregator::Params params;
bool final; bool final;

View File

@ -51,6 +51,9 @@ public:
const std::string & getStepDescription() const { return step_description; } const std::string & getStepDescription() const { return step_description; }
void setStepDescription(std::string description) { step_description = std::move(description); } void setStepDescription(std::string description) { step_description = std::move(description); }
/// Get detailed description of step actions. This is shown in EXPLAIN query with options `actions = 1`.
virtual Strings describeActions() const { return {}; }
protected: protected:
DataStreams input_streams; DataStreams input_streams;
std::optional<DataStream> output_stream; std::optional<DataStream> output_stream;

View File

@ -216,6 +216,25 @@ static void explainStep(
buffer.write('\n'); buffer.write('\n');
} }
if (options.actions)
{
auto actions = step.describeActions();
if (!actions.empty())
{
buffer << "Actions: ";
bool first = true;
for (auto & action : actions)
{
if (!first)
buffer << ",\n" << prefix << " ";
first = false;
buffer << action;
}
}
}
} }
void QueryPlan::explain(WriteBuffer & buffer, const ExplainOptions & options) void QueryPlan::explain(WriteBuffer & buffer, const ExplainOptions & options)

View File

@ -37,6 +37,7 @@ public:
{ {
bool header = false; bool header = false;
bool description = true; bool description = true;
bool actions = false;
}; };
void explain(WriteBuffer & buffer, const ExplainOptions & options); void explain(WriteBuffer & buffer, const ExplainOptions & options);