summaryrefslogtreecommitdiffstats
path: root/yql/essentials/minikql/mkql_program_builder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'yql/essentials/minikql/mkql_program_builder.cpp')
-rw-r--r--yql/essentials/minikql/mkql_program_builder.cpp108
1 files changed, 97 insertions, 11 deletions
diff --git a/yql/essentials/minikql/mkql_program_builder.cpp b/yql/essentials/minikql/mkql_program_builder.cpp
index e9d68fe254c..68c92cda92c 100644
--- a/yql/essentials/minikql/mkql_program_builder.cpp
+++ b/yql/essentials/minikql/mkql_program_builder.cpp
@@ -6185,23 +6185,59 @@ TRuntimeNode TProgramBuilder::PgConst(TPgType* pgType, const std::string_view& v
TRuntimeNode TProgramBuilder::PgResolvedCall(bool useContext, const std::string_view& name,
ui32 id, const TArrayRef<const TRuntimeNode>& args,
- TType* returnType, bool rangeFunction) {
- TCallableBuilder callableBuilder(Env_, __func__, returnType);
- callableBuilder.Add(NewDataLiteral(useContext));
- callableBuilder.Add(NewDataLiteral(rangeFunction));
- callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(name));
- callableBuilder.Add(NewDataLiteral(id));
- for (const auto& arg : args) {
- callableBuilder.Add(arg);
+ TType* returnType, bool rangeFunction, ui32 collationOid) {
+ // On old runtimes, always use the "PgResolvedCall" callable exactly as before (and
+ // explicit COLLATE, which needs the collation oid slot, isn't representable at all).
+ // Once the runtime is new enough, ALWAYS use the distinct "PgResolvedCall2" callable -
+ // with an extra collation oid slot right after `id` - even when collationOid is 0, so
+ // that "PgResolvedCall" stops being emitted entirely once the whole fleet is upgraded
+ // past this version, and its read-side support can eventually be deleted. The two
+ // shapes are told apart by callable name rather than input count/type, since an arg's
+ // own static type can legitimately be non-Pg (e.g. a NULL literal).
+ if constexpr (RuntimeVersion < 81U) {
+ Y_ENSURE(collationOid == 0, "Explicit COLLATE requires minikql runtime version >= 81, current: " << RuntimeVersion);
+ TCallableBuilder callableBuilder(Env_, "PgResolvedCall", returnType);
+ callableBuilder.Add(NewDataLiteral(useContext));
+ callableBuilder.Add(NewDataLiteral(rangeFunction));
+ callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(name));
+ callableBuilder.Add(NewDataLiteral(id));
+ for (const auto& arg : args) {
+ callableBuilder.Add(arg);
+ }
+ return TRuntimeNode(callableBuilder.Build(), /*isImmediate=*/false);
+ } else {
+ TCallableBuilder callableBuilder(Env_, "PgResolvedCall2", returnType);
+ callableBuilder.Add(NewDataLiteral(useContext));
+ callableBuilder.Add(NewDataLiteral(rangeFunction));
+ callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(name));
+ callableBuilder.Add(NewDataLiteral(id));
+ callableBuilder.Add(NewDataLiteral(collationOid));
+ for (const auto& arg : args) {
+ callableBuilder.Add(arg);
+ }
+ return TRuntimeNode(callableBuilder.Build(), /*isImmediate=*/false);
}
- return TRuntimeNode(callableBuilder.Build(), /*isImmediate=*/false);
}
TRuntimeNode TProgramBuilder::BlockPgResolvedCall(const std::string_view& name, ui32 id,
- const TArrayRef<const TRuntimeNode>& args, TType* returnType) {
- TCallableBuilder callableBuilder(Env_, __func__, returnType);
+ const TArrayRef<const TRuntimeNode>& args, TType* returnType,
+ ui32 collationOid) {
+ // Mirrors TProgramBuilder::PgResolvedCall - see the comment there.
+ if constexpr (RuntimeVersion < 81U) {
+ Y_ENSURE(collationOid == 0, "Explicit COLLATE requires minikql runtime version >= 81, current: " << RuntimeVersion);
+ TCallableBuilder callableBuilder(Env_, "BlockPgResolvedCall", returnType);
+ callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(name));
+ callableBuilder.Add(NewDataLiteral(id));
+ for (const auto& arg : args) {
+ callableBuilder.Add(arg);
+ }
+ return TRuntimeNode(callableBuilder.Build(), /*isImmediate=*/false);
+ }
+
+ TCallableBuilder callableBuilder(Env_, "BlockPgResolvedCall2", returnType);
callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(name));
callableBuilder.Add(NewDataLiteral(id));
+ callableBuilder.Add(NewDataLiteral(collationOid));
for (const auto& arg : args) {
callableBuilder.Add(arg);
}
@@ -6354,6 +6390,56 @@ TRuntimeNode TProgramBuilder::BlockWay(TRuntimeNode variant) {
return TRuntimeNode(callableBuilder.Build(), /*isImmediate=*/false);
}
+TRuntimeNode TProgramBuilder::BlockVariant(TRuntimeNode item, ui32 tupleIndex, TType* variantType) {
+ if constexpr (RuntimeVersion < 81) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+ auto itemBlockType = AS_TYPE(TBlockType, item.GetStaticType());
+ auto varType = AS_TYPE(TVariantType, variantType);
+ auto underlying = AS_TYPE(TTupleType, varType->GetUnderlyingType());
+ MKQL_ENSURE(tupleIndex < underlying->GetElementsCount(), "Wrong tuple index");
+
+ auto returnType = NewBlockType(variantType, itemBlockType->GetShape());
+ TCallableBuilder callableBuilder(Env_, __func__, returnType);
+ callableBuilder.Add(item);
+ callableBuilder.Add(NewDataLiteral<ui32>(tupleIndex));
+ return TRuntimeNode(callableBuilder.Build(), /*isImmediate=*/false);
+}
+
+TRuntimeNode TProgramBuilder::BlockVariant(TRuntimeNode item, const std::string_view& memberName, TType* variantType) {
+ if constexpr (RuntimeVersion < 81) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+ auto itemBlockType = AS_TYPE(TBlockType, item.GetStaticType());
+ auto varType = AS_TYPE(TVariantType, variantType);
+ auto underlying = AS_TYPE(TStructType, varType->GetUnderlyingType());
+ auto structIndex = underlying->GetMemberIndex(memberName);
+
+ auto returnType = NewBlockType(variantType, itemBlockType->GetShape());
+ TCallableBuilder callableBuilder(Env_, __func__, returnType);
+ callableBuilder.Add(item);
+ callableBuilder.Add(NewDataLiteral<ui32>(structIndex));
+ return TRuntimeNode(callableBuilder.Build(), /*isImmediate=*/false);
+}
+
+TRuntimeNode TProgramBuilder::BlockVariantItem(TRuntimeNode variant) {
+ if constexpr (RuntimeVersion < 82) {
+ THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__;
+ }
+ auto blockType = AS_TYPE(TBlockType, variant.GetStaticType());
+ auto inputItemType = blockType->GetItemType();
+ bool isOptional;
+ auto unpacked = UnpackOptional(inputItemType, isOptional);
+ auto variantType = AS_TYPE(TVariantType, unpacked);
+ auto alternativeType = variantType->GetAlternativeType(0);
+ auto itemReturnType = isOptional ? NewOptionalType(alternativeType) : alternativeType;
+ auto returnType = NewBlockType(itemReturnType, blockType->GetShape());
+
+ TCallableBuilder callableBuilder(Env_, __func__, returnType);
+ callableBuilder.Add(variant);
+ return TRuntimeNode(callableBuilder.Build(), /*isImmediate=*/false);
+}
+
TRuntimeNode TProgramBuilder::BlockIf(TRuntimeNode condition, TRuntimeNode thenBranch, TRuntimeNode elseBranch) {
const auto conditionType = AS_TYPE(TBlockType, condition.GetStaticType());
MKQL_ENSURE(AS_TYPE(TDataType, conditionType->GetItemType())->GetSchemeType() == NUdf::TDataType<bool>::Id,