SQLUserDefinedFunctions support lambdas

This commit is contained in:
Maksim Kita 2021-10-20 12:43:03 +03:00
parent 6b9a1ab60b
commit 83787e26f2
7 changed files with 24 additions and 37 deletions

View File

@ -1,14 +1,17 @@
#include <Interpreters/InterpreterCreateFunctionQuery.h>
#include <stack>
#include <Access/ContextAccess.h>
#include <Parsers/ASTCreateFunctionQuery.h>
#include <Parsers/ASTIdentifier.h>
#include <Interpreters/Context.h>
#include <Interpreters/ExpressionActions.h>
#include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/InterpreterCreateFunctionQuery.h>
#include <Interpreters/FunctionNameNormalizer.h>
#include <Interpreters/UserDefinedSQLObjectsLoader.h>
#include <Interpreters/UserDefinedSQLFunctionFactory.h>
#include <stack>
namespace DB
{
@ -66,42 +69,9 @@ void InterpreterCreateFunctionQuery::validateFunction(ASTPtr function, const Str
}
ASTPtr function_body = function->as<ASTFunction>()->children.at(0)->children.at(1);
std::unordered_set<String> identifiers_in_body = getIdentifiers(function_body);
for (const auto & identifier : identifiers_in_body)
{
if (!arguments.contains(identifier))
throw Exception(ErrorCodes::UNKNOWN_IDENTIFIER, "Identifier {} does not exist in arguments", backQuote(identifier));
}
validateFunctionRecursiveness(function_body, name);
}
std::unordered_set<String> InterpreterCreateFunctionQuery::getIdentifiers(ASTPtr node)
{
std::unordered_set<String> identifiers;
std::stack<ASTPtr> ast_nodes_to_process;
ast_nodes_to_process.push(node);
while (!ast_nodes_to_process.empty())
{
auto ast_node_to_process = ast_nodes_to_process.top();
ast_nodes_to_process.pop();
for (const auto & child : ast_node_to_process->children)
{
auto identifier_name_opt = tryGetIdentifierName(child);
if (identifier_name_opt)
identifiers.insert(identifier_name_opt.value());
ast_nodes_to_process.push(child);
}
}
return identifiers;
}
void InterpreterCreateFunctionQuery::validateFunctionRecursiveness(ASTPtr node, const String & function_to_create)
{
for (const auto & child : node->children)

View File

@ -22,7 +22,6 @@ public:
private:
static void validateFunction(ASTPtr function, const String & name);
static std::unordered_set<String> getIdentifiers(ASTPtr node);
static void validateFunctionRecursiveness(ASTPtr node, const String & function_to_create);
ASTPtr query_ptr;

View File

@ -25,6 +25,7 @@ void UserDefinedSQLFunctionMatcher::visit(ASTPtr & ast, Data &)
return;
auto result = tryToReplaceFunction(*function);
if (result)
ast = result;
}
@ -83,9 +84,16 @@ ASTPtr UserDefinedSQLFunctionMatcher::tryToReplaceFunction(const ASTFunction & f
if (identifier_name_opt)
{
auto function_argument_it = identifier_name_to_function_argument.find(*identifier_name_opt);
assert(function_argument_it != identifier_name_to_function_argument.end());
if (function_argument_it == identifier_name_to_function_argument.end())
continue;
auto child_alias = child->tryGetAlias();
child = function_argument_it->second->clone();
if (!child_alias.empty())
child->setAlias(child_alias);
continue;
}

View File

@ -0,0 +1,4 @@
-- Tags: no-parallel
CREATE FUNCTION alias_function AS x -> (((x * 2) AS x_doubled) + x_doubled);
SELECT alias_function(2);
DROP FUNCTION alias_function;

View File

@ -0,0 +1,4 @@
-- Tags: no-parallel
CREATE FUNCTION lambda_function AS x -> arrayMap(array_element -> array_element * 2, x);
SELECT lambda_function([1,2,3]);
DROP FUNCTION lambda_function;