Skip to content

Commit

Permalink
Merge pull request ClickHouse#65190 from ClickHouse/support-aliases-i…
Browse files Browse the repository at this point in the history
…n-param-view-function

Support aliases in parametrized view function (only new analyzer)
  • Loading branch information
novikd authored and shiyer7474 committed Oct 11, 2024
1 parent aaf7d5e commit 678a8e1
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 6 deletions.
36 changes: 34 additions & 2 deletions src/Analyzer/Passes/QueryAnalysisPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <IO/Operators.h>

#include <DataTypes/IDataType.h>
#include <Common/FieldVisitorToString.h>

#include <DataTypes/DataTypesNumber.h>
#include <DataTypes/DataTypeString.h>
#include <DataTypes/DataTypeNullable.h>
Expand Down Expand Up @@ -6248,7 +6250,8 @@ ProjectionNames QueryAnalyzer::resolveFunction(QueryTreeNodePtr & node, Identifi
*
* 4. If node has alias, update its value in scope alias map. Deregister alias from expression_aliases_in_resolve_process.
*/
ProjectionNames QueryAnalyzer::resolveExpressionNode(QueryTreeNodePtr & node, IdentifierResolveScope & scope, bool allow_lambda_expression, bool allow_table_expression)
ProjectionNames QueryAnalyzer::resolveExpressionNode(
QueryTreeNodePtr & node, IdentifierResolveScope & scope, bool allow_lambda_expression, bool allow_table_expression)
{
checkStackSize();

Expand Down Expand Up @@ -7264,7 +7267,36 @@ void QueryAnalyzer::resolveTableFunction(QueryTreeNodePtr & table_function_node,
table_name = table_identifier[1];
}

auto parametrized_view_storage = scope_context->getQueryContext()->buildParametrizedViewStorage(function_ast, database_name, table_name);
/// Collect parametrized view arguments
NameToNameMap view_params;
for (const auto & argument : table_function_node_typed.getArguments())
{
if (auto * arg_func = argument->as<FunctionNode>())
{
if (arg_func->getFunctionName() != "equals")
continue;

auto nodes = arg_func->getArguments().getNodes();
if (nodes.size() != 2)
continue;

if (auto * identifier_node = nodes[0]->as<IdentifierNode>())
{
resolveExpressionNode(nodes[1], scope, /* allow_lambda_expression */false, /* allow_table_function */false);
if (auto * constant = nodes[1]->as<ConstantNode>())
{
view_params[identifier_node->getIdentifier().getFullName()] = convertFieldToString(constant->getValue());
}
}
}
}

auto context = scope_context->getQueryContext();
auto parametrized_view_storage = context->buildParametrizedViewStorage(
database_name,
table_name,
view_params);

if (parametrized_view_storage)
{
auto fake_table_node = std::make_shared<TableNode>(parametrized_view_storage, scope_context);
Expand Down
5 changes: 2 additions & 3 deletions src/Interpreters/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2018,7 +2018,7 @@ StoragePtr Context::executeTableFunction(const ASTPtr & table_expression, const
}


StoragePtr Context::buildParametrizedViewStorage(const ASTPtr & table_expression, const String & database_name, const String & table_name)
StoragePtr Context::buildParametrizedViewStorage(const String & database_name, const String & table_name, const NameToNameMap & param_values)
{
if (table_name.empty())
return nullptr;
Expand All @@ -2031,8 +2031,7 @@ StoragePtr Context::buildParametrizedViewStorage(const ASTPtr & table_expression
return nullptr;

auto query = original_view->getInMemoryMetadataPtr()->getSelectQuery().inner_query->clone();
NameToNameMap parameterized_view_values = analyzeFunctionParamValues(table_expression, getQueryContext());
StorageView::replaceQueryParametersIfParametrizedView(query, parameterized_view_values);
StorageView::replaceQueryParametersIfParametrizedView(query, param_values);

ASTCreateQuery create;
create.select = query->as<ASTSelectWithUnionQuery>();
Expand Down
2 changes: 1 addition & 1 deletion src/Interpreters/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ class Context: public ContextData, public std::enable_shared_from_this<Context>
/// Overload for the new analyzer. Structure inference is performed in QueryAnalysisPass.
StoragePtr executeTableFunction(const ASTPtr & table_expression, const TableFunctionPtr & table_function_ptr);

StoragePtr buildParametrizedViewStorage(const ASTPtr & table_expression, const String & database_name, const String & table_name);
StoragePtr buildParametrizedViewStorage(const String & database_name, const String & table_name, const NameToNameMap & param_values);

void addViewSource(const StoragePtr & storage);
StoragePtr getViewSource() const;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
OK
123
123
123
123
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
SET allow_experimental_analyzer=1;
CREATE OR REPLACE VIEW param_test AS SELECT {test_str:String} as s_result;
WITH 'OK' AS s SELECT * FROM param_test(test_str=s);
WITH (SELECT 123) AS s SELECT * FROM param_test(test_str=s);
WITH (SELECT 100 + 20 + 3) AS s SELECT * FROM param_test(test_str=s);
WITH (SELECT number FROM numbers(123, 1)) AS s SELECT * FROM param_test(test_str=s);
WITH CAST(123, 'String') AS s SELECT * FROM param_test(test_str=s);

0 comments on commit 678a8e1

Please sign in to comment.