aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzverevgeny <zverevgeny@ydb.tech>2023-09-29 09:34:47 +0300
committerzverevgeny <zverevgeny@ydb.tech>2023-09-29 10:00:01 +0300
commit0f10245df98b9bb58f2be8b1fd680a75c26da724 (patch)
tree611b7af130a4c8ae024d48e7d8edd4044344c32d
parentceda18005f87ee1bc87fbc1d516b8b9e39028df5 (diff)
downloadydb-0f10245df98b9bb58f2be8b1fd680a75c26da724.tar.gz
fail parse on errors in MATCH_RECOGNIZE
-rw-r--r--ydb/library/yql/sql/v1/match_recognize.cpp2
-rw-r--r--ydb/library/yql/sql/v1/select.cpp14
-rw-r--r--ydb/library/yql/sql/v1/source.cpp10
-rw-r--r--ydb/library/yql/sql/v1/source.h1
-rw-r--r--ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp15
5 files changed, 33 insertions, 9 deletions
diff --git a/ydb/library/yql/sql/v1/match_recognize.cpp b/ydb/library/yql/sql/v1/match_recognize.cpp
index ee95fbfafa..92fe9257d0 100644
--- a/ydb/library/yql/sql/v1/match_recognize.cpp
+++ b/ydb/library/yql/sql/v1/match_recognize.cpp
@@ -202,6 +202,7 @@ bool TMatchRecognizeNavigate::DoInit(TContext& ctx, ISource* src) {
if (DefaultNavigatingFunction == Name) {
if (not varColumn->IsTheSameVar()) {
ctx.Error(Pos) << "Row pattern navigation function is required";
+ return false;
}
navigatedRowIndex = varLastRowIndex;
}
@@ -229,6 +230,7 @@ bool TMatchRecognizeNavigate::DoInit(TContext& ctx, ISource* src) {
);
} else {
ctx.Error(Pos) << "Internal logic error";
+ return false;
}
Add("Member");
Add(
diff --git a/ydb/library/yql/sql/v1/select.cpp b/ydb/library/yql/sql/v1/select.cpp
index af72542a37..ce789ba386 100644
--- a/ydb/library/yql/sql/v1/select.cpp
+++ b/ydb/library/yql/sql/v1/select.cpp
@@ -1680,11 +1680,15 @@ public:
auto block(Y(Y("let", "core", input)));
- if (auto matchRecognize = Source->BuildMatchRecognize(ctx, "core")) {
- //use unique name match_recognize to find this block easily in unit tests
- block = L(block, Y("let", "match_recognize", matchRecognize));
- //then bind to the conventional name
- block = L(block, Y("let", "core", "match_recognize"));
+ if (Source->HasMatchRecognize()) {
+ if (auto matchRecognize = Source->BuildMatchRecognize(ctx, "core")) {
+ //use unique name match_recognize to find this block easily in unit tests
+ block = L(block, Y("let", "match_recognize", matchRecognize));
+ //then bind to the conventional name
+ block = L(block, Y("let", "core", "match_recognize"));
+ } else {
+ return nullptr;
+ }
}
bool ordered = ctx.UseUnordered(*this);
diff --git a/ydb/library/yql/sql/v1/source.cpp b/ydb/library/yql/sql/v1/source.cpp
index 5fa609be62..bf5fbbe979 100644
--- a/ydb/library/yql/sql/v1/source.cpp
+++ b/ydb/library/yql/sql/v1/source.cpp
@@ -937,11 +937,13 @@ TNodePtr ISource::BuildSortSpec(const TVector<TSortSpecificationPtr>& orderBy, c
}
}
+bool ISource::HasMatchRecognize() const {
+ return static_cast<bool>(MatchRecognizeBuilder);
+}
+
TNodePtr ISource::BuildMatchRecognize(TContext& ctx, TString&& inputTable){
- if (MatchRecognizeBuilder){
- return MatchRecognizeBuilder->Build(ctx, std::move(inputTable), this);
- }
- return TNodePtr{};
+ YQL_ENSURE(HasMatchRecognize());
+ return MatchRecognizeBuilder->Build(ctx, std::move(inputTable), this);
};
IJoin::IJoin(TPosition pos)
diff --git a/ydb/library/yql/sql/v1/source.h b/ydb/library/yql/sql/v1/source.h
index 0c729fc3ef..3214b95e08 100644
--- a/ydb/library/yql/sql/v1/source.h
+++ b/ydb/library/yql/sql/v1/source.h
@@ -94,6 +94,7 @@ namespace NSQLTranslationV1 {
virtual bool ShouldUseSourceAsColumn(const TString& source) const;
virtual bool IsJoinKeysInitializing() const;
virtual const TString* GetWindowName() const;
+ virtual bool HasMatchRecognize() const;
virtual TNodePtr BuildMatchRecognize(TContext& ctx, TString&& inputTable);
virtual bool DoInit(TContext& ctx, ISource* src);
virtual TNodePtr Build(TContext& ctx) = 0;
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 0c7f93d190..9d99445ab6 100644
--- a/ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp
+++ b/ydb/library/yql/sql/v1/sql_match_recognize_ut.cpp
@@ -648,4 +648,19 @@ FROM Input MATCH_RECOGNIZE(
UNIT_ASSERT(IsLambda(defines->GetChild(5), 3));
UNIT_ASSERT(IsLambda(defines->GetChild(6), 3));
}
+
+ Y_UNIT_TEST(CheckRequiredNavigationFunction) {
+ TString stmtPrefix = R"(
+USE plato;
+SELECT *
+FROM Input MATCH_RECOGNIZE(
+ PATTERN ( Y Q L )
+ DEFINE
+ L as L.V =
+)";
+ //Be aware that right parenthesis is added at the end of the query as required
+ UNIT_ASSERT(MatchRecognizeSqlToYql(stmtPrefix + "LAST(Q.dt) )").IsOk());
+ UNIT_ASSERT(!MatchRecognizeSqlToYql(stmtPrefix + "Q.dt )").IsOk());
+ }
+
}