Skip to content

Commit d649934

Browse files
author
Steve Loughran
committed
shredded types -read path.
claude had done the write path; get it to do what I wanted this time round
1 parent 2efa3ee commit d649934

1 file changed

Lines changed: 11 additions & 76 deletions

File tree

‎parquet-variant/src/test/java/org/apache/parquet/variant/TestHardenedReader.java‎

Lines changed: 11 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.apache.parquet.io.PositionOutputStream;
4242
import org.apache.parquet.io.SeekableInputStream;
4343
import org.apache.parquet.io.api.Binary;
44-
import org.apache.parquet.io.api.RecordConsumer;
4544
import org.apache.parquet.schema.MessageType;
4645
import org.apache.parquet.schema.MessageTypeParser;
4746
import org.junit.Rule;
@@ -470,45 +469,20 @@ public void testUnknownPrimitiveType() throws IOException {
470469
}
471470

472471
/**
473-
* Shredding a container that holds an unknown primitive type raises an exception. The shredding
474-
* writer walks children through {@link Variant#getElementAtIndex}/{@link Variant#getFieldAtIndex},
475-
* each of which materializes (and therefore validates) a child Variant. An unknown primitive type
476-
* cannot be materialized, so the known elements shred into their typed_value columns and the
477-
* unknown element aborts the write rather than being silently dropped or corrupted.
478-
*
479-
* <p>The current specification is: "new types may be added to the specification without
480-
* incrementing the version ID. In such a situation, an implementation should be able to read the
481-
* rest of the Variant value if desired." Reading the unknown value is optional; the shredding
482-
* writer here declines and raises when it cannot reconstruct the value. A future policy may always
483-
* reject on reconstruction.
472+
* Reconstructing a residual {@code value} column that carries an unknown primitive type fails to
473+
* parse. On the shredded read path the residual {@code value} column is the only channel that can
474+
* carry an unknown variant type (a {@code typed_value} column's type is fixed by the Parquet
475+
* schema), and it is replayed through {@link VariantBuilder#appendEncodedValue} — exactly what
476+
* {@code VariantConverters.VariantValueConverter} does on read.
484477
*/
485478
@Test
486-
public void testUnknownPrimitiveTypeShredding() {
487-
// Shredded schema: metadata + residual value + a typed_value LIST whose element shreds INT8.
488-
// Known BYTE elements land in element.typed_value; an unknown element cannot be reconstructed.
489-
MessageType shreddedSchema = MessageTypeParser.parseMessageType("message variant {"
490-
+ " required binary metadata;"
491-
+ " optional binary value;"
492-
+ " optional group typed_value (LIST) {"
493-
+ " repeated group list {"
494-
+ " required group element {"
495-
+ " optional binary value;"
496-
+ " optional int32 typed_value (INTEGER(8, true));"
497-
+ " }"
498-
+ " }"
499-
+ " }"
500-
+ "}");
501-
502-
// Array [BYTE(10), unknown-type-63, BYTE(20)]: the top-level array is well-formed, so it
503-
// constructs; the unknown element is only rejected when the writer descends into it.
504-
final byte unknownPrimitive = (byte) 0xFC;
505-
byte[] value = {0b0011, 0x03, 0x00, 0x02, 0x03, 0x05, 0x0C, 0x0A, unknownPrimitive, 0x0C, 0x14};
506-
Variant variant = new Variant(ByteBuffer.wrap(value), ByteBuffer.wrap(EMPTY_METADATA));
507-
assertThat(variant.getType()).isEqualTo(Variant.Type.ARRAY);
479+
public void testUnknownShreddededPrimitiveTypeReconstruction() {
480+
final byte unknownPrimitive = (byte) 0xFC; // primitive typeInfo 63
508481

509-
assertThatThrownBy(() -> VariantValueWriter.write(new NoOpRecordConsumer(), shreddedSchema, variant))
510-
.isInstanceOf(IllegalArgumentException.class)
511-
.hasMessageContaining("Unknown primitive type");
482+
assertThatThrownBy(
483+
() -> new VariantBuilder().appendEncodedValue(ByteBuffer.wrap(new byte[] {unknownPrimitive})))
484+
.isInstanceOf(UnsupportedOperationException.class)
485+
.hasMessageContaining("Unknown type in Variant");
512486
}
513487

514488
/**
@@ -651,45 +625,6 @@ private byte[][] roundTrip(byte[] metadata, byte[] value) throws IOException {
651625
}
652626
}
653627

654-
/** A {@link RecordConsumer} that discards everything: used to drive a shredded write to the point of failure. */
655-
private static final class NoOpRecordConsumer extends RecordConsumer {
656-
@Override
657-
public void startMessage() {}
658-
659-
@Override
660-
public void endMessage() {}
661-
662-
@Override
663-
public void startField(String field, int index) {}
664-
665-
@Override
666-
public void endField(String field, int index) {}
667-
668-
@Override
669-
public void startGroup() {}
670-
671-
@Override
672-
public void endGroup() {}
673-
674-
@Override
675-
public void addInteger(int value) {}
676-
677-
@Override
678-
public void addLong(long value) {}
679-
680-
@Override
681-
public void addBoolean(boolean value) {}
682-
683-
@Override
684-
public void addBinary(Binary value) {}
685-
686-
@Override
687-
public void addFloat(float value) {}
688-
689-
@Override
690-
public void addDouble(double value) {}
691-
}
692-
693628
/**
694629
* ParquetReader.Builder<Group> over an InputFile, using GroupReadSupport.
695630
*/

0 commit comments

Comments
 (0)