summaryrefslogtreecommitdiffstats
path: root/yql/essentials/ast
diff options
context:
space:
mode:
authorvvvv <[email protected]>2025-04-04 11:39:21 +0300
committervvvv <[email protected]>2025-04-04 11:52:29 +0300
commitc92f4715eea8c91b4cd80b83c97648b349fd8023 (patch)
treee4fd75bfd798c7837404f060c10291613c1de5bf /yql/essentials/ast
parent631486945a52bca43ab638058f5ef1883cf0ed77 (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.cpp62
-rw-r--r--yql/essentials/ast/yql_type_string_ut.cpp4
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);