Skip to content

Commit c3b8932

Browse files
lszskyezjw1111
authored andcommitted
feat: remove support for FLOAT/DOUBLE type partition field (#333)
1 parent a6196af commit c3b8932

8 files changed

Lines changed: 116 additions & 166 deletions

src/paimon/core/io/field_mapping_reader.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,6 @@ Result<std::shared_ptr<arrow::Array>> FieldMappingReader::GenerateSinglePartitio
220220
scalar = std::make_shared<arrow::Int64Scalar>(value);
221221
break;
222222
}
223-
case arrow::Type::type::FLOAT: {
224-
float value = partition_.GetFloat(partition_info_.value().idx_in_partition[idx]);
225-
scalar = std::make_shared<arrow::FloatScalar>(value);
226-
break;
227-
}
228-
case arrow::Type::type::DOUBLE: {
229-
double value = partition_.GetDouble(partition_info_.value().idx_in_partition[idx]);
230-
scalar = std::make_shared<arrow::DoubleScalar>(value);
231-
break;
232-
}
233223
case arrow::Type::type::STRING: {
234224
BinaryString value =
235225
partition_.GetString(partition_info_.value().idx_in_partition[idx]);

src/paimon/core/io/field_mapping_reader_test.cpp

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -209,104 +209,85 @@ class FieldMappingReaderTest : public ::testing::Test {
209209

210210
TEST_F(FieldMappingReaderTest, TestGenerateSinglePartitionArray) {
211211
PartitionInfo partition_info;
212-
// read schema: p9-p0
213-
// partition key: p0-p9
214-
partition_info.partition_read_schema = {DataField(9, arrow::field("p9", arrow::date32())),
215-
DataField(8, arrow::field("p8", arrow::binary())),
216-
DataField(7, arrow::field("p7", arrow::utf8())),
217-
DataField(6, arrow::field("p6", arrow::float64())),
218-
DataField(5, arrow::field("p5", arrow::float32())),
212+
// read schema: p7-p0
213+
// partition key: p0-p7
214+
partition_info.partition_read_schema = {DataField(7, arrow::field("p7", arrow::date32())),
215+
DataField(6, arrow::field("p6", arrow::binary())),
216+
DataField(5, arrow::field("p5", arrow::utf8())),
219217
DataField(4, arrow::field("p4", arrow::int64())),
220218
DataField(3, arrow::field("p3", arrow::int32())),
221219
DataField(2, arrow::field("p2", arrow::int16())),
222220
DataField(1, arrow::field("p1", arrow::int8())),
223221
DataField(0, arrow::field("p0", arrow::boolean()))};
224-
partition_info.idx_in_target_read_schema = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
225-
partition_info.idx_in_partition = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
222+
partition_info.idx_in_target_read_schema = {0, 1, 2, 3, 4, 5, 6, 7};
223+
partition_info.idx_in_partition = {7, 6, 5, 4, 3, 2, 1, 0};
226224

227225
NonPartitionInfo non_part_info;
228226
auto field_mapping = std::make_unique<FieldMapping>(partition_info, non_part_info,
229227
/*non_exist_field_info=*/std::nullopt);
230228
auto partition = BinaryRowGenerator::GenerateRow(
231229
{false, static_cast<int8_t>(1), static_cast<int16_t>(2), static_cast<int32_t>(3),
232-
static_cast<int64_t>(4), static_cast<float>(5.1), 6.21, std::string("7"),
233-
std::make_shared<Bytes>("8", pool_.get()), 100},
230+
static_cast<int64_t>(4), std::string("5"), std::make_shared<Bytes>("6", pool_.get()), 100},
234231
pool_.get());
235232
auto mapping_reader = std::make_unique<FieldMappingReader>(
236-
/*field_count=*/10, /*reader=*/nullptr, partition, std::move(field_mapping), pool_);
233+
/*field_count=*/8, /*reader=*/nullptr, partition, std::move(field_mapping), pool_);
237234

238-
{
239-
ASSERT_OK_AND_ASSIGN(auto p9_array, mapping_reader->GenerateSinglePartitionArray(
240-
/*idx in read schema*/ 0, /*batch_size=*/2));
241-
ASSERT_EQ(p9_array->length(), 2);
242-
ASSERT_EQ(arrow::internal::checked_cast<arrow::Date32Array*>(p9_array.get())->Value(0),
243-
100);
244-
}
245-
{
246-
ASSERT_OK_AND_ASSIGN(auto p8_array, mapping_reader->GenerateSinglePartitionArray(
247-
/*idx in read schema*/ 1, /*batch_size=*/2));
248-
ASSERT_EQ(p8_array->length(), 2);
249-
ASSERT_EQ(arrow::internal::checked_cast<arrow::BinaryArray*>(p8_array.get())->Value(0),
250-
"8");
251-
}
252235
{
253236
ASSERT_OK_AND_ASSIGN(auto p7_array, mapping_reader->GenerateSinglePartitionArray(
254-
/*idx in read schema*/ 2, /*batch_size=*/1));
255-
ASSERT_EQ(p7_array->length(), 1);
256-
ASSERT_EQ(arrow::internal::checked_cast<arrow::StringArray*>(p7_array.get())->Value(0),
257-
"7");
237+
/*idx=*/0, /*batch_size=*/2));
238+
ASSERT_EQ(p7_array->length(), 2);
239+
ASSERT_EQ(arrow::internal::checked_cast<arrow::Date32Array*>(p7_array.get())->Value(0),
240+
100);
258241
}
259242
{
260243
ASSERT_OK_AND_ASSIGN(auto p6_array, mapping_reader->GenerateSinglePartitionArray(
261-
/*idx in read schema*/ 3, /*batch_size=*/1));
262-
ASSERT_EQ(
263-
arrow::internal::checked_cast<arrow::NumericArray<arrow::DoubleType>*>(p6_array.get())
264-
->Value(0),
265-
static_cast<double>(6.21));
244+
/*idx=*/1, /*batch_size=*/2));
245+
ASSERT_EQ(p6_array->length(), 2);
246+
ASSERT_EQ(arrow::internal::checked_cast<arrow::BinaryArray*>(p6_array.get())->Value(0),
247+
"6");
266248
}
267249
{
268250
ASSERT_OK_AND_ASSIGN(auto p5_array, mapping_reader->GenerateSinglePartitionArray(
269-
/*idx in read schema*/ 4, /*batch_size=*/1));
270-
ASSERT_EQ(
271-
arrow::internal::checked_cast<arrow::NumericArray<arrow::FloatType>*>(p5_array.get())
272-
->Value(0),
273-
static_cast<float>(5.1));
251+
/*idx=*/2, /*batch_size=*/1));
252+
ASSERT_EQ(p5_array->length(), 1);
253+
ASSERT_EQ(arrow::internal::checked_cast<arrow::StringArray*>(p5_array.get())->Value(0),
254+
"5");
274255
}
275256
{
276257
ASSERT_OK_AND_ASSIGN(auto p4_array, mapping_reader->GenerateSinglePartitionArray(
277-
/*idx in read schema*/ 5, /*batch_size=*/1));
258+
/*idx=*/3, /*batch_size=*/1));
278259
ASSERT_EQ(
279260
arrow::internal::checked_cast<arrow::NumericArray<arrow::Int64Type>*>(p4_array.get())
280261
->Value(0),
281262
static_cast<int64_t>(4));
282263
}
283264
{
284265
ASSERT_OK_AND_ASSIGN(auto p3_array, mapping_reader->GenerateSinglePartitionArray(
285-
/*idx in read schema*/ 6, /*batch_size=*/1));
266+
/*idx=*/4, /*batch_size=*/1));
286267
ASSERT_EQ(
287268
arrow::internal::checked_cast<arrow::NumericArray<arrow::Int32Type>*>(p3_array.get())
288269
->Value(0),
289270
static_cast<int32_t>(3));
290271
}
291272
{
292273
ASSERT_OK_AND_ASSIGN(auto p2_array, mapping_reader->GenerateSinglePartitionArray(
293-
/*idx in read schema*/ 7, /*batch_size=*/1));
274+
/*idx=*/5, /*batch_size=*/1));
294275
ASSERT_EQ(
295276
arrow::internal::checked_cast<arrow::NumericArray<arrow::Int16Type>*>(p2_array.get())
296277
->Value(0),
297278
static_cast<int16_t>(2));
298279
}
299280
{
300281
ASSERT_OK_AND_ASSIGN(auto p1_array, mapping_reader->GenerateSinglePartitionArray(
301-
/*idx in read schema*/ 8, /*batch_size=*/1));
282+
/*idx=*/6, /*batch_size=*/1));
302283
ASSERT_EQ(
303284
arrow::internal::checked_cast<arrow::NumericArray<arrow::Int8Type>*>(p1_array.get())
304285
->Value(0),
305286
static_cast<int64_t>(1));
306287
}
307288
{
308289
ASSERT_OK_AND_ASSIGN(auto p0_array, mapping_reader->GenerateSinglePartitionArray(
309-
/*idx in read schema*/ 9, /*batch_size=*/1));
290+
/*idx=*/7, /*batch_size=*/1));
310291
ASSERT_EQ(arrow::internal::checked_cast<arrow::BooleanArray*>(p0_array.get())->Value(0),
311292
false);
312293
}

src/paimon/core/schema/schema_validation.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ Status SchemaValidation::ValidateTableSchema(const TableSchema& schema) {
7373
ValidateOnlyContainPrimitiveType(schema.Fields(), schema.PrimaryKeys(), "primary key"));
7474
PAIMON_RETURN_NOT_OK(
7575
ValidateOnlyContainPrimitiveType(schema.Fields(), schema.PartitionKeys(), "partition"));
76-
// TODO(lisizhuo.lsz): C++ Paimon do not support timestamp & decimal type in partition keys for
77-
// now.
78-
PAIMON_RETURN_NOT_OK(ValidateNotContainComplexType(schema.Fields(), schema.PartitionKeys()));
76+
// TODO(lisizhuo.lsz): C++ Paimon do not support timestamp & decimal & float & double type in
77+
// partition keys for now.
78+
PAIMON_RETURN_NOT_OK(ValidateNotContainSpecificType(schema.Fields(), schema.PartitionKeys()));
7979

8080
PAIMON_ASSIGN_OR_RAISE(CoreOptions options, CoreOptions::FromMap(schema.Options()));
8181
PAIMON_RETURN_NOT_OK(ValidateBucket(schema, options));
@@ -163,7 +163,7 @@ Status SchemaValidation::ValidateOnlyContainPrimitiveType(
163163
return Status::OK();
164164
}
165165

166-
Status SchemaValidation::ValidateNotContainComplexType(
166+
Status SchemaValidation::ValidateNotContainSpecificType(
167167
const std::vector<DataField>& fields, const std::vector<std::string>& field_names) {
168168
if (field_names.empty()) {
169169
return Status::OK();
@@ -178,8 +178,12 @@ Status SchemaValidation::ValidateNotContainComplexType(
178178
auto field = it->second;
179179
if (IsComplexType(field)) {
180180
return Status::Invalid(
181-
fmt::format("The field {} in partition field {} is unsupported",
182-
field->ToString(), it->first));
181+
fmt::format("partition field {} cannot be TIMESTAMP/DECIMAL/BLOB", field_name));
182+
}
183+
if (field->type()->id() == arrow::Type::FLOAT ||
184+
field->type()->id() == arrow::Type::DOUBLE) {
185+
return Status::Invalid(
186+
fmt::format("partition field {} cannot be FLOAT/DOUBLE", field_name));
183187
}
184188
} else {
185189
assert(false);

src/paimon/core/schema/schema_validation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ class SchemaValidation {
5454
static Status ValidateOnlyContainPrimitiveType(const std::vector<DataField>& fields,
5555
const std::vector<std::string>& field_names,
5656
const std::string& error_message_intro);
57-
static Status ValidateNotContainComplexType(const std::vector<DataField>& fields,
58-
const std::vector<std::string>& field_names);
57+
static Status ValidateNotContainSpecificType(const std::vector<DataField>& fields,
58+
const std::vector<std::string>& field_names);
5959
static Status ValidateBucket(const TableSchema& schema, const CoreOptions& options);
6060
static Status ValidateDefaultValues(const TableSchema& schema) {
6161
return Status::NotImplemented("validate default values not implemented");

src/paimon/core/schema/schema_validation_test.cpp

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -393,19 +393,34 @@ TEST(SchemaValidationTest, NonPrimitivePartitionKeyStruct) {
393393
"field f1 is unsupported");
394394
}
395395

396-
TEST(SchemaValidationTest, TestComplexPartitionKey) {
397-
auto f0 = arrow::field("f0", arrow::utf8());
398-
auto f1 = arrow::field("f1", arrow::decimal128(5, 2));
399-
auto f2 = arrow::field("f2", arrow::float64());
400-
arrow::FieldVector fields = {f0, f1, f2};
401-
auto schema = arrow::schema(fields);
402-
std::vector<std::string> primary_keys = {"f0", "f1"};
403-
std::vector<std::string> partition_keys = {"f1"};
404-
ASSERT_OK_AND_ASSIGN(
405-
std::shared_ptr<TableSchema> table_schema,
406-
TableSchema::Create(/*schema_id=*/0, schema, partition_keys, primary_keys, {}));
407-
ASSERT_NOK_WITH_MSG(SchemaValidation::ValidateTableSchema(*table_schema),
408-
"partition field f1 is unsupported");
396+
TEST(SchemaValidationTest, TestSpecificPartitionKey) {
397+
{
398+
auto f0 = arrow::field("f0", arrow::utf8());
399+
auto f1 = arrow::field("f1", arrow::decimal128(5, 2));
400+
auto f2 = arrow::field("f2", arrow::float64());
401+
arrow::FieldVector fields = {f0, f1, f2};
402+
auto schema = arrow::schema(fields);
403+
std::vector<std::string> primary_keys = {"f0", "f1"};
404+
std::vector<std::string> partition_keys = {"f1"};
405+
ASSERT_OK_AND_ASSIGN(
406+
std::shared_ptr<TableSchema> table_schema,
407+
TableSchema::Create(/*schema_id=*/0, schema, partition_keys, primary_keys, {}));
408+
ASSERT_NOK_WITH_MSG(SchemaValidation::ValidateTableSchema(*table_schema),
409+
"partition field f1 cannot be TIMESTAMP/DECIMAL/BLOB");
410+
}
411+
{
412+
auto f0 = arrow::field("f0", arrow::utf8());
413+
auto f1 = arrow::field("f1", arrow::float64());
414+
arrow::FieldVector fields = {f0, f1};
415+
auto schema = arrow::schema(fields);
416+
std::vector<std::string> primary_keys = {"f0", "f1"};
417+
std::vector<std::string> partition_keys = {"f1"};
418+
ASSERT_OK_AND_ASSIGN(
419+
std::shared_ptr<TableSchema> table_schema,
420+
TableSchema::Create(/*schema_id=*/0, schema, partition_keys, primary_keys, {}));
421+
ASSERT_NOK_WITH_MSG(SchemaValidation::ValidateTableSchema(*table_schema),
422+
"partition field f1 cannot be FLOAT/DOUBLE");
423+
}
409424
}
410425

411426
TEST(SchemaValidationTest, TestComplexPartitionKeyWithBlob) {
@@ -419,7 +434,7 @@ TEST(SchemaValidationTest, TestComplexPartitionKeyWithBlob) {
419434
std::shared_ptr<TableSchema> table_schema,
420435
TableSchema::Create(/*schema_id=*/0, schema, partition_keys, /*primary_keys=*/{}, {}));
421436
ASSERT_NOK_WITH_MSG(SchemaValidation::ValidateTableSchema(*table_schema),
422-
"partition field f1 is unsupported");
437+
"partition field f1 cannot be TIMESTAMP/DECIMAL/BLOB");
423438
}
424439

425440
TEST(SchemaValidationTest, TestDateTypePartitionKey) {
@@ -511,8 +526,8 @@ TEST(SchemaValidationTest, ValidateBucket) {
511526
"The number of buckets needs to be greater than 0.");
512527
}
513528
{
514-
std::vector<std::string> primary_keys = {"f0", "f1"};
515-
std::vector<std::string> partition_keys = {"f2"};
529+
std::vector<std::string> primary_keys = {"f0", "f2"};
530+
std::vector<std::string> partition_keys = {"f1"};
516531
std::map<std::string, std::string> options = {{Options::BUCKET, "2"},
517532
{Options::BUCKET_KEY, "f0"}};
518533
ASSERT_OK_AND_ASSIGN(
@@ -524,7 +539,7 @@ TEST(SchemaValidationTest, ValidateBucket) {
524539
}
525540
{
526541
std::vector<std::string> primary_keys = {};
527-
std::vector<std::string> partition_keys = {"f2"};
542+
std::vector<std::string> partition_keys = {"f1"};
528543
std::map<std::string, std::string> options = {{Options::BUCKET, "2"}};
529544
ASSERT_OK_AND_ASSIGN(
530545
std::shared_ptr<TableSchema> table_schema,
@@ -533,7 +548,7 @@ TEST(SchemaValidationTest, ValidateBucket) {
533548
"You should define a 'bucket-key' for bucketed append mode");
534549
}
535550
{
536-
std::vector<std::string> partition_keys = {"f2"};
551+
std::vector<std::string> partition_keys = {"f1"};
537552
std::map<std::string, std::string> options = {{"full-compaction.delta-commits", "2"}};
538553
ASSERT_OK_AND_ASSIGN(std::shared_ptr<TableSchema> table_schema,
539554
TableSchema::Create(/*schema_id=*/0, schema, partition_keys,
@@ -633,11 +648,11 @@ TEST(SchemaValidationTest, ValidateSequenceField) {
633648
std::map<std::string, std::string> options = {{Options::BUCKET, "-1"},
634649
{Options::SEQUENCE_FIELD, "f0,f1,f2"}};
635650
ASSERT_OK_AND_ASSIGN(std::shared_ptr<TableSchema> table_schema,
636-
TableSchema::Create(/*schema_id=*/0, schema, /*partition_keys=*/{"f2"},
637-
/*primary_keys=*/{"f0", "f1"}, options));
651+
TableSchema::Create(/*schema_id=*/0, schema, /*partition_keys=*/{"f1"},
652+
/*primary_keys=*/{"f0", "f2"}, options));
638653
ASSERT_NOK_WITH_MSG(SchemaValidation::ValidateTableSchema(*table_schema),
639654
"You cannot use sequence.field in cross partition update case (Primary "
640-
"key constraint 'f0, f1' not including all partition fields 'f2').");
655+
"key constraint 'f0, f2' not including all partition fields 'f1').");
641656
}
642657
}
643658

src/paimon/core/stats/simple_stats_collector.cpp

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -133,40 +133,6 @@ Status SimpleStatsCollector::Collect(const BinaryRow& row) {
133133
}
134134
break;
135135
}
136-
case arrow::Type::FLOAT: {
137-
if (column_stats_[i] == nullptr) {
138-
column_stats_[i] = ColumnStats::CreateFloatColumnStats(
139-
std::nullopt, std::nullopt, std::nullopt);
140-
}
141-
auto typed_stats = dynamic_cast<FloatColumnStats*>(column_stats_[i].get());
142-
if (typed_stats == nullptr) {
143-
assert(false);
144-
return Status::Invalid("cast typed stats failed");
145-
}
146-
if (!row.IsNullAt(i)) {
147-
typed_stats->Collect(row.GetFloat(i));
148-
} else {
149-
typed_stats->Collect(std::nullopt);
150-
}
151-
break;
152-
}
153-
case arrow::Type::DOUBLE: {
154-
if (column_stats_[i] == nullptr) {
155-
column_stats_[i] = ColumnStats::CreateDoubleColumnStats(
156-
std::nullopt, std::nullopt, std::nullopt);
157-
}
158-
auto typed_stats = dynamic_cast<DoubleColumnStats*>(column_stats_[i].get());
159-
if (typed_stats == nullptr) {
160-
assert(false);
161-
return Status::Invalid("cast typed stats failed");
162-
}
163-
if (!row.IsNullAt(i)) {
164-
typed_stats->Collect(row.GetDouble(i));
165-
} else {
166-
typed_stats->Collect(std::nullopt);
167-
}
168-
break;
169-
}
170136
case arrow::Type::STRING:
171137
case arrow::Type::BINARY: {
172138
if (column_stats_[i] == nullptr) {

0 commit comments

Comments
 (0)