diff options
author | kniv <kniv@yandex-team.ru> | 2022-05-04 14:20:38 +0300 |
---|---|---|
committer | kniv <kniv@yandex-team.ru> | 2022-05-04 14:20:38 +0300 |
commit | 8084db094800173c86cb75c707a7ecd3bdf4a84d (patch) | |
tree | 49ed0b99e927308b107b0a1075994deab8913a6d | |
parent | 2a360769e991982cceffc8dbb2bb30757cef5407 (diff) | |
download | ydb-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.h | 8 | ||||
-rw-r--r-- | ydb/library/yql/core/type_ann/type_ann_core.cpp | 11 |
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 |