@@ -3225,14 +3225,32 @@ namespace NTypeAnnImpl {
3225
3225
return IGraphTransformer::TStatus::Repeat;
3226
3226
}
3227
3227
3228
- bool isOptional1, isOptional2;
3229
- if (const TDataExprType *dataTypeOne, *dataTypeTwo;
3230
- !(EnsureDataOrOptionalOfData(input->Head(), isOptional1, dataTypeOne, ctx.Expr) && EnsureDataOrOptionalOfData(input->Tail(), isOptional2, dataTypeTwo, ctx.Expr)
3231
- && EnsureStringOrUtf8Type(input->Head().Pos(), *dataTypeOne, ctx.Expr) && EnsureStringOrUtf8Type(input->Tail().Pos(), *dataTypeTwo, ctx.Expr))) {
3228
+ if (!EnsureComputable(input->Head(), ctx.Expr) || !EnsureComputable(input->Tail(), ctx.Expr)) {
3232
3229
return IGraphTransformer::TStatus::Error;
3233
3230
}
3234
3231
3235
- if (isOptional1 || isOptional2)
3232
+ bool hasOptionals = false;
3233
+ for (auto& child : input->ChildrenList()) {
3234
+ const TTypeAnnotationNode* type = child->GetTypeAnn();
3235
+ if (type->GetKind() == ETypeAnnotationKind::Pg) {
3236
+ type = FromPgImpl(child->Pos(), type, ctx.Expr);
3237
+ if (!type) {
3238
+ return IGraphTransformer::TStatus::Error;
3239
+ }
3240
+ }
3241
+ bool isOptional = false;
3242
+ const TDataExprType* dataType = nullptr;
3243
+ if (!IsDataOrOptionalOfData(type, isOptional, dataType) ||
3244
+ !(dataType->GetSlot() == EDataSlot::String || dataType->GetSlot() == EDataSlot::Utf8))
3245
+ {
3246
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder()
3247
+ << "Expected (optional) string/utf8 or corresponding Pg type, but got: " << *child->GetTypeAnn()));
3248
+ return IGraphTransformer::TStatus::Error;
3249
+ }
3250
+ hasOptionals = hasOptionals || isOptional;
3251
+ }
3252
+
3253
+ if (hasOptionals)
3236
3254
input->SetTypeAnn(ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool)));
3237
3255
else
3238
3256
input->SetTypeAnn(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Bool));
@@ -11107,6 +11125,48 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
11107
11125
return IGraphTransformer::TStatus::Ok;
11108
11126
}
11109
11127
11128
+ IGraphTransformer::TStatus RangeToPgWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
11129
+ Y_UNUSED(output);
11130
+
11131
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
11132
+ return IGraphTransformer::TStatus::Error;
11133
+ }
11134
+
11135
+ if (!EnsureListType(input->Head(), ctx.Expr)) {
11136
+ return IGraphTransformer::TStatus::Error;
11137
+ }
11138
+
11139
+ auto argType = input->Head().GetTypeAnn();
11140
+ auto rangeType = argType->Cast<TListExprType>()->GetItemType();
11141
+ if (!EnsureValidRange(input->Head().Pos(), rangeType, ctx.Expr)) {
11142
+ return IGraphTransformer::TStatus::Error;
11143
+ }
11144
+
11145
+ auto boundaryType = rangeType->Cast<TTupleExprType>()->GetItems().front();
11146
+ const auto& boundaryItems = boundaryType->Cast<TTupleExprType>()->GetItems();
11147
+
11148
+ TTypeAnnotationNode::TListType resultBoundaryItems;
11149
+ resultBoundaryItems.reserve(boundaryItems.size());
11150
+ for (size_t i = 0; i < boundaryItems.size(); ++i) {
11151
+ if (i % 2 == 0) {
11152
+ resultBoundaryItems.push_back(boundaryItems[i]);
11153
+ } else {
11154
+ auto keyType = boundaryItems[i]->Cast<TOptionalExprType>()->GetItemType();
11155
+ auto pgKeyType = ToPgImpl(input->Head().Pos(), keyType, ctx.Expr);
11156
+ if (!pgKeyType) {
11157
+ return IGraphTransformer::TStatus::Error;
11158
+ }
11159
+ resultBoundaryItems.push_back(ctx.Expr.MakeType<TOptionalExprType>(pgKeyType));
11160
+ }
11161
+ }
11162
+
11163
+ const TTypeAnnotationNode* resultBoundaryType = ctx.Expr.MakeType<TTupleExprType>(resultBoundaryItems);
11164
+ const TTypeAnnotationNode* resultRangeType =
11165
+ ctx.Expr.MakeType<TTupleExprType>(TTypeAnnotationNode::TListType{resultBoundaryType, resultBoundaryType});
11166
+ input->SetTypeAnn(ctx.Expr.MakeType<TListExprType>(resultRangeType));
11167
+ return IGraphTransformer::TStatus::Ok;
11168
+ }
11169
+
11110
11170
IGraphTransformer::TStatus RangeCreateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
11111
11171
Y_UNUSED(output);
11112
11172
@@ -12164,6 +12224,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
12164
12224
ExtFunctions["OrderedSqlRename"] = &SqlRenameWrapper;
12165
12225
12166
12226
Functions["AsRange"] = &AsRangeWrapper;
12227
+ Functions["RangeToPg"] = &RangeToPgWrapper;
12167
12228
Functions["RangeCreate"] = &RangeCreateWrapper;
12168
12229
Functions["RangeEmpty"] = &RangeEmptyWrapper;
12169
12230
Functions["RangeFor"] = &RangeForWrapper;
0 commit comments