From 2e5a5bcce59bc7769764e59319729d9122ad48bc Mon Sep 17 00:00:00 2001 From: erezrokah Date: Thu, 10 Sep 2026 12:30:06 +0100 Subject: [PATCH 1/2] fix: Make max_row_group_length default a deliberate row count WithMaxRowGroupLength takes a number of rows, but the default was 128 * 1024 * 1024, a byte-shaped value that made every written parquet file a single row group. Default is now 1024 * 1024 rows. --- parquet/spec.go | 10 ++++++---- parquet/write_read_test.go | 31 +++++++++++++++++++++++++++++++ schema.json | 4 ++-- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/parquet/spec.go b/parquet/spec.go index e6e4ee28..6b8c6bce 100644 --- a/parquet/spec.go +++ b/parquet/spec.go @@ -9,15 +9,17 @@ import ( "github.com/invopop/jsonschema" ) -const defaultMaxRowGroupLength = 128 * 1024 * 1024 +// defaultMaxRowGroupLength is a number of rows, not a number of bytes. +const defaultMaxRowGroupLength = 1024 * 1024 var allowedVersions = []string{"v1.0", "v2.4", "v2.6", "v2Latest"} var allowedRootRepetitions = []string{"undefined", "required", "optional", "repeated"} // nolint:revive type ParquetSpec struct { - Version string `json:"version,omitempty"` - RootRepetition string `json:"root_repetition,omitempty"` + Version string `json:"version,omitempty"` + RootRepetition string `json:"root_repetition,omitempty"` + // MaxRowGroupLength is the maximum number of rows in a single Parquet row group. MaxRowGroupLength *int64 `json:"max_row_group_length,omitempty"` } @@ -82,7 +84,7 @@ func (ParquetSpec) JSONSchema() *jsonschema.Schema { properties.Set("max_row_group_length", &jsonschema.Schema{ Type: "integer", - Description: "Max row group length", + Description: "Maximum number of rows per Parquet row group.", Default: defaultMaxRowGroupLength, Minimum: "0", }) diff --git a/parquet/write_read_test.go b/parquet/write_read_test.go index 1e8edae6..e03b5df9 100644 --- a/parquet/write_read_test.go +++ b/parquet/write_read_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/apache/arrow-go/v18/arrow" + "github.com/apache/arrow-go/v18/parquet/file" "github.com/cloudquery/filetypes/v4/types" "github.com/cloudquery/plugin-sdk/v4/plugin" "github.com/cloudquery/plugin-sdk/v4/schema" @@ -149,3 +150,33 @@ func BenchmarkWrite(b *testing.B) { b.Fatal(err) } } + +func TestWriteMultipleRowGroups(t *testing.T) { + const rows = 20 + const maxRowGroupLength = 5 + + table := schema.TestTable("test", schema.TestSourceOptions{}) + tg := schema.NewTestDataGenerator(0) + record := tg.Generate(table, schema.GenTestDataOptions{ + SourceName: "test-source", + SyncTime: time.Now().UTC().Round(time.Second), + MaxRows: rows, + }) + + maxRowGroupLengthValue := int64(maxRowGroupLength) + cl, err := NewClient(WithSpec(ParquetSpec{MaxRowGroupLength: &maxRowGroupLengthValue})) + require.NoError(t, err) + + var b bytes.Buffer + writer := bufio.NewWriter(&b) + require.NoError(t, types.WriteAll(cl, writer, table, []arrow.RecordBatch{record})) + require.NoError(t, writer.Flush()) + + pf, err := file.NewParquetReader(bytes.NewReader(b.Bytes())) + require.NoError(t, err) + defer pf.Close() + + require.Equal(t, rows/maxRowGroupLength, pf.NumRowGroups()) + require.Greater(t, pf.NumRowGroups(), 1) + require.EqualValues(t, rows, pf.NumRows()) +} diff --git a/schema.json b/schema.json index e246bebb..4b38d2a3 100644 --- a/schema.json +++ b/schema.json @@ -155,8 +155,8 @@ "max_row_group_length": { "type": "integer", "minimum": 0, - "description": "Max row group length", - "default": 134217728 + "description": "Maximum number of rows per Parquet row group.", + "default": 1048576 } }, "additionalProperties": false, From 57d2e82bf35c75a8778ee28c0efd21118456c7e4 Mon Sep 17 00:00:00 2001 From: erezrokah Date: Thu, 10 Sep 2026 12:37:49 +0100 Subject: [PATCH 2/2] chore: Drop redundant comment on defaultMaxRowGroupLength --- parquet/spec.go | 1 - 1 file changed, 1 deletion(-) diff --git a/parquet/spec.go b/parquet/spec.go index 6b8c6bce..ba2b4304 100644 --- a/parquet/spec.go +++ b/parquet/spec.go @@ -9,7 +9,6 @@ import ( "github.com/invopop/jsonschema" ) -// defaultMaxRowGroupLength is a number of rows, not a number of bytes. const defaultMaxRowGroupLength = 1024 * 1024 var allowedVersions = []string{"v1.0", "v2.4", "v2.6", "v2Latest"}