Skip to content

Commit c92f471

Browse files
committed
YQL-19758 fixed parsing of Error type, prevent expanding of aggregation/window over inputs with errors
commit_hash:fa39bb9947d55827107b96ddf0c102fe6a5ae0bd
1 parent 6314869 commit c92f471

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

yql/essentials/ast/yql_type_string.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ enum EToken
9292
TOKEN_TZDATETIME64 = -57,
9393
TOKEN_TZTIMESTAMP64 = -58,
9494
TOKEN_MULTI = -59,
95+
TOKEN_ERROR = -60,
9596

9697
// identifiers
9798
TOKEN_IDENTIFIER = -100,
@@ -164,6 +165,7 @@ EToken TokenTypeFromStr(TStringBuf str)
164165
{ TStringBuf("TzDate32"), TOKEN_TZDATE32 },
165166
{ TStringBuf("TzDatetime64"), TOKEN_TZDATETIME64},
166167
{ TStringBuf("TzTimestamp64"), TOKEN_TZTIMESTAMP64 },
168+
{ TStringBuf("Error"), TOKEN_ERROR},
167169
};
168170

169171
auto it = map.find(str);
@@ -343,6 +345,10 @@ class TTypeParser
343345
type = ParseScalarType();
344346
break;
345347

348+
case TOKEN_ERROR:
349+
type = ParseErrorType();
350+
break;
351+
346352
default:
347353
if (Identifier.empty()) {
348354
return AddError("Expected type");
@@ -703,6 +709,51 @@ class TTypeParser
703709
return MakeScalarType(itemType);
704710
}
705711

712+
TAstNode* ParseErrorType() {
713+
GetNextToken(); // eat keyword
714+
EXPECT_AND_SKIP_TOKEN('<', nullptr);
715+
716+
TString file;
717+
if (Token == TOKEN_IDENTIFIER ||
718+
Token == TOKEN_ESCAPED_IDENTIFIER)
719+
{
720+
file = Identifier;
721+
} else {
722+
return AddError("Expected file name");
723+
}
724+
725+
GetNextToken(); // eat file name
726+
EXPECT_AND_SKIP_TOKEN(':', nullptr);
727+
ui32 line;
728+
if (!(Token == TOKEN_IDENTIFIER ||
729+
Token == TOKEN_ESCAPED_IDENTIFIER) || !TryFromString(Identifier, line)) {
730+
return AddError("Expected line");
731+
}
732+
733+
GetNextToken();
734+
EXPECT_AND_SKIP_TOKEN(':', nullptr);
735+
ui32 column;
736+
if (!(Token == TOKEN_IDENTIFIER ||
737+
Token == TOKEN_ESCAPED_IDENTIFIER) || !TryFromString(Identifier, column)) {
738+
return AddError("Expected column");
739+
}
740+
741+
GetNextToken();
742+
EXPECT_AND_SKIP_TOKEN(':', nullptr);
743+
TString message;
744+
if (Token == TOKEN_IDENTIFIER ||
745+
Token == TOKEN_ESCAPED_IDENTIFIER)
746+
{
747+
message = Identifier;
748+
} else {
749+
return AddError("Expected message");
750+
}
751+
752+
GetNextToken();
753+
EXPECT_AND_SKIP_TOKEN('>', nullptr);
754+
return MakeErrorType(file, line, column, message);
755+
}
756+
706757
TAstNode* ParseDecimalType() {
707758
GetNextToken(); // eat keyword
708759
EXPECT_AND_SKIP_TOKEN('(', nullptr);
@@ -974,6 +1025,17 @@ class TTypeParser
9741025
return MakeList(items, Y_ARRAY_SIZE(items));
9751026
}
9761027

1028+
TAstNode* MakeErrorType(TStringBuf file, ui32 row, ui32 column, TStringBuf message) {
1029+
TAstNode* items[] = {
1030+
MakeLiteralAtom(TStringBuf("ErrorType")),
1031+
MakeQuotedAtom(ToString(row)),
1032+
MakeQuotedAtom(ToString(column)),
1033+
MakeQuotedAtom(file, TNodeFlags::ArbitraryContent),
1034+
MakeQuotedAtom(message, TNodeFlags::ArbitraryContent)
1035+
};
1036+
return MakeList(items, Y_ARRAY_SIZE(items));
1037+
}
1038+
9771039
TAstNode* MakeVariantType(TAstNode* underlyingType) {
9781040
TAstNode* items[] = {
9791041
MakeLiteralAtom(TStringBuf("VariantType")),

yql/essentials/ast/yql_type_string_ut.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,10 @@ Y_UNIT_TEST_SUITE(TTypeString)
520520
TestOk("Struct<>", "(StructType)");
521521
}
522522

523+
Y_UNIT_TEST(ParseErrorType) {
524+
TestOk("Error<'<main>':1:2:'message'>", "(ErrorType '1 '2 '\"<main>\" '\"message\")");
525+
}
526+
523527
void TestFormat(const TString& yql, const TString& expectedTypeStr) {
524528
TMemoryPool pool(4096);
525529

yql/essentials/core/yql_aggregate_expander.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ namespace NYql {
1212

1313
TExprNode::TPtr TAggregateExpander::ExpandAggregate() {
1414
YQL_CLOG(DEBUG, Core) << "Expand " << Node->Content();
15+
if (Node->Head().GetTypeAnn()->HasErrors()) {
16+
TErrorTypeVisitor errorVisitor(Ctx);
17+
Node->Head().GetTypeAnn()->Accept(errorVisitor);
18+
return nullptr;
19+
}
20+
1521
auto result = ExpandAggregateWithFullOutput();
1622
if (result) {
1723
auto outputColumns = GetSetting(*Node->Child(NNodes::TCoAggregate::idx_Settings), "output_columns");

yql/essentials/core/yql_opt_window.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3292,6 +3292,12 @@ TExprNode::TPtr ExpandCalcOverWindow(const TExprNode::TPtr& node, TExprContext&
32923292
return input;
32933293
}
32943294

3295+
if (input->GetTypeAnn()->HasErrors()) {
3296+
TErrorTypeVisitor errorVisitor(ctx);
3297+
input->GetTypeAnn()->Accept(errorVisitor);
3298+
return nullptr;
3299+
}
3300+
32953301
TCoCalcOverWindowTuple calc(calcs.front());
32963302
if (calc.Frames().Size() != 0 || calc.SessionColumns().Size() != 0) {
32973303
const TStructExprType& outputRowType = *node->GetTypeAnn()->Cast<TListExprType>()->GetItemType()->Cast<TStructExprType>();

0 commit comments

Comments
 (0)