aboutsummaryrefslogtreecommitdiffstats
path: root/yt
diff options
context:
space:
mode:
authorgrigminakov <grigminakov@yandex-team.com>2024-10-09 12:28:46 +0300
committergrigminakov <grigminakov@yandex-team.com>2024-10-09 13:05:12 +0300
commita44b779cd359f06c3ebbef4ec98c6b38609d9d85 (patch)
treeb1e7b32908f35ff082c314507a032fe1a7eb0178 /yt
parent9e0d2b2a078fe922b45eac2d134976736b73980c (diff)
downloadydb-a44b779cd359f06c3ebbef4ec98c6b38609d9d85.tar.gz
YT: Fix YPathFilteringConsumer support for multiple nested paths
В реализации YPathFilteringConsumer был баг, который приводил к неправильной фильтрации двух вложенных путей в режиме `ForcedEntities`. В этом ПР’е он исправлен и добавлен соответсвующий тест. commit_hash:bfbf72bdf5e80822ed556c71c8d2d3918b573cab
Diffstat (limited to 'yt')
-rw-r--r--yt/yt/core/yson/unittests/ypath_filtering_yson_consumer_ut.cpp14
-rw-r--r--yt/yt/core/yson/ypath_filtering_consumer.cpp88
2 files changed, 54 insertions, 48 deletions
diff --git a/yt/yt/core/yson/unittests/ypath_filtering_yson_consumer_ut.cpp b/yt/yt/core/yson/unittests/ypath_filtering_yson_consumer_ut.cpp
index 3fb7db7395..64540ce495 100644
--- a/yt/yt/core/yson/unittests/ypath_filtering_yson_consumer_ut.cpp
+++ b/yt/yt/core/yson/unittests/ypath_filtering_yson_consumer_ut.cpp
@@ -299,6 +299,20 @@ TEST_F(TYPathFilteringConsumerTest, ForcedNested)
ASSERT_EQ(FlushOutput(), R"({"data"={"forced_key"=#;};})");
}
+TEST_F(TYPathFilteringConsumerTest, ForcedNestedMultiple)
+{
+ auto consumer = CreateYPathFilteringConsumer(
+ GetConsumer(),
+ /*paths*/ {"/data/forced_key1", "/data/forced_key2"},
+ EYPathFilteringMode::WhitelistWithForcedEntities);
+
+ NYTree::BuildYsonFluently(consumer.get())
+ .BeginMap()
+ .EndMap();
+
+ ASSERT_EQ(FlushOutput(), R"({"data"={"forced_key1"=#;"forced_key2"=#;};})");
+}
+
TEST_F(TYPathFilteringConsumerTest, ForcedWhitelistMixedNested)
{
auto consumer = CreateYPathFilteringConsumer(
diff --git a/yt/yt/core/yson/ypath_filtering_consumer.cpp b/yt/yt/core/yson/ypath_filtering_consumer.cpp
index 9adf46c801..51d4d03740 100644
--- a/yt/yt/core/yson/ypath_filtering_consumer.cpp
+++ b/yt/yt/core/yson/ypath_filtering_consumer.cpp
@@ -62,17 +62,15 @@ public:
void OnBeginMap() override
{
BeforeValue();
- AfterCollectionBegin_ = true;
+ PendingRollback_ = false;
Forward_->OnBeginMap();
}
void OnKeyedItem(TStringBuf key) override
{
- if (!AfterCollectionBegin_) {
- RollbackPath();
- }
- AfterCollectionBegin_ = false;
+ FlushPendingRollback();
+ PendingRollback_ = true;
AppendPath(key);
Forward_->OnKeyedItem(key);
@@ -80,18 +78,17 @@ public:
void OnEndMap() override
{
- if (!AfterCollectionBegin_) {
- RollbackPath();
- }
- AfterCollectionBegin_ = false;
BeforeEndDictionary();
+
+ FlushPendingRollback();
+ PendingRollback_ = true;
Forward_->OnEndMap();
}
void OnBeginList() override
{
BeforeValue();
- AfterCollectionBegin_ = true;
+ PendingRollback_ = false;
ListIndexes_.push_back(0);
Forward_->OnBeginList();
@@ -99,10 +96,10 @@ public:
void OnListItem() override
{
- if (!AfterCollectionBegin_) {
+ if (PendingRollback_) {
RollbackPath();
}
- AfterCollectionBegin_ = false;
+ PendingRollback_ = true;
AppendPath(ListIndexes_.back());
++ListIndexes_.back();
@@ -111,10 +108,8 @@ public:
void OnEndList() override
{
- if (!AfterCollectionBegin_) {
- RollbackPath();
- }
- AfterCollectionBegin_ = false;
+ FlushPendingRollback();
+ PendingRollback_ = true;
ListIndexes_.pop_back();
Forward_->OnEndList();
@@ -125,18 +120,17 @@ public:
{
AppendPath(TAtTokenTag{});
- AfterCollectionBegin_ = true;
+ PendingRollback_ = false;
Forward_->OnBeginAttributes();
}
void OnEndAttributes() override
{
- if (!AfterCollectionBegin_) {
- RollbackPath();
- }
-
BeforeEndDictionary();
+
+ FlushPendingRollback();
+ PendingRollback_ = true;
Forward_->OnEndAttributes();
RollbackPath();
}
@@ -166,9 +160,16 @@ protected:
return Forward_;
}
+ void FlushPendingRollback() {
+ if (PendingRollback_) {
+ RollbackPath();
+ PendingRollback_ = false;
+ }
+ }
+
private:
NYson::IYsonConsumer* Forward_;
- bool AfterCollectionBegin_ = false;
+ bool PendingRollback_ = false;
std::vector<int> ListIndexes_;
};
@@ -310,39 +311,30 @@ private:
return;
}
- for (auto& state : PerPathFilteringStates_) {
+ for (const auto& state : PerPathFilteringStates_) {
+ FlushPendingRollback();
+
if (Depth_ != state.MaxMatchedDepth || state.Fulfilled) {
continue;
}
- auto& tokenizer = state.Tokenizer;
- std::vector<bool> isAttributesStack;
+ const auto& tokenizer = state.Tokenizer;
tokenizer.Expect(NYPath::ETokenType::Literal);
- GetForward()->OnKeyedItem(tokenizer.GetLiteralValue());
- while(ToNextLiteral(tokenizer)) {
- if (tokenizer.GetType() == NYPath::ETokenType::At) {
- isAttributesStack.push_back(true);
- GetForward()->OnBeginAttributes();
- tokenizer.Advance();
- } else {
- isAttributesStack.push_back(false);
- GetForward()->OnBeginMap();
- }
- tokenizer.Expect(NYPath::ETokenType::Literal);
- GetForward()->OnKeyedItem(tokenizer.GetLiteralValue());
- }
- GetForward()->OnEntity();
- tokenizer.Expect(NYPath::ETokenType::EndOfStream);
- while(!isAttributesStack.empty()) {
- if (isAttributesStack.back()) {
- GetForward()->OnEndAttributes();
- } else {
- GetForward()->OnEndMap();
- }
- isAttributesStack.pop_back();
+ auto currentLiteral = tokenizer.GetLiteralValue();
+ OnKeyedItem(currentLiteral);
+
+ YT_VERIFY(tokenizer.GetType() != NYPath::ETokenType::Slash);
+ if (tokenizer.GetType() == NYPath::ETokenType::EndOfStream) {
+ OnEntity();
+ } else if (tokenizer.GetType() == NYPath::ETokenType::At) {
+ OnBeginAttributes();
+ OnEndAttributes();
+ } else {
+ OnBeginMap();
+ OnEndMap();
}
- state.Fulfilled = true;
+ YT_VERIFY(state.Fulfilled);
}
}