mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Shadow lambda arguments
In case of ambiguity, lambda functions should prefer its arguments to other aliases or identifiers
This commit is contained in:
parent
4f0dbae0f9
commit
8b9778ebb6
@ -3,6 +3,7 @@
|
||||
#include <Interpreters/QueryNormalizer.h>
|
||||
#include <Interpreters/IdentifierSemantic.h>
|
||||
#include <Interpreters/Context.h>
|
||||
#include <Interpreters/RequiredSourceColumnsVisitor.h>
|
||||
#include <Parsers/ASTFunction.h>
|
||||
#include <Parsers/ASTIdentifier.h>
|
||||
#include <Parsers/ASTSelectQuery.h>
|
||||
@ -170,6 +171,24 @@ void QueryNormalizer::visitChildren(IAST * node, Data & data)
|
||||
/// Don't go into query argument.
|
||||
return;
|
||||
}
|
||||
|
||||
/// For lambda functions we need to avoid replacing lambda parameters with external aliases, for example,
|
||||
/// Select 1 as x, arrayMap(x -> x + 2, [1, 2, 3])
|
||||
/// shouldn't be replaced with Select 1 as x, arrayMap(x -> **(1 as x)** + 2, [1, 2, 3])
|
||||
Aliases extracted_aliases;
|
||||
if (func_node->name == "lambda")
|
||||
{
|
||||
Names lambda_aliases = RequiredSourceColumnsMatcher::extractNamesFromLambda(*func_node);
|
||||
for (const auto & name : lambda_aliases)
|
||||
{
|
||||
auto it = data.aliases.find(name);
|
||||
if (it != data.aliases.end())
|
||||
{
|
||||
extracted_aliases.insert(data.aliases.extract(it));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// We skip the first argument. We also assume that the lambda function can not have parameters.
|
||||
size_t first_pos = 0;
|
||||
if (func_node->name == "lambda")
|
||||
@ -192,6 +211,11 @@ void QueryNormalizer::visitChildren(IAST * node, Data & data)
|
||||
{
|
||||
visitChildren(func_node->window_definition.get(), data);
|
||||
}
|
||||
|
||||
for (auto & it : extracted_aliases)
|
||||
{
|
||||
data.aliases.insert(it);
|
||||
}
|
||||
}
|
||||
else if (!node->as<ASTSelectQuery>())
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
using SetOfASTs = std::set<const IAST *>;
|
||||
using MapOfASTs = std::map<ASTPtr, ASTPtr>;
|
||||
|
||||
const Aliases & aliases;
|
||||
Aliases & aliases;
|
||||
const NameSet & source_columns_set;
|
||||
ExtractedSettings settings;
|
||||
|
||||
@ -53,7 +53,7 @@ public:
|
||||
/// It's Ok to have "c + 1 AS c" in queries, but not in table definition
|
||||
const bool allow_self_aliases; /// for constructs like "SELECT column + 1 AS column"
|
||||
|
||||
Data(const Aliases & aliases_, const NameSet & source_columns_set_, bool ignore_alias_, ExtractedSettings && settings_, bool allow_self_aliases_)
|
||||
Data(Aliases & aliases_, const NameSet & source_columns_set_, bool ignore_alias_, ExtractedSettings && settings_, bool allow_self_aliases_)
|
||||
: aliases(aliases_)
|
||||
, source_columns_set(source_columns_set_)
|
||||
, settings(settings_)
|
||||
|
@ -0,0 +1,3 @@
|
||||
1000 [2,3,4]
|
||||
1
|
||||
1
|
25
tests/queries/0_stateless/01960_lambda_precedence.sql
Normal file
25
tests/queries/0_stateless/01960_lambda_precedence.sql
Normal file
@ -0,0 +1,25 @@
|
||||
SELECT
|
||||
1000 AS a,
|
||||
arrayMap(a -> (a + 1), [1, 2, 3]);
|
||||
|
||||
|
||||
-- https://github.com/ClickHouse/ClickHouse/issues/5046
|
||||
SELECT sum(c1) AS v
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
1 AS c1,
|
||||
['v'] AS c2
|
||||
)
|
||||
WHERE arrayExists(v -> (v = 'v'), c2);
|
||||
|
||||
|
||||
SELECT sum(c1) AS v
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
1 AS c1,
|
||||
['v'] AS c2,
|
||||
['d'] AS d
|
||||
)
|
||||
WHERE arrayExists(i -> (d = ['d']), c2);
|
Loading…
Reference in New Issue
Block a user