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 190c476341 [core] Ignore DV merge-on-read for non-DV tables (#8922)
190c476341 is described below

commit 190c476341703a055c8cc701cc55079f91b0ea39
Author: Zouxxyy <[email protected]>
AuthorDate: Thu Jul 30 15:51:09 2026 +0800

    [core] Ignore DV merge-on-read for non-DV tables (#8922)
---
 .../org/apache/paimon/schema/SchemaValidation.java |  8 ++---
 .../java/org/apache/paimon/CoreOptionsTest.java    | 18 ++++++++++
 .../PrimaryKeyFullTextIndexValidationTest.java     |  3 +-
 .../PrimaryKeyVectorIndexValidationTest.java       |  3 +-
 .../apache/paimon/schema/SchemaValidationTest.java |  6 ++--
 .../apache/paimon/spark/sql/PaimonOptionTest.scala | 38 ++++++++++++++++++++++
 6 files changed, 64 insertions(+), 12 deletions(-)

diff --git 
a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaValidation.java 
b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaValidation.java
index cdd2555c36..fc1c539455 100644
--- a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaValidation.java
+++ b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaValidation.java
@@ -331,10 +331,6 @@ public class SchemaValidation {
 
         if (options.deletionVectorsEnabled()) {
             validateForDeletionVectors(options);
-        } else {
-            checkArgument(
-                    !options.deletionVectorsMergeOnRead(),
-                    "deletion-vectors.merge-on-read requires 
deletion-vectors.enabled to be true.");
         }
 
         if (options.snapshotSequenceOrdering()) {
@@ -976,7 +972,7 @@ public class SchemaValidation {
                 options.mergeEngine() == MergeEngine.FIRST_ROW || 
options.deletionVectorsEnabled(),
                 "Primary-key vector index requires deletion-vectors.enabled = 
true.");
         checkArgument(
-                !options.deletionVectorsMergeOnRead(),
+                !options.deletionVectorsEnabled() || 
!options.deletionVectorsMergeOnRead(),
                 "Primary-key vector index with merge-engine = %s requires 
deletion-vectors.merge-on-read = false.",
                 options.mergeEngine());
         checkArgument(
@@ -1034,7 +1030,7 @@ public class SchemaValidation {
                 options.mergeEngine() == MergeEngine.FIRST_ROW || 
options.deletionVectorsEnabled(),
                 "Primary-key full-text index requires deletion-vectors.enabled 
= true.");
         checkArgument(
-                !options.deletionVectorsMergeOnRead(),
+                !options.deletionVectorsEnabled() || 
!options.deletionVectorsMergeOnRead(),
                 "Primary-key full-text index requires 
deletion-vectors.merge-on-read = false.");
         checkArgument(
                 options.bucket() > 0 || options.bucket() == 
BucketMode.POSTPONE_BUCKET,
diff --git a/paimon-core/src/test/java/org/apache/paimon/CoreOptionsTest.java 
b/paimon-core/src/test/java/org/apache/paimon/CoreOptionsTest.java
index 1eefc0377c..266ff305f4 100644
--- a/paimon-core/src/test/java/org/apache/paimon/CoreOptionsTest.java
+++ b/paimon-core/src/test/java/org/apache/paimon/CoreOptionsTest.java
@@ -89,6 +89,24 @@ public class CoreOptionsTest {
         assertThat(options.prepareCommitWaitCompaction()).isFalse();
     }
 
+    @Test
+    public void testDeletionVectorsMergeOnRead() {
+        Options conf = new Options();
+        conf.set(CoreOptions.DELETION_VECTORS_MERGE_ON_READ, true);
+        CoreOptions options = new CoreOptions(conf);
+
+        assertThat(options.deletionVectorsMergeOnRead()).isTrue();
+        assertThat(options.batchScanSkipLevel0()).isFalse();
+
+        conf.set(CoreOptions.DELETION_VECTORS_ENABLED, true);
+        assertThat(options.deletionVectorsMergeOnRead()).isTrue();
+        assertThat(options.batchScanSkipLevel0()).isFalse();
+
+        conf.set(CoreOptions.DELETION_VECTORS_MERGE_ON_READ, false);
+        assertThat(options.deletionVectorsMergeOnRead()).isFalse();
+        assertThat(options.batchScanSkipLevel0()).isTrue();
+    }
+
     @Test
     public void testSequenceFieldTrim() {
         Options conf = new Options();
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/schema/PrimaryKeyFullTextIndexValidationTest.java
 
b/paimon-core/src/test/java/org/apache/paimon/schema/PrimaryKeyFullTextIndexValidationTest.java
index 39cc905f8b..e5a927f470 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/schema/PrimaryKeyFullTextIndexValidationTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/schema/PrimaryKeyFullTextIndexValidationTest.java
@@ -111,10 +111,11 @@ class PrimaryKeyFullTextIndexValidationTest {
     }
 
     @Test
-    void testSupportsFirstRowWithoutDeletionVectors() {
+    void testIgnoresMergeOnReadForFirstRowWithoutDeletionVectors() {
         Map<String, String> options = enabledOptions();
         options.put(CoreOptions.MERGE_ENGINE.key(), "first-row");
         options.put(CoreOptions.DELETION_VECTORS_ENABLED.key(), "false");
+        options.put(CoreOptions.DELETION_VECTORS_MERGE_ON_READ.key(), "true");
 
         assertThatCode(() -> 
validateTableSchema(schema(options))).doesNotThrowAnyException();
     }
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/schema/PrimaryKeyVectorIndexValidationTest.java
 
b/paimon-core/src/test/java/org/apache/paimon/schema/PrimaryKeyVectorIndexValidationTest.java
index 2a666f6ebc..748b697a26 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/schema/PrimaryKeyVectorIndexValidationTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/schema/PrimaryKeyVectorIndexValidationTest.java
@@ -132,10 +132,11 @@ class PrimaryKeyVectorIndexValidationTest {
     }
 
     @Test
-    void testSupportsFirstRowWithoutDeletionVectors() {
+    void testIgnoresMergeOnReadForFirstRowWithoutDeletionVectors() {
         Map<String, String> options = enabledOptions();
         options.put(CoreOptions.MERGE_ENGINE.key(), "first-row");
         options.put(CoreOptions.DELETION_VECTORS_ENABLED.key(), "false");
+        options.put(CoreOptions.DELETION_VECTORS_MERGE_ON_READ.key(), "true");
 
         assertThatCode(() -> 
validateTableSchema(schema(options))).doesNotThrowAnyException();
     }
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java 
b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
index 36a085c6a8..ddc904978f 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
@@ -1595,12 +1595,10 @@ class SchemaValidationTest {
     }
 
     @Test
-    public void testMergeOnReadRequiresDvEnabled() {
+    public void testMergeOnReadIgnoredWhenDvDisabled() {
         Map<String, String> options = new HashMap<>();
         options.put("deletion-vectors.merge-on-read", "true");
-        assertThatThrownBy(() -> validateTableSchemaExec(options))
-                .hasMessageContaining(
-                        "deletion-vectors.merge-on-read requires 
deletion-vectors.enabled to be true");
+        assertThatCode(() -> 
validateTableSchemaExec(options)).doesNotThrowAnyException();
     }
 
     @Test
diff --git 
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/PaimonOptionTest.scala
 
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/PaimonOptionTest.scala
index f602be161c..d37f109e7e 100644
--- 
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/PaimonOptionTest.scala
+++ 
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/PaimonOptionTest.scala
@@ -120,6 +120,44 @@ class PaimonOptionTest extends PaimonSparkTestBase {
     }
   }
 
+  test("Paimon Option: global deletion-vector merge-on-read supports mixed 
tables") {
+    withTable("non_dv", "dv") {
+      sql("CREATE TABLE non_dv (id INT, v STRING)")
+      sql("""
+            |CREATE TABLE dv (id INT, v STRING)
+            |TBLPROPERTIES (
+            |  'primary-key' = 'id',
+            |  'bucket' = '1',
+            |  'deletion-vectors.enabled' = 'true',
+            |  'write-only' = 'true'
+            |)
+            |""".stripMargin)
+
+      sql("INSERT INTO non_dv VALUES (1, 'append')")
+      sql("INSERT INTO dv VALUES (2, 'dv')")
+
+      checkAnswer(sql("SELECT * FROM dv"), Nil)
+      withSparkSQLConf("spark.paimon.deletion-vectors.merge-on-read" -> 
"true") {
+        checkAnswer(
+          sql("""
+                |SELECT * FROM non_dv
+                |UNION ALL
+                |SELECT * FROM dv
+                |ORDER BY id
+                |""".stripMargin),
+          Row(1, "append") :: Row(2, "dv") :: Nil
+        )
+      }
+
+      checkAnswer(
+        spark.read
+          .format("paimon")
+          .option("deletion-vectors.merge-on-read", "true")
+          .table("non_dv"),
+        Row(1, "append"))
+    }
+  }
+
   test("Paimon Table Options: query one table with sql conf and table 
options") {
     sql("CREATE TABLE T (id INT)")
     sql("INSERT INTO T VALUES 1")

Reply via email to