Skip to content

Commit 742d347

Browse files
committed
Added merger factory
1 parent 3dcbfdf commit 742d347

12 files changed

Lines changed: 132 additions & 40 deletions

File tree

ydb/core/kqp/gateway/behaviour/resource_pool_classifier/initializer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ void TResourcePoolClassifierInitializer::DoPrepare(NMetadata::NInitializer::IIni
2727
AddColumn(request, TResourcePoolClassifierConfig::TDecoder::Database, Ydb::Type::UTF8, true);
2828
AddColumn(request, TResourcePoolClassifierConfig::TDecoder::Name, Ydb::Type::UTF8, true);
2929
AddColumn(request, TResourcePoolClassifierConfig::TDecoder::Rank, Ydb::Type::INT64);
30-
AddColumn(request, TResourcePoolClassifierConfig::TDecoder::ResourcePool, Ydb::Type::UTF8);
31-
AddColumn(request, TResourcePoolClassifierConfig::TDecoder::Membername, Ydb::Type::UTF8);
30+
AddColumn(request, TResourcePoolClassifierConfig::TDecoder::ConfigJson, Ydb::Type::JSON_DOCUMENT);
3231
result.emplace_back(std::make_shared<NMetadata::NInitializer::TGenericTableModifier<NMetadata::NRequest::TDialogCreateTable>>(request, "create"));
3332

3433
auto historyRequest = TResourcePoolClassifierConfig::AddHistoryTableScheme(request);

ydb/core/kqp/gateway/behaviour/resource_pool_classifier/manager.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ NMetadata::NModifications::TOperationParsingResult TResourcePoolClassifierManage
4444
auto& featuresExtractor = settings.GetFeaturesExtractor();
4545
featuresExtractor.ValidateResetFeatures();
4646

47+
NJson::TJsonValue configJson = NJson::JSON_MAP;
4748
TClassifierSettings resourcePoolClassifierSettings;
4849
for (const auto& [property, setting] : resourcePoolClassifierSettings.GetPropertiesMap()) {
4950
if (std::optional<TString> value = featuresExtractor.Extract(property)) {
@@ -57,13 +58,17 @@ NMetadata::NModifications::TOperationParsingResult TResourcePoolClassifierManage
5758
}
5859

5960
const TString value = std::visit(TClassifierSettings::TExtractor(), setting);
60-
if (property == "rank") {
61+
if (property == TResourcePoolClassifierConfig::TDecoder::Rank) {
6162
result.SetColumn(property, NMetadata::NInternal::TYDBValue::Int64(FromString<i64>(value)));
6263
} else {
63-
result.SetColumn(property, NMetadata::NInternal::TYDBValue::Utf8(value));
64+
configJson.InsertValue(property, value);
6465
}
6566
}
6667

68+
NJsonWriter::TBuf writer;
69+
writer.WriteJsonValue(&configJson);
70+
result.SetColumn(TResourcePoolClassifierConfig::TDecoder::ConfigJson, NMetadata::NInternal::TYDBValue::Utf8(writer.Str()));
71+
6772
if (!featuresExtractor.IsFinished()) {
6873
ythrow yexception() << "Unknown property: " << featuresExtractor.GetRemainedParamsString();
6974
}

ydb/core/kqp/gateway/behaviour/resource_pool_classifier/object.cpp

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "object.h"
22
#include "behaviour.h"
33

4-
#include <ydb/core/resource_pools/resource_pool_settings.h>
4+
#include <library/cpp/json/json_reader.h>
55

66

77
namespace NKikimr::NKqp {
@@ -15,8 +15,7 @@ TResourcePoolClassifierConfig::TDecoder::TDecoder(const Ydb::ResultSet& rawData)
1515
: DatabaseIdx(GetFieldIndex(rawData, Database))
1616
, NameIdx(GetFieldIndex(rawData, Name))
1717
, RankIdx(GetFieldIndex(rawData, Rank))
18-
, ResourcePoolIdx(GetFieldIndex(rawData, ResourcePool))
19-
, MembernameIdx(GetFieldIndex(rawData, Membername))
18+
, ConfigJsonIdx(GetFieldIndex(rawData, ConfigJson))
2019
{}
2120

2221
//// TResourcePoolClassifierConfig
@@ -31,12 +30,15 @@ bool TResourcePoolClassifierConfig::DeserializeFromRecord(const TDecoder& decode
3130
if (!decoder.Read(decoder.GetRankIdx(), Rank, rawData)) {
3231
Rank = -1;
3332
}
34-
if (!decoder.Read(decoder.GetResourcePoolIdx(), ResourcePool, rawData)) {
35-
ResourcePool = DEFAULT_POOL_ID;
33+
34+
TString configJsonString;
35+
if (!decoder.Read(decoder.GetConfigJsonIdx(), configJsonString, rawData)) {
36+
return false;
3637
}
37-
if (!decoder.Read(decoder.GetMembernameIdx(), Membername, rawData)) {
38-
Membername = "";
38+
if (!NJson::ReadJsonTree(configJsonString, &ConfigJson)) {
39+
return false;
3940
}
41+
4042
return true;
4143
}
4244

@@ -45,24 +47,46 @@ NMetadata::NInternal::TTableRecord TResourcePoolClassifierConfig::SerializeToRec
4547
result.SetColumn(TDecoder::Database, NMetadata::NInternal::TYDBValue::Utf8(Database));
4648
result.SetColumn(TDecoder::Name, NMetadata::NInternal::TYDBValue::Utf8(Name));
4749
result.SetColumn(TDecoder::Rank, NMetadata::NInternal::TYDBValue::Int64(Rank));
48-
result.SetColumn(TDecoder::ResourcePool, NMetadata::NInternal::TYDBValue::Utf8(ResourcePool));
49-
result.SetColumn(TDecoder::Membername, NMetadata::NInternal::TYDBValue::Utf8(Membername));
50+
51+
NJsonWriter::TBuf writer;
52+
writer.WriteJsonValue(&ConfigJson);
53+
result.SetColumn(TDecoder::ConfigJson, NMetadata::NInternal::TYDBValue::Utf8(writer.Str()));
54+
5055
return result;
5156
}
5257

58+
TClassifierSettings TResourcePoolClassifierConfig::GetClassifierSettings() const {
59+
TClassifierSettings resourcePoolClassifierSettings;
60+
61+
resourcePoolClassifierSettings.Rank = Rank;
62+
63+
const auto& properties = resourcePoolClassifierSettings.GetPropertiesMap();
64+
for (const auto& [propery, value] : ConfigJson.GetMap()) {
65+
const auto it = properties.find(propery);
66+
if (it == properties.end()) {
67+
continue;
68+
}
69+
try {
70+
std::visit(TClassifierSettings::TParser{value.GetString()}, it->second);
71+
} catch (...) {
72+
continue;
73+
}
74+
}
75+
76+
return resourcePoolClassifierSettings;
77+
}
78+
5379
NJson::TJsonValue TResourcePoolClassifierConfig::GetDebugJson() const {
5480
NJson::TJsonValue result = NJson::JSON_MAP;
5581
result.InsertValue(TDecoder::Database, Database);
5682
result.InsertValue(TDecoder::Name, Name);
5783
result.InsertValue(TDecoder::Rank, Rank);
58-
result.InsertValue(TDecoder::ResourcePool, ResourcePool);
59-
result.InsertValue(TDecoder::Membername, Membername);
84+
result.InsertValue(TDecoder::ConfigJson, ConfigJson);
6085
return result;
6186
}
6287

6388
bool TResourcePoolClassifierConfig::operator==(const TResourcePoolClassifierConfig& other) const {
64-
return std::tie(Database, Name, Rank, ResourcePool, Membername)
65-
== std::tie(other.Database, other.Name, other.Rank, other.ResourcePool, other.Membername);
89+
return std::tie(Database, Name, Rank, ConfigJson) != std::tie(other.Database, other.Name, other.Rank, other.ConfigJson);
6690
}
6791

6892
NMetadata::IClassBehaviour::TPtr TResourcePoolClassifierConfig::GetBehaviour() {
@@ -73,4 +97,33 @@ TString TResourcePoolClassifierConfig::GetTypeId() {
7397
return "RESOURCE_POOL_CLASSIFIER";
7498
}
7599

100+
NMetadata::NModifications::NColumnMerger::TMerger TResourcePoolClassifierConfig::MergerFactory(const TString& columnName) {
101+
if (columnName == TDecoder::ConfigJson) {
102+
return &JsonConfigsMerger;
103+
}
104+
return TBase::MergerFactory(columnName);
105+
}
106+
107+
bool TResourcePoolClassifierConfig::JsonConfigsMerger(Ydb::Value& self, const Ydb::Value& other) {
108+
NJson::TJsonValue selfConfigJson;
109+
if (!NJson::ReadJsonTree(self.text_value(), &selfConfigJson)) {
110+
return false;
111+
}
112+
113+
NJson::TJsonValue otherConfigJson;
114+
if (!NJson::ReadJsonTree(other.text_value(), &otherConfigJson)) {
115+
return false;
116+
}
117+
118+
for (const auto& [key, value] : otherConfigJson.GetMap()) {
119+
selfConfigJson.InsertValue(key, value);
120+
}
121+
122+
NJsonWriter::TBuf writer;
123+
writer.WriteJsonValue(&selfConfigJson);
124+
*self.mutable_text_value() = writer.Str();
125+
126+
return true;
127+
}
128+
76129
} // namespace NKikimr::NKqp
Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,50 @@
11
#pragma once
22

3+
#include <ydb/core/resource_pools/resource_pool_classifier_settings.h>
4+
35
#include <ydb/services/metadata/abstract/decoder.h>
46
#include <ydb/services/metadata/manager/object.h>
57

68

79
namespace NKikimr::NKqp {
810

911
class TResourcePoolClassifierConfig : public NMetadata::NModifications::TObject<TResourcePoolClassifierConfig> {
12+
using TBase = NMetadata::NModifications::TObject<TResourcePoolClassifierConfig>;
13+
1014
YDB_ACCESSOR_DEF(TString, Database);
1115
YDB_ACCESSOR_DEF(TString, Name);
1216
YDB_ACCESSOR_DEF(i64, Rank);
13-
YDB_ACCESSOR_DEF(TString, ResourcePool);
14-
YDB_ACCESSOR_DEF(TString, Membername);
17+
YDB_ACCESSOR_DEF(NJson::TJsonValue, ConfigJson);
1518

1619
public:
1720
class TDecoder : public NMetadata::NInternal::TDecoderBase {
1821
private:
1922
YDB_READONLY(i32, DatabaseIdx, -1);
2023
YDB_READONLY(i32, NameIdx, -1);
2124
YDB_READONLY(i32, RankIdx, -1);
22-
YDB_READONLY(i32, ResourcePoolIdx, -1);
23-
YDB_READONLY(i32, MembernameIdx, -1);
25+
YDB_READONLY(i32, ConfigJsonIdx, -1);
2426

2527
public:
2628
static inline const TString Database = "database";
2729
static inline const TString Name = "name";
2830
static inline const TString Rank = "rank";
29-
static inline const TString ResourcePool = "resource_pool";
30-
static inline const TString Membername = "membername";
31+
static inline const TString ConfigJson = "config";
3132

3233
explicit TDecoder(const Ydb::ResultSet& rawData);
3334
};
3435

3536
bool DeserializeFromRecord(const TDecoder& decoder, const Ydb::Value& rawData);
3637
NMetadata::NInternal::TTableRecord SerializeToRecord() const;
38+
NResourcePool::TClassifierSettings GetClassifierSettings() const;
3739
NJson::TJsonValue GetDebugJson() const;
3840

3941
bool operator==(const TResourcePoolClassifierConfig& other) const;
4042

4143
static NMetadata::IClassBehaviour::TPtr GetBehaviour();
4244
static TString GetTypeId();
45+
46+
static NMetadata::NModifications::NColumnMerger::TMerger MergerFactory(const TString& columnName);
47+
static bool JsonConfigsMerger(Ydb::Value& self, const Ydb::Value& other);
4348
};
4449

4550
} // namespace NKikimr::NKqp

ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6921,7 +6921,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
69216921
);)";
69226922
auto result = session.ExecuteSchemeQuery(query).GetValueSync();
69236923
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
6924-
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"membername\":\"test@user\",\"resource_pool\":\"test_pool\",\"database\":\"\\/Root\"}]}");
6924+
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"config\":{\"membername\":\"test@user\",\"resource_pool\":\"test_pool\"},\"database\":\"\\/Root\"}]}");
69256925

69266926
// Auto rank
69276927
query = R"(
@@ -6930,7 +6930,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
69306930
);)";
69316931
result = session.ExecuteSchemeQuery(query).GetValueSync();
69326932
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
6933-
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"membername\":\"test@user\",\"resource_pool\":\"test_pool\",\"database\":\"\\/Root\"},{\"rank\":1020,\"name\":\"AnotherResourcePoolClassifier\",\"membername\":\"another@user\",\"resource_pool\":\"default\",\"database\":\"\\/Root\"}]}");
6933+
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"config\":{\"membername\":\"test@user\",\"resource_pool\":\"test_pool\"},\"database\":\"\\/Root\"},{\"rank\":1020,\"name\":\"AnotherResourcePoolClassifier\",\"config\":{\"membername\":\"another@user\"},\"database\":\"\\/Root\"}]}");
69346934
}
69356935

69366936
Y_UNIT_TEST(DoubleCreateResourcePoolClassifier) {
@@ -6984,19 +6984,18 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
69846984
);)";
69856985
auto result = session.ExecuteSchemeQuery(query).GetValueSync();
69866986
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
6987-
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"membername\":\"\",\"resource_pool\":\"test_pool\",\"database\":\"\\/Root\"}]}");
6987+
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"config\":{\"resource_pool\":\"test_pool\"},\"database\":\"\\/Root\"}]}");
69886988
}
69896989

6990-
// Alter sample pool
6990+
// Test update one property
69916991
{
69926992
auto query = R"(
69936993
ALTER RESOURCE POOL CLASSIFIER MyResourcePoolClassifier
6994-
SET (RANK = 1, MEMBERNAME = "test@user"),
6995-
RESET (RESOURCE_POOL);
6994+
SET (MEMBERNAME = "test@user")
69966995
)";
69976996
auto result = session.ExecuteSchemeQuery(query).GetValueSync();
69986997
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
6999-
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":1,\"name\":\"MyResourcePoolClassifier\",\"membername\":\"test@user\",\"resource_pool\":\"default\",\"database\":\"\\/Root\"}]}");
6998+
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"config\":{\"membername\":\"test@user\",\"resource_pool\":\"test_pool\"},\"database\":\"\\/Root\"}]}");
70006999
}
70017000

70027001
// Create another pool
@@ -7007,18 +7006,18 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
70077006
);)";
70087007
auto result = session.ExecuteSchemeQuery(query).GetValueSync();
70097008
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
7010-
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":1,\"name\":\"MyResourcePoolClassifier\",\"membername\":\"test@user\",\"resource_pool\":\"default\",\"database\":\"\\/Root\"},{\"rank\":42,\"name\":\"AnotherResourcePoolClassifier\",\"membername\":\"\",\"resource_pool\":\"default\",\"database\":\"\\/Root\"}]}");
7009+
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"config\":{\"membername\":\"test@user\",\"resource_pool\":\"test_pool\"},\"database\":\"\\/Root\"},{\"rank\":42,\"name\":\"AnotherResourcePoolClassifier\",\"config\":{},\"database\":\"\\/Root\"}]}");
70117010
}
70127011

7013-
// Test rank reset
7012+
// Test reset
70147013
{
70157014
auto query = R"(
70167015
ALTER RESOURCE POOL CLASSIFIER MyResourcePoolClassifier
7017-
RESET (RANK);
7016+
RESET (RANK, RESOURCE_POOL);
70187017
)";
70197018
auto result = session.ExecuteSchemeQuery(query).GetValueSync();
70207019
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
7021-
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":1042,\"name\":\"MyResourcePoolClassifier\",\"membername\":\"test@user\",\"resource_pool\":\"default\",\"database\":\"\\/Root\"},{\"rank\":42,\"name\":\"AnotherResourcePoolClassifier\",\"membername\":\"\",\"resource_pool\":\"default\",\"database\":\"\\/Root\"}]}");
7020+
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":1042,\"name\":\"MyResourcePoolClassifier\",\"config\":{\"membername\":\"test@user\",\"resource_pool\":\"default\"},\"database\":\"\\/Root\"},{\"rank\":42,\"name\":\"AnotherResourcePoolClassifier\",\"config\":{},\"database\":\"\\/Root\"}]}");
70227021
}
70237022
}
70247023

@@ -7040,7 +7039,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
70407039
);)";
70417040
auto result = session.ExecuteSchemeQuery(query).GetValueSync();
70427041
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
7043-
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"membername\":\"\",\"resource_pool\":\"default\",\"database\":\"\\/Root\"}]}");
7042+
UNIT_ASSERT_VALUES_EQUAL(FetchResourcePoolClassifiers(kikimr), "{\"resource_pool_classifiers\":[{\"rank\":20,\"name\":\"MyResourcePoolClassifier\",\"config\":{},\"database\":\"\\/Root\"}]}");
70447043
}
70457044

70467045
{

ydb/services/metadata/manager/alter_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ class TModificationActor: public TModificationActorImpl<TObject> {
236236
if (!trPatch) {
237237
TBase::ExternalController->OnAlteringProblem("cannot found patch for object");
238238
return false;
239-
} else if (!trObject.TakeValuesFrom(*trPatch)) {
239+
} else if (!trObject.TakeValuesFrom(*trPatch, &TObject::MergerFactory)) {
240240
TBase::ExternalController->OnAlteringProblem("cannot patch object");
241241
return false;
242242
} else if (!TObject::TDecoder::DeserializeFromRecord(objectPatched, trObject)) {

ydb/services/metadata/manager/common.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,23 @@
22
#include <ydb/core/base/events.h>
33
#include <ydb/library/actors/core/events.h>
44

5+
namespace Ydb {
6+
7+
class Value;
8+
9+
};
10+
511
namespace NKikimr::NMetadata {
612

713
namespace NModifications {
814

15+
namespace NColumnMerger {
16+
17+
using TMerger = std::function<bool(Ydb::Value& self, const Ydb::Value& other)>;
18+
using TMergerFactory = std::function<TMerger(const TString& columnName)>;
19+
20+
}
21+
922
template <class TObject>
1023
class IAlterPreparationController {
1124
public:

ydb/services/metadata/manager/object.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,14 @@ Ydb::Table::CreateTableRequest TBaseObject::AddHistoryTableScheme(const Ydb::Tab
2424
return result;
2525
}
2626

27+
NColumnMerger::TMerger TBaseObject::MergerFactory(const TString& columnName) {
28+
Y_UNUSED(columnName);
29+
return &DefaultColumnMerger;
30+
}
31+
32+
bool TBaseObject::DefaultColumnMerger(Ydb::Value& self, const Ydb::Value& other) {
33+
self = other;
34+
return true;
35+
}
36+
2737
}

ydb/services/metadata/manager/object.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ namespace NKikimr::NMetadata::NModifications {
99
class TBaseObject {
1010
public:
1111
static Ydb::Table::CreateTableRequest AddHistoryTableScheme(const Ydb::Table::CreateTableRequest& baseScheme, const TString& tableName);
12+
static NColumnMerger::TMerger MergerFactory(const TString& columnName);
1213

14+
private:
15+
static bool DefaultColumnMerger(Ydb::Value& self, const Ydb::Value& other);
1316
};
1417

1518
template <class TDerived>

ydb/services/metadata/manager/table_record.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@ ui32 TTableRecord::CountIntersectColumns(const std::vector<TString>& columnIds)
4949
return result;
5050
}
5151

52-
bool TTableRecord::TakeValuesFrom(const TTableRecord& item) {
52+
bool TTableRecord::TakeValuesFrom(const TTableRecord& item, const NModifications::NColumnMerger::TMergerFactory& mergerFactory) {
5353
for (auto&& i : item.Values) {
54-
Values[i.first] = i.second;
54+
if (!mergerFactory(i.first)(Values[i.first], i.second)) {
55+
return false;
56+
}
5557
}
5658
return true;
5759
}

0 commit comments

Comments
 (0)