diff options
author | aneporada <[email protected]> | 2022-02-14 00:49:52 +0300 |
---|---|---|
committer | aneporada <[email protected]> | 2022-02-14 00:49:52 +0300 |
commit | 2e3663422353da95615fec18d1aa32fa7b6e9edf (patch) | |
tree | 8dc96e9600af2ffb04e70c5683d1e096a0024093 | |
parent | 82cfd1b7cab2d843cdf5467d9737f72597a493bd (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.cpp | 1 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/context.h | 2 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/node.cpp | 10 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/sql.cpp | 38 |
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"); |