fix parsing of arrays in cast operator

This commit is contained in:
Anton Popov 2023-10-09 14:14:05 +00:00
parent df037e079d
commit 4b76ab91a1
3 changed files with 30 additions and 24 deletions

View File

@ -719,66 +719,70 @@ static bool isOneOf(TokenType token)
bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{ {
using enum TokenType;
/// Parse numbers (including decimals), strings, arrays and tuples of them. /// Parse numbers (including decimals), strings, arrays and tuples of them.
const char * data_begin = pos->begin; const char * data_begin = pos->begin;
const char * data_end = pos->end; const char * data_end = pos->end;
bool is_string_literal = pos->type == TokenType::StringLiteral; bool is_string_literal = pos->type == StringLiteral;
if (pos->type == TokenType::Minus) if (pos->type == Minus)
{ {
++pos; ++pos;
if (pos->type != TokenType::Number) if (pos->type != Number)
return false; return false;
data_end = pos->end; data_end = pos->end;
++pos; ++pos;
} }
else if (pos->type == TokenType::Number || is_string_literal) else if (pos->type == Number || is_string_literal)
{ {
++pos; ++pos;
} }
else if (isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket>(pos->type)) else if (isOneOf<OpeningSquareBracket, OpeningRoundBracket>(pos->type))
{ {
TokenType last_token = TokenType::OpeningSquareBracket; TokenType last_token = OpeningSquareBracket;
std::vector<TokenType> stack; std::vector<TokenType> stack;
while (pos.isValid()) while (pos.isValid())
{ {
if (isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket>(pos->type)) if (isOneOf<OpeningSquareBracket, OpeningRoundBracket>(pos->type))
{ {
stack.push_back(pos->type); stack.push_back(pos->type);
if (!isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma>(last_token)) if (!isOneOf<OpeningSquareBracket, OpeningRoundBracket, Comma>(last_token))
return false; return false;
} }
else if (pos->type == TokenType::ClosingSquareBracket) else if (pos->type == ClosingSquareBracket)
{ {
if (isOneOf<TokenType::Comma, TokenType::OpeningRoundBracket, TokenType::Minus>(last_token)) if (isOneOf<Comma, OpeningRoundBracket, Minus>(last_token))
return false; return false;
if (stack.empty() || stack.back() != TokenType::OpeningSquareBracket) if (stack.empty() || stack.back() != OpeningSquareBracket)
return false; return false;
stack.pop_back(); stack.pop_back();
} }
else if (pos->type == TokenType::ClosingRoundBracket) else if (pos->type == ClosingRoundBracket)
{ {
if (isOneOf<TokenType::Comma, TokenType::OpeningSquareBracket, TokenType::Minus>(last_token)) if (isOneOf<Comma, OpeningSquareBracket, Minus>(last_token))
return false; return false;
if (stack.empty() || stack.back() != TokenType::OpeningRoundBracket) if (stack.empty() || stack.back() != OpeningRoundBracket)
return false; return false;
stack.pop_back(); stack.pop_back();
} }
else if (pos->type == TokenType::Comma) else if (pos->type == Comma)
{ {
if (isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma, TokenType::Minus>(last_token)) if (isOneOf<OpeningSquareBracket, OpeningRoundBracket, Comma, Minus>(last_token))
return false;
if (stack.empty())
break;
}
else if (pos->type == Number)
{
if (!isOneOf<OpeningSquareBracket, OpeningRoundBracket, Comma, Minus>(last_token))
return false; return false;
} }
else if (pos->type == TokenType::Number) else if (isOneOf<StringLiteral, Minus>(pos->type))
{ {
if (!isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma, TokenType::Minus>(last_token)) if (!isOneOf<OpeningSquareBracket, OpeningRoundBracket, Comma>(last_token))
return false;
}
else if (isOneOf<TokenType::StringLiteral, TokenType::Minus>(pos->type))
{
if (!isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma>(last_token))
return false; return false;
} }
else else
@ -800,7 +804,7 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
return false; return false;
ASTPtr type_ast; ASTPtr type_ast;
if (ParserToken(TokenType::DoubleColon).ignore(pos, expected) if (ParserToken(DoubleColon).ignore(pos, expected)
&& ParserDataType().parse(pos, type_ast, expected)) && ParserDataType().parse(pos, type_ast, expected))
{ {
String s; String s;

View File

@ -0,0 +1 @@
[1] 0

View File

@ -0,0 +1 @@
SELECT [1], 0::UInt16;