diff options
author | vvvv <vvvv@yandex-team.com> | 2024-11-07 04:19:26 +0300 |
---|---|---|
committer | vvvv <vvvv@yandex-team.com> | 2024-11-07 04:29:50 +0300 |
commit | 2661be00f3bc47590fda9218bf0386d6355c8c88 (patch) | |
tree | 3d316c07519191283d31c5f537efc6aabb42a2f0 /yql/essentials/minikql/mkql_node_builder.cpp | |
parent | cf2a23963ac10add28c50cc114fbf48953eca5aa (diff) | |
download | ydb-2661be00f3bc47590fda9218bf0386d6355c8c88.tar.gz |
Moved yql/minikql YQL-19206
init
[nodiff:caesar]
commit_hash:d1182ef7d430ccf7e4d37ed933c7126d7bd5d6e4
Diffstat (limited to 'yql/essentials/minikql/mkql_node_builder.cpp')
-rw-r--r-- | yql/essentials/minikql/mkql_node_builder.cpp | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/yql/essentials/minikql/mkql_node_builder.cpp b/yql/essentials/minikql/mkql_node_builder.cpp new file mode 100644 index 0000000000..de027eb30c --- /dev/null +++ b/yql/essentials/minikql/mkql_node_builder.cpp @@ -0,0 +1,399 @@ +#include "mkql_node_builder.h" +#include "mkql_node_printer.h" + +#include <util/generic/algorithm.h> + +namespace NKikimr { +namespace NMiniKQL { + +using namespace NDetail; + +namespace { + TNode* BuildCallableTypePayload(const TVector<TStringBuf>& argNames, + const TVector<ui64>& argFlags, TStringBuf payload, const TTypeEnvironment& env) { + TStructTypeBuilder itemTypeBuilder(env); + itemTypeBuilder.Add("Name", TDataType::Create(NUdf::TDataType<char*>::Id, env)); + itemTypeBuilder.Add("Flags", TDataType::Create(NUdf::TDataType<ui64>::Id, env)); + TType* itemType = itemTypeBuilder.Build(); + + bool startedNames = false; + THashSet<TStringBuf> usedNames; + TListLiteralBuilder argsListBuilder(env, itemType); + for (ui32 i = 0; i < argNames.size(); ++i) { + TStructLiteralBuilder itemBuilder(env); + auto name = argNames[i]; + auto flags = argFlags[i]; + bool hasName = name.size() > 0; + if (startedNames) { + MKQL_ENSURE(hasName, "Named arguments already started"); + } else { + startedNames = hasName; + } + + if (hasName) { + MKQL_ENSURE(usedNames.insert(name).second, "Duplication of argument name: " << name); + } + + itemBuilder.Add("Name", TRuntimeNode(BuildDataLiteral(name, NUdf::EDataSlot::String, env), true)); + itemBuilder.Add("Flags", TRuntimeNode(BuildDataLiteral(NUdf::TUnboxedValuePod(flags), NUdf::EDataSlot::Uint64, env), true)); + argsListBuilder.Add(TRuntimeNode(itemBuilder.Build(), true)); + } + + TRuntimeNode argsList = TRuntimeNode(argsListBuilder.Build(), true); + TStructLiteralBuilder payloadBuilder(env); + payloadBuilder.Add("Args", argsList); + payloadBuilder.Add("Payload", TRuntimeNode(BuildDataLiteral(payload, NUdf::EDataSlot::String, env), true)); + return payloadBuilder.Build(); + } +} + +TDataLiteral* BuildDataLiteral(const NUdf::TUnboxedValuePod& value, NUdf::TDataTypeId type, const TTypeEnvironment& env) { + return TDataLiteral::Create(value, TDataType::Create(type, env), env); +} + +TDataLiteral* BuildDataLiteral(const NUdf::TStringRef& data, NUdf::TDataTypeId type, const TTypeEnvironment& env) { + return BuildDataLiteral(env.NewStringValue(data), type, env); +} + +TOptionalLiteral* BuildOptionalLiteral(TRuntimeNode value, const TTypeEnvironment& env) { + auto type = TOptionalType::Create(value.GetStaticType(), env); + return TOptionalLiteral::Create(value, type, env); +} + +TOptionalLiteral* BuildEmptyOptionalLiteral(TType *itemType, const TTypeEnvironment& env) { + auto type = TOptionalType::Create(itemType, env); + return TOptionalLiteral::Create(type, env); +} + +TOptionalLiteral* BuildEmptyOptionalDataLiteral(NUdf::TDataTypeId schemeType, const TTypeEnvironment& env) { + return BuildEmptyOptionalLiteral(TDataType::Create(schemeType, env), env); +} + +TType* UnpackOptional(TRuntimeNode data, bool& isOptional) { + return UnpackOptional(data.GetStaticType(), isOptional); +} + +TType* UnpackOptional(TType* type, bool& isOptional) { + isOptional = type->IsOptional(); + if (!isOptional) + return type; + + auto optType = static_cast<TOptionalType*>(type); + return optType->GetItemType(); +} + +TDataType* UnpackOptionalData(TRuntimeNode data, bool& isOptional) { + return UnpackOptionalData(data.GetStaticType(), isOptional); +} + +TDataType* UnpackOptionalData(TType* type, bool& isOptional) { + auto unpackedType = UnpackOptional(type, isOptional); + MKQL_ENSURE(unpackedType->IsData(), + "Expected data or optional of data, actual: " << PrintNode(type, true)); + + return static_cast<TDataType*>(unpackedType); +} + +TBlockType::EShape GetResultShape(const TVector<TType*>& types) { + TBlockType::EShape result = TBlockType::EShape::Scalar; + for (auto& type : types) { + MKQL_ENSURE(type->IsBlock(), + "Expected block, actual: " << PrintNode(type, true)); + if (static_cast<TBlockType*>(type)->GetShape() == TBlockType::EShape::Many) { + result = TBlockType::EShape::Many; + } + } + return result; +} + +TTupleLiteralBuilder::TTupleLiteralBuilder(const TTypeEnvironment& env) : Env(env) +{} + +void TTupleLiteralBuilder::Reserve(ui32 size) { + Types.reserve(size); + Values.reserve(size); +} + +TTupleLiteralBuilder& TTupleLiteralBuilder::Add(TRuntimeNode value) { + Types.push_back(value.GetRuntimeType()); + Values.push_back(value); + return *this; +} + +TTupleLiteral* TTupleLiteralBuilder::Build() { + const auto& type = TTupleType::Create(Types.size(), Types.data(), Env); + return TTupleLiteral::Create(Values.size(), Values.data(), type, Env); +} + +void TTupleLiteralBuilder::Clear() { + Values.clear(); + Types.clear(); +} + +TStructTypeBuilder::TStructTypeBuilder(const TTypeEnvironment& env) + : Env(&env) +{ +} + +void TStructTypeBuilder::Reserve(ui32 size) { + Members.reserve(size); +} + +TStructTypeBuilder& TStructTypeBuilder::Add(const TStringBuf& name, TType* type, ui32* index) { + Members.push_back(TStructMember(Env->InternName(name).Str(), type, index)); + return *this; +} + +TStructType* TStructTypeBuilder::Build() { + if (Members.empty()) + return Env->GetEmptyStructLazy()->GetType(); + + Sort(Members.begin(), Members.end()); + return TStructType::Create(Members.size(), Members.data(), *Env); +} + +void TStructTypeBuilder::FillIndexes() { + ui32 index = 0; + for (const TStructMember& member: Members) { + if (member.Index) { + *(member.Index) = index++; + } + } +} + +void TStructTypeBuilder::Clear() { + Members.clear(); +} + +TStructLiteralBuilder::TStructLiteralBuilder(const TTypeEnvironment& env) + : Env(&env) +{ +} + +void TStructLiteralBuilder::Reserve(ui32 size) { + Members.reserve(size); + Values.reserve(size); +} + +TStructLiteralBuilder& TStructLiteralBuilder::Add(const TStringBuf& name, TRuntimeNode value) { + TType* valueType = value.GetStaticType(); + Members.push_back(TStructMember(Env->InternName(name).Str(), valueType)); + Values.push_back(value); + return *this; +} + +TStructLiteral* TStructLiteralBuilder::Build() { + Y_DEBUG_ABORT_UNLESS(Members.size() == Values.size()); + if (Members.empty()) + return Env->GetEmptyStructLazy(); + + TVector<std::pair<TStringBuf, ui32>> sortedIndicies(Members.size()); + for (ui32 i = 0, e = Members.size(); i < e; ++i) { + sortedIndicies[i] = std::make_pair(Members[i].Name, i); + } + + Sort(sortedIndicies.begin(), sortedIndicies.end(), + [](const std::pair<TStringBuf, ui32>& x, const std::pair<TStringBuf, ui32>& y) { + return x.first < y.first; + }); + + TVector<TStructMember> sortedMembers(Members.size()); + TVector<TRuntimeNode> sortedValues(Members.size()); + + for (ui32 i = 0, e = Members.size(); i < e; ++i) { + sortedMembers[i] = Members[sortedIndicies[i].second]; + sortedValues[i] = Values[sortedIndicies[i].second]; + } + + auto type = TStructType::Create(sortedMembers.size(), sortedMembers.data(), *Env); + return TStructLiteral::Create(sortedValues.size(), sortedValues.data(), type, *Env); +} + +void TStructLiteralBuilder::Clear() { + Members.clear(); +} + +TListLiteralBuilder::TListLiteralBuilder(const TTypeEnvironment& env, TType* type) + : Env(&env) + , Type(type) +{} + +TListLiteralBuilder& TListLiteralBuilder::Add(TRuntimeNode item) { + Items.push_back(item); + return *this; +} + +TListLiteral* TListLiteralBuilder::Build() { + auto type = TListType::Create(Type, *Env); + return TListLiteral::Create(Items.data(), Items.size(), type, *Env); +} + +void TListLiteralBuilder::Clear() { + Items.clear(); +} + +TDictLiteralBuilder::TDictLiteralBuilder(const TTypeEnvironment& env, TType* keyType, TType* payloadType) + : Env(&env) + , KeyType(keyType) + , PayloadType(payloadType) +{ +} + +void TDictLiteralBuilder::Reserve(ui32 size) { + Items.reserve(size); +} + +TDictLiteralBuilder& TDictLiteralBuilder::Add(TRuntimeNode key, TRuntimeNode payload) { + Items.push_back(std::make_pair(key, payload)); + return *this; +} + +TDictLiteral* TDictLiteralBuilder::Build() { + auto type = TDictType::Create(KeyType, PayloadType, *Env); + return TDictLiteral::Create(Items.size(), Items.data(), type, *Env); +} + +void TDictLiteralBuilder::Clear() { + Items.clear(); +} + +TCallableTypeBuilder::TCallableTypeBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType) + : Env(&env) + , Name(Env->InternName(name)) + , ReturnType(returnType) + , OptionalArgsCount(0) + , HasPayload(false) +{} + +void TCallableTypeBuilder::Reserve(ui32 size) { + Arguments.reserve(size); + ArgNames.reserve(size); + ArgFlags.reserve(size); +} + +TCallableTypeBuilder& TCallableTypeBuilder::Add(TType *type) { + Arguments.push_back(type); + ArgNames.emplace_back(); + ArgFlags.emplace_back(); + return *this; +} + +TCallableTypeBuilder& TCallableTypeBuilder::SetArgumentName(const TStringBuf& name) { + MKQL_ENSURE(!ArgNames.empty(), "No arguments"); + HasPayload = true; + ArgNames.back() = name; + return *this; +} + +TCallableTypeBuilder& TCallableTypeBuilder::SetArgumentFlags(ui64 flags) { + MKQL_ENSURE(!ArgFlags.empty(), "No arguments"); + HasPayload = true; + ArgFlags.back() = flags; + return *this; +} + +TCallableTypeBuilder& TCallableTypeBuilder::SetOptionalArgs(ui32 count) { + OptionalArgsCount = count; + return *this; +} + +TCallableTypeBuilder& TCallableTypeBuilder::SetPayload(const TStringBuf& data) { + HasPayload = true; + FuncPayload = data; + return *this; +} + +TCallableType* TCallableTypeBuilder::Build() { + TNode* payload = nullptr; + if (HasPayload) { + payload = BuildCallableTypePayload(ArgNames, ArgFlags, FuncPayload, *Env); + } + + auto ret = TCallableType::Create(ReturnType, Name.Str(), Arguments.size(), Arguments.data(), payload, *Env); + ret->SetOptionalArgumentsCount(OptionalArgsCount); + return ret; +} + +void TCallableTypeBuilder::Clear() { + Arguments.clear(); + ArgNames.clear(); + ArgFlags.clear(); + OptionalArgsCount = 0; + HasPayload = false; + FuncPayload = TStringBuf(); +} + +TCallableBuilder::TCallableBuilder(const TTypeEnvironment& env, const TStringBuf& name, TType* returnType, bool disableMerge) + : Env(&env) + , Name(Env->InternName(name)) + , ReturnType(returnType) + , DisableMerge(disableMerge) + , OptionalArgsCount(0) + , HasPayload(false) +{} + +void TCallableBuilder::Reserve(ui32 size) { + Arguments.reserve(size); + Inputs.reserve(size); + ArgNames.reserve(size); + ArgFlags.reserve(size); +} + +TCallableBuilder& TCallableBuilder::Add(TRuntimeNode input) { + TType* inputType = input.GetStaticType(); + Arguments.push_back(inputType); + Inputs.push_back(input); + ArgNames.emplace_back(); + ArgFlags.emplace_back(); + return *this; +} + +TCallableBuilder& TCallableBuilder::SetOptionalArgs(ui32 count) { + OptionalArgsCount = count; + return *this; +} + +TCallableBuilder& TCallableBuilder::SetTypePayload(const TStringBuf& data) { + HasPayload = true; + FuncPayload = data; + return *this; +} + +TCallableBuilder& TCallableBuilder::SetArgumentName(const TStringBuf& name) { + MKQL_ENSURE(!ArgNames.empty(), "No arguments"); + HasPayload = true; + ArgNames.back() = name; + return *this; +} + +TCallableBuilder& TCallableBuilder::SetArgumentFlags(ui64 flags) { + MKQL_ENSURE(!ArgFlags.empty(), "No arguments"); + HasPayload = true; + ArgFlags.back() = flags; + return *this; +} + +TCallable* TCallableBuilder::Build() { + TNode* payload = nullptr; + if (HasPayload) { + payload = BuildCallableTypePayload(ArgNames, ArgFlags, FuncPayload, *Env); + } + + auto type = TCallableType::Create(ReturnType, Name.Str(), Arguments.size(), Arguments.data(), payload, *Env); + type->SetOptionalArgumentsCount(OptionalArgsCount); + if (DisableMerge) + type->DisableMerge(); + return TCallable::Create(Inputs.size(), Inputs.data(), type, *Env); +} + +void TCallableBuilder::Clear() { + Arguments.clear(); + Inputs.clear(); + ArgNames.clear(); + ArgFlags.clear(); + OptionalArgsCount = 0; + FuncPayload = TStringBuf(); +} + +} +} |