Skip to content

Commit af80965

Browse files
authored
feat(shredding): support adaptive schemas across rolling files (alibaba#455)
1 parent 575a3d8 commit af80965

91 files changed

Lines changed: 3613 additions & 1080 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

include/paimon/data/shredding/map_shared_shredding_schema_utils.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,9 @@ class PAIMON_EXPORT MapSharedShreddingSchemaUtils {
8585
/// @param physical_schema The Arrow C physical schema that contains the target field.
8686
/// Ownership of schema resources is transferred to this method.
8787
/// @param field_name The physical field name whose metadata should be extracted.
88-
/// @param compression Compression codec name for field_dict deserialization.
8988
/// @return Parsed shared-shredding metadata for the field.
9089
static Result<MapSharedShreddingFieldMeta> ExtractMetadataFromField(
91-
std::unique_ptr<::ArrowSchema> physical_schema, const std::string& field_name,
92-
const std::string& compression);
90+
std::unique_ptr<::ArrowSchema> physical_schema, const std::string& field_name);
9391
};
9492

9593
} // namespace paimon

include/paimon/defs.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ struct PAIMON_EXPORT Options {
117117
/// append table: the default value is 256 MB.
118118
static const char TARGET_FILE_SIZE[];
119119

120+
/// "target-file-row-num" - Target number of rows per newly written data file. Disabled by
121+
/// default. A file rolls when this or target-file-size is reached, whichever comes first.
122+
/// This limit is enforced at write-batch granularity, so a file may exceed the target by up
123+
/// to one batch.
124+
static const char TARGET_FILE_ROW_NUM[];
125+
120126
/// "blob.target-file-size" - Target size of a blob file. Default is TARGET_FILE_SIZE.
121127
static const char BLOB_TARGET_FILE_SIZE[];
122128

@@ -433,6 +439,8 @@ struct PAIMON_EXPORT Options {
433439
/// "variant.inferShreddingSchema" - Whether to automatically infer the shredding schema when
434440
/// writing Variant columns. Default value is "false".
435441
static const char VARIANT_INFER_SHREDDING_SCHEMA[];
442+
/// "variant.shredding.inferenceMode" - "per-file" or "adaptive". Default is "per-file".
443+
static const char VARIANT_SHREDDING_INFERENCE_MODE[];
436444
/// "variant.shredding.maxSchemaWidth" - Maximum number of shredded fields allowed in an
437445
/// inferred schema. Default value is 300.
438446
static const char VARIANT_SHREDDING_MAX_SCHEMA_WIDTH[];
@@ -446,6 +454,12 @@ struct PAIMON_EXPORT Options {
446454
/// "variant.shredding.maxInferBufferRow" - Maximum number of rows to buffer for schema
447455
/// inference. Default value is 4096.
448456
static const char VARIANT_SHREDDING_MAX_INFER_BUFFER_ROW[];
457+
/// "variant.shredding.adaptive.maxInferBufferRow" - Maximum prefix rows sampled after the
458+
/// first file in an adaptive session. Default value is 256.
459+
static const char VARIANT_SHREDDING_ADAPTIVE_MAX_INFER_BUFFER_ROW[];
460+
/// "variant.shredding.adaptive.retentionRatio" - Minimum combined ratio for retaining a
461+
/// previously selected path. Default value is 0.05.
462+
static const char VARIANT_SHREDDING_ADAPTIVE_RETENTION_RATIO[];
449463

450464
/// "blob-as-descriptor" - Read blob field using blob descriptor rather than blob
451465
/// bytes. Default value is "false".

src/paimon/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ set(PAIMON_COMMON_SRCS
4040
common/data/timestamp.cpp
4141
common/data/variant/generic_variant.cpp
4242
common/data/variant/infer_variant_shredding_schema.cpp
43+
common/data/variant/variant_shredding_inference_session.cpp
4344
common/data/variant/variant.cpp
4445
common/data/variant/variant_binary_util.cpp
4546
common/data/variant/variant_builder.cpp
@@ -264,7 +265,6 @@ set(PAIMON_CORE_SRCS
264265
core/io/key_value_meta_projection_consumer.cpp
265266
core/io/key_value_projection_consumer.cpp
266267
core/io/key_value_projection_reader.cpp
267-
core/io/map_shared_shredding_core_utils.cpp
268268
core/io/shredding_append_data_file_writer_factory.cpp
269269
core/io/shredding_key_value_data_file_writer_factory.cpp
270270
core/io/multiple_blob_file_writer.cpp

src/paimon/common/data/shredding/map_shared_shredding_batch_converter.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,17 @@ Result<MapSharedShreddingFieldMeta> MapSharedShreddingBatchConverter::BuildField
337337
"cannot find field_name '{}' in MapSharedShreddingBatchConverter contexts", field_name));
338338
}
339339

340+
Result<int32_t> MapSharedShreddingBatchConverter::GetMaxRowWidth(
341+
const std::string& field_name) const {
342+
for (const auto& context : contexts_) {
343+
if (context.field_name == field_name) {
344+
return context.allocator->GetMaxRowWidth();
345+
}
346+
}
347+
return Status::Invalid(fmt::format(
348+
"cannot find field_name '{}' in MapSharedShreddingBatchConverter contexts", field_name));
349+
}
350+
340351
const std::vector<std::string>& MapSharedShreddingBatchConverter::GetShreddingColumnNames() const {
341352
return shredding_field_names_;
342353
}

src/paimon/common/data/shredding/map_shared_shredding_batch_converter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ class MapSharedShreddingBatchConverter : public ShreddingBatchConverter {
7171
/// Called at file close to serialize metadata.
7272
Result<MapSharedShreddingFieldMeta> BuildFieldMeta(const std::string& field_name) const;
7373

74+
/// Returns the maximum number of entries observed in one row for a shredding column.
75+
Result<int32_t> GetMaxRowWidth(const std::string& field_name) const;
76+
7477
/// Returns all shredding column field names.
7578
const std::vector<std::string>& GetShreddingColumnNames() const;
7679

src/paimon/common/data/shredding/map_shared_shredding_batch_converter_test.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "gtest/gtest.h"
2929
#include "paimon/common/data/shredding/map_shared_shredding_context.h"
3030
#include "paimon/common/data/shredding/map_shared_shredding_utils.h"
31+
#include "paimon/common/data/shredding/map_shared_shredding_write_plan_factory.h"
3132
#include "paimon/common/data/shredding/map_shredding_defs.h"
3233
#include "paimon/core/core_options.h"
3334
#include "paimon/memory/memory_pool.h"
@@ -118,6 +119,77 @@ TEST_F(MapSharedShreddingBatchConverterTest, BasicConversion) {
118119
ASSERT_EQ(expected_meta, converter->BuildFieldMeta("tags").value());
119120
}
120121

122+
TEST_F(MapSharedShreddingBatchConverterTest, MapWithNullValue) {
123+
auto logical_schema =
124+
arrow::schema({arrow::field("metrics", arrow::map(arrow::utf8(), arrow::int64()))});
125+
auto context =
126+
std::make_shared<MapSharedShreddingContext>(std::map<std::string, int32_t>{{"metrics", 2}});
127+
ASSERT_OK_AND_ASSIGN(CoreOptions options, MakeCoreOptions({{"metrics", "plain"}}));
128+
ASSERT_OK_AND_ASSIGN(auto converter, MapSharedShreddingBatchConverter::Create(
129+
logical_schema, context, options, pool_));
130+
auto logical_type = arrow::struct_(logical_schema->fields());
131+
auto physical_type = arrow::struct_(converter->GetPhysicalSchema()->fields());
132+
133+
auto actual =
134+
RunConvert(logical_type, R"([[[["a", null], ["b", 20]]]])", physical_type, converter.get());
135+
auto expected = ArrayFromJSON(physical_type, R"([[[[0, 1], null, 20, null]]])").ValueOrDie();
136+
AssertArrayEquals(expected, actual);
137+
138+
MapSharedShreddingFieldMeta expected_meta;
139+
expected_meta.name_to_id = {{"a", 0}, {"b", 1}};
140+
expected_meta.field_to_columns = {{0, {0}}, {1, {1}}};
141+
expected_meta.num_columns = 2;
142+
expected_meta.max_row_width = 2;
143+
ASSERT_EQ(expected_meta, converter->BuildFieldMeta("metrics").value());
144+
}
145+
146+
TEST_F(MapSharedShreddingBatchConverterTest, OverflowWhenExceedK) {
147+
auto logical_schema =
148+
arrow::schema({arrow::field("metrics", arrow::map(arrow::utf8(), arrow::int64()))});
149+
auto context =
150+
std::make_shared<MapSharedShreddingContext>(std::map<std::string, int32_t>{{"metrics", 2}});
151+
ASSERT_OK_AND_ASSIGN(CoreOptions options, MakeCoreOptions({{"metrics", "plain"}}));
152+
ASSERT_OK_AND_ASSIGN(auto converter, MapSharedShreddingBatchConverter::Create(
153+
logical_schema, context, options, pool_));
154+
auto logical_type = arrow::struct_(logical_schema->fields());
155+
auto physical_type = arrow::struct_(converter->GetPhysicalSchema()->fields());
156+
157+
auto actual = RunConvert(logical_type, R"([[[["a", 10], ["b", 20], ["c", 30]]]])",
158+
physical_type, converter.get());
159+
auto expected = ArrayFromJSON(physical_type, R"([[[[0, 1], 10, 20, [[2, 30]]]]])").ValueOrDie();
160+
AssertArrayEquals(expected, actual);
161+
162+
MapSharedShreddingFieldMeta expected_meta;
163+
expected_meta.name_to_id = {{"a", 0}, {"b", 1}, {"c", 2}};
164+
expected_meta.field_to_columns = {{0, {0}}, {1, {1}}};
165+
expected_meta.overflow_field_set = {2};
166+
expected_meta.num_columns = 2;
167+
expected_meta.max_row_width = 3;
168+
ASSERT_EQ(expected_meta, converter->BuildFieldMeta("metrics").value());
169+
}
170+
171+
TEST_F(MapSharedShreddingBatchConverterTest, EmptyAndNullMaps) {
172+
auto logical_schema =
173+
arrow::schema({arrow::field("metrics", arrow::map(arrow::utf8(), arrow::int64()))});
174+
auto context =
175+
std::make_shared<MapSharedShreddingContext>(std::map<std::string, int32_t>{{"metrics", 2}});
176+
ASSERT_OK_AND_ASSIGN(CoreOptions options, MakeCoreOptions({{"metrics", "plain"}}));
177+
ASSERT_OK_AND_ASSIGN(auto converter, MapSharedShreddingBatchConverter::Create(
178+
logical_schema, context, options, pool_));
179+
auto logical_type = arrow::struct_(logical_schema->fields());
180+
auto physical_type = arrow::struct_(converter->GetPhysicalSchema()->fields());
181+
182+
auto actual = RunConvert(logical_type, R"([[null], [[]]])", physical_type, converter.get());
183+
auto expected =
184+
ArrayFromJSON(physical_type, R"([[null], [[[-1, -1], null, null, null]]])").ValueOrDie();
185+
AssertArrayEquals(expected, actual);
186+
187+
MapSharedShreddingFieldMeta expected_meta;
188+
expected_meta.num_columns = 2;
189+
expected_meta.max_row_width = 0;
190+
ASSERT_EQ(expected_meta, converter->BuildFieldMeta("metrics").value());
191+
}
192+
121193
TEST_F(MapSharedShreddingBatchConverterTest, NestedValueStruct) {
122194
// MAP<STRING, STRUCT<x:INT32, y:DOUBLE>>, K=2
123195
auto value_type = arrow::struct_({
@@ -408,13 +480,18 @@ TEST_F(MapSharedShreddingBatchConverterTest, BuildFieldMetaInvalidFieldName) {
408480

409481
// Valid case: "tags" exists
410482
ASSERT_OK_AND_ASSIGN([[maybe_unused]] auto meta, converter->BuildFieldMeta("tags"));
483+
ASSERT_OK_AND_ASSIGN(int32_t max_row_width, converter->GetMaxRowWidth("tags"));
484+
ASSERT_EQ(0, max_row_width);
411485

412486
// Invalid case: "id" is not a shredding field
413487
ASSERT_NOK_WITH_MSG(converter->BuildFieldMeta("id"), "cannot find field_name 'id'");
488+
ASSERT_NOK_WITH_MSG(converter->GetMaxRowWidth("id"), "cannot find field_name 'id'");
414489

415490
// Invalid case: nonexistent field name
416491
ASSERT_NOK_WITH_MSG(converter->BuildFieldMeta("nonexistent"),
417492
"cannot find field_name 'nonexistent'");
493+
ASSERT_NOK_WITH_MSG(converter->GetMaxRowWidth("nonexistent"),
494+
"cannot find field_name 'nonexistent'");
418495
}
419496

420497
TEST_F(MapSharedShreddingBatchConverterTest, SequentialPlacementUsesSmallestColumn) {
@@ -496,4 +573,57 @@ TEST_F(MapSharedShreddingBatchConverterTest, LruPlacementPreservesResidentColumn
496573
ASSERT_EQ(expected_meta, converter->BuildFieldMeta("tags").value());
497574
}
498575

576+
TEST_F(MapSharedShreddingBatchConverterTest, FactoryUsesMaxColumnCountForFirstFile) {
577+
auto logical_schema =
578+
arrow::schema({arrow::field("tags", arrow::map(arrow::utf8(), arrow::int32()))});
579+
ASSERT_OK_AND_ASSIGN(
580+
CoreOptions options,
581+
CoreOptions::FromMap({{"fields.tags.map.storage-layout", "shared-shredding"},
582+
{"fields.tags.map.shared-shredding.max-columns", "4"}}));
583+
ASSERT_OK_AND_ASSIGN(
584+
auto factory, MapSharedShreddingWritePlanFactory::Create(options, logical_schema, pool_));
585+
586+
ASSERT_TRUE(factory->ShouldCreateWritePlan());
587+
ASSERT_FALSE(factory->ShouldInferWritePlan());
588+
ASSERT_EQ(0, factory->InferBufferRowCount());
589+
ASSERT_OK_AND_ASSIGN(auto converter, factory->CreateConverter("parquet", {}));
590+
ASSERT_OK_AND_ASSIGN(auto expected, MapSharedShreddingUtils::LogicalToPhysicalSchema(
591+
logical_schema, {{"tags", 4}}));
592+
ASSERT_TRUE(converter->GetPhysicalSchema()->Equals(*expected));
593+
}
594+
595+
TEST_F(MapSharedShreddingBatchConverterTest, FactoryUsesCompletedFileStatsForNextFile) {
596+
auto logical_schema =
597+
arrow::schema({arrow::field("tags", arrow::map(arrow::utf8(), arrow::int32()))});
598+
ASSERT_OK_AND_ASSIGN(
599+
CoreOptions options,
600+
CoreOptions::FromMap({{"fields.tags.map.storage-layout", "shared-shredding"},
601+
{"fields.tags.map.shared-shredding.max-columns", "8"}}));
602+
ASSERT_OK_AND_ASSIGN(
603+
auto factory, MapSharedShreddingWritePlanFactory::Create(options, logical_schema, pool_));
604+
ASSERT_OK_AND_ASSIGN(auto first, factory->CreateConverter("parquet", {}));
605+
606+
auto logical_type = arrow::struct_(logical_schema->fields());
607+
auto first_physical_type = arrow::struct_(first->GetPhysicalSchema()->fields());
608+
auto input = ArrayFromJSON(logical_type, R"([
609+
[[["a", 1], ["b", 2]]],
610+
[[["c", 3], ["d", 4], ["e", 5]]]
611+
])")
612+
.ValueOrDie();
613+
ArrowArray c_input;
614+
ASSERT_TRUE(arrow::ExportArray(*input, &c_input).ok());
615+
ASSERT_OK_AND_ASSIGN(auto c_output, first->Convert(&c_input));
616+
auto first_output = arrow::ImportArray(c_output.get(), first_physical_type).ValueOrDie();
617+
ASSERT_EQ(2, first_output->length());
618+
ASSERT_OK(factory->OnFileCompleted(first));
619+
620+
ASSERT_OK_AND_ASSIGN(auto second, factory->CreateConverter("parquet", {}));
621+
ASSERT_OK_AND_ASSIGN(auto expected_first, MapSharedShreddingUtils::LogicalToPhysicalSchema(
622+
logical_schema, {{"tags", 8}}));
623+
ASSERT_OK_AND_ASSIGN(auto expected_second, MapSharedShreddingUtils::LogicalToPhysicalSchema(
624+
logical_schema, {{"tags", 3}}));
625+
ASSERT_TRUE(first->GetPhysicalSchema()->Equals(*expected_first));
626+
ASSERT_TRUE(second->GetPhysicalSchema()->Equals(*expected_second));
627+
}
628+
499629
} // namespace paimon

src/paimon/common/data/shredding/map_shared_shredding_context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace paimon {
2525

2626
/// Cross-file shared context for shared-shredding MAP columns.
2727
///
28-
/// Lifetime: same as the owning writer (e.g. AppendOnlyWriter).
28+
/// Lifetime: same as one rolling writer / write-plan factory.
2929
/// Holds per-column K_max and a sliding window of recent max_row_width
3030
/// values to support adaptive K sizing across files.
3131
///

src/paimon/common/data/shredding/map_shared_shredding_file_reader_test.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,7 @@ class MapSharedShreddingFileReaderTest : public ::testing::Test {
108108
if (!MapSharedShreddingUtils::HasShreddingMetadata(metadata)) {
109109
continue;
110110
}
111-
EXPECT_OK_AND_ASSIGN(auto meta,
112-
MapSharedShreddingUtils::DeserializeMetadata(
113-
metadata, MapSharedShreddingDefine::kDefaultDictCompression));
111+
EXPECT_OK_AND_ASSIGN(auto meta, MapSharedShreddingUtils::DeserializeMetadata(metadata));
114112
auto physical_type =
115113
arrow::internal::checked_pointer_cast<arrow::StructType>(field->type());
116114
std::shared_ptr<arrow::Field> item_field;
@@ -219,12 +217,9 @@ class MapSharedShreddingFileReaderTest : public ::testing::Test {
219217
const std::optional<std::vector<std::string>>& write_cols, int64_t max_sequence_number,
220218
const std::shared_ptr<DataFilePathFactory>& path_factory,
221219
const std::shared_ptr<CompactManager>& compact_manager) const {
222-
PAIMON_ASSIGN_OR_RAISE(
223-
std::shared_ptr<MapSharedShreddingContext> shredding_context,
224-
MapSharedShreddingUtils::CreateShreddingContext(logical_schema, core_options));
225220
return std::make_unique<AppendOnlyWriter>(core_options, schema_id, logical_schema,
226221
write_cols, max_sequence_number, path_factory,
227-
compact_manager, shredding_context, pool_);
222+
compact_manager, pool_);
228223
}
229224

230225
private:

src/paimon/common/data/shredding/map_shared_shredding_schema_utils.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ Result<std::unique_ptr<::ArrowSchema>> MapSharedShreddingSchemaUtils::AttachMeta
7575
}
7676

7777
Result<MapSharedShreddingFieldMeta> MapSharedShreddingSchemaUtils::ExtractMetadataFromField(
78-
std::unique_ptr<::ArrowSchema> physical_schema, const std::string& field_name,
79-
const std::string& compression) {
78+
std::unique_ptr<::ArrowSchema> physical_schema, const std::string& field_name) {
8079
if (!physical_schema) {
8180
return Status::Invalid("physical schema is null");
8281
}
@@ -90,7 +89,7 @@ Result<MapSharedShreddingFieldMeta> MapSharedShreddingSchemaUtils::ExtractMetada
9089

9190
auto metadata =
9291
field->metadata() ? field->metadata()->Copy() : std::shared_ptr<arrow::KeyValueMetadata>();
93-
return MapSharedShreddingUtils::DeserializeMetadata(metadata, compression);
92+
return MapSharedShreddingUtils::DeserializeMetadata(metadata);
9493
}
9594

9695
} // namespace paimon

src/paimon/common/data/shredding/map_shared_shredding_schema_utils_test.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ TEST(MapSharedShreddingSchemaUtilsTest, AttachMetadataToSchemaBasic) {
6262
auto tags_metadata = updated_schema->GetFieldByName("tags")->metadata()->Copy();
6363
ASSERT_TRUE(MapSharedShreddingUtils::HasShreddingMetadata(tags_metadata));
6464
ASSERT_OK_AND_ASSIGN(auto deserialized,
65-
MapSharedShreddingUtils::DeserializeMetadata(tags_metadata, "none"));
65+
MapSharedShreddingUtils::DeserializeMetadata(tags_metadata));
6666
ASSERT_EQ(deserialized, tags_meta);
6767
}
6868

@@ -159,7 +159,7 @@ TEST(MapSharedShreddingSchemaUtilsTest, AttachMetadataToSchemaOverwritesExisting
159159
}
160160
ASSERT_EQ(storage_layout_key_count, 1);
161161
ASSERT_OK_AND_ASSIGN(auto deserialized,
162-
MapSharedShreddingUtils::DeserializeMetadata(updated_metadata, "none"));
162+
MapSharedShreddingUtils::DeserializeMetadata(updated_metadata));
163163
ASSERT_EQ(deserialized, tags_meta);
164164
}
165165

@@ -183,7 +183,7 @@ TEST(MapSharedShreddingSchemaUtilsTest, ExtractMetadataFromField) {
183183
auto c_schema = std::make_unique<::ArrowSchema>();
184184
ASSERT_TRUE(arrow::ExportSchema(*schema, c_schema.get()).ok());
185185
ASSERT_OK_AND_ASSIGN(auto parsed_meta, MapSharedShreddingSchemaUtils::ExtractMetadataFromField(
186-
std::move(c_schema), "tags", "none"));
186+
std::move(c_schema), "tags"));
187187
ASSERT_EQ(parsed_meta, tags_meta);
188188
}
189189

@@ -194,24 +194,24 @@ TEST(MapSharedShreddingSchemaUtilsTest, ExtractMetadataFromFieldNoShreddingMetad
194194
auto c_schema = std::make_unique<::ArrowSchema>();
195195
ASSERT_TRUE(arrow::ExportSchema(*schema, c_schema.get()).ok());
196196

197-
ASSERT_NOK_WITH_MSG(MapSharedShreddingSchemaUtils::ExtractMetadataFromField(std::move(c_schema),
198-
"tags", "none"),
199-
"metadata is null or storage layout is not shared-shredding");
197+
ASSERT_NOK_WITH_MSG(
198+
MapSharedShreddingSchemaUtils::ExtractMetadataFromField(std::move(c_schema), "tags"),
199+
"metadata is null or storage layout is not shared-shredding");
200200
}
201201

202202
TEST(MapSharedShreddingSchemaUtilsTest, ExtractMetadataFromFieldInvalidInput) {
203203
ASSERT_NOK_WITH_MSG(MapSharedShreddingSchemaUtils::ExtractMetadataFromField(
204-
std::unique_ptr<::ArrowSchema>(), "tags", "none"),
204+
std::unique_ptr<::ArrowSchema>(), "tags"),
205205
"physical schema is null");
206206

207207
auto schema = arrow::schema({arrow::field("id", arrow::int32())});
208208

209209
auto c_schema = std::make_unique<::ArrowSchema>();
210210
ASSERT_TRUE(arrow::ExportSchema(*schema, c_schema.get()).ok());
211211

212-
ASSERT_NOK_WITH_MSG(MapSharedShreddingSchemaUtils::ExtractMetadataFromField(std::move(c_schema),
213-
"tags", "none"),
214-
"Shared-shredding field 'tags' not found in physical schema.");
212+
ASSERT_NOK_WITH_MSG(
213+
MapSharedShreddingSchemaUtils::ExtractMetadataFromField(std::move(c_schema), "tags"),
214+
"Shared-shredding field 'tags' not found in physical schema.");
215215
}
216216

217217
TEST(MapSharedShreddingSchemaUtilsTest, LogicalToPhysicalSchemaInvalidInput) {

0 commit comments

Comments
 (0)