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

yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git

commit b30e0c95c58e9032384fcfa817b816688abd1bf2
Author: deardeng <[email protected]>
AuthorDate: Tue Oct 13 10:18:50 2026 +0800

    [fix](cloud) Fix SHOW TABLETS visible version (#68467) (#68949)
    
    pick from https://github.com/apache/doris/pull/68467
    Problem Summary: Cloud replicas keep placeholder version fields in FE
    metadata. SHOW TABLETS constructed TabletsProcDir without the partition
    visible version, so it displayed -1 and filtered on the stale replica
    version. Batch-read partition visible versions outside the table
    metadata lock, pass each version through the existing TabletsProcDir
    constructor, and filter on the same displayed version returned to users.
    Enable the existing partitioned and non-partitioned regression case in
    cloud mode and add a focused unit test for version filtering.
    
    Fix SHOW TABLETS to display and filter by the current partition visible
    version in cloud mode.
    
    - Test: Unit Test
    - ./run-fe-ut.sh --run
    org.apache.doris.common.proc.CloudProcVersionDisplayTest
    - ./run-fe-ut.sh --run
    
org.apache.doris.nereids.trees.plans.commands.TruncateTableCommandTest#testTruncateTable
    - Cloud regression case enabled but not run because this worktree has no
    running cloud cluster
    - Behavior changed: Yes, cloud SHOW TABLETS now reports and filters by
    partition visible version
    - Does this need documentation: No
    
    (cherry picked from commit e75325840cb928030f3212a3380dc6b8969b994f)
    
    ### What problem does this PR solve?
    
    Issue Number: close #xxx
    
    Related PR: #xxx
    
    Problem Summary:
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [ ] Regression test
        - [ ] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [ ] No need to test or manual test. Explain why:
    - [ ] This is a refactor/code format and no logic has been changed.
            - [ ] Previous test can cover this change.
            - [ ] No code files have been changed.
            - [ ] Other reason <!-- Add your reason?  -->
    
    - Behavior changed:
        - [ ] No.
        - [ ] Yes. <!-- Explain the behavior change -->
    
    - Does this need documentation?
        - [ ] No.
    - [ ] Yes. <!-- Add document PR link here. eg:
    https://github.com/apache/doris-website/pull/1214 -->
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
---
 .../apache/doris/common/proc/TabletsProcDir.java   |  6 ++--
 .../commands/ShowTabletsFromTableCommand.java      | 40 +++++++++++++---------
 .../common/proc/CloudProcVersionDisplayTest.java   | 16 +++++++++
 .../select_tablets/select_with_tablets.groovy      |  3 --
 4 files changed, 43 insertions(+), 22 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/common/proc/TabletsProcDir.java 
b/fe/fe-core/src/main/java/org/apache/doris/common/proc/TabletsProcDir.java
index 2e47a8f707a..19bdc78aa16 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/common/proc/TabletsProcDir.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/common/proc/TabletsProcDir.java
@@ -175,13 +175,13 @@ public class TabletsProcDir implements ProcDirInterface {
                     }
                     for (Replica replica : tablet.getReplicas()) {
                         long beId = replica.getBackendIdWithoutException();
-                        if ((version > -1 && replica.getVersion() != version)
+                        long displayVersion = 
ProcReplicaVersionDisplay.getDisplayReplicaVersion(
+                                replica, partitionVisibleVersion);
+                        if ((version > -1 && displayVersion != version)
                                 || (backendId > -1 && beId != backendId)
                                 || (state != null && replica.getState() != 
state)) {
                             continue;
                         }
-                        long displayVersion = 
ProcReplicaVersionDisplay.getDisplayReplicaVersion(
-                                replica, partitionVisibleVersion);
                         long displayLastSuccessVersion = 
ProcReplicaVersionDisplay.getDisplayReplicaLastSuccessVersion(
                                 replica, partitionVisibleVersion);
                         List<Comparable> tabletInfo = new 
ArrayList<Comparable>();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTabletsFromTableCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTabletsFromTableCommand.java
index 491bc93b60c..bf52ddf5f13 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTabletsFromTableCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowTabletsFromTableCommand.java
@@ -57,7 +57,6 @@ import org.apache.doris.qe.StmtExecutor;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
@@ -200,19 +199,20 @@ public class ShowTabletsFromTableCommand extends 
ShowCommand {
         Env env = Env.getCurrentEnv();
         Database db = 
env.getInternalCatalog().getDbOrAnalysisException(dbTableName.getDb());
         OlapTable olapTable = 
db.getOlapTableOrAnalysisException(dbTableName.getTbl());
+
+        // The parser passes limit = 0 when the statement carries no LIMIT 
clause
+        // (see LogicalPlanBuilder#visitShowTabletsFromTable), so only a 
positive limit
+        // bounds the result. sizeLimit is how many sorted rows have to be 
kept: the LIMIT
+        // rows plus the OFFSET rows that are skipped afterwards.
+        Optional<Integer> sizeLimit = Optional.empty();
+        if (limit > 0) {
+            long capped = limit + Math.max(offset, 0);
+            sizeLimit = Optional.of((int) Math.min(capped, Integer.MAX_VALUE));
+        }
+
+        List<Partition> partitions = new ArrayList<>();
         olapTable.readLock();
         try {
-            // The parser passes limit = 0 when the statement carries no LIMIT 
clause
-            // (see LogicalPlanBuilder#visitShowTabletsFromTable), so only a 
positive limit
-            // bounds the result. sizeLimit is how many sorted rows have to be 
kept: the LIMIT
-            // rows plus the OFFSET rows that are skipped afterwards.
-            Optional<Integer> sizeLimit = Optional.empty();
-            if (limit > 0) {
-                long capped = limit + Math.max(offset, 0);
-                sizeLimit = Optional.of((int) Math.min(capped, 
Integer.MAX_VALUE));
-            }
-
-            Collection<Partition> partitions = new ArrayList<Partition>();
             if (partitionNames != null) {
                 List<String> paNames = partitionNames.getPartitionNames();
                 if (!paNames.isEmpty()) {
@@ -225,21 +225,29 @@ public class ShowTabletsFromTableCommand extends 
ShowCommand {
                     }
                 }
             } else {
-                partitions = olapTable.getPartitions();
+                partitions.addAll(olapTable.getPartitions());
             }
+        } finally {
+            olapTable.readUnlock();
+        }
+
+        List<Long> visibleVersions = Partition.getVisibleVersions(partitions);
+        List<List<Comparable>> tabletInfos = new ArrayList<>();
+        olapTable.readLock();
+        try {
             // With an explicit ORDER BY every tablet has to be collected 
before the result can be
             // truncated, otherwise the sort only sees an arbitrary prefix of 
the scan and returns
             // the wrong rows -- the bug reported in #65871. Without ORDER BY 
the scan still stops
             // as soon as enough rows are gathered, as it did before: LIMIT 
then returns a prefix
             // of the scan, ordered by (tabletId, replicaId) among itself.
             boolean stop = false;
-            List<List<Comparable>> tabletInfos = new ArrayList<>();
-            for (Partition partition : partitions) {
+            for (int i = 0; i < partitions.size(); i++) {
                 if (stop) {
                     break;
                 }
+                Partition partition = partitions.get(i);
                 for (MaterializedIndex index : 
partition.getMaterializedIndices(IndexExtState.ALL)) {
-                    TabletsProcDir procDir = new TabletsProcDir(olapTable, 
index);
+                    TabletsProcDir procDir = new TabletsProcDir(olapTable, 
index, visibleVersions.get(i));
                     tabletInfos.addAll(procDir.fetchComparableResult(
                             version, backendId, replicaState));
                     if (orderByPairs == null && sizeLimit.isPresent() && 
tabletInfos.size() >= sizeLimit.get()) {
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/common/proc/CloudProcVersionDisplayTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/common/proc/CloudProcVersionDisplayTest.java
index 1957e565787..bde328500ff 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/common/proc/CloudProcVersionDisplayTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/common/proc/CloudProcVersionDisplayTest.java
@@ -53,6 +53,8 @@ import org.junit.Test;
 import org.mockito.MockedStatic;
 import org.mockito.Mockito;
 
+import java.util.List;
+
 public class CloudProcVersionDisplayTest {
     private static final long DB_ID = 10001L;
     private static final long TABLE_ID = 20001L;
@@ -120,6 +122,20 @@ public class CloudProcVersionDisplayTest {
         assertVersionColumns(result, PARTITION_VISIBLE_VERSION);
     }
 
+    @Test
+    public void testTabletsProcDirFiltersByDisplayedCloudVersion() throws 
AnalysisException {
+        ProcTestContext context = createProcTestContext();
+        TabletsProcDir procDir = new TabletsProcDir(
+                context.table, context.partition.getBaseIndex(), 
PARTITION_VISIBLE_VERSION);
+
+        List<List<Comparable>> result = 
procDir.fetchComparableResult(PARTITION_VISIBLE_VERSION, -1, null);
+
+        Assert.assertEquals(1, result.size());
+        Assert.assertEquals(
+                PARTITION_VISIBLE_VERSION, 
result.get(0).get(TabletsProcDir.TITLE_NAMES.indexOf("Version")));
+        Assert.assertTrue(procDir.fetchComparableResult(STALE_REPLICA_VERSION, 
-1, null).isEmpty());
+    }
+
     @Test
     public void testReplicasProcNodeShowsPartitionCachedVersionInCloudMode() 
throws AnalysisException {
         ProcTestContext context = createProcTestContext();
diff --git 
a/regression-test/suites/nereids_p0/select_tablets/select_with_tablets.groovy 
b/regression-test/suites/nereids_p0/select_tablets/select_with_tablets.groovy
index a76750712a1..6cb6b2436e2 100644
--- 
a/regression-test/suites/nereids_p0/select_tablets/select_with_tablets.groovy
+++ 
b/regression-test/suites/nereids_p0/select_tablets/select_with_tablets.groovy
@@ -16,9 +16,6 @@
 // under the License.
 
 suite("select_with_tablets") {
-    if (isCloudMode()) {
-        return
-    }
     sql 'set enable_nereids_planner=true;'
     sql 'set enable_fallback_to_original_planner=false;'
 


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

Reply via email to