#include "mkql_lookup.h" #include // Y_IGNORE #include namespace NKikimr { namespace NMiniKQL { namespace { class TLookupWrapper : public TMutableCodegeneratorPtrNode { typedef TMutableCodegeneratorPtrNode TBaseComputation; public: TLookupWrapper(TComputationMutables& mutables, EValueRepresentation kind, IComputationNode* dict, IComputationNode* key) : TBaseComputation(mutables, kind) , Dict(dict) , Key(key) { } NUdf::TUnboxedValue DoCalculate(TComputationContext& ctx) const { return Dict->GetValue(ctx).Lookup(Key->GetValue(ctx)); } #ifndef MKQL_DISABLE_CODEGEN void DoGenerateGetValue(const TCodegenContext& ctx, Value* pointer, BasicBlock*& block) const { const auto dict = GetNodeValue(Dict, ctx, block); GetNodeValue(pointer, Key, ctx, block); const auto keyp = new LoadInst(Type::getInt128Ty(ctx.Codegen.GetContext()), pointer, "key", block); CallBoxedValueVirtualMethod(pointer, dict, ctx.Codegen, block, pointer); ValueUnRef(Key->GetRepresentation(), keyp, ctx, block); if (Dict->IsTemporaryValue()) CleanupBoxed(dict, ctx, block); } #endif private: void RegisterDependencies() const final { DependsOn(Dict); DependsOn(Key); } IComputationNode* const Dict; IComputationNode* const Key; }; } IComputationNode* WrapLookup(TCallable& callable, const TComputationNodeFactoryContext& ctx) { MKQL_ENSURE(callable.GetInputsCount() == 2, "Expected 2 args"); const auto dict = LocateNode(ctx.NodeLocator, callable, 0); const auto key = LocateNode(ctx.NodeLocator, callable, 1); return new TLookupWrapper(ctx.Mutables, GetValueRepresentation(callable.GetType()->GetReturnType()), dict, key); } } }