diff options
author | zverevgeny <zverevgeny@ydb.tech> | 2023-12-07 19:14:33 +0300 |
---|---|---|
committer | zverevgeny <zverevgeny@ydb.tech> | 2023-12-07 20:13:18 +0300 |
commit | 154fc21683f37e62d4369d304c9072e39081ebb2 (patch) | |
tree | 339250662fea64f68b6678a808b58a146aa7b7dc | |
parent | a2043f21c2c07ed59112aab640ca405d793d530a (diff) | |
download | ydb-154fc21683f37e62d4369d304c9072e39081ebb2.tar.gz |
fix too deep recursion detect in match_recognize pattern
-rw-r--r-- | ydb/library/yql/core/yql_match_recognize.h | 2 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/sql_match_recognize.cpp | 1 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp | 14 |
3 files changed, 16 insertions, 1 deletions
diff --git a/ydb/library/yql/core/yql_match_recognize.h b/ydb/library/yql/core/yql_match_recognize.h index 9089b963b5..5c623cf860 100644 --- a/ydb/library/yql/core/yql_match_recognize.h +++ b/ydb/library/yql/core/yql_match_recognize.h @@ -14,7 +14,7 @@ inline TRowPattern ConvertPattern(const TExprNode::TPtr& pattern, TExprContext & result.back().push_back(TRowPatternFactor{ factor->ChildRef(0)->IsAtom() ? TRowPatternPrimary(TString(factor->ChildRef(0)->Content())) : - ConvertPattern(factor->ChildRef(0), ctx, ++nestingLevel), + ConvertPattern(factor->ChildRef(0), ctx, nestingLevel + 1), FromString<ui64>(factor->ChildRef(1)->Content()), FromString<ui64>(factor->ChildRef(2)->Content()), FromString<bool>(factor->ChildRef(3)->Content()), diff --git a/ydb/library/yql/sql/v1/sql_match_recognize.cpp b/ydb/library/yql/sql/v1/sql_match_recognize.cpp index 17697b9082..4a41a8f2c8 100644 --- a/ydb/library/yql/sql/v1/sql_match_recognize.cpp +++ b/ydb/library/yql/sql/v1/sql_match_recognize.cpp @@ -248,6 +248,7 @@ NYql::NMatchRecognize::TRowPatternTerm TSqlMatchRecognizeClause::ParsePatternTer case TRule_row_pattern_primary::kAltRowPatternPrimary4: { if (++PatternNestingLevel <= NYql::NMatchRecognize::MaxPatternNesting) { primary = ParsePattern(primaryVar.GetAlt_row_pattern_primary4().GetBlock2().GetRule_row_pattern1()); + --PatternNestingLevel; } else { Ctx.Error(TokenPosition(primaryVar.GetAlt_row_pattern_primary4().GetToken1())) << "To big nesting level in the pattern"; diff --git a/ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp b/ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp index 1c94a54593..43cfa35962 100644 --- a/ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp +++ b/ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp @@ -412,6 +412,20 @@ FROM Input MATCH_RECOGNIZE( UNIT_ASSERT(IsQuotedListOfSize(nestedPattern->GetChild(1), 2)); } + Y_UNIT_TEST(PatternManyAlternatives) { + const auto stmt = R"( +USE plato; +SELECT * +FROM Input MATCH_RECOGNIZE( +PATTERN ( + (A B C D ) | (B A C D ) | (C B A D ) | (B C A D ) | (C A B D ) | (A C B D ) | (D A B C ) | (A D B C ) | (B A D C ) | (A B D C ) | (B D A C ) | (D B A C ) | (C D A B ) | (D C A B ) | (A D C B ) | (D A C B ) | (A C D B ) | (C A D B ) | (B C D A ) | (C B D A ) | (D C B A ) | (C D B A ) | (D B C A ) | (B D C A ) + ) + DEFINE A as A +) +)"; + UNIT_ASSERT(MatchRecognizeSqlToYql(stmt).IsOk()); + } + Y_UNIT_TEST(PatternLimitedNesting) { const size_t MaxNesting = 20; for (size_t extraNesting = 0; extraNesting <= 1; ++extraNesting) { |