summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvvvv <[email protected]>2025-02-20 17:52:55 +0300
committervvvv <[email protected]>2025-02-20 18:09:50 +0300
commit85a37e6d028089a8eb1680d5a8d701c58ea48965 (patch)
tree0d43ed225e659989a021ade01d84aa7329883977
parenta9b386524b35fd2b5f62cf1fd22a7304120e9cec (diff)
YQL-19588 early scan for error types
commit_hash:65fc8d62e0b7fa491747980a3a40e14b4742d1bc
-rw-r--r--yql/essentials/ast/yql_expr.h17
-rw-r--r--yql/essentials/core/common_opt/yql_co_transformer.cpp36
-rw-r--r--yql/essentials/core/services/yql_transform_pipeline.cpp1
-rw-r--r--yql/essentials/providers/common/udf_resolve/yql_simple_udf_resolver.cpp14
-rw-r--r--yt/yql/tests/sql/suites/aggregate/error_type.cfg2
-rw-r--r--yt/yql/tests/sql/suites/aggregate/error_type.sql16
6 files changed, 74 insertions, 12 deletions
diff --git a/yql/essentials/ast/yql_expr.h b/yql/essentials/ast/yql_expr.h
index a64a2f9aec6..92e6c00e54e 100644
--- a/yql/essentials/ast/yql_expr.h
+++ b/yql/essentials/ast/yql_expr.h
@@ -178,6 +178,7 @@ enum ETypeAnnotationFlags : ui32 {
TypeNonPresortable = 0x1000,
TypeHasDynamicSize = 0x2000,
TypeNonComparableInternal = 0x4000,
+ TypeHasError = 0x8000,
};
const ui64 TypeHashMagic = 0x10000;
@@ -313,6 +314,10 @@ public:
return (GetFlags() & TypeNonPresortable) == 0;
}
+ bool HasErrors() const {
+ return (GetFlags() & TypeHasError) != 0;
+ }
+
ui32 GetFlags() const {
return Flags;
}
@@ -1038,7 +1043,7 @@ public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Type;
TTypeExprType(ui64 hash, const TTypeAnnotationNode* type)
- : TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeNonComputable, hash, 0)
+ : TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeNonComputable | (type->GetFlags() & TypeHasError), hash, 0)
, Type(type)
{
}
@@ -1157,7 +1162,7 @@ public:
TCallableExprType(ui64 hash, const TTypeAnnotationNode* returnType, const TVector<TArgumentInfo>& arguments
, size_t optionalArgumentsCount, const TStringBuf& payload)
- : TTypeAnnotationNode(KindValue, MakeFlags(returnType), hash, returnType->GetUsedPgExtensions())
+ : TTypeAnnotationNode(KindValue, MakeFlags(arguments, returnType), hash, returnType->GetUsedPgExtensions())
, ReturnType(returnType)
, Arguments(arguments)
, OptionalArgumentsCount(optionalArgumentsCount)
@@ -1244,9 +1249,13 @@ public:
}
private:
- static ui32 MakeFlags(const TTypeAnnotationNode* returnType) {
+ static ui32 MakeFlags(const TVector<TArgumentInfo>& arguments, const TTypeAnnotationNode* returnType) {
ui32 flags = TypeNonPersistable;
flags |= returnType->GetFlags();
+ for (const auto& arg : arguments) {
+ flags |= (arg.Type->GetFlags() & TypeHasError);
+ }
+
return flags;
}
@@ -1346,7 +1355,7 @@ public:
static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Error;
TErrorExprType(ui64 hash, const TIssue& error)
- : TTypeAnnotationNode(KindValue, 0, hash, 0)
+ : TTypeAnnotationNode(KindValue, TypeHasError, hash, 0)
, Error(error)
{}
diff --git a/yql/essentials/core/common_opt/yql_co_transformer.cpp b/yql/essentials/core/common_opt/yql_co_transformer.cpp
index d589e168e5e..52b454a5af0 100644
--- a/yql/essentials/core/common_opt/yql_co_transformer.cpp
+++ b/yql/essentials/core/common_opt/yql_co_transformer.cpp
@@ -34,10 +34,14 @@ private:
IGraphTransformer::TStatus DoTransform(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx,
const TFinalizingOptimizerMap& callables);
+ bool ScanErrors(const TExprNode& node, TExprContext& ctx);
+
private:
TProcessedNodesSet SimpleProcessedNodes[TCoCallableRules::SIMPLE_STEPS];
TProcessedNodesSet FlowProcessedNodes[TCoCallableRules::FLOW_STEPS];
TProcessedNodesSet FinalProcessedNodes;
+ TProcessedNodesSet ErrorProcessedNodes;
+ THashSet<TIssue> AddedErrors;
TTypeAnnotationContext* TypeCtx;
const bool Final;
};
@@ -79,10 +83,16 @@ IGraphTransformer::TStatus TCommonOptTransformer::DoTransform(TExprNode::TPtr in
return status;
}
- return status;
+ if (!ScanErrors(*output, ctx)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ return IGraphTransformer::TStatus::Ok;
}
void TCommonOptTransformer::Rewind() {
+ AddedErrors.clear();
+ ErrorProcessedNodes.clear();
FinalProcessedNodes.clear();
for (auto& set : FlowProcessedNodes) {
@@ -94,6 +104,30 @@ void TCommonOptTransformer::Rewind() {
}
}
+bool TCommonOptTransformer::ScanErrors(const TExprNode& node, TExprContext& ctx) {
+ auto [it, inserted] = ErrorProcessedNodes.emplace(node.UniqueId());
+ if (!inserted) {
+ return true;
+ }
+
+ for (const auto& child : node.Children()) {
+ if (!ScanErrors(*child, ctx)) {
+ return false;
+ }
+ }
+
+ if (!node.IsCallable("ErrorType")) {
+ return true;
+ }
+
+ auto issue = node.GetTypeAnn()->Cast<TTypeExprType>()->GetType()->Cast<TErrorExprType>()->GetError();
+ if (AddedErrors.insert(issue).second) {
+ ctx.AddError(issue);
+ }
+
+ return false;
+}
+
IGraphTransformer::TStatus TCommonOptTransformer::DoTransform(
const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx,
const TCallableOptimizerMap& callables,
diff --git a/yql/essentials/core/services/yql_transform_pipeline.cpp b/yql/essentials/core/services/yql_transform_pipeline.cpp
index 5f7165c10df..2dd8f2c2787 100644
--- a/yql/essentials/core/services/yql_transform_pipeline.cpp
+++ b/yql/essentials/core/services/yql_transform_pipeline.cpp
@@ -200,7 +200,6 @@ TTransformationPipeline& TTransformationPipeline::AddOptimization(bool checkWorl
TTransformationPipeline& TTransformationPipeline::AddLineageOptimization(TMaybe<TString>& lineageOut, EYqlIssueCode issueCode) {
AddCommonOptimization(issueCode);
- AddCheckExecution(false, issueCode);
Transformers_.push_back(TTransformStage(
CreateFunctorTransformer(
[typeCtx = TypeAnnotationContext_, &lineageOut](const TExprNode::TPtr& input, TExprNode::TPtr& output, TExprContext& ctx) {
diff --git a/yql/essentials/providers/common/udf_resolve/yql_simple_udf_resolver.cpp b/yql/essentials/providers/common/udf_resolve/yql_simple_udf_resolver.cpp
index 0dbc7ce4d26..f85050b5644 100644
--- a/yql/essentials/providers/common/udf_resolve/yql_simple_udf_resolver.cpp
+++ b/yql/essentials/providers/common/udf_resolve/yql_simple_udf_resolver.cpp
@@ -178,12 +178,14 @@ bool LoadFunctionsMetadata(const TVector<IUdfResolver::TFunction*>& functions,
try {
TType* mkqlUserType = nullptr;
if (udf.UserType) {
- // scan for error types
- TErrorTypeVisitor errorVisitor(ctx);
- udf.UserType->Accept(errorVisitor);
- if (errorVisitor.HasErrors()) {
- hasErrors = true;
- continue;
+ if (udf.UserType->HasErrors()) {
+ // scan for error types
+ TErrorTypeVisitor errorVisitor(ctx);
+ udf.UserType->Accept(errorVisitor);
+ if (errorVisitor.HasErrors()) {
+ hasErrors = true;
+ continue;
+ }
}
TStringStream err;
diff --git a/yt/yql/tests/sql/suites/aggregate/error_type.cfg b/yt/yql/tests/sql/suites/aggregate/error_type.cfg
new file mode 100644
index 00000000000..83cfd96179a
--- /dev/null
+++ b/yt/yql/tests/sql/suites/aggregate/error_type.cfg
@@ -0,0 +1,2 @@
+xfail
+
diff --git a/yt/yql/tests/sql/suites/aggregate/error_type.sql b/yt/yql/tests/sql/suites/aggregate/error_type.sql
new file mode 100644
index 00000000000..a0e54ef444c
--- /dev/null
+++ b/yt/yql/tests/sql/suites/aggregate/error_type.sql
@@ -0,0 +1,16 @@
+/* custom error: Uncompatible member x types: Int32 and String */
+use plato;
+
+insert into @foo
+select 1 as x;
+
+insert into @bar
+select 'z' as x;
+
+commit;
+
+select * from @foo
+union
+select * from @bar;
+
+