blob: 2c5de2cf330df90b4b242eb51e5f1b9b5b02ecba [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "paimon/format/parquet/parquet_writer_builder.h"
#include <limits>
#include "arrow/type_fwd.h"
#include "arrow/util/type_fwd.h"
#include "gtest/gtest.h"
#include "paimon/defs.h"
#include "paimon/format/parquet/parquet_format_defs.h"
#include "paimon/status.h"
#include "paimon/testing/utils/testharness.h"
#include "parquet/properties.h"
#include "parquet/type_fwd.h"
namespace arrow {
class Schema;
} // namespace arrow
namespace paimon::parquet::test {
TEST(ParquetWriterBuilderTest, DefaultPrepareWriterProperties) {
arrow::FieldVector fields;
std::shared_ptr<arrow::Schema> schema = arrow::schema(fields);
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("zstd"));
ASSERT_EQ(::parquet::ParquetVersion::PARQUET_2_6, properties->version());
ASSERT_EQ(1024 * 1024, properties->dictionary_pagesize_limit());
ASSERT_EQ(1024 * 1024, properties->data_pagesize());
ASSERT_EQ(std::numeric_limits<int64_t>::max(), properties->max_row_group_length());
ASSERT_EQ(128 * 1024 * 1024, properties->max_row_group_size());
ASSERT_EQ(1024, properties->write_batch_size());
ASSERT_EQ(1, properties->default_column_properties().compression_level());
ASSERT_TRUE(properties->store_decimal_as_integer());
}
TEST(ParquetWriterBuilderTest, PrepareWriterProperties) {
arrow::FieldVector fields;
std::shared_ptr<arrow::Schema> schema = arrow::schema(fields);
std::map<std::string, std::string> options;
options[PARQUET_PAGE_SIZE] = "1024";
options[PARQUET_DICTIONARY_PAGE_SIZE] = "4096";
options[PARQUET_WRITER_VERSION] = "PARQUET_2_0";
options[PARQUET_COMPRESSION_CODEC_ZSTD_LEVEL] = "3";
options[PARQUET_BLOCK_SIZE] = "2048";
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024 * 1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("zstd"));
// Version numbering differs between C++ and Java Parquet implementations. Java's PARQUET_2_0
// format version corresponds to C++'s PARQUET_2_6 enum value.
ASSERT_EQ(::parquet::ParquetVersion::PARQUET_2_6, properties->version());
ASSERT_EQ(4096, properties->dictionary_pagesize_limit());
ASSERT_EQ(1024, properties->data_pagesize());
ASSERT_EQ(2048, properties->max_row_group_size());
ASSERT_EQ(1024 * 1024, properties->write_batch_size());
ASSERT_EQ(3, properties->default_column_properties().compression_level());
}
TEST(ParquetWriterBuilderTest, PrepareWriterPropertiesWithZstdLevelPriority) {
arrow::FieldVector fields;
std::shared_ptr<arrow::Schema> schema = arrow::schema(fields);
{
std::map<std::string, std::string> options;
options[Options::FILE_COMPRESSION_ZSTD_LEVEL] = "4";
options[PARQUET_COMPRESSION_CODEC_ZSTD_LEVEL] = "3";
options[PARQUET_WRITER_VERSION] = "PARQUET_1_0";
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024 * 1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("zstd"));
ASSERT_EQ(3, properties->default_column_properties().compression_level());
ASSERT_EQ(::parquet::ParquetVersion::PARQUET_1_0, properties->version());
}
{
std::map<std::string, std::string> options;
options[Options::FILE_COMPRESSION_ZSTD_LEVEL] = "4";
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024 * 1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("zstd"));
ASSERT_EQ(4, properties->default_column_properties().compression_level());
}
}
TEST(ParquetWriterBuilderTest, TestPrepareWriterPropertiesFileCompression) {
arrow::FieldVector fields;
std::shared_ptr<arrow::Schema> schema = arrow::schema(fields);
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("lz4"));
ASSERT_EQ(properties->default_column_properties().compression(),
arrow::Compression::LZ4_FRAME);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("lz4_raW"));
ASSERT_EQ(properties->default_column_properties().compression(), arrow::Compression::LZ4);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("zstd"));
ASSERT_EQ(properties->default_column_properties().compression(), arrow::Compression::ZSTD);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("LZ4"));
ASSERT_EQ(properties->default_column_properties().compression(),
arrow::Compression::LZ4_FRAME);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("ZSTd"));
ASSERT_EQ(properties->default_column_properties().compression(), arrow::Compression::ZSTD);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
options[PARQUET_COMPRESSION_CODEC_ZLIB_LEVEL] = "3";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("gzip"));
ASSERT_EQ(3, properties->default_column_properties().compression_level());
ASSERT_EQ(properties->default_column_properties().compression(), arrow::Compression::GZIP);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("snappy"));
ASSERT_EQ(properties->default_column_properties().compression(),
arrow::Compression::SNAPPY);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("lzo"));
ASSERT_EQ(properties->default_column_properties().compression(), arrow::Compression::LZO);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_NOK(builder.PrepareWriterProperties("unknown"));
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("uncompressed"));
ASSERT_EQ(properties->default_column_properties().compression(),
arrow::Compression::UNCOMPRESSED);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("lz4_hadoop"));
ASSERT_EQ(properties->default_column_properties().compression(),
arrow::Compression::LZ4_HADOOP);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
options[PARQUET_COMPRESSION_CODEC_BROTLI_LEVEL] = "2";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("brotli"));
ASSERT_EQ(2, properties->default_column_properties().compression_level());
ASSERT_EQ(properties->default_column_properties().compression(),
arrow::Compression::BROTLI);
}
{
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_OK_AND_ASSIGN(auto properties, builder.PrepareWriterProperties("None"));
ASSERT_EQ(properties->default_column_properties().compression(),
arrow::Compression::UNCOMPRESSED);
}
}
TEST(ParquetWriterBuilderTest, TestInvalidWriterVersion) {
arrow::FieldVector fields;
std::shared_ptr<arrow::Schema> schema = arrow::schema(fields);
std::map<std::string, std::string> options;
options[Options::FILE_FORMAT] = "parquet";
options[Options::MANIFEST_FORMAT] = "parquet";
options[PARQUET_WRITER_VERSION] = "PARQUET_3_0";
ParquetWriterBuilder builder(schema, /*batch_size=*/1024, options);
ASSERT_NOK_WITH_MSG(builder.PrepareWriterProperties("zstd"),
"Unknown writer version PARQUET_3_0");
}
} // namespace paimon::parquet::test