Merge pull request #68435 from ClickHouse/tuple-element-identifier

Support expressions with tuples like `expr().name`
This commit is contained in:
Alexey Milovidov 2024-08-16 20:57:55 +00:00 committed by GitHub
commit da1d09b2d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 3 deletions

View File

@ -2811,8 +2811,8 @@ Action ParserExpressionImpl::tryParseOperator(Layers & layers, IParser::Pos & po
if (op.type == OperatorType::TupleElement)
{
ASTPtr tmp;
if (asterisk_parser.parse(pos, tmp, expected) ||
columns_matcher_parser.parse(pos, tmp, expected))
if (asterisk_parser.parse(pos, tmp, expected)
|| columns_matcher_parser.parse(pos, tmp, expected))
{
if (auto * asterisk = tmp->as<ASTAsterisk>())
{
@ -2833,6 +2833,17 @@ Action ParserExpressionImpl::tryParseOperator(Layers & layers, IParser::Pos & po
layers.back()->pushOperand(std::move(tmp));
return Action::OPERATOR;
}
/// If it is an identifier,
/// replace it with literal, because an expression `expr().elem`
/// should be transformed to `tupleElement(expr(), 'elem')` for query analysis,
/// otherwise the identifier `elem` will not be found.
if (ParserIdentifier().parse(pos, tmp, expected))
{
layers.back()->pushOperator(op);
layers.back()->pushOperand(std::make_shared<ASTLiteral>(tmp->as<ASTIdentifier>()->name()));
return Action::OPERATOR;
}
}
/// isNull & isNotNull are postfix unary operators
@ -2863,7 +2874,7 @@ Action ParserExpressionImpl::tryParseOperator(Layers & layers, IParser::Pos & po
layers.push_back(std::make_unique<ArrayElementLayer>());
if (op.type == OperatorType::StartBetween || op.type == OperatorType::StartNotBetween)
layers.back()->between_counter++;
++layers.back()->between_counter;
return Action::OPERAND;
}

View File

@ -0,0 +1,4 @@
([('wtf')]) [('wtf')] wtf
([('wtf')]) [('wtf')] wtf
Hello
('Hello') Hello Hello Hello

View File

@ -0,0 +1,13 @@
SET enable_analyzer = 1;
SELECT JSONExtract('{"hello":[{"world":"wtf"}]}', 'Tuple(hello Array(Tuple(world String)))') AS x,
x.hello, x.hello[1].world;
SELECT JSONExtract('{"hello":[{" wow ":"wtf"}]}', 'Tuple(hello Array(Tuple(` wow ` String)))') AS x,
x.hello, x.hello[1].` wow `;
SELECT JSONExtract('{"hello":[{" wow ":"wtf"}]}', 'Tuple(hello Array(Tuple(` wow ` String)))') AS x,
x.hello, x.hello[1].`wow`; -- { serverError NOT_FOUND_COLUMN_IN_BLOCK }
SELECT ('Hello' AS world,).world;
SELECT ('Hello' AS world,) AS t, t.world, (t).world, identity(t).world;