This is an automated email from the ASF dual-hosted git repository.

JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git


The following commit(s) were added to refs/heads/master by this push:
     new 6ef05fe2f1 [core] Bypass append write buffer for BLOB payload writers 
(#10535)
6ef05fe2f1 is described below

commit 6ef05fe2f1c36679317a95a5ebb701e822e35baf
Author: zhoulii <[email protected]>
AuthorDate: Wed Oct 14 09:57:32 2026 +0800

    [core] Bypass append write buffer for BLOB payload writers (#10535)
---
 docs/docs/multimodal-table/blob.mdx                |  2 ++
 .../paimon/operation/BaseAppendFileStoreWrite.java |  8 +++++-
 .../org/apache/paimon/flink/BlobTableITCase.java   | 30 ++++++++++++++++++++++
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/docs/docs/multimodal-table/blob.mdx 
b/docs/docs/multimodal-table/blob.mdx
index 315ae663cb..1809bb95fa 100644
--- a/docs/docs/multimodal-table/blob.mdx
+++ b/docs/docs/multimodal-table/blob.mdx
@@ -537,6 +537,8 @@ for Python partial writes.
 4. **Append Table Options**: For append tables, `row-tracking.enabled` and 
`data-evolution.enabled` must be set to `true`.
 5. **Blob View Dependency**: Blob view fields depend on the referenced 
upstream table and row. If the upstream data is removed or no longer readable, 
the view cannot be resolved.
 6. **Collection Storage Mode**: `ARRAY<BLOB>` and `MAP<K, BLOB>` are supported 
only for raw managed blob storage (`__BLOB_FIELD`), not for 
`__BLOB_DESCRIPTOR_FIELD` or `__BLOB_VIEW_FIELD`.
+7. **Append Write Buffer**: Writers that write BLOB payload files ignore 
`write-buffer-for-append`
+   and write directly, because the buffer cannot preserve descriptor source 
readers.
 
 ## Best Practices
 
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/operation/BaseAppendFileStoreWrite.java
 
b/paimon-core/src/main/java/org/apache/paimon/operation/BaseAppendFileStoreWrite.java
index 07d15637fe..61c2cef4c8 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/operation/BaseAppendFileStoreWrite.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/operation/BaseAppendFileStoreWrite.java
@@ -164,6 +164,12 @@ public abstract class BaseAppendFileStoreWrite extends 
MemoryFileStoreWrite<Inte
             boolean ignorePreviousFiles) {
         DataFilePathFactory dataPathFactory =
                 pathFactory.createDataFilePathFactory(partition, bucket);
+        boolean useWriteBuffer = options.useWriteBufferForAppend() || 
forceBufferSpill;
+        if (blobContext != null
+                && !fieldNamesInBlobFile(writeType, 
blobContext.blobInlineFields()).isEmpty()) {
+            // Buffer serialization drops source readers needed to copy 
descriptor-backed BLOBs.
+            useWriteBuffer = false;
+        }
         return new AppendOnlyWriter(
                 fileIO,
                 ioManager,
@@ -183,7 +189,7 @@ public abstract class BaseAppendFileStoreWrite extends 
MemoryFileStoreWrite<Inte
                 options.commitForceCompact(),
                 dataPathFactory,
                 restoreIncrement,
-                options.useWriteBufferForAppend() || forceBufferSpill,
+                useWriteBuffer,
                 options.writeBufferSpillable() || forceBufferSpill,
                 options.fileCompression(),
                 options.spillCompressOptions(),
diff --git 
a/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/BlobTableITCase.java
 
b/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/BlobTableITCase.java
index 839483f970..abbfb34079 100644
--- 
a/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/BlobTableITCase.java
+++ 
b/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/BlobTableITCase.java
@@ -48,6 +48,7 @@ import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.OutputStream;
 import java.net.URI;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
@@ -667,6 +668,35 @@ public class BlobTableITCase extends CatalogITCaseBase {
                 .containsExactlyInAnyOrder(Row.of(1, "paimon", blobData));
     }
 
+    @ParameterizedTest
+    @ValueSource(booleans = {false, true})
+    public void testWriteBlobDescriptorWithAppendBuffer(boolean streaming) 
throws Exception {
+        byte[] payload = new byte[] {1, 2, 3};
+        Path source = warehouse.resolve("buffered_blob_source");
+        Files.write(source, payload);
+        tEnv.executeSql(
+                "CREATE TABLE buffered_blob_table (id INT, picture BYTES)"
+                        + " WITH ('row-tracking.enabled'='true',"
+                        + " 'data-evolution.enabled'='true',"
+                        + " 'blob-field'='picture',"
+                        + " 'write-buffer-for-append'='true',"
+                        + " 'write-buffer-spillable'='false',"
+                        + " 'blob-write-null-on-fetch-failure'='true')");
+
+        (streaming ? sEnv : tEnv)
+                .executeSql(
+                        "INSERT INTO buffered_blob_table "
+                                + "/*+ OPTIONS('sink.parallelism'='2') */ "
+                                + "VALUES (1, sys.path_to_descriptor('"
+                                + source.toUri()
+                                + "'))")
+                .await();
+
+        Files.delete(source);
+        assertThat(batchSql("SELECT * FROM buffered_blob_table"))
+                .containsExactly(Row.of(1, payload));
+    }
+
     @Test
     public void testDescriptorToPresignedUrlBuiltInFunctions() {
         assertThat(batchSql("SHOW FUNCTIONS IN sys"))

Reply via email to