aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Neporada <aneporada@ydb.tech>2024-08-12 17:18:43 +0300
committerGitHub <noreply@github.com>2024-08-12 17:18:43 +0300
commit1345ce6aaa0ea9d99a77d9866dd588b84b46ed2c (patch)
tree0cb56eb2e2946324799f720dd3fd8aaa7e1b1b5c
parent976e2c703afb734c8996d901b3b87e862595234e (diff)
downloadydb-1345ce6aaa0ea9d99a77d9866dd588b84b46ed2c.tar.gz
Collect statistic about unsuccessful block rewrites for callables and types (#7642)
-rw-r--r--ydb/library/yql/core/facade/yql_facade.cpp43
-rw-r--r--ydb/library/yql/core/facade/yql_facade.h23
-rw-r--r--ydb/library/yql/core/issue/protos/issue_id.proto4
-rw-r--r--ydb/library/yql/core/issue/yql_issue.txt8
-rw-r--r--ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp28
-rw-r--r--ydb/library/yql/core/yql_arrow_resolver.h7
-rw-r--r--ydb/library/yql/core/yql_expr_type_annotation.cpp12
-rw-r--r--ydb/library/yql/core/yql_expr_type_annotation.h2
-rw-r--r--ydb/library/yql/core/yql_type_annotation.cpp55
-rw-r--r--ydb/library/yql/core/yql_type_annotation.h10
-rw-r--r--ydb/library/yql/minikql/mkql_type_builder.cpp20
-rw-r--r--ydb/library/yql/minikql/mkql_type_builder.h3
-rw-r--r--ydb/library/yql/providers/common/arrow_resolve/yql_simple_arrow_resolver.cpp29
-rw-r--r--ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp60
-rw-r--r--ydb/library/yql/providers/common/mkql/yql_type_mkql.h1
-rw-r--r--ydb/library/yql/tests/common/test_framework/yql_utils.py5
-rw-r--r--ydb/library/yql/tests/sql/dq_file.py12
-rw-r--r--ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json26
-rw-r--r--ydb/library/yql/tests/sql/dq_file/part5/canondata/test.test_blocks-type_and_callable_stats--Results_/extracted3
-rw-r--r--ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json14
-rw-r--r--ydb/library/yql/tests/sql/sql2yql/canondata/result.json14
-rw-r--r--ydb/library/yql/tests/sql/suites/blocks/type_and_callable_stats.cfg4
-rw-r--r--ydb/library/yql/tests/sql/suites/blocks/type_and_callable_stats.sql16
-rw-r--r--ydb/library/yql/tests/sql/utils.py1
-rw-r--r--ydb/library/yql/tests/sql/yt_file.py7
-rw-r--r--ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json31
-rw-r--r--ydb/library/yql/tests/sql/yt_native_file/part5/canondata/test.test_blocks-type_and_callable_stats--Results_/extracted3
-rw-r--r--ydb/library/yql/tools/dqrun/dqrun.cpp9
-rw-r--r--ydb/library/yql/tools/yqlrun/http/yql_server.cpp6
-rw-r--r--ydb/library/yql/tools/yqlrun/http/yql_servlet.h2
-rw-r--r--ydb/library/yql/tools/yqlrun/yqlrun.cpp11
31 files changed, 422 insertions, 47 deletions
diff --git a/ydb/library/yql/core/facade/yql_facade.cpp b/ydb/library/yql/core/facade/yql_facade.cpp
index f58b26f08f9..bff0ec24adc 100644
--- a/ydb/library/yql/core/facade/yql_facade.cpp
+++ b/ydb/library/yql/core/facade/yql_facade.cpp
@@ -30,6 +30,7 @@
#include <util/stream/file.h>
#include <util/stream/null.h>
+#include <util/string/join.h>
#include <util/string/split.h>
#include <util/generic/guid.h>
#include <util/system/rusage.h>
@@ -1629,6 +1630,48 @@ NThreading::TFuture<void> TProgram::Abort()
return CloseLastSession();
}
+TIssues TProgram::Issues() const {
+ TIssues result;
+ if (ExprCtx_) {
+ result.AddIssues(ExprCtx_->IssueManager.GetIssues());
+ }
+ result.AddIssues(FinalIssues_);
+ return result;
+}
+
+TIssues TProgram::CompletedIssues() const {
+ TIssues result;
+ if (ExprCtx_) {
+ result.AddIssues(ExprCtx_->IssueManager.GetCompletedIssues());
+ }
+ result.AddIssues(FinalIssues_);
+ return result;
+}
+
+TIssue MakeNoBlocksInfoIssue(const TVector<TString>& names, bool isTypes) {
+ TIssue result;
+ TString msg = TStringBuilder() << "Most frequent " << (isTypes ? "types " : "callables ")
+ << "which do not support block mode: " << JoinRange(", ", names.begin(), names.end());
+ result.SetMessage(msg);
+ result.SetCode(isTypes ? TIssuesIds::CORE_TOP_UNSUPPORTED_BLOCK_TYPES : TIssuesIds::CORE_TOP_UNSUPPORTED_BLOCK_CALLABLES, TSeverityIds::S_INFO);
+ return result;
+}
+
+void TProgram::FinalizeIssues() {
+ FinalIssues_.Clear();
+ if (TypeCtx_) {
+ static const size_t topCount = 10;
+ auto noBlockTypes = TypeCtx_->GetTopNoBlocksTypes(topCount);
+ if (!noBlockTypes.empty()) {
+ FinalIssues_.AddIssue(MakeNoBlocksInfoIssue(noBlockTypes, true));
+ }
+ auto noBlockCallables = TypeCtx_->GetTopNoBlocksCallables(topCount);
+ if (!noBlockCallables.empty()) {
+ FinalIssues_.AddIssue(MakeNoBlocksInfoIssue(noBlockCallables, false));
+ }
+ }
+}
+
NThreading::TFuture<void> TProgram::CleanupLastSession() {
YQL_LOG_CTX_ROOT_SESSION_SCOPE(GetSessionId());
diff --git a/ydb/library/yql/core/facade/yql_facade.h b/ydb/library/yql/core/facade/yql_facade.h
index 3536d7a4758..9aceae87c37 100644
--- a/ydb/library/yql/core/facade/yql_facade.h
+++ b/ydb/library/yql/core/facade/yql_facade.h
@@ -192,28 +192,14 @@ public:
[[nodiscard]]
NThreading::TFuture<void> Abort();
- inline TIssues Issues() {
- if (ExprCtx_) {
- return ExprCtx_->IssueManager.GetIssues();
- } else {
- return {};
- }
- }
-
- inline TIssues CompletedIssues() const {
- if (ExprCtx_) {
- return ExprCtx_->IssueManager.GetCompletedIssues();
- } else {
- return {};
- }
- }
+ TIssues Issues() const;
+ TIssues CompletedIssues() const;
+ void FinalizeIssues();
void Print(IOutputStream* exprOut, IOutputStream* planOut, bool cleanPlan = false);
inline void PrintErrorsTo(IOutputStream& out) const {
- if (ExprCtx_) {
- ExprCtx_->IssueManager.GetIssues().PrintWithProgramTo(out, Filename_, SourceCode_);
- }
+ Issues().PrintWithProgramTo(out, Filename_, SourceCode_);
}
inline const TAstNode* AstRoot() const {
@@ -455,6 +441,7 @@ private:
TMaybe<TString> LineageStr_;
TQContext QContext_;
+ TIssues FinalIssues_;
};
} // namspace NYql
diff --git a/ydb/library/yql/core/issue/protos/issue_id.proto b/ydb/library/yql/core/issue/protos/issue_id.proto
index 5d8812c6402..a635b9b9a52 100644
--- a/ydb/library/yql/core/issue/protos/issue_id.proto
+++ b/ydb/library/yql/core/issue/protos/issue_id.proto
@@ -39,6 +39,10 @@ message TIssuesIds {
CORE_ALIAS_SHADOWS_COLUMN = 1111;
CORE_LINEAGE_INTERNAL_ERROR = 1112;
+// core informational
+ CORE_TOP_UNSUPPORTED_BLOCK_TYPES = 1200;
+ CORE_TOP_UNSUPPORTED_BLOCK_CALLABLES = 1201;
+
// core errors
CORE_GC_NODES_LIMIT_EXCEEDED = 1500;
CORE_GC_STRINGS_LIMIT_EXCEEDED = 1501;
diff --git a/ydb/library/yql/core/issue/yql_issue.txt b/ydb/library/yql/core/issue/yql_issue.txt
index d9ecca2db9e..7a4151a1898 100644
--- a/ydb/library/yql/core/issue/yql_issue.txt
+++ b/ydb/library/yql/core/issue/yql_issue.txt
@@ -663,3 +663,11 @@ ids {
code: YT_SECURE_DATA_IN_COMMON_TMP
severity: S_WARNING
}
+ids {
+ code: CORE_TOP_UNSUPPORTED_BLOCK_TYPES
+ severity: S_INFO
+}
+ids {
+ code: CORE_TOP_UNSUPPORTED_BLOCK_CALLABLES
+ severity: S_INFO
+}
diff --git a/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp b/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp
index b2ba6f70743..940656f76ca 100644
--- a/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp
+++ b/ydb/library/yql/core/peephole_opt/yql_opt_peephole_physical.cpp
@@ -2291,10 +2291,11 @@ IGraphTransformer::TStatus PeepHoleFinalStage(const TExprNode::TPtr& input, TExp
}
IGraphTransformer::TStatus PeepHoleBlockStage(const TExprNode::TPtr& input, TExprNode::TPtr& output,
- TExprContext& ctx, TTypeAnnotationContext& types, const TExtPeepHoleOptimizerMap& extOptimizers)
+ TExprContext& ctx, TTypeAnnotationContext& types, const TExtPeepHoleOptimizerMap& extOptimizers, TProcessedNodesSet& cache)
{
TOptimizeExprSettings settings(&types);
settings.CustomInstantTypeTransformer = types.CustomInstantTypeTransformer.Get();
+ settings.ProcessedNodes = &cache;
return OptimizeExpr(input, output, [&types, &extOptimizers](
const TExprNode::TPtr& node, TExprContext& ctx) -> TExprNode::TPtr {
@@ -5693,7 +5694,11 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
allInputTypes.push_back(i);
}
- auto resolveStatus = types.ArrowResolver->AreTypesSupported(ctx.GetPosition(lambda->Pos()), allInputTypes, ctx);
+ const IArrowResolver::TUnsupportedTypeCallback onUnsupportedType = [&types](const auto& typeKindOrSlot) {
+ std::visit([&types](const auto& value) { types.IncNoBlockType(value); }, typeKindOrSlot);
+ };
+
+ auto resolveStatus = types.ArrowResolver->AreTypesSupported(ctx.GetPosition(lambda->Pos()), allInputTypes, ctx, onUnsupportedType);
YQL_ENSURE(resolveStatus != IArrowResolver::ERROR);
if (resolveStatus != IArrowResolver::OK) {
return false;
@@ -5747,7 +5752,7 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
if (node->IsList() || rewriteAsIs ||
node->IsCallable({"And", "Or", "Xor", "Not", "Coalesce", "Exists", "If", "Just", "AsStruct", "Member", "Nth", "ToPg", "FromPg", "PgResolvedCall", "PgResolvedOp"}))
{
- if (node->IsCallable() && !IsSupportedAsBlockType(node->Pos(), *node->GetTypeAnn(), ctx, types)) {
+ if (node->IsCallable() && !IsSupportedAsBlockType(node->Pos(), *node->GetTypeAnn(), ctx, types, true)) {
return true;
}
@@ -5775,7 +5780,7 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
auto child = node->ChildPtr(index);
if (!child->GetTypeAnn()->IsComputable()) {
funcArgs.push_back(child);
- } else if (child->IsComplete() && IsSupportedAsBlockType(child->Pos(), *child->GetTypeAnn(), ctx, types)) {
+ } else if (child->IsComplete() && IsSupportedAsBlockType(child->Pos(), *child->GetTypeAnn(), ctx, types, true)) {
funcArgs.push_back(ctx.NewCallable(node->Pos(), "AsScalar", { child }));
} else if (auto rit = rewrites.find(child.Get()); rit != rewrites.end()) {
funcArgs.push_back(rit->second);
@@ -5796,7 +5801,7 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
auto member = funcArgs[index];
auto child = member->TailPtr();
TExprNodePtr rewrite;
- if (child->IsComplete() && IsSupportedAsBlockType(child->Pos(), *child->GetTypeAnn(), ctx, types)) {
+ if (child->IsComplete() && IsSupportedAsBlockType(child->Pos(), *child->GetTypeAnn(), ctx, types, true)) {
rewrite = ctx.NewCallable(child->Pos(), "AsScalar", { child });
} else if (auto rit = rewrites.find(child.Get()); rit != rewrites.end()) {
rewrite = rit->second;
@@ -5821,6 +5826,7 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
const bool isUdf = node->IsCallable("Apply") && node->Head().IsCallable("Udf");
if (isUdf) {
if (!GetSetting(*node->Head().Child(7), "blocks")) {
+ types.IncNoBlockCallable(node->Head().Head().Content());
return true;
}
}
@@ -5832,7 +5838,7 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
allTypes.push_back(node->Child(i)->GetTypeAnn());
}
- auto resolveStatus = types.ArrowResolver->AreTypesSupported(ctx.GetPosition(node->Pos()), allTypes, ctx);
+ auto resolveStatus = types.ArrowResolver->AreTypesSupported(ctx.GetPosition(node->Pos()), allTypes, ctx, onUnsupportedType);
YQL_ENSURE(resolveStatus != IArrowResolver::ERROR);
if (resolveStatus != IArrowResolver::OK) {
return true;
@@ -5898,6 +5904,7 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
} else {
auto fit = funcs.find(node->Content());
if (fit == funcs.end()) {
+ types.IncNoBlockCallable(node->Content());
return true;
}
@@ -5907,6 +5914,7 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
auto resolveStatus = types.ArrowResolver->LoadFunctionMetadata(ctx.GetPosition(node->Pos()), arrowFunctionName, argTypes, outType, ctx);
YQL_ENSURE(resolveStatus != IArrowResolver::ERROR);
if (resolveStatus != IArrowResolver::OK) {
+ types.IncNoBlockCallable(node->Content());
return true;
}
funcArgs.push_back(ExpandType(node->Pos(), *outType, ctx));
@@ -8555,10 +8563,10 @@ THolder<IGraphTransformer> CreatePeepHoleFinalStageTransformer(TTypeAnnotationCo
pipeline.Add(
CreateFunctorTransformer(
- [&types](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) -> IGraphTransformer::TStatus {
+ [&types, cache = TProcessedNodesSet()](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) mutable -> IGraphTransformer::TStatus {
if (types.IsBlockEngineEnabled()) {
const auto& extStageRules = TPeepHoleRules::Instance().BlockStageExtRules;
- return PeepHoleBlockStage(input, output, ctx, types, extStageRules);
+ return PeepHoleBlockStage(input, output, ctx, types, extStageRules, cache);
} else {
output = input;
return IGraphTransformer::TStatus::Ok;
@@ -8574,10 +8582,10 @@ THolder<IGraphTransformer> CreatePeepHoleFinalStageTransformer(TTypeAnnotationCo
pipeline.Add(
CreateFunctorTransformer(
- [&types](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) -> IGraphTransformer::TStatus {
+ [&types, cache = TProcessedNodesSet()](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) mutable -> IGraphTransformer::TStatus {
if (types.IsBlockEngineEnabled()) {
const auto& extStageRules = TPeepHoleRules::Instance().BlockStageExtFinalRules;
- return PeepHoleBlockStage(input, output, ctx, types, extStageRules);
+ return PeepHoleBlockStage(input, output, ctx, types, extStageRules, cache);
} else {
output = input;
return IGraphTransformer::TStatus::Ok;
diff --git a/ydb/library/yql/core/yql_arrow_resolver.h b/ydb/library/yql/core/yql_arrow_resolver.h
index d30f6239ca3..b22dfe3ee9a 100644
--- a/ydb/library/yql/core/yql_arrow_resolver.h
+++ b/ydb/library/yql/core/yql_arrow_resolver.h
@@ -2,11 +2,15 @@
#include <ydb/library/yql/ast/yql_expr.h>
+#include <functional>
+#include <variant>
+
namespace NYql {
class IArrowResolver : public TThrRefBase {
public:
using TPtr = TIntrusiveConstPtr<IArrowResolver>;
+ using TUnsupportedTypeCallback = std::function<void(std::variant<ETypeAnnotationKind, NUdf::EDataSlot>)>;
enum EStatus {
OK,
@@ -21,7 +25,8 @@ public:
virtual EStatus HasCast(const TPosition& pos, const TTypeAnnotationNode* from, const TTypeAnnotationNode* to, TExprContext& ctx) const = 0;
- virtual EStatus AreTypesSupported(const TPosition& pos, const TVector<const TTypeAnnotationNode*>& types, TExprContext& ctx) const = 0;
+ virtual EStatus AreTypesSupported(const TPosition& pos, const TVector<const TTypeAnnotationNode*>& types, TExprContext& ctx,
+ const TUnsupportedTypeCallback& onUnsupported = {}) const = 0;
};
}
diff --git a/ydb/library/yql/core/yql_expr_type_annotation.cpp b/ydb/library/yql/core/yql_expr_type_annotation.cpp
index d4bdae90694..57636a4d52c 100644
--- a/ydb/library/yql/core/yql_expr_type_annotation.cpp
+++ b/ydb/library/yql/core/yql_expr_type_annotation.cpp
@@ -3126,12 +3126,20 @@ bool IsWideSequenceBlockType(const TTypeAnnotationNode& type) {
return IsWideBlockType(*itemType);
}
-bool IsSupportedAsBlockType(TPositionHandle pos, const TTypeAnnotationNode& type, TExprContext& ctx, TTypeAnnotationContext& types) {
+bool IsSupportedAsBlockType(TPositionHandle pos, const TTypeAnnotationNode& type, TExprContext& ctx, TTypeAnnotationContext& types,
+ bool reportUnspported)
+{
if (!types.ArrowResolver) {
return false;
}
- auto resolveStatus = types.ArrowResolver->AreTypesSupported(ctx.GetPosition(pos), { &type }, ctx);
+ IArrowResolver::TUnsupportedTypeCallback onUnsupportedType;
+ if (reportUnspported) {
+ onUnsupportedType = [&types](const auto& typeKindOrSlot) {
+ std::visit([&types](const auto& value) { types.IncNoBlockType(value); }, typeKindOrSlot);
+ };
+ }
+ auto resolveStatus = types.ArrowResolver->AreTypesSupported(ctx.GetPosition(pos), { &type }, ctx, onUnsupportedType);
YQL_ENSURE(resolveStatus != IArrowResolver::ERROR);
return resolveStatus == IArrowResolver::OK;
}
diff --git a/ydb/library/yql/core/yql_expr_type_annotation.h b/ydb/library/yql/core/yql_expr_type_annotation.h
index 8030fdbad85..46e37ef4bfd 100644
--- a/ydb/library/yql/core/yql_expr_type_annotation.h
+++ b/ydb/library/yql/core/yql_expr_type_annotation.h
@@ -130,7 +130,7 @@ bool EnsureWideStreamType(const TExprNode& node, TExprContext& ctx);
bool EnsureWideStreamType(TPositionHandle position, const TTypeAnnotationNode& type, TExprContext& ctx);
bool IsWideBlockType(const TTypeAnnotationNode& type);
bool IsWideSequenceBlockType(const TTypeAnnotationNode& type);
-bool IsSupportedAsBlockType(TPositionHandle pos, const TTypeAnnotationNode& type, TExprContext& ctx, TTypeAnnotationContext& types);
+bool IsSupportedAsBlockType(TPositionHandle pos, const TTypeAnnotationNode& type, TExprContext& ctx, TTypeAnnotationContext& types, bool reportUnspported = false);
bool EnsureSupportedAsBlockType(TPositionHandle pos, const TTypeAnnotationNode& type, TExprContext& ctx, TTypeAnnotationContext& types);
bool EnsureWideBlockType(TPositionHandle position, const TTypeAnnotationNode& type, TTypeAnnotationNode::TListType& blockItemTypes, TExprContext& ctx, bool allowScalar = true);
bool EnsureWideFlowBlockType(const TExprNode& node, TTypeAnnotationNode::TListType& blockItemTypes, TExprContext& ctx, bool allowScalar = true);
diff --git a/ydb/library/yql/core/yql_type_annotation.cpp b/ydb/library/yql/core/yql_type_annotation.cpp
index 14f80c335e1..b565f615650 100644
--- a/ydb/library/yql/core/yql_type_annotation.cpp
+++ b/ydb/library/yql/core/yql_type_annotation.cpp
@@ -56,6 +56,61 @@ void TTypeAnnotationContext::Reset() {
ExpectedConstraints.clear();
ExpectedColumnOrders.clear();
StatisticsMap.clear();
+ NoBlockRewriteCallableStats.clear();
+ NoBlockRewriteTypeStats.clear();
+}
+
+void TTypeAnnotationContext::IncNoBlockCallable(TStringBuf callableName) {
+ ++NoBlockRewriteCallableStats[callableName];
+}
+
+void TTypeAnnotationContext::IncNoBlockType(const TTypeAnnotationNode& type) {
+ if (type.GetKind() == ETypeAnnotationKind::Data) {
+ IncNoBlockType(type.Cast<TDataExprType>()->GetSlot());
+ } else {
+ IncNoBlockType(type.GetKind());
+ }
+}
+
+void TTypeAnnotationContext::IncNoBlockType(ETypeAnnotationKind kind) {
+ ++NoBlockRewriteTypeStats[ToString(kind)];
+}
+
+void TTypeAnnotationContext::IncNoBlockType(NUdf::EDataSlot slot) {
+ ++NoBlockRewriteTypeStats[ToString(slot)];
+}
+
+namespace {
+
+template<typename T>
+TVector<T> GetMaxByCount(const THashMap<T, size_t>& stats, size_t maxCount) {
+ TVector<T> result;
+ result.reserve(stats.size());
+ for (auto& [key, _] : stats) {
+ result.push_back(key);
+ }
+ size_t n = std::min(maxCount, stats.size());
+ std::partial_sort(result.begin(), result.begin() + n, result.end(),
+ [&stats](const T& l, const T& r) {
+ const auto& cntLeft = stats.find(l)->second;
+ const auto& cntRight = stats.find(r)->second;
+ if (cntLeft != cntRight) {
+ return cntLeft < cntRight;
+ }
+ return l < r;
+ });
+ result.resize(n);
+ return result;
+}
+
+}
+
+TVector<TString> TTypeAnnotationContext::GetTopNoBlocksCallables(size_t maxCount) const {
+ return GetMaxByCount(NoBlockRewriteCallableStats, maxCount);
+}
+
+TVector<TString> TTypeAnnotationContext::GetTopNoBlocksTypes(size_t maxCount) const {
+ return GetMaxByCount(NoBlockRewriteTypeStats, maxCount);
}
TString TColumnOrder::Find(const TString& name) const {
diff --git a/ydb/library/yql/core/yql_type_annotation.h b/ydb/library/yql/core/yql_type_annotation.h
index 8e8bbaa53a4..dbc63d61d5f 100644
--- a/ydb/library/yql/core/yql_type_annotation.h
+++ b/ydb/library/yql/core/yql_type_annotation.h
@@ -334,6 +334,8 @@ struct TTypeAnnotationContext: public TThrRefBase {
ui32 FolderSubDirsLimit = 1000;
bool UseBlocks = false;
EBlockEngineMode BlockEngineMode = EBlockEngineMode::Disable;
+ THashMap<TString, size_t> NoBlockRewriteCallableStats;
+ THashMap<TString, size_t> NoBlockRewriteTypeStats;
TMaybe<bool> PgEmitAggApply;
IArrowResolver::TPtr ArrowResolver;
TFileStoragePtr FileStorage;
@@ -441,6 +443,14 @@ struct TTypeAnnotationContext: public TThrRefBase {
bool IsBlockEngineEnabled() const {
return BlockEngineMode != EBlockEngineMode::Disable || UseBlocks;
}
+
+ void IncNoBlockCallable(TStringBuf callableName);
+ void IncNoBlockType(const TTypeAnnotationNode& type);
+ void IncNoBlockType(ETypeAnnotationKind kind);
+ void IncNoBlockType(NUdf::EDataSlot slot);
+
+ TVector<TString> GetTopNoBlocksCallables(size_t maxCount) const;
+ TVector<TString> GetTopNoBlocksTypes(size_t maxCount) const;
};
template <> inline
diff --git a/ydb/library/yql/minikql/mkql_type_builder.cpp b/ydb/library/yql/minikql/mkql_type_builder.cpp
index 8fc007e9c82..2116718db5f 100644
--- a/ydb/library/yql/minikql/mkql_type_builder.cpp
+++ b/ydb/library/yql/minikql/mkql_type_builder.cpp
@@ -1517,7 +1517,7 @@ bool ConvertArrowType(NUdf::EDataSlot slot, std::shared_ptr<arrow::DataType>& ty
}
}
-bool ConvertArrowType(TType* itemType, std::shared_ptr<arrow::DataType>& type) {
+bool ConvertArrowType(TType* itemType, std::shared_ptr<arrow::DataType>& type, const TArrowConvertFailedCallback& onFail) {
bool isOptional;
auto unpacked = UnpackOptional(itemType, isOptional);
if (unpacked->IsOptional() || isOptional && unpacked->IsPg()) {
@@ -1538,7 +1538,7 @@ bool ConvertArrowType(TType* itemType, std::shared_ptr<arrow::DataType>& type) {
// previousType is always Optional
std::shared_ptr<arrow::DataType> innerArrowType;
- if (!ConvertArrowType(previousType, innerArrowType)) {
+ if (!ConvertArrowType(previousType, innerArrowType, onFail)) {
return false;
}
@@ -1560,7 +1560,7 @@ bool ConvertArrowType(TType* itemType, std::shared_ptr<arrow::DataType>& type) {
std::shared_ptr<arrow::DataType> childType;
const TString memberName(structType->GetMemberName(i));
auto memberType = structType->GetMemberType(i);
- if (!ConvertArrowType(memberType, childType)) {
+ if (!ConvertArrowType(memberType, childType, onFail)) {
return false;
}
members.emplace_back(std::make_shared<arrow::Field>(memberName, childType, memberType->IsOptional()));
@@ -1576,7 +1576,7 @@ bool ConvertArrowType(TType* itemType, std::shared_ptr<arrow::DataType>& type) {
for (ui32 i = 0; i < tupleType->GetElementsCount(); ++i) {
std::shared_ptr<arrow::DataType> childType;
auto elementType = tupleType->GetElementType(i);
- if (!ConvertArrowType(elementType, childType)) {
+ if (!ConvertArrowType(elementType, childType, onFail)) {
return false;
}
@@ -1605,15 +1605,25 @@ bool ConvertArrowType(TType* itemType, std::shared_ptr<arrow::DataType>& type) {
}
if (!unpacked->IsData()) {
+ if (onFail) {
+ onFail(unpacked);
+ }
return false;
}
auto slot = AS_TYPE(TDataType, unpacked)->GetDataSlot();
if (!slot) {
+ if (onFail) {
+ onFail(unpacked);
+ }
return false;
}
- return ConvertArrowType(*slot, type);
+ bool result = ConvertArrowType(*slot, type);
+ if (!result && onFail) {
+ onFail(unpacked);
+ }
+ return result;
}
void TArrowType::Export(ArrowSchema* out) const {
diff --git a/ydb/library/yql/minikql/mkql_type_builder.h b/ydb/library/yql/minikql/mkql_type_builder.h
index 6c2f9b4acc6..285cc1c8b2b 100644
--- a/ydb/library/yql/minikql/mkql_type_builder.h
+++ b/ydb/library/yql/minikql/mkql_type_builder.h
@@ -30,7 +30,8 @@ inline size_t CalcBlockLen(size_t maxBlockItemSize) {
return MaxBlockSizeInBytes / std::max<size_t>(maxBlockItemSize, 1);
}
-bool ConvertArrowType(TType* itemType, std::shared_ptr<arrow::DataType>& type);
+using TArrowConvertFailedCallback = std::function<void(TType*)>;
+bool ConvertArrowType(TType* itemType, std::shared_ptr<arrow::DataType>& type, const TArrowConvertFailedCallback& = {});
bool ConvertArrowType(NUdf::EDataSlot slot, std::shared_ptr<arrow::DataType>& type);
template<NUdf::EDataSlot slot>
diff --git a/ydb/library/yql/providers/common/arrow_resolve/yql_simple_arrow_resolver.cpp b/ydb/library/yql/providers/common/arrow_resolve/yql_simple_arrow_resolver.cpp
index 8376d71f781..0a417ef5d8c 100644
--- a/ydb/library/yql/providers/common/arrow_resolve/yql_simple_arrow_resolver.cpp
+++ b/ydb/library/yql/providers/common/arrow_resolve/yql_simple_arrow_resolver.cpp
@@ -57,20 +57,41 @@ private:
}
}
- EStatus AreTypesSupported(const TPosition& pos, const TVector<const TTypeAnnotationNode*>& types, TExprContext& ctx) const override {
+ EStatus AreTypesSupported(const TPosition& pos, const TVector<const TTypeAnnotationNode*>& types, TExprContext& ctx,
+ const TUnsupportedTypeCallback& onUnsupported = {}) const override
+ {
try {
TScopedAlloc alloc(__LOCATION__);
TTypeEnvironment env(alloc);
TTypeBuilder typeBuilder(env);
+
+ bool allOk = true;
+ TArrowConvertFailedCallback cb;
+ if (onUnsupported) {
+ cb = [&](TType* failed) {
+ if (failed->IsData()) {
+ auto slot = static_cast<TDataType*>(failed)->GetDataSlot();
+ YQL_ENSURE(slot);
+ onUnsupported(*slot);
+ } else {
+ onUnsupported(NYql::NCommon::ConvertMiniKQLTypeKind(failed));
+ }
+ };
+ }
+
for (const auto& type : types) {
+ YQL_ENSURE(type);
TNullOutput null;
auto mkqlType = NCommon::BuildType(*type, typeBuilder, null);
std::shared_ptr<arrow::DataType> arrowType;
- if (!ConvertArrowType(mkqlType, arrowType)) {
- return EStatus::NOT_FOUND;
+ if (!ConvertArrowType(mkqlType, arrowType, cb)) {
+ allOk = false;
+ if (!cb) {
+ break;
+ }
}
}
- return EStatus::OK;
+ return allOk ? EStatus::OK : EStatus::NOT_FOUND;
} catch (const std::exception& e) {
ctx.AddError(TIssue(pos, e.what()));
return EStatus::ERROR;
diff --git a/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp b/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
index 2d74fc1c55c..0b40b5b339b 100644
--- a/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
+++ b/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp
@@ -426,5 +426,65 @@ const TTypeAnnotationNode* ConvertMiniKQLType(TPosition position, NKikimr::NMini
YQL_ENSURE(false, "Unknown kind");
}
+ETypeAnnotationKind ConvertMiniKQLTypeKind(NKikimr::NMiniKQL::TType* type) {
+ using namespace NKikimr::NMiniKQL;
+ switch (type->GetKind()) {
+ case TType::EKind::Type:
+ return ETypeAnnotationKind::Generic;
+ case TType::EKind::Void:
+ return ETypeAnnotationKind::Void;
+ case TType::EKind::Data:
+ return ETypeAnnotationKind::Data;
+ case TType::EKind::Struct:
+ return ETypeAnnotationKind::Struct;
+ case TType::EKind::List:
+ return ETypeAnnotationKind::List;
+ case TType::EKind::Optional:
+ return ETypeAnnotationKind::Optional;
+ case TType::EKind::Dict:
+ return ETypeAnnotationKind::Dict;
+ case TType::EKind::Callable:
+ return ETypeAnnotationKind::Callable;
+ case TType::EKind::Any:
+ case TType::EKind::ReservedKind:
+ YQL_ENSURE(false, "Not supported");
+ break;
+ case TType::EKind::Tuple:
+ return ETypeAnnotationKind::Tuple;
+ case TType::EKind::Resource:
+ return ETypeAnnotationKind::Resource;
+ case TType::EKind::Stream:
+ return ETypeAnnotationKind::Stream;
+ case TType::EKind::Variant:
+ return ETypeAnnotationKind::Variant;
+ case TType::EKind::Null:
+ return ETypeAnnotationKind::Null;
+ case TType::EKind::EmptyList:
+ return ETypeAnnotationKind::EmptyList;
+ case TType::EKind::EmptyDict:
+ return ETypeAnnotationKind::EmptyDict;
+ case TType::EKind::Tagged:
+ return ETypeAnnotationKind::Tagged;
+ case TType::EKind::Block:
+ {
+ auto blockType = static_cast<TBlockType*>(type);
+ if (blockType->GetShape() == NKikimr::NMiniKQL::TBlockType::EShape::Many) {
+ return ETypeAnnotationKind::Block;
+ } else {
+ return ETypeAnnotationKind::Scalar;
+ }
+ }
+ case TType::EKind::Flow:
+ return ETypeAnnotationKind::Flow;
+ case TType::EKind::Pg:
+ return ETypeAnnotationKind::Pg;
+ case TType::EKind::Multi:
+ return ETypeAnnotationKind::Multi;
+ }
+
+ YQL_ENSURE(false, "Unknown kind");
+}
+
+
} // namespace NCommon
} // namespace NYql
diff --git a/ydb/library/yql/providers/common/mkql/yql_type_mkql.h b/ydb/library/yql/providers/common/mkql/yql_type_mkql.h
index 53c5b1f7be5..a00def3ac80 100644
--- a/ydb/library/yql/providers/common/mkql/yql_type_mkql.h
+++ b/ydb/library/yql/providers/common/mkql/yql_type_mkql.h
@@ -22,6 +22,7 @@ NKikimr::NMiniKQL::TType* BuildType(TPositionHandle pos, const TTypeAnnotationNo
NKikimr::NMiniKQL::TType* BuildType(const TExprNode& owner, const TTypeAnnotationNode& annotation, NKikimr::NMiniKQL::TTypeBuilder& typeBuilder);
const TTypeAnnotationNode* ConvertMiniKQLType(TPosition position, NKikimr::NMiniKQL::TType* type, TExprContext& ctx);
+ETypeAnnotationKind ConvertMiniKQLTypeKind(NKikimr::NMiniKQL::TType* type);
} // namespace NCommon
} // namespace NYql
diff --git a/ydb/library/yql/tests/common/test_framework/yql_utils.py b/ydb/library/yql/tests/common/test_framework/yql_utils.py
index 12d733af861..d19561f9ee8 100644
--- a/ydb/library/yql/tests/common/test_framework/yql_utils.py
+++ b/ydb/library/yql/tests/common/test_framework/yql_utils.py
@@ -501,6 +501,11 @@ def is_canonize_yt(cfg):
return True
return False
+def is_with_final_result_issues(cfg):
+ for item in cfg:
+ if item[0] == 'with_final_result_issues':
+ return True
+ return False
def skip_test_if_required(cfg):
for item in cfg:
diff --git a/ydb/library/yql/tests/sql/dq_file.py b/ydb/library/yql/tests/sql/dq_file.py
index dbacef45fe2..1e96ae5bb14 100644
--- a/ydb/library/yql/tests/sql/dq_file.py
+++ b/ydb/library/yql/tests/sql/dq_file.py
@@ -6,7 +6,7 @@ import re
import yatest.common
from yql_utils import get_supported_providers, yql_binary_path, is_xfail, is_skip_forceblocks, get_param, \
normalize_source_code_path, dump_table_yson, get_gateway_cfg_suffix, do_custom_query_check, normalize_result, \
- stable_result_file, stable_table_file
+ stable_result_file, stable_table_file, is_with_final_result_issues
from utils import get_config, DATA_PATH
from file_common import run_file, run_file_no_cache
@@ -32,10 +32,16 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
if force_blocks and is_skip_forceblocks(config):
pytest.skip('skip force blocks requested')
+ extra_args=["--emulate-yt"]
if what == 'Analyze':
- (res, tables_res) = run_file_no_cache('dq', suite, case, cfg, config, yql_http_file_server, DQRUN_PATH, extra_args=["--emulate-yt", "--analyze-query", "--optimize"])
+ extra_args += ["--analyze-query", "--optimize"]
+ if is_with_final_result_issues(config):
+ extra_args += ["--with-final-issues"]
+
+ if what == 'Analyze':
+ (res, tables_res) = run_file_no_cache('dq', suite, case, cfg, config, yql_http_file_server, DQRUN_PATH, extra_args=extra_args)
else:
- (res, tables_res) = run_file('dq', suite, case, cfg, config, yql_http_file_server, DQRUN_PATH, extra_args=["--emulate-yt"])
+ (res, tables_res) = run_file('dq', suite, case, cfg, config, yql_http_file_server, DQRUN_PATH, extra_args=extra_args)
to_canonize = []
diff --git a/ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json b/ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json
index f94775c7e3b..54e040cc89a 100644
--- a/ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json
+++ b/ydb/library/yql/tests/sql/dq_file/part5/canondata/result.json
@@ -711,6 +711,32 @@
}
],
"test.test[blocks-sub_uint64_opt2--Results]": [],
+ "test.test[blocks-type_and_callable_stats--Analyze]": [
+ {
+ "checksum": "ba2a8428a72e0ef51d7f5a825ffd3d1e",
+ "size": 3705,
+ "uri": "https://{canondata_backend}/1784117/9a53e0c31670253d78108c8a3b4f81fc219a1c68/resource.tar.gz#test.test_blocks-type_and_callable_stats--Analyze_/plan.txt"
+ }
+ ],
+ "test.test[blocks-type_and_callable_stats--Debug]": [
+ {
+ "checksum": "fea9bf013d4fa84ee9ed1470290a2247",
+ "size": 2819,
+ "uri": "https://{canondata_backend}/1689644/40519f669ee0ff4cd14681f4648f099da23d476a/resource.tar.gz#test.test_blocks-type_and_callable_stats--Debug_/opt.yql_patched"
+ }
+ ],
+ "test.test[blocks-type_and_callable_stats--Plan]": [
+ {
+ "checksum": "ba2a8428a72e0ef51d7f5a825ffd3d1e",
+ "size": 3705,
+ "uri": "https://{canondata_backend}/1784117/9a53e0c31670253d78108c8a3b4f81fc219a1c68/resource.tar.gz#test.test_blocks-type_and_callable_stats--Plan_/plan.txt"
+ }
+ ],
+ "test.test[blocks-type_and_callable_stats--Results]": [
+ {
+ "uri": "file://test.test_blocks-type_and_callable_stats--Results_/extracted"
+ }
+ ],
"test.test[coalesce-coalesce_symmetry-default.txt-Analyze]": [
{
"checksum": "4d9d7cd78393c759728e69e95aefb913",
diff --git a/ydb/library/yql/tests/sql/dq_file/part5/canondata/test.test_blocks-type_and_callable_stats--Results_/extracted b/ydb/library/yql/tests/sql/dq_file/part5/canondata/test.test_blocks-type_and_callable_stats--Results_/extracted
new file mode 100644
index 00000000000..4260358aac6
--- /dev/null
+++ b/ydb/library/yql/tests/sql/dq_file/part5/canondata/test.test_blocks-type_and_callable_stats--Results_/extracted
@@ -0,0 +1,3 @@
+<tmp_path>/program.sql:<main>: Info: Most frequent types which do not support block mode: Dict, DyNumber, List, Void
+
+<tmp_path>/program.sql:<main>: Info: Most frequent callables which do not support block mode: Re2.Grep, Re2.Match, SafeCast \ No newline at end of file
diff --git a/ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json b/ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json
index 1c19f535b85..3ec49bf3e03 100644
--- a/ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json
+++ b/ydb/library/yql/tests/sql/hybrid_file/part7/canondata/result.json
@@ -741,6 +741,20 @@
"uri": "https://{canondata_backend}/1031349/8b8964a29e1f3930fc799646d4ad2b51c549588e/resource.tar.gz#test.test_blocks-top_sort_one_asc--Plan_/plan.txt"
}
],
+ "test.test[blocks-type_and_callable_stats--Debug]": [
+ {
+ "checksum": "a01ceb9ea4ea544c1a7e54496bffec41",
+ "size": 3907,
+ "uri": "https://{canondata_backend}/1031349/61ef6576b4067a10cada6609ae12eda1d03e8ab5/resource.tar.gz#test.test_blocks-type_and_callable_stats--Debug_/opt.yql_patched"
+ }
+ ],
+ "test.test[blocks-type_and_callable_stats--Plan]": [
+ {
+ "checksum": "4f5ebace275ca31a34ca23bdb57a6dc7",
+ "size": 4074,
+ "uri": "https://{canondata_backend}/1031349/61ef6576b4067a10cada6609ae12eda1d03e8ab5/resource.tar.gz#test.test_blocks-type_and_callable_stats--Plan_/plan.txt"
+ }
+ ],
"test.test[coalesce-coalesce_sugar-default.txt-Debug]": [
{
"checksum": "f6a160186160453bd01f600884397730",
diff --git a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json
index 551be78940d..f6980ccf3b4 100644
--- a/ydb/library/yql/tests/sql/sql2yql/canondata/result.json
+++ b/ydb/library/yql/tests/sql/sql2yql/canondata/result.json
@@ -4262,6 +4262,13 @@
"uri": "https://{canondata_backend}/1889210/525a727248199e4967ca2f854e5235352e3d5482/resource.tar.gz#test_sql2yql.test_blocks-tuple_type_/sql.yql"
}
],
+ "test_sql2yql.test[blocks-type_and_callable_stats]": [
+ {
+ "checksum": "9efa02df55deb6b8dbdca1b440e96fc1",
+ "size": 2601,
+ "uri": "https://{canondata_backend}/1937424/7dd37eb1e9f9f10e476a8c866a4f6d9d8a2ae8d2/resource.tar.gz#test_sql2yql.test_blocks-type_and_callable_stats_/sql.yql"
+ }
+ ],
"test_sql2yql.test[case-case_many_val]": [
{
"checksum": "bda507979f30604c929d345df0b011e0",
@@ -23708,6 +23715,13 @@
"uri": "https://{canondata_backend}/1889210/525a727248199e4967ca2f854e5235352e3d5482/resource.tar.gz#test_sql_format.test_blocks-tuple_type_/formatted.sql"
}
],
+ "test_sql_format.test[blocks-type_and_callable_stats]": [
+ {
+ "checksum": "0c26e93da59abd323c566a60d42be7c6",
+ "size": 401,
+ "uri": "https://{canondata_backend}/1937424/7dd37eb1e9f9f10e476a8c866a4f6d9d8a2ae8d2/resource.tar.gz#test_sql_format.test_blocks-type_and_callable_stats_/formatted.sql"
+ }
+ ],
"test_sql_format.test[case-case_many_val]": [
{
"checksum": "b47f8a0a4b6bdb400396d301c9371805",
diff --git a/ydb/library/yql/tests/sql/suites/blocks/type_and_callable_stats.cfg b/ydb/library/yql/tests/sql/suites/blocks/type_and_callable_stats.cfg
new file mode 100644
index 00000000000..6a380025730
--- /dev/null
+++ b/ydb/library/yql/tests/sql/suites/blocks/type_and_callable_stats.cfg
@@ -0,0 +1,4 @@
+with_final_result_issues
+in Input input_strings.txt
+udf string_udf
+udf re2_udf
diff --git a/ydb/library/yql/tests/sql/suites/blocks/type_and_callable_stats.sql b/ydb/library/yql/tests/sql/suites/blocks/type_and_callable_stats.sql
new file mode 100644
index 00000000000..5357170adb0
--- /dev/null
+++ b/ydb/library/yql/tests/sql/suites/blocks/type_and_callable_stats.sql
@@ -0,0 +1,16 @@
+pragma BlockEngine='force';
+
+USE plato;
+$match = Re2::Match(@@\d+@@);
+$grep = Re2::Grep('911');
+
+SELECT
+ key,
+ String::EscapeC(value) as ok1,
+ $match(key) as no_block_udf1,
+ $grep(key) as no_block_udf2,
+ AsList(key) as no_block_list,
+ AsSet(key) as no_block_set_and_void,
+ cast(key as Double) as no_block_cast,
+ AsTuple(key, DyNumber("123")) as no_block_dynumber,
+FROM Input;
diff --git a/ydb/library/yql/tests/sql/utils.py b/ydb/library/yql/tests/sql/utils.py
index f385428abda..aaf62644516 100644
--- a/ydb/library/yql/tests/sql/utils.py
+++ b/ydb/library/yql/tests/sql/utils.py
@@ -117,6 +117,7 @@ def validate_cfg(result):
"canonize_peephole",
"canonize_lineage",
"peephole_use_blocks",
+ "with_final_result_issues",
"xfail",
"pragma",
"canonize_yt",
diff --git a/ydb/library/yql/tests/sql/yt_file.py b/ydb/library/yql/tests/sql/yt_file.py
index b41e66a3146..2ab410f0867 100644
--- a/ydb/library/yql/tests/sql/yt_file.py
+++ b/ydb/library/yql/tests/sql/yt_file.py
@@ -8,7 +8,7 @@ import yatest.common
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
+ do_custom_query_check, stable_result_file, stable_table_file, is_with_final_result_issues
from yqlrun import YQLRun
from utils import get_config, get_parameters_json, DATA_PATH
@@ -55,7 +55,10 @@ def run_test(suite, case, cfg, tmpdir, what, yql_http_file_server):
(res, tables_res) = run_file_no_cache('yt', suite, case, cfg, config, yql_http_file_server, extra_args=['--lineage'])
return [yatest.common.canonical_file(res.results_file)]
- (res, tables_res) = run_file('yt', suite, case, cfg, config, yql_http_file_server)
+ extra_final_args = []
+ if is_with_final_result_issues(config):
+ extra_final_args += ['--with-final-issues']
+ (res, tables_res) = run_file('yt', suite, case, cfg, config, yql_http_file_server, extra_args=extra_final_args)
to_canonize = []
diff --git a/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json b/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json
index 2c6162416b1..2b693945837 100644
--- a/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json
+++ b/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/result.json
@@ -727,6 +727,37 @@
"uri": "https://{canondata_backend}/1817427/0b979af6b2bfa42e752a296b0288b726527203dd/resource.tar.gz#test.test_blocks-sub_uint64_opt2--Results_/results.txt"
}
],
+ "test.test[blocks-type_and_callable_stats--Debug]": [
+ {
+ "checksum": "abf887f971c093b3c766c0d61de9bfa5",
+ "size": 3140,
+ "uri": "https://{canondata_backend}/1942278/7c66ffff1df826f3e0283b5718f3b64fef634b24/resource.tar.gz#test.test_blocks-type_and_callable_stats--Debug_/opt.yql"
+ }
+ ],
+ "test.test[blocks-type_and_callable_stats--Peephole]": [
+ {
+ "checksum": "7c4459aaef912df4e3a670d1353db50b",
+ "size": 3060,
+ "uri": "https://{canondata_backend}/1942278/7c66ffff1df826f3e0283b5718f3b64fef634b24/resource.tar.gz#test.test_blocks-type_and_callable_stats--Peephole_/opt.yql"
+ }
+ ],
+ "test.test[blocks-type_and_callable_stats--Plan]": [
+ {
+ "checksum": "990c31fd75086073adb260445a1886fa",
+ "size": 3527,
+ "uri": "https://{canondata_backend}/1936842/85945930c4a0d22d0dbc35897f90760fc842f68b/resource.tar.gz#test.test_blocks-type_and_callable_stats--Plan_/plan.txt"
+ }
+ ],
+ "test.test[blocks-type_and_callable_stats--Results]": [
+ {
+ "checksum": "d73069afcdb42caedfabf2180cc11bc2",
+ "size": 10729,
+ "uri": "https://{canondata_backend}/1942278/7c66ffff1df826f3e0283b5718f3b64fef634b24/resource.tar.gz#test.test_blocks-type_and_callable_stats--Results_/results.txt"
+ },
+ {
+ "uri": "file://test.test_blocks-type_and_callable_stats--Results_/extracted"
+ }
+ ],
"test.test[coalesce-coalesce_symmetry-default.txt-Debug]": [
{
"checksum": "eaea85a7f97f5d800e13e8d9676a846e",
diff --git a/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/test.test_blocks-type_and_callable_stats--Results_/extracted b/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/test.test_blocks-type_and_callable_stats--Results_/extracted
new file mode 100644
index 00000000000..4260358aac6
--- /dev/null
+++ b/ydb/library/yql/tests/sql/yt_native_file/part5/canondata/test.test_blocks-type_and_callable_stats--Results_/extracted
@@ -0,0 +1,3 @@
+<tmp_path>/program.sql:<main>: Info: Most frequent types which do not support block mode: Dict, DyNumber, List, Void
+
+<tmp_path>/program.sql:<main>: Info: Most frequent callables which do not support block mode: Re2.Grep, Re2.Match, SafeCast \ No newline at end of file
diff --git a/ydb/library/yql/tools/dqrun/dqrun.cpp b/ydb/library/yql/tools/dqrun/dqrun.cpp
index 9370779057d..c69af2f6c7c 100644
--- a/ydb/library/yql/tools/dqrun/dqrun.cpp
+++ b/ydb/library/yql/tools/dqrun/dqrun.cpp
@@ -132,6 +132,7 @@ struct TRunOptions {
IOutputStream* ErrStream = &Cerr;
IOutputStream* TracePlan = &Cerr;
bool UseMetaFromGraph = false;
+ bool WithFinalIssues = false;
};
class TStoreMappingFunctor: public NLastGetopt::IOptHandler {
@@ -409,6 +410,9 @@ int RunProgram(TProgramPtr program, const TRunOptions& options, const THashMap<T
auto config = TOptPipelineConfigurator(program, options.PrintPlan, options.TracePlan);
status = program->RunWithConfig(options.User, config);
}
+ if (options.WithFinalIssues) {
+ program->FinalizeIssues();
+ }
program->PrintErrorsTo(*options.ErrStream);
if (status == TProgram::TStatus::Error) {
if (options.TraceOpt) {
@@ -677,6 +681,7 @@ int RunMain(int argc, const char* argv[])
.StoreResult(&tokenAccessorEndpoint);
opts.AddLongOption("yson-attrs", "Provide operation yson attribues").StoreResult(&ysonAttrs);
opts.AddLongOption("pg-ext", "pg extensions config file").StoreResult(&pgExtConfig);
+ opts.AddLongOption("with-final-issues").NoArgument();
opts.AddHelpOption('h');
opts.SetFreeArgsNum(0);
@@ -1090,6 +1095,10 @@ int RunMain(int argc, const char* argv[])
program->SetOperationAttrsYson(ysonAttrs);
}
+ if (res.Has("with-final-issues")) {
+ runOptions.WithFinalIssues = true;
+ }
+
int result = RunProgram(std::move(program), runOptions, clusters, sqlFlags);
if (res.Has("metrics")) {
NProto::TMetricsRegistrySnapshot snapshot;
diff --git a/ydb/library/yql/tools/yqlrun/http/yql_server.cpp b/ydb/library/yql/tools/yqlrun/http/yql_server.cpp
index 7edbd52bd41..357e1c5bc33 100644
--- a/ydb/library/yql/tools/yqlrun/http/yql_server.cpp
+++ b/ydb/library/yql/tools/yqlrun/http/yql_server.cpp
@@ -442,6 +442,9 @@ YQL_ACTION(OptimizeOrValidateFile)
Writer.Write(TStringBuf("opttrace"), traceOut->Str());
}
+ if (options & TYqlAction::WithFinalIssues) {
+ prg->FinalizeIssues();
+ }
WriteStatus(noError, prg->Issues());
}
};
@@ -509,6 +512,9 @@ YQL_ACTION(FileRun)
Writer.Write(TStringBuf("opttrace"), traceOut->Str());
}
+ if (options & TYqlAction::WithFinalIssues) {
+ prg->FinalizeIssues();
+ }
WriteStatus(status != TProgram::TStatus::Error, prg->Issues());
if (status != TProgram::TStatus::Error) {
diff --git a/ydb/library/yql/tools/yqlrun/http/yql_servlet.h b/ydb/library/yql/tools/yqlrun/http/yql_servlet.h
index d6e65fa31b4..8ee9b402880 100644
--- a/ydb/library/yql/tools/yqlrun/http/yql_servlet.h
+++ b/ydb/library/yql/tools/yqlrun/http/yql_servlet.h
@@ -37,6 +37,7 @@ public:
PrintAst = 0x0100,
PrintExpr = 0x0200,
PrintTraceOpt = 0x0400,
+ WithFinalIssues = 0x0800,
};
public:
@@ -105,6 +106,7 @@ public:
} else if (lang == TStringBuf("sql")) {
options |= TYqlAction::SqlProgram;
}
+ options |= TYqlAction::WithFinalIssues;
TStringStream output;
NJson::TJsonWriter writer(&output, false);
diff --git a/ydb/library/yql/tools/yqlrun/yqlrun.cpp b/ydb/library/yql/tools/yqlrun/yqlrun.cpp
index 67057b0f096..21c5f337132 100644
--- a/ydb/library/yql/tools/yqlrun/yqlrun.cpp
+++ b/ydb/library/yql/tools/yqlrun/yqlrun.cpp
@@ -138,6 +138,13 @@ public:
out << baseSS.Data();
}
+ void FinalizeIssues() {
+ BaseProg->FinalizeIssues();
+ for (auto& info : Infos) {
+ info.Prog->FinalizeIssues();
+ }
+ }
+
void PrintErrorsTo(IOutputStream& out) const {
TStringStream baseSS;
BaseProg->PrintErrorsTo(baseSS);
@@ -474,6 +481,7 @@ int Main(int argc, const char *argv[])
opts.AddLongOption("test-format", "compare formatted query's AST with the original query's AST (only syntaxVersion=1 is supported)").NoArgument();
opts.AddLongOption("show-kernels", "show all Arrow kernel families").NoArgument();
opts.AddLongOption("pg-ext", "pg extensions config file").StoreResult(&pgExtConfig);
+ opts.AddLongOption("with-final-issues", "Include some final messages (like statistic) in issues").NoArgument();
opts.SetFreeArgsMax(0);
TOptsParseResult res(&opts, argc, argv);
@@ -842,6 +850,9 @@ int Main(int argc, const char *argv[])
status = program->Lineage(username, traceOut, exprOut, withTypes);
}
+ if (res.Has("with-final-issues")) {
+ program->FinalizeIssues();
+ }
program->PrintErrorsTo(*errStream);
if (status == TProgram::TStatus::Error) {
return 1;