fix several cases in cast operator

This commit is contained in:
Anton Popov 2021-05-25 02:42:13 +03:00
parent 83ef34374c
commit 35e2cc7b2b
4 changed files with 60 additions and 10 deletions

View File

@ -2523,7 +2523,7 @@ private:
if (!from_type)
{
throw Exception(ErrorCodes::TYPE_MISMATCH,
"CAST AS Array can only be perforamed between same-dimensional Array or String types");
"CAST AS Array can only be performed between same-dimensional Array or String types");
}
DataTypePtr from_nested_type = from_type->getNestedType();
@ -2533,7 +2533,7 @@ private:
if (from_type->getNumberOfDimensions() != to_type.getNumberOfDimensions() && !from_empty_array)
throw Exception(ErrorCodes::TYPE_MISMATCH,
"CAST AS Array can only be perforamed between same-dimensional array types");
"CAST AS Array can only be performed between same-dimensional array types");
const DataTypePtr & to_nested_type = to_type.getNestedType();

View File

@ -824,34 +824,48 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
/// Parse numbers (including decimals), strings and arrays 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)
{
++pos;
}
else if (pos->type == TokenType::OpeningSquareBracket)
else if (isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket>(pos->type))
{
TokenType last_token = TokenType::OpeningSquareBracket;
std::vector<TokenType> stack;
while (pos.isValid())
{
if (pos->type == TokenType::OpeningSquareBracket)
if (isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket>(pos->type))
{
if (!isOneOf<TokenType::OpeningSquareBracket, TokenType::Comma>(last_token))
stack.push_back(pos->type);
if (!isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma>(last_token))
return false;
}
else if (pos->type == TokenType::ClosingSquareBracket)
{
if (last_token == TokenType::Comma)
if (isOneOf<TokenType::Comma, TokenType::OpeningRoundBracket>(last_token))
return false;
if (stack.empty() || stack.back() != TokenType::OpeningSquareBracket)
return false;
stack.pop_back();
}
else if (pos->type == TokenType::ClosingRoundBracket)
{
if (isOneOf<TokenType::Comma, TokenType::OpeningSquareBracket>(last_token))
return false;
if (stack.empty() || stack.back() != TokenType::OpeningRoundBracket)
return false;
stack.pop_back();
}
else if (pos->type == TokenType::Comma)
{
if (isOneOf<TokenType::OpeningSquareBracket, TokenType::Comma>(last_token))
if (isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma>(last_token))
return false;
}
else if (isOneOf<TokenType::Number, TokenType::StringLiteral>(pos->type))
{
if (!isOneOf<TokenType::OpeningSquareBracket, TokenType::Comma>(last_token))
if (!isOneOf<TokenType::OpeningSquareBracket, TokenType::OpeningRoundBracket, TokenType::Comma>(last_token))
return false;
}
else
@ -859,14 +873,18 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
break;
}
/// Update data_end on every iteration to avoid appearances of extra trailing
/// whitespaces into data. Whitespaces are skipped at operator '++' of Pos.
data_end = pos->end;
last_token = pos->type;
++pos;
}
if (!stack.empty())
return false;
}
ASTPtr type_ast;
const char * data_end = pos->begin;
if (ParserToken(TokenType::DoubleColon).ignore(pos, expected)
&& ParserDataType().parse(pos, type_ast, expected))
{

View File

@ -0,0 +1,13 @@
(0.1000000000000000000000000000000000000000000000000000000000000000000000,0.2000000000000000000000000000000000000000000000000000000000000000000000)
SELECT CAST(\'(0.1, 0.2)\', \'Tuple(Decimal(75, 70), Decimal(75, 70))\')
0.1000
SELECT CAST(\'0.1\', \'Decimal(4, 4)\')
[1,2,3]
SELECT CAST(\'[1, 2, 3]\', \'Array(Int32)\')
[1,2]
SELECT CAST([CAST(\'1\', \'UInt32\'), CAST(\'2\', \'UInt32\')], \'Array(UInt64)\')
[[1,2],[3]]
SELECT CAST([CAST(\'[1, 2]\', \'Array(UInt32)\'), [3]], \'Array(Array(UInt64))\')
[[1,2],[3]]
SELECT CAST([CAST([CAST(\'1\', \'UInt16\'), CAST(\'2\', \'UInt16\')], \'Array(UInt32)\'), [3]], \'Array(Array(UInt64))\')
[(1,'a'),(3,'b')] Nested(u UInt8, s String)

View File

@ -0,0 +1,19 @@
SELECT (0.1, 0.2)::Tuple(Decimal(75, 70), Decimal(75, 70));
EXPLAIN SYNTAX SELECT (0.1, 0.2)::Tuple(Decimal(75, 70), Decimal(75, 70));
SELECT 0.1 :: Decimal(4, 4);
EXPLAIN SYNTAX SELECT 0.1 :: Decimal(4, 4);
SELECT [1, 2, 3] :: Array(Int32);
EXPLAIN SYNTAX SELECT [1, 2, 3] :: Array(Int32);
SELECT [1::UInt32, 2::UInt32]::Array(UInt64);
EXPLAIN SYNTAX SELECT [1::UInt32, 2::UInt32]::Array(UInt64);
SELECT [[1, 2]::Array(UInt32), [3]]::Array(Array(UInt64));
EXPLAIN SYNTAX SELECT [[1, 2]::Array(UInt32), [3]]::Array(Array(UInt64));
SELECT [[1::UInt16, 2::UInt16]::Array(UInt32), [3]]::Array(Array(UInt64));
EXPLAIN SYNTAX SELECT [[1::UInt16, 2::UInt16]::Array(UInt32), [3]]::Array(Array(UInt64));
SELECT [(1, 'a'), (3, 'b')]::Nested(u UInt8, s String) AS t, toTypeName(t);