aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkniv <kniv@yandex-team.ru>2022-05-04 14:20:38 +0300
committerkniv <kniv@yandex-team.ru>2022-05-04 14:20:38 +0300
commit8084db094800173c86cb75c707a7ecd3bdf4a84d (patch)
tree49ed0b99e927308b107b0a1075994deab8913a6d
parent2a360769e991982cceffc8dbb2bb30757cef5407 (diff)
downloadydb-8084db094800173c86cb75c707a7ecd3bdf4a84d.tar.gz
YQL-14775: [Script UDF] Forbid to use nested optionals in function signatures
[Script UDF] Forbid to use nested optionals in function signatures ref:c52c32133c43b2399bc84f1508ea4e62ecef9584
-rw-r--r--ydb/library/yql/ast/yql_expr.h8
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_core.cpp11
2 files changed, 19 insertions, 0 deletions
diff --git a/ydb/library/yql/ast/yql_expr.h b/ydb/library/yql/ast/yql_expr.h
index fd7e2dbeb18..83d36702822 100644
--- a/ydb/library/yql/ast/yql_expr.h
+++ b/ydb/library/yql/ast/yql_expr.h
@@ -122,6 +122,7 @@ enum ETypeAnnotationFlags {
TypeHasOptional = 0x100,
TypeHasManyValues = 0x200,
TypeHasBareYson = 0x400,
+ TypeHasNestedOptional = 0x800,
};
const ui64 TypeHashMagic = 0x10000;
@@ -211,6 +212,10 @@ public:
return (GetFlags() & TypeHasOptional) != 0;
}
+ bool HasNestedOptional() const {
+ return (GetFlags() & TypeHasNestedOptional) != 0;
+ }
+
bool HasOptionalOrNull() const {
return (GetFlags() & (TypeHasOptional | TypeHasNull)) != 0;
}
@@ -765,6 +770,9 @@ public:
itemType->Cast<TDataExprType>()->GetSlot() == NUdf::EDataSlot::Yson) {
ret = ret & ~TypeHasBareYson;
}
+ if (itemType->IsOptionalOrNull()) {
+ ret |= TypeHasNestedOptional;
+ }
return ret;
}
diff --git a/ydb/library/yql/core/type_ann/type_ann_core.cpp b/ydb/library/yql/core/type_ann/type_ann_core.cpp
index 8d85fe04c72..e3f7fe093d9 100644
--- a/ydb/library/yql/core/type_ann/type_ann_core.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_core.cpp
@@ -6983,6 +6983,17 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
if (!EnsureComputableType(input->Child(2)->Pos(), *callableType, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
+ bool hasNestedOptional = callableType->HasNestedOptional();
+ if (!hasNestedOptional) {
+ for (const TCallableExprType::TArgumentInfo& arg : callableType->GetArguments()) {
+ hasNestedOptional |= arg.Type->HasNestedOptional();
+ }
+ }
+ if (hasNestedOptional) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()),
+ TStringBuilder() << "Nested optionals are unsupported in script UDF"));
+ return IGraphTransformer::TStatus::Error;
+ }
}
// script body