Skip to content

Commit

Permalink
Merge pull request #62362 from ucasfl/analyzer-position-arguments
Browse files Browse the repository at this point in the history
Fix analyzer with positional arguments in distributed query
  • Loading branch information
novikd authored Apr 10, 2024
2 parents 4560f7c + eeeb8f3 commit 14566fc
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 13 deletions.
25 changes: 12 additions & 13 deletions src/Analyzer/Passes/QueryAnalysisPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2275,6 +2275,10 @@ void QueryAnalyzer::mergeWindowWithParentWindow(const QueryTreeNodePtr & window_
*/
void QueryAnalyzer::replaceNodesWithPositionalArguments(QueryTreeNodePtr & node_list, const QueryTreeNodes & projection_nodes, IdentifierResolveScope & scope)
{
const auto & settings = scope.context->getSettingsRef();
if (!settings.enable_positional_arguments || scope.context->getClientInfo().query_kind != ClientInfo::QueryKind::INITIAL_QUERY)
return;

auto & node_list_typed = node_list->as<ListNode &>();

for (auto & node : node_list_typed.getNodes())
Expand All @@ -2287,7 +2291,8 @@ void QueryAnalyzer::replaceNodesWithPositionalArguments(QueryTreeNodePtr & node_
auto * constant_node = (*node_to_replace)->as<ConstantNode>();

if (!constant_node
|| (constant_node->getValue().getType() != Field::Types::UInt64 && constant_node->getValue().getType() != Field::Types::Int64))
|| (constant_node->getValue().getType() != Field::Types::UInt64
&& constant_node->getValue().getType() != Field::Types::Int64))
continue;

UInt64 pos;
Expand Down Expand Up @@ -6681,15 +6686,12 @@ void expandTuplesInList(QueryTreeNodes & key_list)
*/
void QueryAnalyzer::resolveGroupByNode(QueryNode & query_node_typed, IdentifierResolveScope & scope)
{
const auto & settings = scope.context->getSettingsRef();

if (query_node_typed.isGroupByWithGroupingSets())
{
QueryTreeNodes nullable_group_by_keys;
for (auto & grouping_sets_keys_list_node : query_node_typed.getGroupBy().getNodes())
{
if (settings.enable_positional_arguments)
replaceNodesWithPositionalArguments(grouping_sets_keys_list_node, query_node_typed.getProjection().getNodes(), scope);
replaceNodesWithPositionalArguments(grouping_sets_keys_list_node, query_node_typed.getProjection().getNodes(), scope);

// Remove redundant calls to `tuple` function. It simplifies checking if expression is an aggregation key.
// It's required to support queries like: SELECT number FROM numbers(3) GROUP BY (number, number % 2)
Expand All @@ -6708,8 +6710,7 @@ void QueryAnalyzer::resolveGroupByNode(QueryNode & query_node_typed, IdentifierR
}
else
{
if (settings.enable_positional_arguments)
replaceNodesWithPositionalArguments(query_node_typed.getGroupByNode(), query_node_typed.getProjection().getNodes(), scope);
replaceNodesWithPositionalArguments(query_node_typed.getGroupByNode(), query_node_typed.getProjection().getNodes(), scope);

// Remove redundant calls to `tuple` function. It simplifies checking if expression is an aggregation key.
// It's required to support queries like: SELECT number FROM numbers(3) GROUP BY (number, number % 2)
Expand Down Expand Up @@ -7860,8 +7861,6 @@ void QueryAnalyzer::resolveQuery(const QueryTreeNodePtr & query_node, Identifier
if (query_node_typed.isCTE())
cte_in_resolve_process.insert(query_node_typed.getCTEName());

const auto & settings = scope.context->getSettingsRef();

bool is_rollup_or_cube = query_node_typed.isGroupByWithRollup() || query_node_typed.isGroupByWithCube();

if (query_node_typed.isGroupByWithGroupingSets()
Expand Down Expand Up @@ -8045,8 +8044,9 @@ void QueryAnalyzer::resolveQuery(const QueryTreeNodePtr & query_node, Identifier

if (query_node_typed.hasOrderBy())
{
if (settings.enable_positional_arguments)
replaceNodesWithPositionalArguments(query_node_typed.getOrderByNode(), query_node_typed.getProjection().getNodes(), scope);
replaceNodesWithPositionalArguments(query_node_typed.getOrderByNode(), query_node_typed.getProjection().getNodes(), scope);

const auto & settings = scope.context->getSettingsRef();

expandOrderByAll(query_node_typed, settings);
resolveSortNodeList(query_node_typed.getOrderByNode(), scope);
Expand All @@ -8069,8 +8069,7 @@ void QueryAnalyzer::resolveQuery(const QueryTreeNodePtr & query_node, Identifier

if (query_node_typed.hasLimitBy())
{
if (settings.enable_positional_arguments)
replaceNodesWithPositionalArguments(query_node_typed.getLimitByNode(), query_node_typed.getProjection().getNodes(), scope);
replaceNodesWithPositionalArguments(query_node_typed.getLimitByNode(), query_node_typed.getProjection().getNodes(), scope);

resolveExpressionNodeList(query_node_typed.getLimitByNode(), scope, false /*allow_lambda_expression*/, false /*allow_table_expression*/);
}
Expand Down
4 changes: 4 additions & 0 deletions src/Processors/QueryPlan/DistributedCreateLocalPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ std::unique_ptr<QueryPlan> createLocalPlan(

if (context->getSettingsRef().allow_experimental_analyzer)
{
/// For Analyzer, identifier in GROUP BY/ORDER BY/LIMIT BY lists has been resolved to
/// ConstantNode in QueryTree if it is an alias of a constant, so we should not replace
/// ConstantNode with ProjectionNode again(https://github.com/ClickHouse/ClickHouse/issues/62289).
new_context->setSetting("enable_positional_arguments", Field(false));
auto interpreter = InterpreterSelectQueryAnalyzer(query_ast, new_context, select_query_options);
query_plan = std::make_unique<QueryPlan>(std::move(interpreter).extractQueryPlan());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0
0
0
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
select 0 as x
from remote('127.0.0.{1,2}', system.one)
group by x;

select 0 as x
from remote('127.0.0.{1,2}', system.one)
order by x;

0 comments on commit 14566fc

Please sign in to comment.