nssalian opened a new issue, #16325:
URL: https://github.com/apache/iceberg/issues/16325

   ### Apache Iceberg version
   
   1.10.1 (latest release)
   
   ### Query engine
   
   None
   
   ### Please describe the bug 🐞
   
   `ParquetWriter.checkSize()` does not enforce 
`write.parquet.row-group-size-bytes` when using compressing codecs. The method 
compares `writeStore.getBufferedSize()` against the target, but after internal 
page flushes this metric reports compressed bytes. With GZIP or ZSTD on 
compressible data, the compressed total stays below the target even as the 
actual uncompressed data grows well past it. The result is a single oversized 
row group for the entire file.
   
   Readers with page size limits will reject the resulting files. For example, 
Trino enforces a 500 MB uncompressed page limit and will fail reads. Iceberg 
and Spark readers can read the files given sufficient heap, but the configured 
row group target is silently ignored.
   
   ### Steps to reproduce
   
   ```java
   Schema schema = new Schema(
       Types.NestedField.required(1, "id", Types.LongType.get()),
       Types.NestedField.optional(2, "data", Types.StringType.get()));
   
   DataWriter<Record> writer = Parquet.writeData(file)
       .schema(schema)
       .createWriterFunc(GenericParquetWriter::create)
       .overwrite()
       .withSpec(PartitionSpec.unpartitioned())
       .set("write.parquet.row-group-size-bytes", "8388608") // 8 MB target
       .set("write.parquet.page-size-bytes", "1048576")
       .set("write.parquet.compression-codec", "gzip")
       .build();
   
   Random rng = new Random(42);
   for (int i = 0; i < 100; i++) {
     GenericRecord record = GenericRecord.create(schema);
     record.setField("id", (long) i);
     StringBuilder sb = new StringBuilder(512 * 1024);
     sb.append("{\"id\":").append(i).append(",\"values\":[");
     while (sb.length() < 512 * 1024) {
       sb.append(rng.nextInt(100000)).append(',');
     }
     sb.setCharAt(sb.length() - 1, ']');
     sb.append('}');
     record.setField("data", sb.toString());
     writer.write(record);
   }
   writer.close();
   
   DataFile dataFile = writer.toDataFile();
   // Expected: splitOffsets.size() >= 4 (50 MB uncompressed / 8 MB target)
   // Actual: splitOffsets.size() == 1
   ```
   
   ### Expected behavior
   
   With ~50 MB of uncompressed data and an 8 MB row group target, the writer 
should produce multiple row groups.
   
   ### Actual behavior
   
   The writer produces a single row group. `checkSize()` never triggers a flush 
because `getBufferedSize()` reports compressed bytes for internally-flushed 
pages, and the compressed total never exceeds the target.
   
   ### Willingness to contribute
   
   - [x] I can contribute a fix for this bug independently
   - [ ] I would be willing to contribute a fix for this bug with guidance from 
the Iceberg community
   - [ ] I cannot contribute a fix for this bug at this time


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to