Skip to content

GH-50689: [C++][Parquet] Add IEEE-754 total order and nan count for floating types - #50807

Open
HuaHuaY wants to merge 6 commits into
apache:mainfrom
HuaHuaY:nan_count
Open

GH-50689: [C++][Parquet] Add IEEE-754 total order and nan count for floating types#50807
HuaHuaY wants to merge 6 commits into
apache:mainfrom
HuaHuaY:nan_count

Conversation

@HuaHuaY

@HuaHuaY HuaHuaY commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Rationale for this change

Implement IEEE 754 total order and NaN counts from apache/parquet-format#514.

What changes are included in this PR?

  • Use IEEE total order by default, with a writer-level TYPE order fallback.
  • Add nan_count to statistics and nan_counts to PageIndex.
  • Preserve NaN payloads and signed zero in statistics and dictionary encoding.
  • Make Dataset pruning NaN-aware (skip FLOAT16 numeric bounds until comparison kernels are available).

Are these changes tested?

Yes.

Are there any user-facing changes?

  • cpp/src/parquet/types.h: Adds ColumnOrder::IEEE_754_TOTAL_ORDER.
  • cpp/src/parquet/properties.h: Adds the floating-point column-order writer property.
  • cpp/src/parquet/schema.h: Allows column descriptors to use IEEE-ordered min/max statistics.
  • cpp/src/parquet/page_index.h: Exposes has_nan_counts() and nan_counts().
  • cpp/src/parquet/statistics.h: Adds NaN fields and presence APIs to EncodedStatistics and Statistics, and extends encoded-state Statistics::Make / MakeStatistics overloads with nan_count and has_nan_count.

Comment thread cpp/apidoc/Doxyfile
ARROW_SUPPRESS_DEPRECATION_WARNING= \
ARROW_UNSUPPRESS_DEPRECATION_WARNING= \
GANDIVA_EXPORT= \
PARQUET_DEPRECATED(x)= \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add this because I added a PARQUET_DEPRECATED at cpp/src/parquet/statistics.h and ci failed. https://github.com/apache/arrow/actions/runs/30975844655/job/92209544482

I believe this is a long-standing issue. If someone would like me to submit a separate PR to fix it, I can certainly do so.

@github-actions github-actions Bot added awaiting committer review Awaiting committer review and removed awaiting review Awaiting review labels Aug 5, 2026
@HuaHuaY
HuaHuaY force-pushed the nan_count branch 2 times, most recently from bd13067 to f51ffc1 Compare August 5, 2026 08:03
Comment thread cpp/src/parquet/types.h Outdated
Comment thread cpp/src/parquet/schema.h Outdated
Comment thread cpp/src/parquet/schema.cc Outdated
Comment thread cpp/src/parquet/statistics.h Outdated
Comment thread docs/source/python/parquet.rst Outdated
Comment thread cpp/src/parquet/statistics.h Outdated
Comment thread cpp/src/parquet/statistics.h Outdated
Comment thread cpp/src/parquet/statistics.h Outdated
Comment thread cpp/src/parquet/schema_internal.h Outdated
Comment thread cpp/src/parquet/statistics.cc Outdated
Comment thread cpp/src/parquet/statistics.cc Outdated
Comment thread cpp/src/parquet/statistics.cc Outdated
Comment thread cpp/src/parquet/metadata.cc
Comment thread cpp/src/parquet/column_writer.cc
@HuaHuaY
HuaHuaY force-pushed the nan_count branch 3 times, most recently from a306ade to 2f24bb6 Compare August 19, 2026 09:19
Copilot AI lite review requested due to automatic review settings August 25, 2026 06:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Arrow C++’s Parquet implementation to support IEEE-754 total ordering for floating-point statistics and to record NaN counts in statistics and page indexes, aligning with parquet-format changes (apache/parquet-format#514) and improving correctness for pruning, encoding, and metadata round-trips involving NaNs and signed zeros.

Changes:

  • Add ColumnOrder::IEEE_754_TOTAL_ORDER and a writer property to control floating-point column ordering (defaulting to IEEE total order).
  • Track and serialize nan_count in column/page statistics and expose per-page nan_counts via ColumnIndex.
  • Update statistics computation, dictionary encoding, metadata/schema handling, and dataset pruning to be NaN-aware (including special handling for FLOAT16 pruning limitations).

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/source/python/parquet.rst Update example metadata output values to match new behavior/encoding sizes.
cpp/src/parquet/types.h Add IEEE_754_TOTAL_ORDER to ColumnOrder enum and declare static instance.
cpp/src/parquet/types.cc Define ColumnOrder::ieee_754_total_order_.
cpp/src/parquet/thrift_internal.h Serialize/deserialize nan_count; treat IEEE order as min/max-value stats field source.
cpp/src/parquet/statistics.h Extend statistics APIs and encoded state to include optional nan_count; update comparator docs.
cpp/src/parquet/statistics.cc Implement IEEE total-order comparisons, NaN counting, and IEEE-aware min/max handling and merging.
cpp/src/parquet/statistics_test.cc Add/extend tests for NaN counts, IEEE total order, and float16 behaviors.
cpp/src/parquet/schema.h Allow can_use_min_max() for IEEE order (see review note re: non-float types).
cpp/src/parquet/schema.cc Add IsFloatingPointType helper for schema/metadata decisions.
cpp/src/parquet/schema_test.cc Test that IEEE column order allows min/max usage.
cpp/src/parquet/schema_internal.h Expose IsFloatingPointType as a non-public schema utility.
cpp/src/parquet/properties.h Add writer property floating_point_column_order with validation and plumbing.
cpp/src/parquet/page_index.h Add has_nan_counts() / nan_counts() to ColumnIndex API.
cpp/src/parquet/page_index.cc Persist per-page nan_counts when available for floating columns; validate vector lengths.
cpp/src/parquet/page_index_test.cc Add tests covering nan_counts propagation for IEEE total-order float columns.
cpp/src/parquet/metadata.cc Plumb encoded stats into Statistics::Make; enforce column-order compatibility; parse/write IEEE column order in file metadata.
cpp/src/parquet/file_writer.cc Build writer schema with per-float column orders from writer properties and stabilize type_length.
cpp/src/parquet/file_serialize_test.cc Add round-trip test validating floating-point column order behavior and schema stability.
cpp/src/parquet/encoding_test.cc Add tests ensuring dictionary encoding preserves float bit patterns and avoids NaN hash collisions.
cpp/src/parquet/encoder.cc Change float/double dictionary memoization keys to use bitwise representations for NaN payload stability.
cpp/src/parquet/column_writer.cc Gate legacy min/max field population based on effective ordering; enable stats collection via can_use_min_max().
cpp/src/parquet/arrow/reader_internal.cc Decode FLOAT16 min/max statistics into HalfFloat scalars for Arrow conversion.
cpp/src/parquet/arrow/index_test.cc Add nan_counts to column index round-trip expectations; add test parquet file coverage for mixed orders/nan counts.
cpp/src/parquet/arrow/arrow_reader_writer_test.cc Add end-to-end test ensuring float dictionary round-trips preserve NaN payloads and signed zeros with IEEE order and page index.
cpp/src/arrow/dataset/file_parquet.cc Make dataset pruning NaN-aware using nan_count; skip FLOAT16 numeric pruning until kernels exist.
cpp/src/arrow/dataset/file_parquet_test.cc Add tests validating pruning expressions with/without nan_count and for FLOAT16 behavior.
cpp/apidoc/Doxyfile Teach Doxygen about PARQUET_DEPRECATED macro for API docs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cpp/src/parquet/schema.h
Comment on lines +390 to +391
case ColumnOrder::IEEE_754_TOTAL_ORDER:
return true;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this is a public function, we have already checked the type before reading and writing files, so I don't think we need to do any extra checks here.

Comment thread cpp/src/parquet/statistics.cc
Copilot AI review requested due to automatic review settings August 27, 2026 02:26
@HuaHuaY

HuaHuaY commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Run git rebase to resolve conflicts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 27, 2026 09:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.

int16_t max_repetition_level = 0,
const std::vector<PageLevelHistogram>& page_levels = {}) {
const bool build_size_stats = !page_levels.empty();
const bool has_nan_counts = std::all_of(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I guess that you don't want to change the signature here but currently has_nan_counts and has_null_counts are handled differently. It would be more readable to use consistent approach to pass or compute both of them.

/// \param[in] is_min_value_exact whether the min value is exact
/// \param[in] is_max_value_exact whether the max value is exact
/// \param[in] pool a memory pool to use for any memory allocations, optional
static std::shared_ptr<Statistics> Make(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just directly extending the above Make function? We already have several overloads now.

virtual int64_t distinct_count() const = 0;

/// \brief Return true if the count of NaN values is set
virtual bool HasNanCount() const = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not combine HasNanCount and nan_count just like std::optional<bool> is_min_value_exact() does?

}
}

TEST(TestDictionaryEncoding, FloatingPointBits) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to test float16 here?

dictionary->WriteDict(buffer->mutable_data());
const UInt* encoded = reinterpret_cast<const UInt*>(buffer->data());
for (int value_index = 0; value_index < num_entries; ++value_index) {
EXPECT_EQ(bits[value_index], encoded[value_index]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little bit fraigle since it enforces that all distinct values should appear in the beginning of bits. Should we remove num_entries and add a const std::array<UInt, NumValues>& expected_bits to the input parameter instead?

std::transform(bits.begin(), bits.end(), values.begin(),
[](UInt value) { return ::arrow::util::SafeCopy<T>(value); });

auto encoder = MakeTypedEncoder<DType>(Encoding::PLAIN, true);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto encoder = MakeTypedEncoder<DType>(Encoding::PLAIN, true);
auto encoder = MakeTypedEncoder<DType>(Encoding::PLAIN, /*use_dictionary=*/true);

Same apply to others

assert_orders(&input_schema, ColumnOrder::TYPE_DEFINED_ORDER);
assert_orders(type_writer->schema(), ColumnOrder::TYPE_DEFINED_ORDER);
assert_orders(type_file->schema(), ColumnOrder::TYPE_DEFINED_ORDER);
EXPECT_THROW(ieee_file->AppendRowGroups(*type_file), ParquetException);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: check error message

assert_orders(&input_schema, ColumnOrder::TYPE_DEFINED_ORDER);

auto [ieee_writer, ieee_file] = write_orders(ColumnOrder::IEEE_754_TOTAL_ORDER);
assert_orders(&input_schema, ColumnOrder::TYPE_DEFINED_ORDER);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we test that input schema has not been altered?


namespace {

std::shared_ptr<GroupNode> MakeWriterSchema(const GroupNode& input_schema,

@wgtmac wgtmac Aug 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove this function? The Open function below should preserve the input schema. This provides the flexibility of low-level api to enable users to mix ieee754 and type_defined order for different floating-point columns.

Instead, we can move floating_point_column_order() to ArrowWriterProperties so we are converting Arrow schema to parquet GroupNode with expected column order at all once.

auto msg = "AppendRowGroups requires equal schemas.\n" + diff_output.str();
throw ParquetException(msg);
}
for (int column_index = 0; column_index < schema()->num_columns(); ++column_index) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we check this in the above if (!schema()->Equals(*other->schema(), &diff_output))?

auto file_meta_data = std::unique_ptr<FileMetaData>(new FileMetaData());
file_meta_data->impl_->metadata_ = std::move(metadata_);
file_meta_data->impl_->InitSchema();
file_meta_data->impl_->InitColumnOrders();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it mean that parquet-cpp has never emitted column orders?

/// elements with accompanying bitmap indicating which elements are
/// included (bit set) and excluded (bit not set)
///
/// For floating-point types with ColumnOrder::TYPE_DEFINED_ORDER, NaNs are

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::pair<T, T> GetMinMax(const ::arrow::Array& values) does not have this comment. Is it because we have not implemented this new order to it? Should we be explicit about this?

bool TypedStatisticsImpl<DType>::MinMaxEqual(
const TypedStatisticsImpl<DType>& other) const {
if constexpr (IsOneOf<T, float, double>::value) {
if (descr_->column_order().get_order() == ColumnOrder::IEEE_754_TOTAL_ORDER) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that above TypedStatisticsImpl<FLBAType>::MinMaxEqual uses bit-wise comparison for float16 regardless of column order. I think this is acceptable.

Comment thread cpp/src/parquet/statistics.cc

int64_t null_count() const override { return statistics_.null_count; }
int64_t distinct_count() const override { return statistics_.distinct_count; }
int64_t nan_count() const override { return statistics_.nan_count.value_or(0); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think we should just return std::optional<int64_t> for this. If you insist to return int64_t, return -1 if missing seems more appropriate.

::testing::HasSubstr("BloomFilterBuilder does not support boolean type"));
}

TEST(ParquetPageIndex, FloatingPointOrders) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename it to indicate it is an interoperability test.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I think this test case is a little bit weak. This file was added by apache/parquet-testing#104 and it contains following attributes:

» parquet-cli meta target/parquet-testing/data/floating_orders_nan_count.parquet

File path:  data/floating_orders_nan_count.parquet
Created by: parquet-mr version 1.18.0-SNAPSHOT (build c5dcd8ca5bad5fde9c797b876a16b5bf3b9206c0)
Properties:
  original.created.by: parquet-mr version 1.18.0-SNAPSHOT (build c5dcd8ca5bad5fde9c797b876a16b5bf3b9206c0)
    writer.model.name: example
Schema:
message msg {
  required float float_ieee754;
  required float float_typedef;
  required double double_ieee754;
  required double double_typedef;
  required fixed_len_byte_array(2) float16_ieee754 (FLOAT16);
  required fixed_len_byte_array(2) float16_typedef (FLOAT16);
}


Row group 0:  count: 10  42.20 B records  start: 4  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "-2.0" / "5.0"
float_typedef    FLOAT     _   _     10        6.30 B     0       "-2.0" / "5.0"
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "-2.0" / "5.0"
double_typedef   DOUBLE    _   _     10        10.50 B    0       "-2.0" / "5.0"
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "-2.0" / "5.0"
float16_typedef  FIXED[2] _   _     10        4.30 B   0       "-2.0" / "5.0"

Row group 1:  count: 10  42.20 B records  start: 426  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "-2.0" / "3.0"
float_typedef    FLOAT     _   _     10        6.30 B     0
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "-2.0" / "3.0"
double_typedef   DOUBLE    _   _     10        10.50 B    0
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "-2.0" / "3.0"
float16_typedef  FIXED[2] _   _     10        4.30 B   0

Row group 2:  count: 10  42.20 B records  start: 848  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "NaN" / "NaN"
float_typedef    FLOAT     _   _     10        6.30 B     0
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "NaN" / "NaN"
double_typedef   DOUBLE    _   _     10        10.50 B    0
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "NaN" / "NaN"
float16_typedef  FIXED[2] _   _     10        4.30 B   0

Row group 3:  count: 10  42.20 B records  start: 1270  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "0.0" / "5.0"
float_typedef    FLOAT     _   _     10        6.30 B     0       "-0.0" / "5.0"
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "0.0" / "5.0"
double_typedef   DOUBLE    _   _     10        10.50 B    0       "-0.0" / "5.0"
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "0.0" / "5.0"
float16_typedef  FIXED[2] _   _     10        4.30 B   0       "-0.0" / "5.0"

Row group 4:  count: 10  42.20 B records  start: 1692  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "-5.0" / "-0.0"
float_typedef    FLOAT     _   _     10        6.30 B     0       "-5.0" / "0.0"
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "-5.0" / "-0.0"
double_typedef   DOUBLE    _   _     10        10.50 B    0       "-5.0" / "0.0"
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "-5.0" / "-0.0"
float16_typedef  FIXED[2] _   _     10        4.30 B   0       "-5.0" / "0.0"

It would be better to verify column chunk stats and page index of every row group and column are correctly parsed.

Comment thread cpp/src/parquet/schema.h
case ColumnOrder::TYPE_DEFINED_ORDER:
return sort_order() != SortOrder::UNKNOWN;
case ColumnOrder::IEEE_754_TOTAL_ORDER:
return true;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we call IsFloatingPointType here?

@wgtmac wgtmac left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've finished a full round of review. Thanks for working on this!

logical_type_(LogicalTypeId(descr_)) {
if (descr->sort_order() != SortOrder::UNKNOWN) {
logical_type_(LogicalTypeId(descr_)),
is_half_float_(logical_type_ == LogicalType::Type::FLOAT16) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove is_half_float_ by just calling logical_type_ == LogicalType::Type::FLOAT16 where it is called? It looks weird because this variable does not apply to all cases.

}

// Create stats from provided values.
// Only used by the deprecated MakeStatistics overload. Remove it after that

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mark it as deprecated?

FloatingValueSummary<ArrowFloat, column_order> summary;
std::invoke(std::forward<VisitValues>(visit_values),
[&](const auto& value) { summary.Add(value); });
if (HasNanCount() && update_nan_count) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we clear it if update_nan_count is false?

this->has_null_count_ = true;
// NaN counts are collected alongside floating-point bounds and enabled by
// default.
if constexpr (std::same_as<DType, FLBAType>) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we call reset in all cases?

const T positive_nan = SafeCopy<T>(positive_nan_bits);
const T negative_zero = -T{0};
const T positive_zero = T{0};
std::array<T, 4> mixed{negative_nan, positive_zero, negative_zero, positive_nan};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better if we just have only positive_zero or negative_zero but not both to verify that no adjustment is done for zero signedness. Same for float16 test below.

::testing::HasSubstr("BloomFilterBuilder does not support boolean type"));
}

TEST(ParquetPageIndex, FloatingPointOrders) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I think this test case is a little bit weak. This file was added by apache/parquet-testing#104 and it contains following attributes:

» parquet-cli meta target/parquet-testing/data/floating_orders_nan_count.parquet

File path:  data/floating_orders_nan_count.parquet
Created by: parquet-mr version 1.18.0-SNAPSHOT (build c5dcd8ca5bad5fde9c797b876a16b5bf3b9206c0)
Properties:
  original.created.by: parquet-mr version 1.18.0-SNAPSHOT (build c5dcd8ca5bad5fde9c797b876a16b5bf3b9206c0)
    writer.model.name: example
Schema:
message msg {
  required float float_ieee754;
  required float float_typedef;
  required double double_ieee754;
  required double double_typedef;
  required fixed_len_byte_array(2) float16_ieee754 (FLOAT16);
  required fixed_len_byte_array(2) float16_typedef (FLOAT16);
}


Row group 0:  count: 10  42.20 B records  start: 4  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "-2.0" / "5.0"
float_typedef    FLOAT     _   _     10        6.30 B     0       "-2.0" / "5.0"
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "-2.0" / "5.0"
double_typedef   DOUBLE    _   _     10        10.50 B    0       "-2.0" / "5.0"
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "-2.0" / "5.0"
float16_typedef  FIXED[2] _   _     10        4.30 B   0       "-2.0" / "5.0"

Row group 1:  count: 10  42.20 B records  start: 426  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "-2.0" / "3.0"
float_typedef    FLOAT     _   _     10        6.30 B     0
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "-2.0" / "3.0"
double_typedef   DOUBLE    _   _     10        10.50 B    0
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "-2.0" / "3.0"
float16_typedef  FIXED[2] _   _     10        4.30 B   0

Row group 2:  count: 10  42.20 B records  start: 848  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "NaN" / "NaN"
float_typedef    FLOAT     _   _     10        6.30 B     0
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "NaN" / "NaN"
double_typedef   DOUBLE    _   _     10        10.50 B    0
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "NaN" / "NaN"
float16_typedef  FIXED[2] _   _     10        4.30 B   0

Row group 3:  count: 10  42.20 B records  start: 1270  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "0.0" / "5.0"
float_typedef    FLOAT     _   _     10        6.30 B     0       "-0.0" / "5.0"
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "0.0" / "5.0"
double_typedef   DOUBLE    _   _     10        10.50 B    0       "-0.0" / "5.0"
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "0.0" / "5.0"
float16_typedef  FIXED[2] _   _     10        4.30 B   0       "-0.0" / "5.0"

Row group 4:  count: 10  42.20 B records  start: 1692  total(compressed): 422 B total(uncompressed):422 B
--------------------------------------------------------------------------------
                 type      encodings count     avg size   nulls   min / max
float_ieee754    FLOAT     _   _     10        6.30 B     0       "-5.0" / "-0.0"
float_typedef    FLOAT     _   _     10        6.30 B     0       "-5.0" / "0.0"
double_ieee754   DOUBLE    _   _     10        10.50 B    0       "-5.0" / "-0.0"
double_typedef   DOUBLE    _   _     10        10.50 B    0       "-5.0" / "0.0"
float16_ieee754  FIXED[2] _   _     10        4.30 B   0       "-5.0" / "-0.0"
float16_typedef  FIXED[2] _   _     10        4.30 B   0       "-5.0" / "0.0"

It would be better to verify column chunk stats and page index of every row group and column are correctly parsed.

const ::parquet::schema::NodePtr& parquet_node) {
auto field = ::arrow::field("x", type);
auto dataset_schema = ::arrow::schema({field});
::parquet::ColumnDescriptor descr(parquet_node, 0, 0);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These test cases still use type_defined_order and do not cover the new ieee754 total order and do not actually test the filtering logic. Does it make sense to directly use floating_orders_nan_count.parquet from parquet-testing for a real e2e interoperability test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants