This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new d7e5487d fix(parquet_reader): propagate statistics decoding errors
(#1087)
d7e5487d is described below
commit d7e5487d04e7d02f64eedac621c48b8d45502e01
Author: Minh Vu <[email protected]>
AuthorDate: Fri Aug 7 18:43:45 2026 +0200
fix(parquet_reader): propagate statistics decoding errors (#1087)
### Rationale for this change
The parquet_reader command currently treats errors while decoding column
statistics as if statistics were absent. This hides malformed metadata
from users inspecting a file.
### What changes are included in this PR?
Propagate the decoding error and include the affected column index in
the message.
### Are these changes tested?
- `go test ./parquet/cmd/parquet_reader`
### Are there any user-facing changes?
No API changes. This corrects the reported behavior while preserving the
existing ownership and compatibility contracts.
---
parquet/cmd/parquet_reader/main.go | 28 ++++++++++++---
parquet/cmd/parquet_reader/main_test.go | 62 +++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+), 5 deletions(-)
diff --git a/parquet/cmd/parquet_reader/main.go
b/parquet/cmd/parquet_reader/main.go
index 11cb2fbf..3ae0ea0e 100644
--- a/parquet/cmd/parquet_reader/main.go
+++ b/parquet/cmd/parquet_reader/main.go
@@ -61,6 +61,24 @@ func printUsage(fs *flag.FlagSet) {
})
}
+type columnChunkStats interface {
+ StatsSet() (bool, error)
+ Statistics() (metadata.TypedStatistics, error)
+}
+
+func readColumnStats(chunkMeta columnChunkStats) (metadata.TypedStatistics,
bool, error) {
+ set, err := chunkMeta.StatsSet()
+ if err != nil {
+ return nil, false, err
+ }
+ if !set {
+ return nil, false, nil
+ }
+
+ stats, err := chunkMeta.Statistics()
+ return stats, true, err
+}
+
func main() {
var config struct {
ColumnIndexes bool
@@ -261,11 +279,11 @@ func main() {
if !config.NoMetadata {
fmt.Println("Column", c)
- if set, _ := chunkMeta.StatsSet(); set {
- stats, err := chunkMeta.Statistics()
- if err != nil {
- log.Fatal(err)
- }
+ stats, set, err := readColumnStats(chunkMeta)
+ if err != nil {
+ log.Fatalf("unable to read statistics
for column=%d: %s", c, err)
+ }
+ if set {
fmt.Printf(" Values: %d",
chunkMeta.NumValues())
if stats.HasMinMax() {
fmt.Printf(", Min: %v, Max: %v",
diff --git a/parquet/cmd/parquet_reader/main_test.go
b/parquet/cmd/parquet_reader/main_test.go
new file mode 100644
index 00000000..9bbe3dc2
--- /dev/null
+++ b/parquet/cmd/parquet_reader/main_test.go
@@ -0,0 +1,62 @@
+// 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.
+
+package main
+
+import (
+ "errors"
+ "testing"
+
+ "github.com/apache/arrow-go/v18/parquet/metadata"
+ "github.com/stretchr/testify/require"
+)
+
+type columnChunkStatsStub struct {
+ set bool
+ stats metadata.TypedStatistics
+ statsSetErr error
+ statisticsErr error
+}
+
+func (s *columnChunkStatsStub) StatsSet() (bool, error) {
+ return s.set, s.statsSetErr
+}
+
+func (s *columnChunkStatsStub) Statistics() (metadata.TypedStatistics, error) {
+ return s.stats, s.statisticsErr
+}
+
+func TestReadColumnStatsReturnsStatsSetError(t *testing.T) {
+ wantErr := errors.New("malformed statistics")
+ reader := &columnChunkStatsStub{statsSetErr: wantErr}
+
+ stats, set, err := readColumnStats(reader)
+
+ require.ErrorIs(t, err, wantErr)
+ require.False(t, set)
+ require.Nil(t, stats)
+}
+
+func TestReadColumnStatsReturnsStatisticsError(t *testing.T) {
+ wantErr := errors.New("statistics could not be decoded")
+ reader := &columnChunkStatsStub{set: true, statisticsErr: wantErr}
+
+ stats, set, err := readColumnStats(reader)
+
+ require.ErrorIs(t, err, wantErr)
+ require.True(t, set)
+ require.Nil(t, stats)
+}