Merge pull request #27876 from CurtizJ/cast-with-minus

Fix postgres-like cast with negative numbers
This commit is contained in:
Kseniia Sumarokova 2021-08-20 10:55:42 +03:00 committed by GitHub
commit 74ebc5c75c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 9 deletions

View File

@ -850,15 +850,24 @@ static bool isOneOf(TokenType token)
return ((token == tokens) || ...);
}
bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
/// Parse numbers (including decimals), strings and arrays of them.
/// Parse numbers (including decimals), strings, arrays and tuples of them.
const char * data_begin = pos->begin;
const char * data_end = pos->end;
bool is_string_literal = pos->type == TokenType::StringLiteral;
if (pos->type == TokenType::Number || is_string_literal)
if (pos->type == TokenType::Minus)
{
++pos;
if (pos->type != TokenType::Number)
return false;
data_end = pos->end;
++pos;
}
else if (pos->type == TokenType::Number || is_string_literal)
{
++pos;
}
@ -876,7 +885,7 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
}
else if (pos->type == TokenType::ClosingSquareBracket)
{
if (isOneOf<TokenType::Comma, TokenType::OpeningRoundBracket>(last_token))
if (isOneOf<TokenType::Comma, TokenType::OpeningRoundBracket, TokenType::Minus>(last_token))
return false;
if (stack.empty() || stack.back() != TokenType::OpeningSquareBracket)
return false;
@ -884,7 +893,7 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
}
else if (pos->type == TokenType::ClosingRoundBracket)
{
if (isOneOf<TokenType::Comma, TokenType::OpeningSquareBracket>(last_token))
if (isOneOf<TokenType::Comma, TokenType::OpeningSquareBracket, TokenType::Minus>(last_token))
return false;
if (stack.empty() || stack.back() != TokenType::OpeningRoundBracket)
return false;
@ -892,10 +901,15 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
}
else if (pos->type == TokenType::Comma)
{
if (isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma>(last_token))
if (isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma, TokenType::Minus>(last_token))
return false;
}
else if (isOneOf<TokenType::Number, TokenType::StringLiteral>(pos->type))
else if (pos->type == TokenType::Number)
{
if (!isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma, TokenType::Minus>(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;
@ -915,6 +929,8 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
if (!stack.empty())
return false;
}
else
return false;
ASTPtr type_ast;
if (ParserToken(TokenType::DoubleColon).ignore(pos, expected)

View File

@ -664,10 +664,12 @@ bool ParserUnaryExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
if (pos->type == TokenType::Minus)
{
ParserLiteral lit_p;
Pos begin = pos;
if (ParserCastOperator().parse(pos, node, expected))
return true;
if (lit_p.parse(pos, node, expected))
pos = begin;
if (ParserLiteral().parse(pos, node, expected))
return true;
pos = begin;

View File

@ -0,0 +1,10 @@
-1
SELECT CAST(\'-1\', \'Int32\')
-0.1
SELECT CAST(\'-0.1\', \'Decimal(38, 38)\')
-0.111
SELECT CAST(\'-0.111\', \'Float64\')
[-1,2,-3]
SELECT CAST(\'[-1, 2, -3]\', \'Array(Int32)\')
[-1.1,2,-3]
SELECT CAST(\'[-1.1, 2, -3]\', \'Array(Float64)\')

View File

@ -0,0 +1,14 @@
SELECT -1::Int32;
EXPLAIN SYNTAX SELECT -1::Int32;
SELECT -0.1::Decimal(38, 38);
EXPLAIN SYNTAX SELECT -0.1::Decimal(38, 38);
SELECT -0.111::Float64;
EXPLAIN SYNTAX SELECT -0.111::Float64;
SELECT [-1, 2, -3]::Array(Int32);
EXPLAIN SYNTAX SELECT [-1, 2, -3]::Array(Int32);
SELECT [-1.1, 2, -3]::Array(Float64);
EXPLAIN SYNTAX SELECT [-1.1, 2, -3]::Array(Float64);

View File

@ -8,3 +8,11 @@ Syntax error
Syntax error
Syntax error
Code: 6
Syntax error
Syntax error
Syntax error
Syntax error
Syntax error
Syntax error
Syntax error
Syntax error

View File

@ -15,3 +15,13 @@ $CLICKHOUSE_CLIENT --query="SELECT [1 2]::Array(UInt8)" 2>&1 | grep -o -m1 'Syn
$CLICKHOUSE_CLIENT --query="SELECT 1 4::UInt32" 2>&1 | grep -o 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT '1' '4'::UInt32" 2>&1 | grep -o -m1 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT '1''4'::UInt32" 2>&1 | grep -o -m1 'Code: 6'
$CLICKHOUSE_CLIENT --query="SELECT ::UInt32" 2>&1 | grep -o 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT ::String" 2>&1 | grep -o 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT -::Int32" 2>&1 | grep -o 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT [1, -]::Array(Int32)" 2>&1 | grep -o 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT [1, 3-]::Array(Int32)" 2>&1 | grep -o 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT [-, 2]::Array(Int32)" 2>&1 | grep -o 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT [--, 2]::Array(Int32)" 2>&1 | grep -o 'Syntax error'
$CLICKHOUSE_CLIENT --query="SELECT [1, 2]-::Array(Int32)" 2>&1 | grep -o 'Syntax error'