Proper parsing of the PostgreSQL-style CAST operator

This commit is contained in:
Alexey Milovidov 2024-08-16 23:08:16 +02:00
parent 09d4964de5
commit cc7d22a7b8
3 changed files with 25 additions and 11 deletions

View File

@ -853,9 +853,9 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
/// Parse numbers (including decimals), strings, arrays and tuples of them. /// Parse numbers (including decimals), strings, arrays and tuples of them.
Pos begin = pos;
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 == StringLiteral;
if (pos->type == Minus) if (pos->type == Minus)
{ {
@ -866,7 +866,7 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
data_end = pos->end; data_end = pos->end;
++pos; ++pos;
} }
else if (pos->type == Number || is_string_literal) else if (pos->type == Number || pos->type == StringLiteral)
{ {
++pos; ++pos;
} }
@ -939,18 +939,22 @@ bool ParserCastOperator::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
{ {
String s; String s;
size_t data_size = data_end - data_begin; size_t data_size = data_end - data_begin;
if (is_string_literal) if (begin->type == StringLiteral)
{ {
ReadBufferFromMemory buf(data_begin, data_size); ASTPtr literal;
readQuotedStringWithSQLStyle(s, buf); if (ParserStringLiteral().parse(begin, literal, expected))
assert(buf.count() == data_size); {
node = createFunctionCast(literal, type_ast);
return true;
}
return false;
} }
else else
s = String(data_begin, data_size); {
auto literal = std::make_shared<ASTLiteral>(String(data_begin, data_size));
auto literal = std::make_shared<ASTLiteral>(std::move(s)); node = createFunctionCast(literal, type_ast);
node = createFunctionCast(literal, type_ast); return true;
return true; }
} }
return false; return false;

View File

@ -0,0 +1,4 @@
414243
ABC
A
{"a": \'A\'}

View File

@ -0,0 +1,6 @@
SELECT '414243'::String;
SELECT x'414243'::String;
SELECT b'01000001'::String;
SELECT '{"a": \'\x41\'}'::String;
SELECT '{"a": \'\x4\'}'::String; -- { clientError SYNTAX_ERROR }
SELECT '{"a": \'a\x4\'}'::String; -- { clientError SYNTAX_ERROR }