diff --git a/paimon-format/src/main/java/org/apache/paimon/format/blob/BlobFormatReader.java b/paimon-format/src/main/java/org/apache/paimon/format/blob/BlobFormatReader.java index bed455fda72b..3619118ef3bf 100644 --- a/paimon-format/src/main/java/org/apache/paimon/format/blob/BlobFormatReader.java +++ b/paimon-format/src/main/java/org/apache/paimon/format/blob/BlobFormatReader.java @@ -83,7 +83,9 @@ public InternalRow next() { Blob blob; long offset = fileMeta.blobOffset(currentPosition) + 4; long length = fileMeta.blobLength(currentPosition) - 16; - if (in != null) { + if (length == 0) { + blob = null; + } else if (in != null) { blob = Blob.fromData(readInlineBlob(in, offset, length)); } else { blob = Blob.fromFile(fileIO, filePath.toString(), offset, length); diff --git a/paimon-format/src/main/java/org/apache/paimon/format/blob/BlobFormatWriter.java b/paimon-format/src/main/java/org/apache/paimon/format/blob/BlobFormatWriter.java index a1b1c113d5a3..884bf8d8dd7b 100644 --- a/paimon-format/src/main/java/org/apache/paimon/format/blob/BlobFormatWriter.java +++ b/paimon-format/src/main/java/org/apache/paimon/format/blob/BlobFormatWriter.java @@ -55,21 +55,21 @@ public BlobFormatWriter(PositionOutputStream out) { @Override public void addElement(InternalRow element) throws IOException { checkArgument(element.getFieldCount() == 1, "BlobFormatWriter only support one field."); - checkArgument(!element.isNullAt(0), "BlobFormatWriter only support non-null blob."); - Blob blob = element.getBlob(0); long previousPos = out.getPos(); - crc32.reset(); - write(MAGIC_NUMBER_BYTES); - try (SeekableInputStream in = blob.newInputStream()) { - int bytesRead = in.read(tmpBuffer); - while (bytesRead >= 0) { - write(tmpBuffer, bytesRead); - bytesRead = in.read(tmpBuffer); + + if (!element.isNullAt(0)) { + Blob blob = element.getBlob(0); + try (SeekableInputStream in = blob.newInputStream()) { + int bytesRead = in.read(tmpBuffer); + while (bytesRead >= 0) { + write(tmpBuffer, bytesRead); + bytesRead = in.read(tmpBuffer); + } } } - + crc32.reset(); long binLength = out.getPos() - previousPos + 12; lengths.add(binLength); byte[] lenBytes = longToLittleEndian(binLength); diff --git a/paimon-format/src/test/java/org/apache/paimon/format/blob/BlobFileFormatTest.java b/paimon-format/src/test/java/org/apache/paimon/format/blob/BlobFileFormatTest.java index feaaacc5d180..24f7eb3d0f3b 100644 --- a/paimon-format/src/test/java/org/apache/paimon/format/blob/BlobFileFormatTest.java +++ b/paimon-format/src/test/java/org/apache/paimon/format/blob/BlobFileFormatTest.java @@ -78,11 +78,13 @@ private void innerTest(boolean blobAsDescriptor) throws IOException { // write FormatWriterFactory writerFactory = format.createWriterFactory(rowType); - List blobs = Arrays.asList("hello".getBytes(), "world".getBytes()); + List blobs = + Arrays.asList( + "hello".getBytes(), "world".getBytes(), null, "asldfjasldkfjas".getBytes()); try (PositionOutputStream out = fileIO.newOutputStream(file, false)) { FormatWriter formatWriter = writerFactory.create(out, null); for (byte[] bytes : blobs) { - formatWriter.addElement(GenericRow.of(new BlobData(bytes))); + formatWriter.addElement(GenericRow.of(bytes == null ? null : new BlobData(bytes))); } formatWriter.close(); } @@ -96,13 +98,17 @@ private void innerTest(boolean blobAsDescriptor) throws IOException { .createReader(context) .forEachRemaining( row -> { - Blob blob = row.getBlob(0); - if (blobAsDescriptor) { - assertThat(blob).isInstanceOf(BlobRef.class); + if (row.isNullAt(0)) { + result.add(null); } else { - assertThat(blob).isInstanceOf(BlobData.class); + Blob blob = row.getBlob(0); + if (blobAsDescriptor) { + assertThat(blob).isInstanceOf(BlobRef.class); + } else { + assertThat(blob).isInstanceOf(BlobData.class); + } + result.add(blob.toData()); } - result.add(blob.toData()); }); // assert