summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraneporada <[email protected]>2022-02-14 00:49:52 +0300
committeraneporada <[email protected]>2022-02-14 00:49:52 +0300
commit2e3663422353da95615fec18d1aa32fa7b6e9edf (patch)
tree8dc96e9600af2ffb04e70c5683d1e096a0024093
parent82cfd1b7cab2d843cdf5467d9737f72597a493bd (diff)
[YQL-10265] Support implicit row peers when frame definition is missing (sql part)
ref:17a7f716fc0cc4c71162338230544795c45bd59b
-rw-r--r--ydb/library/yql/sql/v1/context.cpp1
-rw-r--r--ydb/library/yql/sql/v1/context.h2
-rw-r--r--ydb/library/yql/sql/v1/node.cpp10
-rw-r--r--ydb/library/yql/sql/v1/sql.cpp38
4 files changed, 41 insertions, 10 deletions
diff --git a/ydb/library/yql/sql/v1/context.cpp b/ydb/library/yql/sql/v1/context.cpp
index c08fe96caeb..7beccd30f42 100644
--- a/ydb/library/yql/sql/v1/context.cpp
+++ b/ydb/library/yql/sql/v1/context.cpp
@@ -53,6 +53,7 @@ THashMap<TStringBuf, TPragmaField> CTX_PRAGMA_FIELDS = {
{"CoalesceJoinKeysOnQualifiedAll", &TContext::CoalesceJoinKeysOnQualifiedAll},
{"UnorderedSubqueries", &TContext::UnorderedSubqueries},
{"FlexibleTypes", &TContext::FlexibleTypes},
+ {"AnsiCurrentRow", &TContext::AnsiCurrentRow},
};
typedef TMaybe<bool> TContext::*TPragmaMaybeField;
diff --git a/ydb/library/yql/sql/v1/context.h b/ydb/library/yql/sql/v1/context.h
index 89517574862..e65d673ea13 100644
--- a/ydb/library/yql/sql/v1/context.h
+++ b/ydb/library/yql/sql/v1/context.h
@@ -254,6 +254,8 @@ namespace NSQLTranslationV1 {
ui32 PragmaGroupByCubeLimit = 5;
// if FlexibleTypes=true, emit TypeOrMember callable and resolve Type/Column uncertainty on type annotation stage, otherwise always emit Type
bool FlexibleTypes = false;
+ // see YQL-10265
+ bool AnsiCurrentRow = false;
THashMap<TString, TMaybe<TString>> Libraries; // alias -> optional file
THashMap<TString, ui32> PackageVersions;
NYql::TWarningPolicy WarningPolicy;
diff --git a/ydb/library/yql/sql/v1/node.cpp b/ydb/library/yql/sql/v1/node.cpp
index 870bbd9cc7f..bd9a303e092 100644
--- a/ydb/library/yql/sql/v1/node.cpp
+++ b/ydb/library/yql/sql/v1/node.cpp
@@ -1839,17 +1839,17 @@ TNodePtr BuildFrameNode(const TFrameBound& frame) {
TNodePtr node = frame.Bound;
TPosition pos = frame.Pos;
if (frame.Settings == FrameCurrentRow) {
- node = new TCallNodeImpl(pos, "Int32", { BuildQuotedAtom(pos, "0", TNodeFlags::Default) });
+ node = BuildQuotedAtom(pos, "currentRow", TNodeFlags::Default);
} else if (!node) {
node = BuildLiteralVoid(pos);
} else if (node->IsLiteral()) {
YQL_ENSURE(node->GetLiteralType() == "Int32");
- auto value = node->GetLiteralValue();
- YQL_ENSURE(!value.StartsWith('-'));
+ i32 value = FromString<i32>(node->GetLiteralValue());
+ YQL_ENSURE(value >= 0);
if (frame.Settings == FramePreceding) {
- value = "-" + value;
+ value = -value;
}
- node = new TCallNodeImpl(pos, "Int32", { BuildQuotedAtom(pos, value, TNodeFlags::Default) });
+ node = new TCallNodeImpl(pos, "Int32", { BuildQuotedAtom(pos, ToString(value), TNodeFlags::Default) });
} else {
if (frame.Settings == FramePreceding) {
node = new TCallNodeImpl(pos, "Minus", { node->Clone() });
diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp
index cba19761b9c..2b0c8178708 100644
--- a/ydb/library/yql/sql/v1/sql.cpp
+++ b/ydb/library/yql/sql/v1/sql.cpp
@@ -6909,6 +6909,22 @@ bool TSqlTranslation::FrameClause(const TRule_window_frame_clause& rule, TFrameS
return false;
}
+ if (frameSpec->FrameType != EFrameType::FrameByRange) {
+ // replace FrameCurrentRow for ROWS/GROUPS with 0 preceding/following
+ // FrameCurrentRow has special meaning ( = first/last peer row)
+ auto replaceCurrent = [](TFrameBound& frame, bool preceding) {
+ frame.Settings = preceding ? EFrameSettings::FramePreceding : EFrameSettings::FrameFollowing;
+ frame.Bound = new TLiteralNumberNode<i32>(frame.Pos, "Int32", "0");
+ };
+ if (frameSpec->FrameBegin->Settings == EFrameSettings::FrameCurrentRow) {
+ replaceCurrent(*frameSpec->FrameBegin, true);
+ }
+
+ if (frameSpec->FrameEnd->Settings == EFrameSettings::FrameCurrentRow) {
+ replaceCurrent(*frameSpec->FrameEnd, false);
+ }
+ }
+
return true;
}
@@ -6961,21 +6977,27 @@ TWindowSpecificationPtr TSqlTranslation::WindowSpecification(const TRule_window_
winSpecPtr->Frame->FrameType = EFrameType::FrameByRows;
winSpecPtr->Frame->FrameExclusion = EFrameExclusions::FrameExclNone;
+ // BETWEEN UNBOUNDED PRECEDING AND ...
winSpecPtr->Frame->FrameBegin = new TFrameBound;
winSpecPtr->Frame->FrameBegin->Settings = EFrameSettings::FramePreceding;
const bool ordered = !winSpecPtr->OrderBy.empty();
winSpecPtr->Frame->FrameEnd = new TFrameBound;
+ winSpecPtr->Frame->FrameBegin->Pos = winSpecPtr->Frame->FrameEnd->Pos = Ctx.Pos();
if (ordered) {
- // ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameCurrentRow;
+ if (Ctx.AnsiCurrentRow) {
+ // RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+ // We emit FrameByRows here, but FrameCurrentRow works specially for ROWS
+ winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameCurrentRow;
+ } else {
+ // ROWS BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING
+ winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameFollowing;
+ winSpecPtr->Frame->FrameEnd->Bound = new TLiteralNumberNode<i32>(Ctx.Pos(), "Int32", "0");
+ }
} else {
// ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameFollowing;
}
-
- // TODO: According to standard this should be RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW with order by clause
- // TODO: and RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING without order by
}
return winSpecPtr;
}
@@ -9575,6 +9597,12 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
} else if (normalizedPragma == "disableflexibletypes") {
Ctx.FlexibleTypes = false;
Ctx.IncrementMonCounter("sql_pragma", "DisableFlexibleTypes");
+ } else if (normalizedPragma == "ansicurrentrow") {
+ Ctx.AnsiCurrentRow = true;
+ Ctx.IncrementMonCounter("sql_pragma", "AnsiCurrentRow");
+ } else if (normalizedPragma == "disableansicurrentrow") {
+ Ctx.AnsiCurrentRow = false;
+ Ctx.IncrementMonCounter("sql_pragma", "DisableAnsiCurrentRow");
} else {
Error() << "Unknown pragma: " << pragma;
Ctx.IncrementMonCounter("sql_errors", "UnknownPragma");