diff options
| author | vvvv <[email protected]> | 2025-04-04 11:39:21 +0300 |
|---|---|---|
| committer | vvvv <[email protected]> | 2025-04-04 11:52:29 +0300 |
| commit | c92f4715eea8c91b4cd80b83c97648b349fd8023 (patch) | |
| tree | e4fd75bfd798c7837404f060c10291613c1de5bf /yql/essentials/ast | |
| parent | 631486945a52bca43ab638058f5ef1883cf0ed77 (diff) | |
YQL-19758 fixed parsing of Error type, prevent expanding of aggregation/window over inputs with errors
commit_hash:fa39bb9947d55827107b96ddf0c102fe6a5ae0bd
Diffstat (limited to 'yql/essentials/ast')
| -rw-r--r-- | yql/essentials/ast/yql_type_string.cpp | 62 | ||||
| -rw-r--r-- | yql/essentials/ast/yql_type_string_ut.cpp | 4 |
2 files changed, 66 insertions, 0 deletions
diff --git a/yql/essentials/ast/yql_type_string.cpp b/yql/essentials/ast/yql_type_string.cpp index 6dfbaa56645..20c86034090 100644 --- a/yql/essentials/ast/yql_type_string.cpp +++ b/yql/essentials/ast/yql_type_string.cpp @@ -92,6 +92,7 @@ enum EToken TOKEN_TZDATETIME64 = -57, TOKEN_TZTIMESTAMP64 = -58, TOKEN_MULTI = -59, + TOKEN_ERROR = -60, // identifiers TOKEN_IDENTIFIER = -100, @@ -164,6 +165,7 @@ EToken TokenTypeFromStr(TStringBuf str) { TStringBuf("TzDate32"), TOKEN_TZDATE32 }, { TStringBuf("TzDatetime64"), TOKEN_TZDATETIME64}, { TStringBuf("TzTimestamp64"), TOKEN_TZTIMESTAMP64 }, + { TStringBuf("Error"), TOKEN_ERROR}, }; auto it = map.find(str); @@ -343,6 +345,10 @@ private: type = ParseScalarType(); break; + case TOKEN_ERROR: + type = ParseErrorType(); + break; + default: if (Identifier.empty()) { return AddError("Expected type"); @@ -703,6 +709,51 @@ private: return MakeScalarType(itemType); } + TAstNode* ParseErrorType() { + GetNextToken(); // eat keyword + EXPECT_AND_SKIP_TOKEN('<', nullptr); + + TString file; + if (Token == TOKEN_IDENTIFIER || + Token == TOKEN_ESCAPED_IDENTIFIER) + { + file = Identifier; + } else { + return AddError("Expected file name"); + } + + GetNextToken(); // eat file name + EXPECT_AND_SKIP_TOKEN(':', nullptr); + ui32 line; + if (!(Token == TOKEN_IDENTIFIER || + Token == TOKEN_ESCAPED_IDENTIFIER) || !TryFromString(Identifier, line)) { + return AddError("Expected line"); + } + + GetNextToken(); + EXPECT_AND_SKIP_TOKEN(':', nullptr); + ui32 column; + if (!(Token == TOKEN_IDENTIFIER || + Token == TOKEN_ESCAPED_IDENTIFIER) || !TryFromString(Identifier, column)) { + return AddError("Expected column"); + } + + GetNextToken(); + EXPECT_AND_SKIP_TOKEN(':', nullptr); + TString message; + if (Token == TOKEN_IDENTIFIER || + Token == TOKEN_ESCAPED_IDENTIFIER) + { + message = Identifier; + } else { + return AddError("Expected message"); + } + + GetNextToken(); + EXPECT_AND_SKIP_TOKEN('>', nullptr); + return MakeErrorType(file, line, column, message); + } + TAstNode* ParseDecimalType() { GetNextToken(); // eat keyword EXPECT_AND_SKIP_TOKEN('(', nullptr); @@ -974,6 +1025,17 @@ private: return MakeList(items, Y_ARRAY_SIZE(items)); } + TAstNode* MakeErrorType(TStringBuf file, ui32 row, ui32 column, TStringBuf message) { + TAstNode* items[] = { + MakeLiteralAtom(TStringBuf("ErrorType")), + MakeQuotedAtom(ToString(row)), + MakeQuotedAtom(ToString(column)), + MakeQuotedAtom(file, TNodeFlags::ArbitraryContent), + MakeQuotedAtom(message, TNodeFlags::ArbitraryContent) + }; + return MakeList(items, Y_ARRAY_SIZE(items)); + } + TAstNode* MakeVariantType(TAstNode* underlyingType) { TAstNode* items[] = { MakeLiteralAtom(TStringBuf("VariantType")), diff --git a/yql/essentials/ast/yql_type_string_ut.cpp b/yql/essentials/ast/yql_type_string_ut.cpp index 2d20e05fc7b..44071e16124 100644 --- a/yql/essentials/ast/yql_type_string_ut.cpp +++ b/yql/essentials/ast/yql_type_string_ut.cpp @@ -520,6 +520,10 @@ Y_UNIT_TEST_SUITE(TTypeString) TestOk("Struct<>", "(StructType)"); } + Y_UNIT_TEST(ParseErrorType) { + TestOk("Error<'<main>':1:2:'message'>", "(ErrorType '1 '2 '\"<main>\" '\"message\")"); + } + void TestFormat(const TString& yql, const TString& expectedTypeStr) { TMemoryPool pool(4096); |
