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

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


The following commit(s) were added to refs/heads/master by this push:
     new 662dc3599db [fix](fe) Preserve delete fallback failure cause (#65697)
662dc3599db is described below

commit 662dc3599db790fa1b3d0e3bf455abace1561b22
Author: Wen Zhenghu <[email protected]>
AuthorDate: Fri Jul 17 14:58:17 2026 +0800

    [fix](fe) Preserve delete fallback failure cause (#65697)
    
    ### What problem does this PR solve?
    
    Problem Summary:
    
    DeleteFromCommand currently falls back to DeleteFromUsingCommand when
    predicate validation fails. If the fallback execution also fails, the
    original validation exception is rethrown directly, which hides the
    actual fallback failure and makes troubleshooting difficult. This change
    preserves both failure causes by surfacing the fallback execution error,
    attaching it as the main cause, and keeping the original validation
    failure as a suppressed exception. The PR also adds FE unit tests to
    verify the merged exception message and the null-message fallback path.
    
    ### Release note
    
    Improve FE error reporting when DELETE fallback execution fails after
    predicate validation failure.
---
 .../trees/plans/commands/DeleteFromCommand.java    | 18 ++++-
 .../plans/commands/DeleteFromCommandTest.java      | 80 ++++++++++++++++++++++
 2 files changed, 97 insertions(+), 1 deletion(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommand.java
index d939d278dde..67a0a81932d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommand.java
@@ -212,7 +212,8 @@ public class DeleteFromCommand extends Command implements 
ForwardWithSync, Expla
                 return;
             } catch (Exception e2) {
                 LOG.warn("delete from command failed", e2);
-                throw e;
+                // Preserve both failure causes so the fallback execution 
error is not masked.
+                throw buildDeleteFallbackException(e, e2);
             }
         }
 
@@ -285,6 +286,21 @@ public class DeleteFromCommand extends Command implements 
ForwardWithSync, Expla
         }
     }
 
+    // Build an exception that keeps both the initial predicate-check failure 
and the fallback failure.
+    private AnalysisException buildDeleteFallbackException(Exception 
initialException,
+            Exception fallbackException) {
+        String initialMessage = StringUtils.defaultIfBlank(
+                initialException.getMessage(), initialException.toString());
+        String fallbackMessage = StringUtils.defaultIfBlank(
+                fallbackException.getMessage(), fallbackException.toString());
+        AnalysisException mergedException = new AnalysisException(
+                "Delete fallback execution failed: " + fallbackMessage
+                        + ". Initial predicate check failed: " + 
initialMessage,
+                fallbackException);
+        mergedException.addSuppressed(initialException);
+        return mergedException;
+    }
+
     private List<Partition> getSelectedPartitions(
             OlapTable olapTable, PhysicalFilter<?> filter,
             PhysicalOlapScan scan,
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommandTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommandTest.java
new file mode 100644
index 00000000000..6cd5d35d39d
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/commands/DeleteFromCommandTest.java
@@ -0,0 +1,80 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans.commands;
+
+import org.apache.doris.nereids.exceptions.AnalysisException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+
+public class DeleteFromCommandTest {
+
+    @Test
+    public void testBuildDeleteFallbackExceptionPreservesBothFailureCauses() 
throws Exception {
+        DeleteFromCommand command = new 
DeleteFromCommand(Collections.emptyList(), null,
+                false, Collections.emptyList(), null);
+        Exception initialException = new Exception("initial predicate 
failure");
+        Exception fallbackException = new Exception("fallback execution 
failure");
+
+        AnalysisException mergedException = 
invokeBuildDeleteFallbackException(command,
+                initialException, fallbackException);
+
+        // Verify the merged exception surfaces the fallback failure and keeps 
the initial failure.
+        Assertions.assertEquals(
+                "Delete fallback execution failed: fallback execution failure"
+                        + ". Initial predicate check failed: initial predicate 
failure",
+                mergedException.getMessage());
+        Assertions.assertSame(fallbackException, mergedException.getCause());
+        Assertions.assertEquals(1, mergedException.getSuppressed().length);
+        Assertions.assertSame(initialException, 
mergedException.getSuppressed()[0]);
+    }
+
+    @Test
+    public void testBuildDeleteFallbackExceptionFallsBackToThrowableToString() 
throws Exception {
+        DeleteFromCommand command = new 
DeleteFromCommand(Collections.emptyList(), null,
+                false, Collections.emptyList(), null);
+        Exception initialException = new Exception((String) null);
+        Exception fallbackException = new Exception((String) null);
+
+        AnalysisException mergedException = 
invokeBuildDeleteFallbackException(command,
+                initialException, fallbackException);
+
+        // Verify null messages still produce debuggable text.
+        Assertions.assertEquals(
+                "Delete fallback execution failed: java.lang.Exception"
+                        + ". Initial predicate check failed: 
java.lang.Exception",
+                mergedException.getMessage());
+        Assertions.assertSame(fallbackException, mergedException.getCause());
+        Assertions.assertEquals(1, mergedException.getSuppressed().length);
+        Assertions.assertSame(initialException, 
mergedException.getSuppressed()[0]);
+    }
+
+    // Use reflection to validate the helper without exposing it only for 
tests.
+    private AnalysisException 
invokeBuildDeleteFallbackException(DeleteFromCommand command,
+            Exception initialException, Exception fallbackException)
+            throws NoSuchMethodException, InvocationTargetException, 
IllegalAccessException {
+        Method method = 
DeleteFromCommand.class.getDeclaredMethod("buildDeleteFallbackException",
+                Exception.class, Exception.class);
+        method.setAccessible(true);
+        return (AnalysisException) method.invoke(command, initialException, 
fallbackException);
+    }
+}


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

Reply via email to