Analyzer view read only necessary columns

This commit is contained in:
Maksim Kita 2024-05-13 13:41:47 +03:00
parent f27a0d6801
commit b8c719f866
5 changed files with 68 additions and 16 deletions

View File

@ -5,6 +5,8 @@
#include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/ASTIdentifier.h>
#include <DataTypes/DataTypesNumber.h>
@ -38,22 +40,46 @@ namespace ErrorCodes
namespace
{
ASTPtr normalizeAndValidateQuery(const ASTPtr & query)
ASTPtr normalizeAndValidateQuery(const ASTPtr & query, const Names & column_names)
{
ASTPtr result_query;
if (query->as<ASTSelectWithUnionQuery>() || query->as<ASTSelectQuery>())
{
return query;
}
result_query = query;
else if (auto * subquery = query->as<ASTSubquery>())
{
return subquery->children[0];
}
result_query = subquery->children[0];
else
{
throw Exception(ErrorCodes::UNSUPPORTED_METHOD,
"Expected ASTSelectWithUnionQuery or ASTSelectQuery. Actual {}",
query->formatForErrorMessage());
}
if (column_names.empty())
return result_query;
auto select_query = std::make_shared<ASTSelectQuery>();
auto result_table_expression_ast = std::make_shared<ASTTableExpression>();
result_table_expression_ast->children.push_back(std::make_shared<ASTSubquery>(std::move(result_query)));
result_table_expression_ast->subquery = result_table_expression_ast->children.back();
auto tables_in_select_query_element_ast = std::make_shared<ASTTablesInSelectQueryElement>();
tables_in_select_query_element_ast->children.push_back(std::move(result_table_expression_ast));
tables_in_select_query_element_ast->table_expression = tables_in_select_query_element_ast->children.back();
ASTPtr tables_in_select_query_ast = std::make_shared<ASTTablesInSelectQuery>();
tables_in_select_query_ast->children.push_back(std::move(tables_in_select_query_element_ast));
select_query->setExpression(ASTSelectQuery::Expression::TABLES, std::move(tables_in_select_query_ast));
auto projection_expression_list_ast = std::make_shared<ASTExpressionList>();
projection_expression_list_ast->children.reserve(column_names.size());
for (const auto & column_name : column_names)
projection_expression_list_ast->children.push_back(std::make_shared<ASTIdentifier>(column_name));
select_query->setExpression(ASTSelectQuery::Expression::SELECT, std::move(projection_expression_list_ast));
return select_query;
}
ContextMutablePtr buildContext(const ContextPtr & context, const SelectQueryOptions & select_query_options)
@ -125,8 +151,9 @@ QueryTreeNodePtr buildQueryTreeAndRunPasses(const ASTPtr & query,
InterpreterSelectQueryAnalyzer::InterpreterSelectQueryAnalyzer(
const ASTPtr & query_,
const ContextPtr & context_,
const SelectQueryOptions & select_query_options_)
: query(normalizeAndValidateQuery(query_))
const SelectQueryOptions & select_query_options_,
const Names & column_names)
: query(normalizeAndValidateQuery(query_, column_names))
, context(buildContext(context_, select_query_options_))
, select_query_options(select_query_options_)
, query_tree(buildQueryTreeAndRunPasses(query, select_query_options, context, nullptr /*storage*/))
@ -138,8 +165,9 @@ InterpreterSelectQueryAnalyzer::InterpreterSelectQueryAnalyzer(
const ASTPtr & query_,
const ContextPtr & context_,
const StoragePtr & storage_,
const SelectQueryOptions & select_query_options_)
: query(normalizeAndValidateQuery(query_))
const SelectQueryOptions & select_query_options_,
const Names & column_names)
: query(normalizeAndValidateQuery(query_, column_names))
, context(buildContext(context_, select_query_options_))
, select_query_options(select_query_options_)
, query_tree(buildQueryTreeAndRunPasses(query, select_query_options, context, storage_))

View File

@ -16,7 +16,8 @@ public:
/// Initialize interpreter with query AST
InterpreterSelectQueryAnalyzer(const ASTPtr & query_,
const ContextPtr & context_,
const SelectQueryOptions & select_query_options_);
const SelectQueryOptions & select_query_options_,
const Names & column_names = {});
/** Initialize interpreter with query AST and storage.
* After query tree is built left most table expression is replaced with table node that
@ -25,7 +26,8 @@ public:
InterpreterSelectQueryAnalyzer(const ASTPtr & query_,
const ContextPtr & context_,
const StoragePtr & storage_,
const SelectQueryOptions & select_query_options_);
const SelectQueryOptions & select_query_options_,
const Names & column_names = {});
/** Initialize interpreter with query tree.
* No query tree passes are applied.

View File

@ -164,7 +164,7 @@ void StorageView::read(
if (context->getSettingsRef().allow_experimental_analyzer)
{
InterpreterSelectQueryAnalyzer interpreter(current_inner_query, getViewContext(context, storage_snapshot), options);
InterpreterSelectQueryAnalyzer interpreter(current_inner_query, getViewContext(context, storage_snapshot), options, column_names);
interpreter.addStorageLimits(*query_info.storage_limits);
query_plan = std::move(interpreter).extractQueryPlan();
}

View File

@ -0,0 +1,8 @@
Expression ((Project names + Projection))
Header: sum(id) UInt64
Aggregating
Header: sum(__table1.id) UInt64
Expression ((Before GROUP BY + (Change column names to column identifiers + (Convert VIEW subquery result to VIEW table structure + (Materialize constants after VIEW subquery + (Project names + (Projection + (Change column names to column identifiers + (Project names + (Projection + Change column names to column identifiers))))))))))
Header: __table1.id UInt64
ReadFromPreparedSource (Read from NullSource)
Header: id UInt64

View File

@ -0,0 +1,14 @@
DROP TABLE IF EXISTS test_table;
CREATE TABLE test_table
(
id UInt64,
value String
) ENGINE=MergeTree ORDER BY id;
DROP VIEW IF EXISTS test_view;
CREATE VIEW test_view AS SELECT id, value FROM test_table;
EXPLAIN header = 1 SELECT sum(id) FROM test_view;
DROP VIEW test_view;
DROP TABLE test_table;