aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzverevgeny <zverevgeny@ydb.tech>2023-12-07 19:14:33 +0300
committerzverevgeny <zverevgeny@ydb.tech>2023-12-07 20:13:18 +0300
commit154fc21683f37e62d4369d304c9072e39081ebb2 (patch)
tree339250662fea64f68b6678a808b58a146aa7b7dc
parenta2043f21c2c07ed59112aab640ca405d793d530a (diff)
downloadydb-154fc21683f37e62d4369d304c9072e39081ebb2.tar.gz
fix too deep recursion detect in match_recognize pattern
-rw-r--r--ydb/library/yql/core/yql_match_recognize.h2
-rw-r--r--ydb/library/yql/sql/v1/sql_match_recognize.cpp1
-rw-r--r--ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp14
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) {