aboutsummaryrefslogtreecommitdiffstats
path: root/yql
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2025-04-18 04:38:27 +0000
committerAlexander Smirnov <alex@ydb.tech>2025-04-18 04:38:27 +0000
commit7ffed5509ed1a1b5633adacf4368ef034e48660e (patch)
tree2e742ad254cf199d620fdd75cb984f4115165b3f /yql
parent332dc5ddfae67b6af527d54cd25a1971d8d78147 (diff)
parent5d15e3b0913f6b537a7940a584fe1347e8551c93 (diff)
downloadydb-7ffed5509ed1a1b5633adacf4368ef034e48660e.tar.gz
Merge pull request #17385 from ydb-platform/merge-libs-250418-0050
Diffstat (limited to 'yql')
-rw-r--r--yql/essentials/core/common_opt/yql_co_flow2.cpp95
-rw-r--r--yql/essentials/core/peephole_opt/yql_opt_peephole_physical.cpp69
-rw-r--r--yql/essentials/core/yql_expr_constraint.cpp18
-rw-r--r--yql/essentials/core/yql_join.cpp33
-rw-r--r--yql/essentials/core/yql_join.h2
-rw-r--r--yql/essentials/core/yql_type_annotation.h1
-rw-r--r--yql/essentials/data/language/pragmas_opensource.json2
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_condense.cpp2
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_condense1.cpp2
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_flatmap.cpp2
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_multimap.cpp10
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_squeeze_to_list.cpp2
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_todict.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_todict_ut.cpp8
-rw-r--r--yql/essentials/sql/v1/context.cpp5
-rw-r--r--yql/essentials/sql/v1/context.h1
-rw-r--r--yql/essentials/sql/v1/select.cpp12
-rw-r--r--yql/essentials/sql/v1/sql_query.cpp6
-rw-r--r--yql/essentials/tests/common/test_framework/test_file_common.py11
-rw-r--r--yql/essentials/tests/common/test_framework/test_utils.py1
-rw-r--r--yql/essentials/tests/common/test_framework/yql_utils.py7
-rw-r--r--yql/essentials/tests/common/test_framework/yqlrun.py8
-rw-r--r--yql/essentials/tests/s-expressions/minirun/pure.py12
-rw-r--r--yql/essentials/tests/sql/minirun/part5/canondata/result.json28
-rw-r--r--yql/essentials/tests/sql/minirun/part6/canondata/result.json14
-rw-r--r--yql/essentials/tests/sql/minirun/part7/canondata/result.json12
-rw-r--r--yql/essentials/tests/sql/minirun/pure.py16
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/result.json42
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_aggregate-group_by_expr_after_where_/formatted.sql13
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_aggregate-group_by_expr_after_where_ver_/formatted.sql11
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_join-prune_keys_/formatted.sql238
-rw-r--r--yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_select-prune_keys_/formatted.sql8
-rw-r--r--yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where.sql4
-rw-r--r--yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where_ver.cfg1
-rw-r--r--yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where_ver.sql3
-rw-r--r--yql/essentials/tests/sql/suites/join/prune_keys.sql50
-rw-r--r--yql/essentials/tests/sql/suites/select/prune_keys.sql3
37 files changed, 699 insertions, 57 deletions
diff --git a/yql/essentials/core/common_opt/yql_co_flow2.cpp b/yql/essentials/core/common_opt/yql_co_flow2.cpp
index 7d521b2ac47..8ebb5243ffa 100644
--- a/yql/essentials/core/common_opt/yql_co_flow2.cpp
+++ b/yql/essentials/core/common_opt/yql_co_flow2.cpp
@@ -2027,7 +2027,100 @@ void RegisterCoFlowCallables2(TCallableOptimizerMap& map) {
return ret;
}
- return node;
+ // Add PruneKeys to EquiJoin
+ static const char optName[] = "EmitPruneKeys";
+ if (!IsOptimizerEnabled<optName>(*optCtx.Types) || IsOptimizerDisabled<optName>(*optCtx.Types)) {
+ return node;
+ }
+ auto equiJoin = TCoEquiJoin(node);
+ if (HasSetting(equiJoin.Arg(equiJoin.ArgCount() - 1).Ref(), "prune_keys_added")) {
+ return node;
+ }
+
+ THashMap<TStringBuf, THashSet<TStringBuf>> columnsForPruneKeysExtractor;
+ GetPruneKeysColumnsForJoinLeaves(equiJoin.Arg(equiJoin.ArgCount() - 2).Cast<TCoEquiJoinTuple>(), columnsForPruneKeysExtractor);
+
+ TExprNode::TListType children;
+ bool hasChanges = false;
+ for (size_t i = 0; i + 2 < equiJoin.ArgCount(); ++i) {
+ auto child = equiJoin.Arg(i).Cast<TCoEquiJoinInput>();
+ auto list = child.List();
+ auto scope = child.Scope();
+
+ if (!scope.Ref().IsAtom()) {
+ children.push_back(equiJoin.Arg(i).Ptr());
+ continue;
+ }
+
+ auto itemNames = columnsForPruneKeysExtractor.find(scope.Ref().Content());
+ if (itemNames == columnsForPruneKeysExtractor.end() || itemNames->second.empty()) {
+ children.push_back(equiJoin.Arg(i).Ptr());
+ continue;
+ }
+
+ if (auto distinct = list.Ref().GetConstraint<TDistinctConstraintNode>()) {
+ if (distinct->ContainsCompleteSet(std::vector<std::string_view>(itemNames->second.cbegin(), itemNames->second.cend()))) {
+ children.push_back(equiJoin.Arg(i).Ptr());
+ continue;
+ }
+ }
+
+ bool isOrdered = false;
+ if (auto sorted = list.Ref().GetConstraint<TSortedConstraintNode>()) {
+ for (const auto& item : sorted->GetContent()) {
+ size_t foundItemNamesCount = 0;
+ for (const auto& path : item.first) {
+ if (itemNames->second.contains(path.front())) {
+ foundItemNamesCount++;
+ }
+ }
+ if (foundItemNamesCount == itemNames->second.size()) {
+ isOrdered = true;
+ break;
+ }
+ }
+ }
+
+ auto pruneKeysCallable = isOrdered ? "PruneAdjacentKeys" : "PruneKeys";
+ YQL_CLOG(DEBUG, Core) << "Add " << pruneKeysCallable << " to EquiJoin input #" << i << ", label " << scope.Ref().Content();
+ children.push_back(ctx.Builder(child.Pos())
+ .List()
+ .Callable(0, pruneKeysCallable)
+ .Add(0, list.Ptr())
+ .Lambda(1)
+ .Param("item")
+ .List(0)
+ .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder & {
+ ui32 i = 0;
+ for (const auto& column : itemNames->second) {
+ parent.Callable(i++, "Member")
+ .Arg(0, "item")
+ .Atom(1, column)
+ .Seal();
+ }
+ return parent;
+ })
+ .Seal()
+ .Seal()
+ .Seal()
+ .Add(1, scope.Ptr())
+ .Seal()
+ .Build());
+ hasChanges = true;
+ }
+
+ if (!hasChanges) {
+ return node;
+ }
+
+ children.push_back(equiJoin.Arg(equiJoin.ArgCount() - 2).Ptr());
+ children.push_back(AddSetting(
+ equiJoin.Arg(equiJoin.ArgCount() - 1).Ref(),
+ equiJoin.Arg(equiJoin.ArgCount() - 1).Pos(),
+ "prune_keys_added",
+ nullptr,
+ ctx));
+ return ctx.ChangeChildren(*node, std::move(children));
};
map["ExtractMembers"] = [](const TExprNode::TPtr& node, TExprContext& ctx, TOptimizeContext& optCtx) {
diff --git a/yql/essentials/core/peephole_opt/yql_opt_peephole_physical.cpp b/yql/essentials/core/peephole_opt/yql_opt_peephole_physical.cpp
index 5755bf1dbf5..28ee1ead8f5 100644
--- a/yql/essentials/core/peephole_opt/yql_opt_peephole_physical.cpp
+++ b/yql/essentials/core/peephole_opt/yql_opt_peephole_physical.cpp
@@ -2760,19 +2760,11 @@ TExprNode::TPtr ExpandListHas(const TExprNode::TPtr& input, TExprContext& ctx) {
return RewriteSearchByKeyForTypesMismatch<true, true>(input, ctx);
}
-TExprNode::TPtr ExpandPruneAdjacentKeys(const TExprNode::TPtr& input, TExprContext& ctx) {
- const auto type = input->Head().GetTypeAnn();
- const auto& keyExtractorLambda = input->ChildRef(1);
-
- YQL_ENSURE(type->GetKind() == ETypeAnnotationKind::List || type->GetKind() == ETypeAnnotationKind::Stream);
-
- const auto elemType = type->GetKind() == ETypeAnnotationKind::List
- ? type->Cast<TListExprType>()->GetItemType()
- : type->Cast<TStreamExprType>()->GetItemType();
- const auto optionalElemType = *ctx.MakeType<TOptionalExprType>(elemType);
+TExprNode::TPtr ExpandPruneAdjacentKeys(const TExprNode::TPtr& input, TExprContext& ctx, TTypeAnnotationContext& /*typesCtx*/) {
+ const auto& keyExtractorLambda = input->ChildPtr(1);
YQL_CLOG(DEBUG, CorePeepHole) << "Expand " << input->Content();
- return ctx.Builder(input->Pos())
+ return KeepConstraints(ctx.Builder(input->Pos())
.Callable("OrderedFlatMap")
.Callable(0, "Fold1Map")
.Add(0, input->HeadPtr())
@@ -2799,7 +2791,11 @@ TExprNode::TPtr ExpandPruneAdjacentKeys(const TExprNode::TPtr& input, TExprConte
.Seal()
.Seal()
.Callable(1, "Nothing")
- .Add(0, ExpandType(input->Pos(), optionalElemType, ctx))
+ .Callable(0, "OptionalType")
+ .Callable(0, "TypeOf")
+ .Arg(0, "item")
+ .Seal()
+ .Seal()
.Seal()
.Callable(2, "Just")
.Arg(0, "item")
@@ -2814,13 +2810,16 @@ TExprNode::TPtr ExpandPruneAdjacentKeys(const TExprNode::TPtr& input, TExprConte
.Arg(0, "item")
.Seal()
.Seal()
- .Build();
+ .Build(), *input, ctx);
}
-TExprNode::TPtr ExpandPruneKeys(const TExprNode::TPtr& input, TExprContext& ctx) {
+TExprNode::TPtr ExpandPruneKeys(const TExprNode::TPtr& input, TExprContext& ctx, TTypeAnnotationContext& typesCtx) {
const auto type = input->Head().GetTypeAnn();
- const auto& keyExtractorLambda = input->ChildRef(1);
- YQL_ENSURE(type->GetKind() == ETypeAnnotationKind::List || type->GetKind() == ETypeAnnotationKind::Stream);
+ auto keyExtractorLambda = input->ChildPtr(1);
+
+ YQL_ENSURE(type->GetKind() == ETypeAnnotationKind::Flow
+ || type->GetKind() == ETypeAnnotationKind::List
+ || type->GetKind() == ETypeAnnotationKind::Stream);
auto initHandler = ctx.Builder(input->Pos())
.Lambda()
@@ -2865,6 +2864,39 @@ TExprNode::TPtr ExpandPruneKeys(const TExprNode::TPtr& input, TExprContext& ctx)
.Seal()
.Build();
} else {
+ // Slight copy of GetDictionaryKeyTypes to check if keyExtractorLambda result type is complicated
+ // mkql CombineCore supports only simple types; for others we should add pickling
+ bool keyExtractorLambdaShouldBePickled = false;
+ auto itemType = keyExtractorLambda->GetTypeAnn();
+ if (itemType->GetKind() == ETypeAnnotationKind::Optional) {
+ itemType = itemType->Cast<TOptionalExprType>()->GetItemType();
+ }
+
+ if (itemType->GetKind() == ETypeAnnotationKind::Tuple) {
+ auto tuple = itemType->Cast<TTupleExprType>();
+ for (const auto& item : tuple->GetItems()) {
+ if (!IsDataOrOptionalOfData(item)) {
+ keyExtractorLambdaShouldBePickled = true;
+ break;
+ }
+ }
+ } else if (itemType->GetKind() != ETypeAnnotationKind::Data) {
+ keyExtractorLambdaShouldBePickled = true;
+ }
+
+ if (keyExtractorLambdaShouldBePickled) {
+ keyExtractorLambda = ctx.Builder(input->Pos())
+ .Lambda()
+ .Param("item")
+ .Callable(0, "StablePickle")
+ .Apply(0, keyExtractorLambda)
+ .With(0, "item")
+ .Seal()
+ .Seal()
+ .Seal()
+ .Build();
+ }
+
return ctx.Builder(input->Pos())
.Callable("CombineCore")
.Add(0, input->HeadPtr())
@@ -2872,6 +2904,7 @@ TExprNode::TPtr ExpandPruneKeys(const TExprNode::TPtr& input, TExprContext& ctx)
.Add(2, initHandler)
.Add(3, updateHandler)
.Add(4, finishHandler)
+ .Atom(5, ToString(typesCtx.PruneKeysMemLimit))
.Seal()
.Build();
}
@@ -8906,8 +8939,6 @@ struct TPeepHoleRules {
{"CheckedDiv", &ExpandCheckedDiv},
{"CheckedMod", &ExpandCheckedMod},
{"CheckedMinus", &ExpandCheckedMinus},
- {"PruneAdjacentKeys", &ExpandPruneAdjacentKeys},
- {"PruneKeys", &ExpandPruneKeys},
{"JsonValue", &ExpandJsonValue},
{"JsonExists", &ExpandJsonExists},
{"EmptyIterator", &DropDependsOnFromEmptyIterator},
@@ -8926,6 +8957,8 @@ struct TPeepHoleRules {
{"CostsOf", &ExpandCostsOf},
{"JsonQuery", &ExpandJsonQuery},
{"MatchRecognize", &ExpandMatchRecognize},
+ {"PruneAdjacentKeys", &ExpandPruneAdjacentKeys},
+ {"PruneKeys", &ExpandPruneKeys},
{"CalcOverWindow", &ExpandCalcOverWindow},
{"CalcOverSessionWindow", &ExpandCalcOverWindow},
{"CalcOverWindowGroup", &ExpandCalcOverWindow},
diff --git a/yql/essentials/core/yql_expr_constraint.cpp b/yql/essentials/core/yql_expr_constraint.cpp
index e67557d9645..7fcf560a2cf 100644
--- a/yql/essentials/core/yql_expr_constraint.cpp
+++ b/yql/essentials/core/yql_expr_constraint.cpp
@@ -822,9 +822,23 @@ private:
}
if constexpr (Adjacent) {
- return CopyAllFrom<0>(input, output, ctx);
+ if (const auto status = CopyAllFrom<0>(input, output, ctx); status != TStatus::Ok) {
+ return status;
+ }
+
+ TPartOfConstraintBase::TSetType keys = GetPathsToKeys<true>(input->Child(1)->Tail(), input->Child(1)->Head().Head());
+ TPartOfConstraintBase::TSetOfSetsType uniqueKeys;
+ for (const auto& elem : keys) {
+ uniqueKeys.insert(TPartOfConstraintBase::TSetType{elem});
+ }
+ if (!keys.empty()) {
+ input->AddConstraint(ctx.MakeConstraint<TUniqueConstraintNode>(TUniqueConstraintNode::TContentType{uniqueKeys}));
+ input->AddConstraint(ctx.MakeConstraint<TDistinctConstraintNode>(TDistinctConstraintNode::TContentType{uniqueKeys}));
+ }
+ return TStatus::Ok;
}
- return FromFirst<TEmptyConstraintNode, TUniqueConstraintNode, TPartOfUniqueConstraintNode, TDistinctConstraintNode, TPartOfDistinctConstraintNode>(input, output, ctx);
+
+ return FromFirst<TEmptyConstraintNode>(input, output, ctx);
}
template<class TConstraint>
diff --git a/yql/essentials/core/yql_join.cpp b/yql/essentials/core/yql_join.cpp
index 7cca45604d1..5ce3fba268b 100644
--- a/yql/essentials/core/yql_join.cpp
+++ b/yql/essentials/core/yql_join.cpp
@@ -820,6 +820,10 @@ IGraphTransformer::TStatus ValidateEquiJoinOptions(TPositionHandle positionHandl
// do nothing
} else if (optionName == "multiple_joins") {
// do nothing
+ } else if (optionName == "prune_keys_added") {
+ if (!EnsureTupleSize(*child, 1, ctx)) {
+ return IGraphTransformer::TStatus::Error;
+ }
} else {
YQL_ENSURE(false, "Cached join option '" << optionName << "' not handled");
}
@@ -2007,7 +2011,7 @@ void GatherJoinInputs(const TExprNode::TPtr& expr, const TExprNode& row,
}
bool IsCachedJoinOption(TStringBuf name) {
- static THashSet<TStringBuf> CachedJoinOptions = {"preferred_sort", "cbo_passed", "multiple_joins"};
+ static THashSet<TStringBuf> CachedJoinOptions = {"preferred_sort", "cbo_passed", "multiple_joins", "prune_keys_added"};
return CachedJoinOptions.contains(name);
}
@@ -2016,4 +2020,31 @@ bool IsCachedJoinLinkOption(TStringBuf name) {
return CachedJoinLinkOptions.contains(name);
}
+void GetPruneKeysColumnsForJoinLeaves(const TCoEquiJoinTuple& joinTree, THashMap<TStringBuf, THashSet<TStringBuf>>& columnsForPruneKeysExtractor) {
+ auto settings = GetEquiJoinLinkSettings(joinTree.Options().Ref());
+ TStringBuf joinKind = joinTree.Type().Value();
+
+ auto left = joinTree.LeftScope();
+ if (!left.Maybe<TCoAtom>()) {
+ GetPruneKeysColumnsForJoinLeaves(left.Cast<TCoEquiJoinTuple>(), columnsForPruneKeysExtractor);
+ } else {
+ if (joinKind == "RightSemi" || joinKind == "RightOnly" || settings.LeftHints.contains("any")) {
+ if (!settings.LeftHints.contains("unique")) {
+ CollectEquiJoinKeyColumnsFromLeaf(joinTree.LeftKeys().Ref(), columnsForPruneKeysExtractor);
+ }
+ }
+ }
+
+ auto right = joinTree.RightScope();
+ if (!right.Maybe<TCoAtom>()) {
+ GetPruneKeysColumnsForJoinLeaves(right.Cast<TCoEquiJoinTuple>(), columnsForPruneKeysExtractor);
+ } else {
+ if (joinKind == "LeftSemi" || joinKind == "LeftOnly" || settings.RightHints.contains("any")) {
+ if (!settings.RightHints.contains("unique")) {
+ CollectEquiJoinKeyColumnsFromLeaf(joinTree.RightKeys().Ref(), columnsForPruneKeysExtractor);
+ }
+ }
+ }
+}
+
} // namespace NYql
diff --git a/yql/essentials/core/yql_join.h b/yql/essentials/core/yql_join.h
index a313aceefa3..26b417cf542 100644
--- a/yql/essentials/core/yql_join.h
+++ b/yql/essentials/core/yql_join.h
@@ -180,4 +180,6 @@ void GatherJoinInputs(const TExprNode::TPtr& expr, const TExprNode& row,
bool IsCachedJoinOption(TStringBuf name);
bool IsCachedJoinLinkOption(TStringBuf name);
+void GetPruneKeysColumnsForJoinLeaves(const NNodes::TCoEquiJoinTuple& joinTree, THashMap<TStringBuf, THashSet<TStringBuf>>& columnsForPruneKeysExtractor);
+
}
diff --git a/yql/essentials/core/yql_type_annotation.h b/yql/essentials/core/yql_type_annotation.h
index bc09c963f4b..a43650a01f4 100644
--- a/yql/essentials/core/yql_type_annotation.h
+++ b/yql/essentials/core/yql_type_annotation.h
@@ -452,6 +452,7 @@ struct TTypeAnnotationContext: public TThrRefBase {
THashSet<TString> PeepholeFlags;
bool StreamLookupJoin = false;
ui32 MaxAggPushdownPredicates = 6; // algorithm complexity is O(2^N)
+ ui32 PruneKeysMemLimit = 128 * 1024 * 1024;
TMaybe<TColumnOrder> LookupColumnOrder(const TExprNode& node) const;
IGraphTransformer::TStatus SetColumnOrder(const TExprNode& node, const TColumnOrder& columnOrder, TExprContext& ctx);
diff --git a/yql/essentials/data/language/pragmas_opensource.json b/yql/essentials/data/language/pragmas_opensource.json
index 26cc1c777a0..a4a3ad73364 100644
--- a/yql/essentials/data/language/pragmas_opensource.json
+++ b/yql/essentials/data/language/pragmas_opensource.json
@@ -1 +1 @@
-[{"name":"yt.Annotations"},{"name":"yt.ApplyStoredConstraints"},{"name":"yt.Auth"},{"name":"yt.AutoMerge"},{"name":"yt.BatchListFolderConcurrency"},{"name":"yt.BinaryExpirationInterval"},{"name":"yt.BinaryTmpFolder"},{"name":"yt.BlockMapJoin"},{"name":"yt.BlockReaderSupportedDataTypes"},{"name":"yt.BlockReaderSupportedTypes"},{"name":"yt.BufferRowCount"},{"name":"yt.ClientMapTimeout"},{"name":"yt.ColumnGroupMode"},{"name":"yt.CombineCoreLimit"},{"name":"yt.CommonJoinCoreLimit"},{"name":"yt.CompactForDistinct"},{"name":"yt.CoreDumpPath"},{"name":"yt.DQRPCReaderInflight"},{"name":"yt.DQRPCReaderTimeout"},{"name":"yt.DataSizePerJob"},{"name":"yt.DataSizePerMapJob"},{"name":"yt.DataSizePerPartition"},{"name":"yt.DataSizePerSortJob"},{"name":"yt.DefaultCalcMemoryLimit"},{"name":"yt.DefaultCluster"},{"name":"yt.DefaultLocalityTimeout"},{"name":"yt.DefaultMapSelectivityFactor"},{"name":"yt.DefaultMaxJobFails"},{"name":"yt.DefaultMemoryDigestLowerBound"},{"name":"yt.DefaultMemoryLimit"},{"name":"yt.DefaultMemoryReserveFactor"},{"name":"yt.DefaultOperationWeight"},{"name":"yt.DefaultRuntimeCluster"},{"name":"yt.Description"},{"name":"yt.DisableFuseOperations"},{"name":"yt.DisableJobSplitting"},{"name":"yt.DisableOptimizers"},{"name":"yt.DockerImage"},{"name":"yt.DqPruneKeyFilterLambda"},{"name":"yt.DropUnusedKeysFromKeyFilter"},{"name":"yt.EnableDynamicStoreReadInDQ"},{"name":"yt.EnableFuseMapToMapReduce"},{"name":"yt.EnforceJobUtc"},{"name":"yt.ErasureCodecCpu"},{"name":"yt.ErasureCodecCpuForDq"},{"name":"yt.EvaluationTableSizeLimit"},{"name":"yt.ExpirationDeadline"},{"name":"yt.ExpirationInterval"},{"name":"yt.ExtendTableLimit"},{"name":"yt.ExtendedStatsMaxChunkCount"},{"name":"yt.ExternalTx"},{"name":"yt.ExtraTmpfsSize"},{"name":"yt.FileCacheTtl"},{"name":"yt.FmrOperationSpec"},{"name":"yt.FolderInlineDataLimit"},{"name":"yt.FolderInlineItemsLimit"},{"name":"yt.ForceInferSchema"},{"name":"yt.ForceJobSizeAdjuster"},{"name":"yt.ForceTmpSecurity"},{"name":"yt.GeobaseDownloadUrl"},{"name":"yt.HybridDqDataSizeLimitForOrdered"},{"name":"yt.HybridDqDataSizeLimitForUnordered"},{"name":"yt.HybridDqExecution"},{"name":"yt.HybridDqExecutionFallback"},{"name":"yt.IgnoreTypeV3"},{"name":"yt.IgnoreWeakSchema"},{"name":"yt.IgnoreYamrDsv"},{"name":"yt.InferSchema"},{"name":"yt.InferSchemaMode"},{"name":"yt.InferSchemaTableCountThreshold"},{"name":"yt.InflightTempTablesLimit"},{"name":"yt.IntermediateAccount"},{"name":"yt.IntermediateDataMedium"},{"name":"yt.IntermediateReplicationFactor"},{"name":"yt.JavascriptCpu"},{"name":"yt.JobBlockInput"},{"name":"yt.JobBlockInputSupportedDataTypes"},{"name":"yt.JobBlockInputSupportedTypes"},{"name":"yt.JobBlockOutput"},{"name":"yt.JobBlockOutputSupportedDataTypes"},{"name":"yt.JobBlockOutputSupportedTypes"},{"name":"yt.JobBlockTableContent"},{"name":"yt.JobEnv"},{"name":"yt.JoinAllowColumnRenames"},{"name":"yt.JoinCollectColumnarStatistics"},{"name":"yt.JoinColumnarStatisticsFetcherMode"},{"name":"yt.JoinCommonUseMapMultiOut"},{"name":"yt.JoinEnableStarJoin"},{"name":"yt.JoinMergeForce"},{"name":"yt.JoinMergeReduceJobMaxSize"},{"name":"yt.JoinMergeSetTopLevelFullSort"},{"name":"yt.JoinMergeTablesLimit"},{"name":"yt.JoinMergeUnsortedFactor"},{"name":"yt.JoinMergeUseSmallAsPrimary"},{"name":"yt.JoinUseColumnarStatistics"},{"name":"yt.JoinWaitAllInputs"},{"name":"yt.KeepTempTables"},{"name":"yt.KeyFilterForStartsWith"},{"name":"yt.LLVMMemSize"},{"name":"yt.LLVMNodeCountLimit"},{"name":"yt.LLVMPerNodeMemSize"},{"name":"yt.LayerPaths"},{"name":"yt.LocalCalcLimit"},{"name":"yt.LookupJoinLimit"},{"name":"yt.LookupJoinMaxRows"},{"name":"yt.MapJoinLimit"},{"name":"yt.MapJoinShardCount"},{"name":"yt.MapJoinShardMinRows"},{"name":"yt.MapJoinUseFlow"},{"name":"yt.MapLocalityTimeout"},{"name":"yt.MaxChunksForDqRead"},{"name":"yt.MaxColumnGroups"},{"name":"yt.MaxCpuUsageToFuseMultiOuts"},{"name":"yt.MaxExtraJobMemoryToFuseOperations"},{"name":"yt.MaxInputTables"},{"name":"yt.MaxInputTablesForSortedMerge"},{"name":"yt.MaxJobCount"},{"name":"yt.MaxKeyRangeCount"},{"name":"yt.MaxKeyWeight"},{"name":"yt.MaxOperationFiles"},{"name":"yt.MaxOutputTables"},{"name":"yt.MaxReplicationFactorToFuseMultiOuts"},{"name":"yt.MaxReplicationFactorToFuseOperations"},{"name":"yt.MaxRowWeight"},{"name":"yt.MaxSpeculativeJobCountPerTask"},{"name":"yt.MergeAdjacentPointRanges"},{"name":"yt.MinColumnGroupSize"},{"name":"yt.MinLocalityInputDataWeight"},{"name":"yt.MinPublishedAvgChunkSize"},{"name":"yt.MinTempAvgChunkSize"},{"name":"yt.NativeYtTypeCompatibility"},{"name":"yt.NetworkProject"},{"name":"yt.NightlyCompress"},{"name":"yt.OperationReaders"},{"name":"yt.OperationSpec"},{"name":"yt.OptimizeFor"},{"name":"yt.Owners"},{"name":"yt.ParallelOperationsLimit"},{"name":"yt.PartitionByConstantKeysViaMap"},{"name":"yt.Pool"},{"name":"yt.PoolTrees"},{"name":"yt.PrimaryMedium"},{"name":"yt.PruneKeyFilterLambda"},{"name":"yt.PruneQLFilterLambda"},{"name":"yt.PublishedAutoMerge"},{"name":"yt.PublishedCompressionCodec"},{"name":"yt.PublishedErasureCodec"},{"name":"yt.PublishedMedia"},{"name":"yt.PublishedPrimaryMedium"},{"name":"yt.PublishedReplicationFactor"},{"name":"yt.PythonCpu"},{"name":"yt.QueryCacheChunkLimit"},{"name":"yt.QueryCacheIgnoreTableRevision"},{"name":"yt.QueryCacheMode"},{"name":"yt.QueryCacheSalt"},{"name":"yt.QueryCacheTtl"},{"name":"yt.QueryCacheUseExpirationTimeout"},{"name":"yt.QueryCacheUseForCalc"},{"name":"yt.ReduceLocalityTimeout"},{"name":"yt.ReleaseTempData"},{"name":"yt.ReportEquiJoinStats"},{"name":"yt.RuntimeCluster"},{"name":"yt.RuntimeClusterSelection"},{"name":"yt.SamplingIoBlockSize"},{"name":"yt.SchedulingTag"},{"name":"yt.SchedulingTagFilter"},{"name":"yt.ScriptCpu"},{"name":"yt.SortLocalityTimeout"},{"name":"yt.StartedBy"},{"name":"yt.StaticPool"},{"name":"yt.SuspendIfAccountLimitExceeded"},{"name":"yt.SwitchLimit"},{"name":"yt.TableContentColumnarStatistics"},{"name":"yt.TableContentCompressLevel"},{"name":"yt.TableContentDeliveryMode"},{"name":"yt.TableContentLocalExecution"},{"name":"yt.TableContentMaxChunksForNativeDelivery"},{"name":"yt.TableContentMaxInputTables"},{"name":"yt.TableContentMinAvgChunkSize"},{"name":"yt.TableContentTmpFolder"},{"name":"yt.TableContentUseSkiff"},{"name":"yt.TablesTmpFolder"},{"name":"yt.TempTablesTtl"},{"name":"yt.TemporaryAutoMerge"},{"name":"yt.TemporaryCompressionCodec"},{"name":"yt.TemporaryErasureCodec"},{"name":"yt.TemporaryMedia"},{"name":"yt.TemporaryPrimaryMedium"},{"name":"yt.TemporaryReplicationFactor"},{"name":"yt.TentativePoolTrees"},{"name":"yt.TentativeTreeEligibilityMaxJobDurationRatio"},{"name":"yt.TentativeTreeEligibilityMinJobDuration"},{"name":"yt.TentativeTreeEligibilitySampleJobCount"},{"name":"yt.TmpFolder"},{"name":"yt.TopSortMaxLimit"},{"name":"yt.TopSortRowMultiplierPerJob"},{"name":"yt.TopSortSizePerJob"},{"name":"yt.UseAggPhases"},{"name":"yt.UseColumnGroupsFromInputTables"},{"name":"yt.UseColumnarStatistics"},{"name":"yt.UseDefaultTentativePoolTrees"},{"name":"yt.UseFlow"},{"name":"yt.UseIntermediateSchema"},{"name":"yt.UseIntermediateStreams"},{"name":"yt.UseNativeDescSort"},{"name":"yt.UseNativeYtTypes"},{"name":"yt.UseNewPredicateExtraction"},{"name":"yt.UsePartitionsByKeysForFinalAgg"},{"name":"yt.UseQLFilter"},{"name":"yt.UseRPCReaderInDQ"},{"name":"yt.UseSkiff"},{"name":"yt.UseSystemColumns"},{"name":"yt.UseTmpfs"},{"name":"yt.UseTypeV2"},{"name":"yt.UseYqlRowSpecCompactForm"},{"name":"yt.UserSlots"},{"name":"yt.ViewIsolation"},{"name":"yt.WideFlowLimit"},{"name":"dq.AggregateStatsByStage"},{"name":"dq.AnalyticsHopping"},{"name":"dq.AnalyzeQuery"},{"name":"dq.ChannelBufferSize"},{"name":"dq.ChunkSizeLimit"},{"name":"dq.CollectCoreDumps"},{"name":"dq.ComputeActorType"},{"name":"dq.DataSizePerJob"},{"name":"dq.DisableCheckpoints"},{"name":"dq.DisableLLVMForBlockStages"},{"name":"dq.EnableChannelStats"},{"name":"dq.EnableComputeActor"},{"name":"dq.EnableDqReplicate"},{"name":"dq.EnableFullResultWrite"},{"name":"dq.EnableInsert"},{"name":"dq.EnableSpillingInChannels"},{"name":"dq.EnableSpillingNodes"},{"name":"dq.EnableStrip"},{"name":"dq.ExportStats"},{"name":"dq.FallbackPolicy"},{"name":"dq.HashJoinMode"},{"name":"dq.HashShuffleMaxTasks"},{"name":"dq.HashShuffleTasksRatio"},{"name":"dq.MaxDataSizePerJob"},{"name":"dq.MaxDataSizePerQuery"},{"name":"dq.MaxNetworkRetries"},{"name":"dq.MaxRetries"},{"name":"dq.MaxTasksPerOperation"},{"name":"dq.MaxTasksPerStage"},{"name":"dq.MemoryLimit"},{"name":"dq.OptLLVM"},{"name":"dq.OutputChunkMaxSize"},{"name":"dq.ParallelOperationsLimit"},{"name":"dq.PingTimeoutMs"},{"name":"dq.PullRequestTimeoutMs"},{"name":"dq.QueryTimeout"},{"name":"dq.RetryBackoffMs"},{"name":"dq.Scheduler"},{"name":"dq.SpillingEngine"},{"name":"dq.SplitStageOnDqReplicate"},{"name":"dq.TaskRunnerStats"},{"name":"dq.UseAggPhases"},{"name":"dq.UseBlockReader"},{"name":"dq.UseFastPickleTransport"},{"name":"dq.UseFinalizeByKey"},{"name":"dq.UseGraceJoinCoreForMap"},{"name":"dq.UseOOBTransport"},{"name":"dq.UseSimpleYtReader"},{"name":"dq.UseWideBlockChannels"},{"name":"dq.UseWideChannels"},{"name":"dq.WatermarksEnableIdlePartitions"},{"name":"dq.WatermarksGranularityMs"},{"name":"dq.WatermarksLateArrivalDelayMs"},{"name":"dq.WatermarksMode"},{"name":"dq.WorkerFilter"},{"name":"dq.WorkersPerOperation"},{"name":"AllowDotInAlias"},{"name":"AllowUnnamedColumns"},{"name":"AnsiCurrentRow"},{"name":"AnsiImplicitCrossJoin"},{"name":"AnsiInForEmptyOrNullableItemsCollections"},{"name":"AnsiLike"},{"name":"AnsiOptionalAs"},{"name":"AnsiRankForNullableKeys"},{"name":"AutoCommit"},{"name":"BlockEngine"},{"name":"BlockEngineEnable"},{"name":"BlockEngineForce"},{"name":"BogousStarInGroupByOverJoin"},{"name":"CheckedOps"},{"name":"ClassicDivision"},{"name":"CoalesceJoinKeysOnQualifiedAll"},{"name":"CompactGroupBy"},{"name":"CompactNamedExprs"},{"name":"CostBasedOptimizer"},{"name":"DataWatermarks"},{"name":"DirectRead"},{"name":"DisableAnsiCurrentRow"},{"name":"DisableAnsiImplicitCrossJoin"},{"name":"DisableAnsiInForEmptyOrNullableItemsCollections"},{"name":"DisableAnsiLike"},{"name":"DisableAnsiOptionalAs"},{"name":"DisableAnsiRankForNullableKeys"},{"name":"DisableBlockEngineEnable"},{"name":"DisableBlockEngineForce"},{"name":"DisableBogousStarInGroupByOverJoin"},{"name":"DisableCoalesceJoinKeysOnQualifiedAll"},{"name":"DisableCompactGroupBy"},{"name":"DisableCompactNamedExprs"},{"name":"DisableDistinctOverKeys"},{"name":"DisableDistinctOverWindow"},{"name":"DisableDqEngineEnable"},{"name":"DisableDqEngineForce"},{"name":"DisableEmitAggApply"},{"name":"DisableEmitStartsWith"},{"name":"DisableEmitTableSource"},{"name":"DisableEmitUnionMerge"},{"name":"DisableFilterPushdownOverJoinOptionalSide"},{"name":"DisableFlexibleTypes"},{"name":"DisableJsonQueryReturnsJsonDocument"},{"name":"DisableOrderedColumns"},{"name":"DisablePullUpFlatMapOverJoin"},{"name":"DisableRegexUseRe2"},{"name":"DisableRotateJoinTree"},{"name":"DisableSeqMode"},{"name":"DisableSimpleColumns"},{"name":"DisableStrictJoinKeyTypes"},{"name":"DisableUnicodeLiterals"},{"name":"DisableUnorderedResult"},{"name":"DisableUnorderedSubqueries"},{"name":"DisableUseBlocks"},{"name":"DisableValidateUnusedExprs"},{"name":"DisableWarnOnAnsiAliasShadowing"},{"name":"DisableWarnUntypedStringLiterals"},{"name":"DiscoveryMode"},{"name":"DistinctOverKeys"},{"name":"DistinctOverWindow"},{"name":"DqEngine"},{"name":"DqEngineEnable"},{"name":"DqEngineForce"},{"name":"EmitAggApply"},{"name":"EmitStartsWith"},{"name":"EmitTableSource"},{"name":"EmitUnionMerge"},{"name":"EnableSystemColumns"},{"name":"Engine"},{"name":"ErrorMsg"},{"name":"FeatureR010"},{"name":"File"},{"name":"FileOption"},{"name":"FilterPushdownOverJoinOptionalSide"},{"name":"FlexibleTypes"},{"name":"Folder"},{"name":"Greetings"},{"name":"GroupByCubeLimit"},{"name":"GroupByLimit"},{"name":"JsonQueryReturnsJsonDocument"},{"name":"Library"},{"name":"OrderedColumns"},{"name":"OverrideLibrary"},{"name":"Package"},{"name":"PackageVersion"},{"name":"PathPrefix"},{"name":"PositionalUnionAll"},{"name":"PqReadBy"},{"name":"PullUpFlatMapOverJoin"},{"name":"RefSelect"},{"name":"RegexUseRe2"},{"name":"ResultRowsLimit"},{"name":"ResultSizeLimit"},{"name":"RotateJoinTree"},{"name":"RuntimeLogLevel"},{"name":"SampleSelect"},{"name":"SeqMode"},{"name":"SimpleColumns"},{"name":"StrictJoinKeyTypes"},{"name":"Udf"},{"name":"UnicodeLiterals"},{"name":"UnorderedResult"},{"name":"UnorderedSubqueries"},{"name":"UseBlocks"},{"name":"UseTablePrefixForEach"},{"name":"ValidateUnusedExprs"},{"name":"WarnOnAnsiAliasShadowing"},{"name":"WarnUnnamedColumns"},{"name":"WarnUntypedStringLiterals"},{"name":"Warning"},{"name":"WarningMsg"},{"name":"yson.AutoConvert"},{"name":"yson.CastToString"},{"name":"yson.DisableCastToString"},{"name":"yson.DisableStrict"},{"name":"yson.Strict"}]
+[{"name":"yt.Annotations"},{"name":"yt.ApplyStoredConstraints"},{"name":"yt.Auth"},{"name":"yt.AutoMerge"},{"name":"yt.BatchListFolderConcurrency"},{"name":"yt.BinaryExpirationInterval"},{"name":"yt.BinaryTmpFolder"},{"name":"yt.BlockMapJoin"},{"name":"yt.BlockReaderSupportedDataTypes"},{"name":"yt.BlockReaderSupportedTypes"},{"name":"yt.BufferRowCount"},{"name":"yt.ClientMapTimeout"},{"name":"yt.ColumnGroupMode"},{"name":"yt.CombineCoreLimit"},{"name":"yt.CommonJoinCoreLimit"},{"name":"yt.CompactForDistinct"},{"name":"yt.CoreDumpPath"},{"name":"yt.DQRPCReaderInflight"},{"name":"yt.DQRPCReaderTimeout"},{"name":"yt.DataSizePerJob"},{"name":"yt.DataSizePerMapJob"},{"name":"yt.DataSizePerPartition"},{"name":"yt.DataSizePerSortJob"},{"name":"yt.DefaultCalcMemoryLimit"},{"name":"yt.DefaultCluster"},{"name":"yt.DefaultLocalityTimeout"},{"name":"yt.DefaultMapSelectivityFactor"},{"name":"yt.DefaultMaxJobFails"},{"name":"yt.DefaultMemoryDigestLowerBound"},{"name":"yt.DefaultMemoryLimit"},{"name":"yt.DefaultMemoryReserveFactor"},{"name":"yt.DefaultOperationWeight"},{"name":"yt.DefaultRuntimeCluster"},{"name":"yt.Description"},{"name":"yt.DisableFuseOperations"},{"name":"yt.DisableJobSplitting"},{"name":"yt.DisableOptimizers"},{"name":"yt.DockerImage"},{"name":"yt.DqPruneKeyFilterLambda"},{"name":"yt.DropUnusedKeysFromKeyFilter"},{"name":"yt.EnableDynamicStoreReadInDQ"},{"name":"yt.EnableFuseMapToMapReduce"},{"name":"yt.EnforceJobUtc"},{"name":"yt.ErasureCodecCpu"},{"name":"yt.ErasureCodecCpuForDq"},{"name":"yt.EvaluationTableSizeLimit"},{"name":"yt.ExpirationDeadline"},{"name":"yt.ExpirationInterval"},{"name":"yt.ExtendTableLimit"},{"name":"yt.ExtendedStatsMaxChunkCount"},{"name":"yt.ExternalTx"},{"name":"yt.ExtraTmpfsSize"},{"name":"yt.FileCacheTtl"},{"name":"yt.FmrOperationSpec"},{"name":"yt.FolderInlineDataLimit"},{"name":"yt.FolderInlineItemsLimit"},{"name":"yt.ForceInferSchema"},{"name":"yt.ForceJobSizeAdjuster"},{"name":"yt.ForceTmpSecurity"},{"name":"yt.GeobaseDownloadUrl"},{"name":"yt.HybridDqDataSizeLimitForOrdered"},{"name":"yt.HybridDqDataSizeLimitForUnordered"},{"name":"yt.HybridDqExecution"},{"name":"yt.HybridDqExecutionFallback"},{"name":"yt.IgnoreTypeV3"},{"name":"yt.IgnoreWeakSchema"},{"name":"yt.IgnoreYamrDsv"},{"name":"yt.InferSchema"},{"name":"yt.InferSchemaMode"},{"name":"yt.InferSchemaTableCountThreshold"},{"name":"yt.InflightTempTablesLimit"},{"name":"yt.IntermediateAccount"},{"name":"yt.IntermediateDataMedium"},{"name":"yt.IntermediateReplicationFactor"},{"name":"yt.JavascriptCpu"},{"name":"yt.JobBlockInput"},{"name":"yt.JobBlockInputSupportedDataTypes"},{"name":"yt.JobBlockInputSupportedTypes"},{"name":"yt.JobBlockOutput"},{"name":"yt.JobBlockOutputSupportedDataTypes"},{"name":"yt.JobBlockOutputSupportedTypes"},{"name":"yt.JobBlockTableContent"},{"name":"yt.JobEnv"},{"name":"yt.JoinAllowColumnRenames"},{"name":"yt.JoinCollectColumnarStatistics"},{"name":"yt.JoinColumnarStatisticsFetcherMode"},{"name":"yt.JoinCommonUseMapMultiOut"},{"name":"yt.JoinEnableStarJoin"},{"name":"yt.JoinMergeForce"},{"name":"yt.JoinMergeReduceJobMaxSize"},{"name":"yt.JoinMergeSetTopLevelFullSort"},{"name":"yt.JoinMergeTablesLimit"},{"name":"yt.JoinMergeUnsortedFactor"},{"name":"yt.JoinMergeUseSmallAsPrimary"},{"name":"yt.JoinUseColumnarStatistics"},{"name":"yt.JoinWaitAllInputs"},{"name":"yt.KeepTempTables"},{"name":"yt.KeyFilterForStartsWith"},{"name":"yt.LLVMMemSize"},{"name":"yt.LLVMNodeCountLimit"},{"name":"yt.LLVMPerNodeMemSize"},{"name":"yt.LayerPaths"},{"name":"yt.LocalCalcLimit"},{"name":"yt.LookupJoinLimit"},{"name":"yt.LookupJoinMaxRows"},{"name":"yt.MapJoinLimit"},{"name":"yt.MapJoinShardCount"},{"name":"yt.MapJoinShardMinRows"},{"name":"yt.MapJoinUseFlow"},{"name":"yt.MapLocalityTimeout"},{"name":"yt.MaxChunksForDqRead"},{"name":"yt.MaxColumnGroups"},{"name":"yt.MaxCpuUsageToFuseMultiOuts"},{"name":"yt.MaxExtraJobMemoryToFuseOperations"},{"name":"yt.MaxInputTables"},{"name":"yt.MaxInputTablesForSortedMerge"},{"name":"yt.MaxJobCount"},{"name":"yt.MaxKeyRangeCount"},{"name":"yt.MaxKeyWeight"},{"name":"yt.MaxOperationFiles"},{"name":"yt.MaxOutputTables"},{"name":"yt.MaxReplicationFactorToFuseMultiOuts"},{"name":"yt.MaxReplicationFactorToFuseOperations"},{"name":"yt.MaxRowWeight"},{"name":"yt.MaxSpeculativeJobCountPerTask"},{"name":"yt.MergeAdjacentPointRanges"},{"name":"yt.MinColumnGroupSize"},{"name":"yt.MinLocalityInputDataWeight"},{"name":"yt.MinPublishedAvgChunkSize"},{"name":"yt.MinTempAvgChunkSize"},{"name":"yt.NativeYtTypeCompatibility"},{"name":"yt.NetworkProject"},{"name":"yt.NightlyCompress"},{"name":"yt.OperationReaders"},{"name":"yt.OperationSpec"},{"name":"yt.OptimizeFor"},{"name":"yt.Owners"},{"name":"yt.ParallelOperationsLimit"},{"name":"yt.PartitionByConstantKeysViaMap"},{"name":"yt.Pool"},{"name":"yt.PoolTrees"},{"name":"yt.PrimaryMedium"},{"name":"yt.PruneKeyFilterLambda"},{"name":"yt.PruneQLFilterLambda"},{"name":"yt.PublishedAutoMerge"},{"name":"yt.PublishedCompressionCodec"},{"name":"yt.PublishedErasureCodec"},{"name":"yt.PublishedMedia"},{"name":"yt.PublishedPrimaryMedium"},{"name":"yt.PublishedReplicationFactor"},{"name":"yt.PythonCpu"},{"name":"yt.QueryCacheChunkLimit"},{"name":"yt.QueryCacheIgnoreTableRevision"},{"name":"yt.QueryCacheMode"},{"name":"yt.QueryCacheSalt"},{"name":"yt.QueryCacheTtl"},{"name":"yt.QueryCacheUseExpirationTimeout"},{"name":"yt.QueryCacheUseForCalc"},{"name":"yt.ReduceLocalityTimeout"},{"name":"yt.ReleaseTempData"},{"name":"yt.ReportEquiJoinStats"},{"name":"yt.RuntimeCluster"},{"name":"yt.RuntimeClusterSelection"},{"name":"yt.SamplingIoBlockSize"},{"name":"yt.SchedulingTag"},{"name":"yt.SchedulingTagFilter"},{"name":"yt.ScriptCpu"},{"name":"yt.SortLocalityTimeout"},{"name":"yt.StartedBy"},{"name":"yt.StaticPool"},{"name":"yt.SuspendIfAccountLimitExceeded"},{"name":"yt.SwitchLimit"},{"name":"yt.TableContentColumnarStatistics"},{"name":"yt.TableContentCompressLevel"},{"name":"yt.TableContentDeliveryMode"},{"name":"yt.TableContentLocalExecution"},{"name":"yt.TableContentMaxChunksForNativeDelivery"},{"name":"yt.TableContentMaxInputTables"},{"name":"yt.TableContentMinAvgChunkSize"},{"name":"yt.TableContentTmpFolder"},{"name":"yt.TableContentUseSkiff"},{"name":"yt.TablesTmpFolder"},{"name":"yt.TempTablesTtl"},{"name":"yt.TemporaryAutoMerge"},{"name":"yt.TemporaryCompressionCodec"},{"name":"yt.TemporaryErasureCodec"},{"name":"yt.TemporaryMedia"},{"name":"yt.TemporaryPrimaryMedium"},{"name":"yt.TemporaryReplicationFactor"},{"name":"yt.TentativePoolTrees"},{"name":"yt.TentativeTreeEligibilityMaxJobDurationRatio"},{"name":"yt.TentativeTreeEligibilityMinJobDuration"},{"name":"yt.TentativeTreeEligibilitySampleJobCount"},{"name":"yt.TmpFolder"},{"name":"yt.TopSortMaxLimit"},{"name":"yt.TopSortRowMultiplierPerJob"},{"name":"yt.TopSortSizePerJob"},{"name":"yt.UseAggPhases"},{"name":"yt.UseColumnGroupsFromInputTables"},{"name":"yt.UseColumnarStatistics"},{"name":"yt.UseDefaultTentativePoolTrees"},{"name":"yt.UseFlow"},{"name":"yt.UseIntermediateSchema"},{"name":"yt.UseIntermediateStreams"},{"name":"yt.UseNativeDescSort"},{"name":"yt.UseNativeDynamicTableRead"},{"name":"yt.UseNativeYtTypes"},{"name":"yt.UseNewPredicateExtraction"},{"name":"yt.UsePartitionsByKeysForFinalAgg"},{"name":"yt.UseQLFilter"},{"name":"yt.UseRPCReaderInDQ"},{"name":"yt.UseSkiff"},{"name":"yt.UseSystemColumns"},{"name":"yt.UseTmpfs"},{"name":"yt.UseTypeV2"},{"name":"yt.UseYqlRowSpecCompactForm"},{"name":"yt.UserSlots"},{"name":"yt.ViewIsolation"},{"name":"yt.WideFlowLimit"},{"name":"dq.AggregateStatsByStage"},{"name":"dq.AnalyticsHopping"},{"name":"dq.AnalyzeQuery"},{"name":"dq.ChannelBufferSize"},{"name":"dq.ChunkSizeLimit"},{"name":"dq.CollectCoreDumps"},{"name":"dq.ComputeActorType"},{"name":"dq.DataSizePerJob"},{"name":"dq.DisableCheckpoints"},{"name":"dq.DisableLLVMForBlockStages"},{"name":"dq.EnableChannelStats"},{"name":"dq.EnableComputeActor"},{"name":"dq.EnableDqReplicate"},{"name":"dq.EnableFullResultWrite"},{"name":"dq.EnableInsert"},{"name":"dq.EnableSpillingInChannels"},{"name":"dq.EnableSpillingNodes"},{"name":"dq.EnableStrip"},{"name":"dq.ExportStats"},{"name":"dq.FallbackPolicy"},{"name":"dq.HashJoinMode"},{"name":"dq.HashShuffleMaxTasks"},{"name":"dq.HashShuffleTasksRatio"},{"name":"dq.MaxDataSizePerJob"},{"name":"dq.MaxDataSizePerQuery"},{"name":"dq.MaxNetworkRetries"},{"name":"dq.MaxRetries"},{"name":"dq.MaxTasksPerOperation"},{"name":"dq.MaxTasksPerStage"},{"name":"dq.MemoryLimit"},{"name":"dq.OptLLVM"},{"name":"dq.OutputChunkMaxSize"},{"name":"dq.ParallelOperationsLimit"},{"name":"dq.PingTimeoutMs"},{"name":"dq.PullRequestTimeoutMs"},{"name":"dq.QueryTimeout"},{"name":"dq.RetryBackoffMs"},{"name":"dq.Scheduler"},{"name":"dq.SpillingEngine"},{"name":"dq.SplitStageOnDqReplicate"},{"name":"dq.TaskRunnerStats"},{"name":"dq.UseAggPhases"},{"name":"dq.UseBlockReader"},{"name":"dq.UseFastPickleTransport"},{"name":"dq.UseFinalizeByKey"},{"name":"dq.UseGraceJoinCoreForMap"},{"name":"dq.UseOOBTransport"},{"name":"dq.UseSimpleYtReader"},{"name":"dq.UseWideBlockChannels"},{"name":"dq.UseWideChannels"},{"name":"dq.WatermarksEnableIdlePartitions"},{"name":"dq.WatermarksGranularityMs"},{"name":"dq.WatermarksLateArrivalDelayMs"},{"name":"dq.WatermarksMode"},{"name":"dq.WorkerFilter"},{"name":"dq.WorkersPerOperation"},{"name":"AllowDotInAlias"},{"name":"AllowUnnamedColumns"},{"name":"AnsiCurrentRow"},{"name":"AnsiImplicitCrossJoin"},{"name":"AnsiInForEmptyOrNullableItemsCollections"},{"name":"AnsiLike"},{"name":"AnsiOptionalAs"},{"name":"AnsiRankForNullableKeys"},{"name":"AutoCommit"},{"name":"BlockEngine"},{"name":"BlockEngineEnable"},{"name":"BlockEngineForce"},{"name":"BogousStarInGroupByOverJoin"},{"name":"CheckedOps"},{"name":"ClassicDivision"},{"name":"CoalesceJoinKeysOnQualifiedAll"},{"name":"CompactGroupBy"},{"name":"CompactNamedExprs"},{"name":"CostBasedOptimizer"},{"name":"DataWatermarks"},{"name":"DirectRead"},{"name":"DisableAnsiCurrentRow"},{"name":"DisableAnsiImplicitCrossJoin"},{"name":"DisableAnsiInForEmptyOrNullableItemsCollections"},{"name":"DisableAnsiLike"},{"name":"DisableAnsiOptionalAs"},{"name":"DisableAnsiRankForNullableKeys"},{"name":"DisableBlockEngineEnable"},{"name":"DisableBlockEngineForce"},{"name":"DisableBogousStarInGroupByOverJoin"},{"name":"DisableCoalesceJoinKeysOnQualifiedAll"},{"name":"DisableCompactGroupBy"},{"name":"DisableCompactNamedExprs"},{"name":"DisableDistinctOverKeys"},{"name":"DisableDistinctOverWindow"},{"name":"DisableDqEngineEnable"},{"name":"DisableDqEngineForce"},{"name":"DisableEmitAggApply"},{"name":"DisableEmitStartsWith"},{"name":"DisableEmitTableSource"},{"name":"DisableEmitUnionMerge"},{"name":"DisableFilterPushdownOverJoinOptionalSide"},{"name":"DisableFlexibleTypes"},{"name":"DisableGroupByExprAfterWhere"},{"name":"DisableJsonQueryReturnsJsonDocument"},{"name":"DisableOrderedColumns"},{"name":"DisablePullUpFlatMapOverJoin"},{"name":"DisableRegexUseRe2"},{"name":"DisableRotateJoinTree"},{"name":"DisableSeqMode"},{"name":"DisableSimpleColumns"},{"name":"DisableStrictJoinKeyTypes"},{"name":"DisableUnicodeLiterals"},{"name":"DisableUnorderedResult"},{"name":"DisableUnorderedSubqueries"},{"name":"DisableUseBlocks"},{"name":"DisableValidateUnusedExprs"},{"name":"DisableWarnOnAnsiAliasShadowing"},{"name":"DisableWarnUntypedStringLiterals"},{"name":"DiscoveryMode"},{"name":"DistinctOverKeys"},{"name":"DistinctOverWindow"},{"name":"DqEngine"},{"name":"DqEngineEnable"},{"name":"DqEngineForce"},{"name":"EmitAggApply"},{"name":"EmitStartsWith"},{"name":"EmitTableSource"},{"name":"EmitUnionMerge"},{"name":"EnableSystemColumns"},{"name":"Engine"},{"name":"ErrorMsg"},{"name":"FeatureR010"},{"name":"File"},{"name":"FileOption"},{"name":"FilterPushdownOverJoinOptionalSide"},{"name":"FlexibleTypes"},{"name":"Folder"},{"name":"Greetings"},{"name":"GroupByCubeLimit"},{"name":"GroupByExprAfterWhere"},{"name":"GroupByLimit"},{"name":"JsonQueryReturnsJsonDocument"},{"name":"Library"},{"name":"OrderedColumns"},{"name":"OverrideLibrary"},{"name":"Package"},{"name":"PackageVersion"},{"name":"PathPrefix"},{"name":"PositionalUnionAll"},{"name":"PqReadBy"},{"name":"PullUpFlatMapOverJoin"},{"name":"RefSelect"},{"name":"RegexUseRe2"},{"name":"ResultRowsLimit"},{"name":"ResultSizeLimit"},{"name":"RotateJoinTree"},{"name":"RuntimeLogLevel"},{"name":"SampleSelect"},{"name":"SeqMode"},{"name":"SimpleColumns"},{"name":"StrictJoinKeyTypes"},{"name":"Udf"},{"name":"UnicodeLiterals"},{"name":"UnorderedResult"},{"name":"UnorderedSubqueries"},{"name":"UseBlocks"},{"name":"UseTablePrefixForEach"},{"name":"ValidateUnusedExprs"},{"name":"WarnOnAnsiAliasShadowing"},{"name":"WarnUnnamedColumns"},{"name":"WarnUntypedStringLiterals"},{"name":"Warning"},{"name":"WarningMsg"},{"name":"yson.AutoConvert"},{"name":"yson.CastToString"},{"name":"yson.DisableCastToString"},{"name":"yson.DisableStrict"},{"name":"yson.Strict"}]
diff --git a/yql/essentials/minikql/comp_nodes/mkql_condense.cpp b/yql/essentials/minikql/comp_nodes/mkql_condense.cpp
index ced3a95d5ab..04181778482 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_condense.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_condense.cpp
@@ -30,7 +30,7 @@ public:
NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
if (state.IsFinish()) {
- return static_cast<const NUdf::TUnboxedValuePod&>(state);
+ return state;
}
if (state.IsInvalid()) {
diff --git a/yql/essentials/minikql/comp_nodes/mkql_condense1.cpp b/yql/essentials/minikql/comp_nodes/mkql_condense1.cpp
index 850a7bff042..b2cda5a5872 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_condense1.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_condense1.cpp
@@ -30,7 +30,7 @@ public:
NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
if (state.IsFinish()) {
- return static_cast<const NUdf::TUnboxedValuePod&>(state);
+ return state;
} else if (state.HasValue()) {
if constexpr (UseCtx) {
CleanupCurrentContext();
diff --git a/yql/essentials/minikql/comp_nodes/mkql_flatmap.cpp b/yql/essentials/minikql/comp_nodes/mkql_flatmap.cpp
index 923974e9e7e..69c42c7afbd 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_flatmap.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_flatmap.cpp
@@ -219,7 +219,7 @@ public:
}
if (state.IsFinish()) {
- return NUdf::TUnboxedValuePod::MakeFinish();
+ return state;
}
while (true) {
diff --git a/yql/essentials/minikql/comp_nodes/mkql_multimap.cpp b/yql/essentials/minikql/comp_nodes/mkql_multimap.cpp
index 1a0639b9e9b..5e33c133c31 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_multimap.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_multimap.cpp
@@ -21,8 +21,9 @@ public:
{}
NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish())
- return NUdf::TUnboxedValuePod::MakeFinish();
+ if (state.IsFinish()) {
+ return state;
+ }
const auto pos = state.IsInvalid() ? 0ULL : state.Get<ui64>();
if (!pos) {
@@ -412,8 +413,9 @@ public:
{}
NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
- if (state.IsFinish())
- return NUdf::TUnboxedValuePod::MakeFinish();
+ if (state.IsFinish()) {
+ return state;
+ }
const auto pos = state.IsInvalid() ? 0ULL : state.Get<ui64>();
if (!pos) {
diff --git a/yql/essentials/minikql/comp_nodes/mkql_squeeze_to_list.cpp b/yql/essentials/minikql/comp_nodes/mkql_squeeze_to_list.cpp
index 548eb0937df..55bd62b112b 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_squeeze_to_list.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_squeeze_to_list.cpp
@@ -47,7 +47,7 @@ public:
NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
if (state.IsFinish()) {
- return NUdf::TUnboxedValuePod::MakeFinish();
+ return state;
} else if (state.IsInvalid()) {
MakeState(ctx, Limit->GetValue(ctx).GetOrDefault(std::numeric_limits<ui64>::max()), state);
}
diff --git a/yql/essentials/minikql/comp_nodes/mkql_todict.cpp b/yql/essentials/minikql/comp_nodes/mkql_todict.cpp
index 738f88232a9..0ca6c68166a 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_todict.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_todict.cpp
@@ -985,7 +985,7 @@ public:
NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
if (state.IsFinish()) {
- return state.Release();
+ return state;
} else if (state.IsInvalid()) {
MakeState(ctx, state);
}
@@ -1162,7 +1162,7 @@ public:
NUdf::TUnboxedValuePod DoCalculate(NUdf::TUnboxedValue& state, TComputationContext& ctx) const {
if (state.IsFinish()) {
- return state.Release();
+ return state;
} else if (state.IsInvalid()) {
MakeState(ctx, state);
}
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_todict_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_todict_ut.cpp
index abb4f5d85e9..f09b9529d26 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_todict_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_todict_ut.cpp
@@ -147,6 +147,10 @@ Y_UNIT_TEST_SUITE(TMiniKQLToDictTest) {
status = res.Fetch(v);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, status);
+ // XXX: Check whether the internal state is not released
+ // and the sentinel is still set (see more info in YQL-19866).
+ status = res.Fetch(v);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, status);
};
for (auto stream : {true, false}) {
@@ -201,6 +205,10 @@ Y_UNIT_TEST_SUITE(TMiniKQLToDictTest) {
status = res.Fetch(v);
UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, status);
+ // XXX: Check whether the internal state is not released
+ // and the sentinel is still set (see more info in YQL-19866).
+ status = res.Fetch(v);
+ UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, status);
};
for (auto hashed : {true, false}) {
diff --git a/yql/essentials/sql/v1/context.cpp b/yql/essentials/sql/v1/context.cpp
index 1a0a1f4b18d..7f3d5433b96 100644
--- a/yql/essentials/sql/v1/context.cpp
+++ b/yql/essentials/sql/v1/context.cpp
@@ -69,6 +69,7 @@ THashMap<TStringBuf, TPragmaField> CTX_PRAGMA_FIELDS = {
{"EmitUnionMerge", &TContext::EmitUnionMerge},
{"SeqMode", &TContext::SeqMode},
{"DistinctOverKeys", &TContext::DistinctOverKeys},
+ {"GroupByExprAfterWhere", &TContext::GroupByExprAfterWhere},
};
typedef TMaybe<bool> TContext::*TPragmaMaybeField;
@@ -104,6 +105,10 @@ TContext::TContext(const TLexers& lexers, const TParsers& parsers,
, WarningPolicy(settings.IsReplay)
, BlockEngineEnable(Settings.BlockDefaultAuto->Allow())
{
+ if (settings.LangVer >= MakeLangVersion(2025, 2)) {
+ GroupByExprAfterWhere = true;
+ }
+
for (auto lib : settings.Libraries) {
Libraries.emplace(lib, TLibraryStuff());
}
diff --git a/yql/essentials/sql/v1/context.h b/yql/essentials/sql/v1/context.h
index 3bdfa1ceab4..e3f70f7515e 100644
--- a/yql/essentials/sql/v1/context.h
+++ b/yql/essentials/sql/v1/context.h
@@ -373,6 +373,7 @@ namespace NSQLTranslationV1 {
bool DistinctOverWindow = false;
bool SeqMode = false;
bool DistinctOverKeys = false;
+ bool GroupByExprAfterWhere = false;
bool EmitUnionMerge = false;
TVector<size_t> ForAllStatementsParts;
diff --git a/yql/essentials/sql/v1/select.cpp b/yql/essentials/sql/v1/select.cpp
index c4290f3268f..cb72dc95f5f 100644
--- a/yql/essentials/sql/v1/select.cpp
+++ b/yql/essentials/sql/v1/select.cpp
@@ -1744,6 +1744,11 @@ public:
if (Flatten) {
block = L(block, Y("let", "core", Y(ordered ? "OrderedFlatMap" : "FlatMap", "core", BuildLambda(Pos, Y("row"), Flatten, "res"))));
}
+ if (ctx.GroupByExprAfterWhere) {
+ if (auto filter = Source->BuildFilter(ctx, "core"); filter) {
+ block = L(block, Y("let", "core", filter));
+ }
+ }
if (PreaggregatedMap) {
block = L(block, Y("let", "core", PreaggregatedMap));
if (Source->IsCompositeSource() && !Columns.QualifiedAll) {
@@ -1752,9 +1757,10 @@ public:
} else if (Source->IsCompositeSource() && !Columns.QualifiedAll) {
block = L(block, Y("let", "origcore", "core"));
}
- auto filter = Source->BuildFilter(ctx, "core");
- if (filter) {
- block = L(block, Y("let", "core", filter));
+ if (!ctx.GroupByExprAfterWhere) {
+ if (auto filter = Source->BuildFilter(ctx, "core"); filter) {
+ block = L(block, Y("let", "core", filter));
+ }
}
if (Aggregate) {
block = L(block, Y("let", "core", Aggregate));
diff --git a/yql/essentials/sql/v1/sql_query.cpp b/yql/essentials/sql/v1/sql_query.cpp
index b60a338d02f..d64a7bf8d61 100644
--- a/yql/essentials/sql/v1/sql_query.cpp
+++ b/yql/essentials/sql/v1/sql_query.cpp
@@ -3393,6 +3393,12 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success
} else if (normalizedPragma == "disabledistinctoverkeys") {
Ctx.DistinctOverKeys = false;
Ctx.IncrementMonCounter("sql_pragma", "DisableDistinctOverKeys");
+ } else if (normalizedPragma == "groupbyexprafterwhere") {
+ Ctx.GroupByExprAfterWhere = true;
+ Ctx.IncrementMonCounter("sql_pragma", "GroupByExprAfterWhere");
+ } else if (normalizedPragma == "disablegroupbyexprafterwhere") {
+ Ctx.GroupByExprAfterWhere = false;
+ Ctx.IncrementMonCounter("sql_pragma", "DisableGroupByExprAfterWhere");
} else if (normalizedPragma == "engine") {
Ctx.IncrementMonCounter("sql_pragma", "Engine");
diff --git a/yql/essentials/tests/common/test_framework/test_file_common.py b/yql/essentials/tests/common/test_framework/test_file_common.py
index 240182e0056..9c91f8a1671 100644
--- a/yql/essentials/tests/common/test_framework/test_file_common.py
+++ b/yql/essentials/tests/common/test_framework/test_file_common.py
@@ -88,7 +88,7 @@ def get_sql_query(provider, suite, case, config, data_path=None, template='.sql'
def run_file_no_cache(provider, suite, case, cfg, config, yql_http_file_server,
yqlrun_binary=None, extra_args=[], force_blocks=False, allow_llvm=True, data_path=None,
- run_sql=True, cfg_postprocess=None):
+ run_sql=True, cfg_postprocess=None, langver=None):
check_provider(provider, config)
sql_query = get_sql_query(provider, suite, case, config, data_path, template='.sql' if run_sql else '.yqls')
@@ -119,7 +119,8 @@ def run_file_no_cache(provider, suite, case, cfg, config, yql_http_file_server,
gateway_config=get_gateways_config(http_files, yql_http_file_server, force_blocks=force_blocks, is_hybrid=is_hybrid(provider), allow_llvm=allow_llvm,
postprocess_func=cfg_postprocess),
extra_args=extra_args,
- udfs_dir=yql_binary_path('yql/essentials/tests/common/test_framework/udfs_deps')
+ udfs_dir=yql_binary_path('yql/essentials/tests/common/test_framework/udfs_deps'),
+ langver=langver
)
res, tables_res = execute(
@@ -156,12 +157,14 @@ def run_file_no_cache(provider, suite, case, cfg, config, yql_http_file_server,
def run_file(provider, suite, case, cfg, config, yql_http_file_server, yqlrun_binary=None,
- extra_args=[], force_blocks=False, allow_llvm=True, data_path=None, run_sql=True, cfg_postprocess=None):
+ extra_args=[], force_blocks=False, allow_llvm=True, data_path=None, run_sql=True,
+ cfg_postprocess=None, langver=None):
if (suite, case, cfg) not in run_file.cache:
run_file.cache[(suite, case, cfg)] = \
run_file_no_cache(provider, suite, case, cfg, config, yql_http_file_server,
yqlrun_binary, extra_args, force_blocks=force_blocks, allow_llvm=allow_llvm,
- data_path=data_path, run_sql=run_sql, cfg_postprocess=cfg_postprocess)
+ data_path=data_path, run_sql=run_sql, cfg_postprocess=cfg_postprocess,
+ langver=langver)
return run_file.cache[(suite, case, cfg)]
diff --git a/yql/essentials/tests/common/test_framework/test_utils.py b/yql/essentials/tests/common/test_framework/test_utils.py
index 0865245fd9b..e760e19a342 100644
--- a/yql/essentials/tests/common/test_framework/test_utils.py
+++ b/yql/essentials/tests/common/test_framework/test_utils.py
@@ -144,6 +144,7 @@ def validate_cfg(result):
"yt_file",
"os",
"param",
+ "langver",
), "Unknown command in .cfg: %s" % (r[0])
diff --git a/yql/essentials/tests/common/test_framework/yql_utils.py b/yql/essentials/tests/common/test_framework/yql_utils.py
index 3e4a4afa3fe..2d59a1fa13f 100644
--- a/yql/essentials/tests/common/test_framework/yql_utils.py
+++ b/yql/essentials/tests/common/test_framework/yql_utils.py
@@ -496,6 +496,13 @@ def is_xfail(cfg):
return False
+def get_langver(cfg):
+ for item in cfg:
+ if item[0] == 'langver':
+ return item[1]
+ return None
+
+
def is_skip_forceblocks(cfg):
for item in cfg:
if item[0] == 'skip_forceblocks':
diff --git a/yql/essentials/tests/common/test_framework/yqlrun.py b/yql/essentials/tests/common/test_framework/yqlrun.py
index e37bf7c38d3..49086ba7e88 100644
--- a/yql/essentials/tests/common/test_framework/yqlrun.py
+++ b/yql/essentials/tests/common/test_framework/yqlrun.py
@@ -25,7 +25,8 @@ FIX_DIR_PREFIXES = {
class YQLRun(object):
- def __init__(self, udfs_dir=None, prov='yt', use_sql2yql=False, keep_temp=True, binary=None, gateway_config=None, fs_config=None, extra_args=[], cfg_dir=None, support_udfs=True):
+ def __init__(self, udfs_dir=None, prov='yt', use_sql2yql=False, keep_temp=True, binary=None, gateway_config=None,
+ fs_config=None, extra_args=[], cfg_dir=None, support_udfs=True, langver=None):
if binary is None:
self.yqlrun_binary = yql_utils.yql_binary_path(os.getenv('YQL_YQLRUN_PATH') or 'yql/tools/yqlrun/yqlrun')
else:
@@ -80,6 +81,8 @@ class YQLRun(object):
flags = yql_utils.get_param('SQL_FLAGS').split(',')
self.gateway_config.SqlCore.TranslationFlags.extend(flags)
+ self.langver = langver
+
def yql_exec(self, program=None, program_file=None, files=None, urls=None,
run_sql=False, verbose=False, check_error=True, tables=None, pretty_plan=True,
wait=True, parameters={}, extra_env={}, require_udf_resolver=False, scan_udfs=True):
@@ -173,6 +176,9 @@ class YQLRun(object):
if ansi_lexer:
cmd += '--ansi-lexer '
+ if self.langver is not None:
+ cmd += '--langver=%s ' % (self.langver,)
+
if self.keep_temp and prov != 'pure':
cmd += '--keep-temp '
diff --git a/yql/essentials/tests/s-expressions/minirun/pure.py b/yql/essentials/tests/s-expressions/minirun/pure.py
index 38318d9fb8a..576230fd00b 100644
--- a/yql/essentials/tests/s-expressions/minirun/pure.py
+++ b/yql/essentials/tests/s-expressions/minirun/pure.py
@@ -9,12 +9,13 @@ from yql_utils import execute, get_tables, get_files, get_http_files, \
KSV_ATTR, yql_binary_path, is_xfail, is_canonize_peephole, is_peephole_use_blocks, is_canonize_lineage, \
is_skip_forceblocks, get_param, normalize_source_code_path, replace_vals, get_gateway_cfg_suffix, \
do_custom_query_check, stable_result_file, stable_table_file, is_with_final_result_issues, \
- normalize_result
+ normalize_result, get_langver
from yqlrun import YQLRun
from test_utils import get_config, get_parameters_json
from test_file_common import run_file, run_file_no_cache, get_gateways_config, get_sql_query
+DEFAULT_LANG_VER = '2025.01'
ASTDIFF_PATH = yql_binary_path('yql/essentials/tools/astdiff/astdiff')
MINIRUN_PATH = yql_binary_path('yql/essentials/tools/minirun/minirun')
DATA_PATH = yatest.common.source_path('yql/essentials/tests/s-expressions/suites')
@@ -25,6 +26,9 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
pytest.skip('non-trivial gateways.conf')
config = get_config(suite, case, cfg, data_path=DATA_PATH)
+ langver = get_langver(config)
+ if langver is None:
+ langver = DEFAULT_LANG_VER
xfail = is_xfail(config)
if xfail and what != 'Results':
@@ -38,7 +42,8 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
if is_with_final_result_issues(config):
extra_final_args += ['--with-final-issues']
(res, tables_res) = run_file('pure', suite, case, cfg, config, yql_http_file_server, MINIRUN_PATH,
- extra_args=extra_final_args, allow_llvm=False, data_path=DATA_PATH, run_sql=False)
+ extra_args=extra_final_args, allow_llvm=False, data_path=DATA_PATH,
+ run_sql=False, langver=langver)
to_canonize = []
assert not tables_res
@@ -72,7 +77,8 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
keep_temp=False,
gateway_config=get_gateways_config(http_files, yql_http_file_server, allow_llvm=is_llvm),
udfs_dir=yql_binary_path('yql/essentials/tests/common/test_framework/udfs_deps'),
- binary=MINIRUN_PATH
+ binary=MINIRUN_PATH,
+ langver=langver
)
opt_res, opt_tables_res = execute(
diff --git a/yql/essentials/tests/sql/minirun/part5/canondata/result.json b/yql/essentials/tests/sql/minirun/part5/canondata/result.json
index 579677b9314..ec17a6eec0b 100644
--- a/yql/essentials/tests/sql/minirun/part5/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part5/canondata/result.json
@@ -237,6 +237,20 @@
"uri": "https://{canondata_backend}/1871002/ab54d2c5acdb4e70fca2cf294e5ea9c225baab0c/resource.tar.gz#test.test_aggr_factory-transform_output-default.txt-Results_/results.txt"
}
],
+ "test.test[aggregate-group_by_expr_after_where_ver--Debug]": [
+ {
+ "checksum": "d0da2a1dc674dc86930994f910eb1c2b",
+ "size": 253,
+ "uri": "https://{canondata_backend}/1130705/42827d049e4963da219fd249860b757d672765ec/resource.tar.gz#test.test_aggregate-group_by_expr_after_where_ver--Debug_/opt.yql"
+ }
+ ],
+ "test.test[aggregate-group_by_expr_after_where_ver--Results]": [
+ {
+ "checksum": "1578f70c73d3ed10cf371be4ce4e70ec",
+ "size": 690,
+ "uri": "https://{canondata_backend}/1130705/42827d049e4963da219fd249860b757d672765ec/resource.tar.gz#test.test_aggregate-group_by_expr_after_where_ver--Results_/results.txt"
+ }
+ ],
"test.test[aggregate-hopping-default.txt-Debug]": [
{
"checksum": "bb23bcbf33c639f7faf92653dd668f3c",
@@ -1044,6 +1058,20 @@
"uri": "https://{canondata_backend}/1936273/19f08c34eba9366d29ee0ffb8eb99e637c34fd97/resource.tar.gz#test.test_join-convert_check_key_mem2-default.txt-Results_/results.txt"
}
],
+ "test.test[join-prune_keys-default.txt-Debug]": [
+ {
+ "checksum": "a706e6bd4285c96ad5120d701109fc82",
+ "size": 3669,
+ "uri": "https://{canondata_backend}/1871102/392832e505c55eb371c9d3241b89c96b5a837c8f/resource.tar.gz#test.test_join-prune_keys-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[join-prune_keys-default.txt-Results]": [
+ {
+ "checksum": "af076a3334031b8cdaa6969f064a4616",
+ "size": 18160,
+ "uri": "https://{canondata_backend}/1130705/620da5a4f19baef17c32a4b3c699ec3c3091ada5/resource.tar.gz#test.test_join-prune_keys-default.txt-Results_/results.txt"
+ }
+ ],
"test.test[json-json_exists/common_syntax-default.txt-Debug]": [
{
"checksum": "1559e7b19e1d1827f8f1ea62929effb1",
diff --git a/yql/essentials/tests/sql/minirun/part6/canondata/result.json b/yql/essentials/tests/sql/minirun/part6/canondata/result.json
index 26ca736cfcf..60e9fee9459 100644
--- a/yql/essentials/tests/sql/minirun/part6/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part6/canondata/result.json
@@ -195,6 +195,20 @@
"uri": "https://{canondata_backend}/1936273/614fe8dff439fd011c07c47361f2a1d0d854297f/resource.tar.gz#test.test_aggregate-distinct_over_keys-default.txt-Results_/results.txt"
}
],
+ "test.test[aggregate-group_by_expr_after_where-default.txt-Debug]": [
+ {
+ "checksum": "d0da2a1dc674dc86930994f910eb1c2b",
+ "size": 253,
+ "uri": "https://{canondata_backend}/1925842/9a344928381729abc8381a7e8ada7e10e2ba51fe/resource.tar.gz#test.test_aggregate-group_by_expr_after_where-default.txt-Debug_/opt.yql"
+ }
+ ],
+ "test.test[aggregate-group_by_expr_after_where-default.txt-Results]": [
+ {
+ "checksum": "1578f70c73d3ed10cf371be4ce4e70ec",
+ "size": 690,
+ "uri": "https://{canondata_backend}/1925842/9a344928381729abc8381a7e8ada7e10e2ba51fe/resource.tar.gz#test.test_aggregate-group_by_expr_after_where-default.txt-Results_/results.txt"
+ }
+ ],
"test.test[ansi_idents-escaping-default.txt-Debug]": [
{
"checksum": "13dd30dd58fd993aa21441bec427f12b",
diff --git a/yql/essentials/tests/sql/minirun/part7/canondata/result.json b/yql/essentials/tests/sql/minirun/part7/canondata/result.json
index e8c9926ae75..8083b15dac8 100644
--- a/yql/essentials/tests/sql/minirun/part7/canondata/result.json
+++ b/yql/essentials/tests/sql/minirun/part7/canondata/result.json
@@ -1232,16 +1232,16 @@
],
"test.test[select-prune_keys-default.txt-Debug]": [
{
- "checksum": "95e58e469ce10fce0d0d5e55c0cf3baf",
- "size": 3292,
- "uri": "https://{canondata_backend}/1931696/04008bc01ad4f562f8e03ad2bc296f7a64a78489/resource.tar.gz#test.test_select-prune_keys-default.txt-Debug_/opt.yql"
+ "checksum": "1dc9319da10b4c1343b6ceb5d0abb5b7",
+ "size": 3788,
+ "uri": "https://{canondata_backend}/212715/392992a262a39acb9e6e49f104e5800a3e731eb6/resource.tar.gz#test.test_select-prune_keys-default.txt-Debug_/opt.yql"
}
],
"test.test[select-prune_keys-default.txt-Results]": [
{
- "checksum": "f53b6976b6a5e1ee5e1d331c25963930",
- "size": 27670,
- "uri": "https://{canondata_backend}/1931696/04008bc01ad4f562f8e03ad2bc296f7a64a78489/resource.tar.gz#test.test_select-prune_keys-default.txt-Results_/results.txt"
+ "checksum": "46c226ab1c00ed4a9a5b57c6639f15b2",
+ "size": 30306,
+ "uri": "https://{canondata_backend}/212715/392992a262a39acb9e6e49f104e5800a3e731eb6/resource.tar.gz#test.test_select-prune_keys-default.txt-Results_/results.txt"
}
],
"test.test[union-union_positional_mix-default.txt-Debug]": [
diff --git a/yql/essentials/tests/sql/minirun/pure.py b/yql/essentials/tests/sql/minirun/pure.py
index c3a78adf354..3ec17bb2fa0 100644
--- a/yql/essentials/tests/sql/minirun/pure.py
+++ b/yql/essentials/tests/sql/minirun/pure.py
@@ -9,12 +9,13 @@ from yql_utils import execute, get_tables, get_files, get_http_files, \
KSV_ATTR, yql_binary_path, is_xfail, is_canonize_peephole, is_peephole_use_blocks, is_canonize_lineage, \
is_skip_forceblocks, get_param, normalize_source_code_path, replace_vals, get_gateway_cfg_suffix, \
do_custom_query_check, stable_result_file, stable_table_file, is_with_final_result_issues, \
- normalize_result
+ normalize_result, get_langver
from yqlrun import YQLRun
from test_utils import get_config, get_parameters_json
from test_file_common import run_file, run_file_no_cache, get_gateways_config, get_sql_query
+DEFAULT_LANG_VER = '2025.01'
DATA_PATH = yatest.common.source_path('yql/essentials/tests/sql/suites')
ASTDIFF_PATH = yql_binary_path('yql/essentials/tools/astdiff/astdiff')
MINIRUN_PATH = yql_binary_path('yql/essentials/tools/minirun/minirun')
@@ -39,6 +40,10 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
config = get_config(suite, case, cfg, data_path = DATA_PATH)
+ langver = get_langver(config)
+ if langver is None:
+ langver = DEFAULT_LANG_VER
+
xfail = is_xfail(config)
if xfail and what != 'Results':
pytest.skip('xfail is not supported in this mode')
@@ -51,7 +56,8 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
if is_with_final_result_issues(config):
extra_final_args += ['--with-final-issues']
(res, tables_res) = run_file('pure', suite, case, cfg, config, yql_http_file_server, MINIRUN_PATH,
- extra_args=extra_final_args, allow_llvm=False, data_path=DATA_PATH)
+ extra_args=extra_final_args, allow_llvm=False, data_path=DATA_PATH,
+ langver=langver)
to_canonize = []
assert xfail or os.path.exists(res.results_file)
@@ -67,7 +73,8 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
force_blocks = is_peephole_use_blocks(config)
(res, tables_res) = run_file_no_cache('pure', suite, case, cfg, config, yql_http_file_server,
force_blocks=force_blocks, extra_args=['--peephole'],
- data_path=DATA_PATH, yqlrun_binary=MINIRUN_PATH)
+ data_path=DATA_PATH, yqlrun_binary=MINIRUN_PATH,
+ langver=langver)
return [yatest.common.canonical_file(res.opt_file, diff_tool=ASTDIFF_PATH)]
if what == 'Results':
@@ -100,7 +107,8 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
keep_temp=False,
gateway_config=get_gateways_config(http_files, yql_http_file_server, allow_llvm=is_llvm, force_blocks=is_blocks),
udfs_dir=yql_binary_path('yql/essentials/tests/common/test_framework/udfs_deps'),
- binary=MINIRUN_PATH
+ binary=MINIRUN_PATH,
+ langver=langver
)
opt_res, opt_tables_res = execute(
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/result.json b/yql/essentials/tests/sql/sql2yql/canondata/result.json
index 4cb7e6cc7af..1022b92f85c 100644
--- a/yql/essentials/tests/sql/sql2yql/canondata/result.json
+++ b/yql/essentials/tests/sql/sql2yql/canondata/result.json
@@ -937,6 +937,20 @@
"uri": "https://{canondata_backend}/1936273/e22f8123b51c2802f50d5a8d4626267f2f28e9ab/resource.tar.gz#test_sql2yql.test_aggregate-distinct_over_keys_/sql.yql"
}
],
+ "test_sql2yql.test[aggregate-group_by_expr_after_where]": [
+ {
+ "checksum": "4799645fef77850f5f5f07de2d1b8bc2",
+ "size": 1762,
+ "uri": "https://{canondata_backend}/1899731/49525280cc90ece19469c3347e616ee12710ec2c/resource.tar.gz#test_sql2yql.test_aggregate-group_by_expr_after_where_/sql.yql"
+ }
+ ],
+ "test_sql2yql.test[aggregate-group_by_expr_after_where_ver]": [
+ {
+ "checksum": "d7d81aab522ef18bb07e619c426594c5",
+ "size": 1762,
+ "uri": "https://{canondata_backend}/1597364/99b2cf59a9975dbc2994ead01aa9dcbd784b5279/resource.tar.gz#test_sql2yql.test_aggregate-group_by_expr_after_where_ver_/sql.yql"
+ }
+ ],
"test_sql2yql.test[aggregate-group_by_rollup_rename]": [
{
"checksum": "bc5b27508587d82ba3e9d0a752d25dcc",
@@ -3933,6 +3947,13 @@
"uri": "https://{canondata_backend}/1942173/99e88108149e222741552e7e6cddef041d6a2846/resource.tar.gz#test_sql2yql.test_join-left_join_with_self_aggr_/sql.yql"
}
],
+ "test_sql2yql.test[join-prune_keys]": [
+ {
+ "checksum": "a04490e5ef3a567ca13cb1ed88272bd8",
+ "size": 22535,
+ "uri": "https://{canondata_backend}/1599023/2a161150407124ac83c2566a6542b19a53abfccb/resource.tar.gz#test_sql2yql.test_join-prune_keys_/sql.yql"
+ }
+ ],
"test_sql2yql.test[join-yql-19192]": [
{
"checksum": "fffdf1cbb40643da9daf9bdf3edec121",
@@ -7022,9 +7043,9 @@
],
"test_sql2yql.test[select-prune_keys]": [
{
- "checksum": "55346f77548ef19f9a09d2f1d3f6f466",
- "size": 17765,
- "uri": "https://{canondata_backend}/1871182/906a4c4e540bb8746f8d7595500d4d1c9f664846/resource.tar.gz#test_sql2yql.test_select-prune_keys_/sql.yql"
+ "checksum": "f7da5706622461ab177712e6c348c61b",
+ "size": 19536,
+ "uri": "https://{canondata_backend}/1814674/c8d78993e8e9976f1e3fae2197140afe33195365/resource.tar.gz#test_sql2yql.test_select-prune_keys_/sql.yql"
}
],
"test_sql2yql.test[select-result_label]": [
@@ -8103,6 +8124,16 @@
"uri": "file://test_sql_format.test_aggregate-distinct_over_keys_/formatted.sql"
}
],
+ "test_sql_format.test[aggregate-group_by_expr_after_where]": [
+ {
+ "uri": "file://test_sql_format.test_aggregate-group_by_expr_after_where_/formatted.sql"
+ }
+ ],
+ "test_sql_format.test[aggregate-group_by_expr_after_where_ver]": [
+ {
+ "uri": "file://test_sql_format.test_aggregate-group_by_expr_after_where_ver_/formatted.sql"
+ }
+ ],
"test_sql_format.test[aggregate-group_by_rollup_rename]": [
{
"uri": "file://test_sql_format.test_aggregate-group_by_rollup_rename_/formatted.sql"
@@ -10243,6 +10274,11 @@
"uri": "file://test_sql_format.test_join-left_join_with_self_aggr_/formatted.sql"
}
],
+ "test_sql_format.test[join-prune_keys]": [
+ {
+ "uri": "file://test_sql_format.test_join-prune_keys_/formatted.sql"
+ }
+ ],
"test_sql_format.test[join-yql-19192]": [
{
"uri": "file://test_sql_format.test_join-yql-19192_/formatted.sql"
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_aggregate-group_by_expr_after_where_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_aggregate-group_by_expr_after_where_/formatted.sql
new file mode 100644
index 00000000000..cb490bcb76c
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_aggregate-group_by_expr_after_where_/formatted.sql
@@ -0,0 +1,13 @@
+PRAGMA GroupByExprAfterWhere;
+
+SELECT
+ x
+FROM (
+ SELECT
+ 1 AS x
+)
+WHERE
+ x == 1
+GROUP BY
+ -x AS x
+;
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_aggregate-group_by_expr_after_where_ver_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_aggregate-group_by_expr_after_where_ver_/formatted.sql
new file mode 100644
index 00000000000..20d25d53d24
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_aggregate-group_by_expr_after_where_ver_/formatted.sql
@@ -0,0 +1,11 @@
+SELECT
+ x
+FROM (
+ SELECT
+ 1 AS x
+)
+WHERE
+ x == 1
+GROUP BY
+ -x AS x
+;
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_join-prune_keys_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_join-prune_keys_/formatted.sql
new file mode 100644
index 00000000000..0f53bcbe441
--- /dev/null
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_join-prune_keys_/formatted.sql
@@ -0,0 +1,238 @@
+PRAGMA config.flags('OptimizerFlags', 'EmitPruneKeys');
+
+$a = (
+ SELECT
+ *
+ FROM
+ as_table([
+ <|x: 1, t: 1|>,
+ <|x: 1, t: 1|>,
+ <|x: 1, t: 2|>,
+ <|x: 3, t: 1|>,
+ <|x: 3, t: 4|>,
+ <|x: 3, t: 2|>,
+ ])
+);
+
+$b = (
+ SELECT
+ *
+ FROM
+ as_table([
+ <|x: 1, y: 1|>,
+ <|x: 1, y: 2|>,
+ <|x: 1, y: 3|>,
+ <|x: 1, y: 3|>,
+ <|x: 2, y: 3|>,
+ <|x: 2, y: 4|>,
+ ])
+);
+
+$c = (
+ SELECT
+ *
+ FROM
+ as_table([
+ <|x: 1|>,
+ <|x: 1|>,
+ <|x: 1|>,
+ <|x: 1|>,
+ <|x: 2|>,
+ <|x: 2|>,
+ ])
+);
+
+-- PruneKeys
+SELECT
+ a.*
+FROM
+ $a AS a
+WHERE
+ a.x IN (
+ SELECT
+ x
+ FROM
+ $b
+ )
+; -- PruneKeys
+
+SELECT
+ a.*
+FROM
+ $a AS a
+WHERE
+ a.x IN (
+ SELECT
+ /*+ distinct(x) */ x
+ FROM
+ $b
+ )
+; -- nothing
+
+SELECT
+ a.*
+FROM
+ $a AS a
+WHERE
+ a.x IN (
+ SELECT
+ x
+ FROM
+ $c
+ )
+; -- PruneKeys
+
+SELECT
+ a.*
+FROM
+ $a AS a
+LEFT SEMI JOIN
+ $b AS b
+ON
+ a.x == b.x
+; -- PruneKeys(b)
+
+SELECT
+ a.*
+FROM
+ $b AS b
+RIGHT SEMI JOIN
+ $a AS a
+ON
+ b.x == a.x
+; -- PruneKeys(b)
+
+SELECT
+ a.x,
+ a.t,
+ b.x
+FROM ANY
+ $a AS a
+JOIN
+ $b AS b
+ON
+ a.x == b.x
+; -- PruneKeys(a)
+
+SELECT
+ a.x,
+ a.t,
+ b.x
+FROM
+ $a AS a
+JOIN ANY
+ $b AS b
+ON
+ a.x == b.x
+; -- PruneKeys(b)
+
+$a_sorted = (
+ SELECT
+ *
+ FROM
+ $a
+ ASSUME ORDER BY
+ x
+);
+
+$b_sorted = (
+ SELECT
+ *
+ FROM
+ $b
+ ASSUME ORDER BY
+ x
+);
+
+$c_sorted = (
+ SELECT
+ *
+ FROM
+ $c
+ ASSUME ORDER BY
+ x
+);
+
+-- PruneAdjacentKeys
+SELECT
+ a.*
+FROM
+ $a AS a
+WHERE
+ a.x IN (
+ SELECT
+ x
+ FROM
+ $b_sorted
+ )
+; -- PruneAdjacentKeys
+
+SELECT
+ a.*
+FROM
+ $a AS a
+WHERE
+ a.x IN (
+ SELECT
+ /*+ distinct(x) */ x
+ FROM
+ $b_sorted
+ )
+; -- nothing
+
+SELECT
+ a.*
+FROM
+ $a AS a
+WHERE
+ a.x IN (
+ SELECT
+ x
+ FROM
+ $c_sorted
+ )
+; -- PruneAdjacentKeys
+
+SELECT
+ a.*
+FROM
+ $a AS a
+LEFT SEMI JOIN
+ $b_sorted AS b
+ON
+ a.x == b.x
+; -- PruneAdjacentKeys(b_sorted)
+
+SELECT
+ a.*
+FROM
+ $b_sorted AS b
+RIGHT SEMI JOIN
+ $a AS a
+ON
+ b.x == a.x
+; -- PruneAdjacentKeys(b_sorted)
+
+SELECT
+ a.x,
+ a.t,
+ b.x
+FROM ANY
+ $a_sorted AS a
+JOIN
+ $b AS b
+ON
+ a.x == b.x
+; -- PruneAdjacentKeys(a_sorted)
+
+SELECT
+ a.x,
+ a.t,
+ b.x
+FROM
+ $a AS a
+JOIN ANY
+ $b_sorted AS b
+ON
+ a.x == b.x
+; -- PruneAdjacentKeys(b_sorted)
diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_select-prune_keys_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_select-prune_keys_/formatted.sql
index 65a0e7c3a79..80c2fa06403 100644
--- a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_select-prune_keys_/formatted.sql
+++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_select-prune_keys_/formatted.sql
@@ -29,6 +29,14 @@ SELECT
ListLength(Yql::PruneKeys(AsList(1, 1, 1, 3, 3, 3, 3), $mod2))
;
+SELECT
+ Yql::PruneAdjacentKeys(AsList(NULL, NULL, NULL, 1, 1, 2, 3, 3, 4, 5), $id)
+;
+
+SELECT
+ Yql::PruneKeys(AsList(1, NULL, 1, NULL, 1, NULL, 1), $id)
+;
+
-- optimize tests
$get_a = ($x) -> {
RETURN <|a: $x.a|>;
diff --git a/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where.sql b/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where.sql
new file mode 100644
index 00000000000..8f23c1f49cd
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where.sql
@@ -0,0 +1,4 @@
+pragma GroupByExprAfterWhere;
+select x from (select 1 as x)
+where x = 1
+group by -x as x
diff --git a/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where_ver.cfg b/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where_ver.cfg
new file mode 100644
index 00000000000..367bc6a9ec0
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where_ver.cfg
@@ -0,0 +1 @@
+langver 2025.02
diff --git a/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where_ver.sql b/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where_ver.sql
new file mode 100644
index 00000000000..e0542689369
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/aggregate/group_by_expr_after_where_ver.sql
@@ -0,0 +1,3 @@
+select x from (select 1 as x)
+where x = 1
+group by -x as x
diff --git a/yql/essentials/tests/sql/suites/join/prune_keys.sql b/yql/essentials/tests/sql/suites/join/prune_keys.sql
new file mode 100644
index 00000000000..9f10de9ace7
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/join/prune_keys.sql
@@ -0,0 +1,50 @@
+pragma config.flags('OptimizerFlags', 'EmitPruneKeys');
+
+$a = select * from as_table([
+ <|x:1, t:1|>,
+ <|x:1, t:1|>,
+ <|x:1, t:2|>,
+ <|x:3, t:1|>,
+ <|x:3, t:4|>,
+ <|x:3, t:2|>,
+ ]);
+
+$b = select * from as_table([
+ <|x:1, y:1|>,
+ <|x:1, y:2|>,
+ <|x:1, y:3|>,
+ <|x:1, y:3|>,
+ <|x:2, y:3|>,
+ <|x:2, y:4|>,
+ ]);
+
+$c = select * from as_table([
+ <|x:1|>,
+ <|x:1|>,
+ <|x:1|>,
+ <|x:1|>,
+ <|x:2|>,
+ <|x:2|>,
+ ]);
+
+-- PruneKeys
+select a.* from $a as a where a.x in (select x from $b); -- PruneKeys
+select a.* from $a as a where a.x in (select /*+ distinct(x) */ x from $b); -- nothing
+select a.* from $a as a where a.x in (select x from $c); -- PruneKeys
+select a.* from $a as a left semi join $b as b on a.x = b.x; -- PruneKeys(b)
+select a.* from $b as b right semi join $a as a on b.x = a.x; -- PruneKeys(b)
+select a.x, a.t, b.x from any $a as a join $b as b on a.x == b.x; -- PruneKeys(a)
+select a.x, a.t, b.x from $a as a join any $b as b on a.x == b.x; -- PruneKeys(b)
+
+$a_sorted = select * from $a assume order by x;
+$b_sorted = select * from $b assume order by x;
+$c_sorted = select * from $c assume order by x;
+
+-- PruneAdjacentKeys
+select a.* from $a as a where a.x in (select x from $b_sorted); -- PruneAdjacentKeys
+select a.* from $a as a where a.x in (select /*+ distinct(x) */ x from $b_sorted); -- nothing
+select a.* from $a as a where a.x in (select x from $c_sorted); -- PruneAdjacentKeys
+select a.* from $a as a left semi join $b_sorted as b on a.x = b.x; -- PruneAdjacentKeys(b_sorted)
+select a.* from $b_sorted as b right semi join $a as a on b.x = a.x; -- PruneAdjacentKeys(b_sorted)
+select a.x, a.t, b.x from any $a_sorted as a join $b as b on a.x == b.x; -- PruneAdjacentKeys(a_sorted)
+select a.x, a.t, b.x from $a as a join any $b_sorted as b on a.x == b.x; -- PruneAdjacentKeys(b_sorted)
diff --git a/yql/essentials/tests/sql/suites/select/prune_keys.sql b/yql/essentials/tests/sql/suites/select/prune_keys.sql
index 9cf5cb3ced7..f541bcfc61d 100644
--- a/yql/essentials/tests/sql/suites/select/prune_keys.sql
+++ b/yql/essentials/tests/sql/suites/select/prune_keys.sql
@@ -11,6 +11,9 @@ SELECT Yql::PruneKeys([], $id);
$mod2 = ($x) -> { RETURN $x % 2; };
SELECT ListLength(Yql::PruneKeys(AsList(1,1,1,3,3,3,3), $mod2));
+SELECT Yql::PruneAdjacentKeys(AsList(null,null,null,1,1,2,3,3,4,5), $id);
+SELECT Yql::PruneKeys(AsList(1,null,1,null,1,null,1), $id);
+
-- optimize tests
$get_a = ($x) -> { RETURN <|a:$x.a|>; };