mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-12 17:32:32 +00:00
Fix for column aliases that use other aliases
This commit is contained in:
parent
55b81a5a5e
commit
6489922dc1
@ -1099,7 +1099,6 @@ public:
|
|||||||
{
|
{
|
||||||
if (table_expression)
|
if (table_expression)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(&Poco::Logger::get("resolve"), "Table expression: {}", table_expression->dumpTree());
|
|
||||||
scope.expression_join_tree_node = table_expression;
|
scope.expression_join_tree_node = table_expression;
|
||||||
validateTableExpressionModifiers(scope.expression_join_tree_node, scope);
|
validateTableExpressionModifiers(scope.expression_join_tree_node, scope);
|
||||||
initializeTableExpressionData(scope.expression_join_tree_node, scope);
|
initializeTableExpressionData(scope.expression_join_tree_node, scope);
|
||||||
@ -1109,7 +1108,6 @@ public:
|
|||||||
resolveExpressionNodeList(node, scope, false /*allow_lambda_expression*/, false /*allow_table_expression*/);
|
resolveExpressionNodeList(node, scope, false /*allow_lambda_expression*/, false /*allow_table_expression*/);
|
||||||
else
|
else
|
||||||
resolveExpressionNode(node, scope, false /*allow_lambda_expression*/, false /*allow_table_expression*/);
|
resolveExpressionNode(node, scope, false /*allow_lambda_expression*/, false /*allow_table_expression*/);
|
||||||
LOG_DEBUG(&Poco::Logger::get("resolve"), "Result: {}", node->dumpTree());
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2681,7 +2679,6 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromAliases(const Identifier
|
|||||||
*/
|
*/
|
||||||
QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromTableColumns(const IdentifierLookup & identifier_lookup, IdentifierResolveScope & scope)
|
QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromTableColumns(const IdentifierLookup & identifier_lookup, IdentifierResolveScope & scope)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(&Poco::Logger::get("tryResolveIdentifierFromTableColumns"), "{} {}", scope.column_name_to_column_node.size(), !identifier_lookup.isExpressionLookup());
|
|
||||||
if (scope.column_name_to_column_node.empty() || !identifier_lookup.isExpressionLookup())
|
if (scope.column_name_to_column_node.empty() || !identifier_lookup.isExpressionLookup())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@ -2841,14 +2838,11 @@ QueryTreeNodePtr QueryAnalyzer::tryResolveIdentifierFromTableExpression(const Id
|
|||||||
QueryTreeNodePtr result_expression;
|
QueryTreeNodePtr result_expression;
|
||||||
bool match_full_identifier = false;
|
bool match_full_identifier = false;
|
||||||
|
|
||||||
LOG_DEBUG(&Poco::Logger::get("resolve_identifier_from_storage_or_throw"), "Looking for id: {}", identifier_without_column_qualifier.getFullName());
|
|
||||||
|
|
||||||
auto it = table_expression_data.column_name_to_column_node.find(identifier_without_column_qualifier.getFullName());
|
auto it = table_expression_data.column_name_to_column_node.find(identifier_without_column_qualifier.getFullName());
|
||||||
if (it != table_expression_data.column_name_to_column_node.end())
|
if (it != table_expression_data.column_name_to_column_node.end())
|
||||||
{
|
{
|
||||||
match_full_identifier = true;
|
match_full_identifier = true;
|
||||||
result_expression = it->second;
|
result_expression = it->second;
|
||||||
LOG_DEBUG(&Poco::Logger::get("resolve_identifier_from_storage_or_throw"), "Found: {}", result_expression->dumpTree());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5397,7 +5391,6 @@ ProjectionNames QueryAnalyzer::resolveExpressionNode(QueryTreeNodePtr & node, Id
|
|||||||
auto unresolved_identifier = identifier_node.getIdentifier();
|
auto unresolved_identifier = identifier_node.getIdentifier();
|
||||||
auto resolve_identifier_expression_result = tryResolveIdentifier({unresolved_identifier, IdentifierLookupContext::EXPRESSION}, scope);
|
auto resolve_identifier_expression_result = tryResolveIdentifier({unresolved_identifier, IdentifierLookupContext::EXPRESSION}, scope);
|
||||||
auto resolved_identifier_node = resolve_identifier_expression_result.resolved_identifier;
|
auto resolved_identifier_node = resolve_identifier_expression_result.resolved_identifier;
|
||||||
LOG_DEBUG(&Poco::Logger::get("resolveExpressionNode"), "Resolved: {}", resolved_identifier_node ? resolved_identifier_node->dumpTree() : "Not resolved");
|
|
||||||
|
|
||||||
if (resolved_identifier_node && result_projection_names.empty() &&
|
if (resolved_identifier_node && result_projection_names.empty() &&
|
||||||
(resolve_identifier_expression_result.isResolvedFromJoinTree() || resolve_identifier_expression_result.isResolvedFromExpressionArguments()))
|
(resolve_identifier_expression_result.isResolvedFromJoinTree() || resolve_identifier_expression_result.isResolvedFromExpressionArguments()))
|
||||||
@ -5479,7 +5472,6 @@ ProjectionNames QueryAnalyzer::resolveExpressionNode(QueryTreeNodePtr & node, Id
|
|||||||
}
|
}
|
||||||
|
|
||||||
node = std::move(resolved_identifier_node);
|
node = std::move(resolved_identifier_node);
|
||||||
LOG_DEBUG(&Poco::Logger::get("resolveExpressionNode"), "Result node: {}", node ? node->dumpTree() : "Not resolved");
|
|
||||||
|
|
||||||
if (node->getNodeType() == QueryTreeNodeType::LIST)
|
if (node->getNodeType() == QueryTreeNodeType::LIST)
|
||||||
{
|
{
|
||||||
@ -6183,7 +6175,6 @@ void QueryAnalyzer::initializeTableExpressionData(const QueryTreeNodePtr & table
|
|||||||
table_expression_data.should_qualify_columns = false;
|
table_expression_data.should_qualify_columns = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG(&Poco::Logger::get("Analyzer"), "Table data: {}", table_expression_data.dump());
|
|
||||||
scope.table_expression_node_to_data.emplace(table_expression_node, std::move(table_expression_data));
|
scope.table_expression_node_to_data.emplace(table_expression_node, std::move(table_expression_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "Analyzer/IQueryTreeNode.h"
|
#include "Analyzer/IQueryTreeNode.h"
|
||||||
#include "Analyzer/Identifier.h"
|
#include "Analyzer/Identifier.h"
|
||||||
#include "Analyzer/IdentifierNode.h"
|
#include "Analyzer/IdentifierNode.h"
|
||||||
|
#include "Analyzer/InDepthQueryTreeVisitor.h"
|
||||||
#include "Analyzer/Passes/QueryAnalysisPass.h"
|
#include "Analyzer/Passes/QueryAnalysisPass.h"
|
||||||
#include "Analyzer/QueryTreeBuilder.h"
|
#include "Analyzer/QueryTreeBuilder.h"
|
||||||
#include "Core/NamesAndTypes.h"
|
#include "Core/NamesAndTypes.h"
|
||||||
@ -564,6 +565,26 @@ void ReadFromMerge::initializePipeline(QueryPipelineBuilder & pipeline, const Bu
|
|||||||
pipeline.addResources(std::move(resources));
|
pipeline.addResources(std::move(resources));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
class ApplyAliasColumnExpressionsVisitor : public InDepthQueryTreeVisitor<ApplyAliasColumnExpressionsVisitor>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ApplyAliasColumnExpressionsVisitor() = default;
|
||||||
|
|
||||||
|
void visitImpl(QueryTreeNodePtr & node)
|
||||||
|
{
|
||||||
|
if (auto * column = node->as<ColumnNode>();
|
||||||
|
column != nullptr && column->hasExpression())
|
||||||
|
{
|
||||||
|
node = column->getExpressionOrThrow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SelectQueryInfo ReadFromMerge::getModifiedQueryInfo(const ContextPtr & modified_context,
|
SelectQueryInfo ReadFromMerge::getModifiedQueryInfo(const ContextPtr & modified_context,
|
||||||
const StorageWithLockAndName & storage_with_lock_and_name,
|
const StorageWithLockAndName & storage_with_lock_and_name,
|
||||||
const StorageSnapshotPtr & storage_snapshot,
|
const StorageSnapshotPtr & storage_snapshot,
|
||||||
@ -611,23 +632,28 @@ SelectQueryInfo ReadFromMerge::getModifiedQueryInfo(const ContextPtr & modified_
|
|||||||
|
|
||||||
QueryTreeNodePtr column_node;
|
QueryTreeNodePtr column_node;
|
||||||
|
|
||||||
|
|
||||||
if (is_alias)
|
if (is_alias)
|
||||||
{
|
{
|
||||||
// column_node = buildQueryTree(column_default->expression, modified_context);
|
// column_node = buildQueryTree(column_default->expression, modified_context);
|
||||||
column_node = std::make_shared<IdentifierNode>(Identifier{column});
|
QueryTreeNodePtr fake_node = std::make_shared<IdentifierNode>(Identifier{column});
|
||||||
|
|
||||||
LOG_DEBUG(&Poco::Logger::get("getModifiedQueryInfo"), "QT before: {}\n{}", column_node->dumpTree(), modified_query_info.table_expression->dumpTree());
|
LOG_DEBUG(&Poco::Logger::get("getModifiedQueryInfo"), "QT before: {}\n{}", fake_node->dumpTree(), modified_query_info.table_expression->dumpTree());
|
||||||
|
|
||||||
QueryAnalysisPass query_analysis_pass(modified_query_info.table_expression);
|
QueryAnalysisPass query_analysis_pass(modified_query_info.table_expression);
|
||||||
query_analysis_pass.run(column_node, modified_context);
|
query_analysis_pass.run(fake_node, modified_context);
|
||||||
|
|
||||||
|
auto * resolved_column = fake_node->as<ColumnNode>();
|
||||||
|
|
||||||
|
column_node = fake_node;
|
||||||
|
ApplyAliasColumnExpressionsVisitor visitor;
|
||||||
|
visitor.visit(column_node);
|
||||||
|
|
||||||
LOG_DEBUG(&Poco::Logger::get("getModifiedQueryInfo"), "QT after: {}", column_node->dumpTree());
|
LOG_DEBUG(&Poco::Logger::get("getModifiedQueryInfo"), "QT after: {}", column_node->dumpTree());
|
||||||
|
|
||||||
auto * resolved_column = column_node->as<ColumnNode>();
|
|
||||||
if (!resolved_column || !resolved_column->getExpression())
|
if (!resolved_column || !resolved_column->getExpression())
|
||||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Alias column is not resolved");
|
throw Exception(ErrorCodes::LOGICAL_ERROR, "Alias column is not resolved");
|
||||||
|
|
||||||
column_node = resolved_column->getExpression();
|
|
||||||
column_name_to_node.emplace(column, column_node);
|
column_name_to_node.emplace(column, column_node);
|
||||||
aliases.push_back({ .name = column, .type = resolved_column->getResultType(), .expression = column_node->toAST() });
|
aliases.push_back({ .name = column, .type = resolved_column->getResultType(), .expression = column_node->toAST() });
|
||||||
}
|
}
|
||||||
@ -1095,6 +1121,8 @@ void ReadFromMerge::convertingSourceStream(
|
|||||||
std::move(convert_actions_dag),
|
std::move(convert_actions_dag),
|
||||||
ExpressionActionsSettings::fromContext(local_context, CompileExpressions::yes));
|
ExpressionActionsSettings::fromContext(local_context, CompileExpressions::yes));
|
||||||
|
|
||||||
|
LOG_DEBUG(&Poco::Logger::get("convertingSourceStream"), "The header: {}", builder.getHeader().dumpStructure());
|
||||||
|
|
||||||
builder.addSimpleTransform([&](const Block & stream_header)
|
builder.addSimpleTransform([&](const Block & stream_header)
|
||||||
{
|
{
|
||||||
return std::make_shared<ExpressionTransform>(stream_header, actions);
|
return std::make_shared<ExpressionTransform>(stream_header, actions);
|
||||||
|
Loading…
Reference in New Issue
Block a user