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 3f5582b3ace [fix](fe) Skip dropped columns in follower stats sync 
(#63882)
3f5582b3ace is described below

commit 3f5582b3acef9c7088c7422832190806729f420c
Author: yujun <[email protected]>
AuthorDate: Mon Jun 1 12:30:40 2026 +0800

    [fix](fe) Skip dropped columns in follower stats sync (#63882)
    
    ### What problem does this PR solve?
    
    FollowerColumnSender drains queued column references on follower FEs and
    syncs the columns that still need analysis to the master. A queued
    column can become stale after DDL changes. If the table still exists but
    the queued column has been dropped, table.getColumn(column.colName)
    returns null and the sender throws a NullPointerException while reading
    the type.
    
    This patch skips dropped columns before checking the column type, so the
    daemon does not emit periodic ERROR logs and can continue processing the
    remaining queued columns.
---
 .../doris/statistics/FollowerColumnSender.java     |  4 +++-
 .../doris/statistics/FollowerColumnSenderTest.java | 28 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/statistics/FollowerColumnSender.java
 
b/fe/fe-core/src/main/java/org/apache/doris/statistics/FollowerColumnSender.java
index 22df039325d..86539a39b67 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/statistics/FollowerColumnSender.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/statistics/FollowerColumnSender.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.statistics;
 
+import org.apache.doris.catalog.Column;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.TableIf;
 import org.apache.doris.common.ClientPool;
@@ -130,7 +131,8 @@ public class FollowerColumnSender extends MasterDaemon {
                 LOG.warn("Failed to find table for column {}", column.colName);
                 continue;
             }
-            if 
(StatisticsUtil.isUnsupportedType(table.getColumn(column.colName).getType())) {
+            Column col = table.getColumn(column.colName);
+            if (col == null || 
StatisticsUtil.isUnsupportedType(col.getType())) {
                 continue;
             }
             Set<Pair<String, String>> columnIndexPairs = 
table.getColumnIndexPairs(
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/statistics/FollowerColumnSenderTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/statistics/FollowerColumnSenderTest.java
index 84a3c45c5bc..d45792ec9b4 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/statistics/FollowerColumnSenderTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/statistics/FollowerColumnSenderTest.java
@@ -72,4 +72,32 @@ public class FollowerColumnSenderTest {
         }
     }
 
+    @Test
+    public void testGetNeedAnalyzeColumnsSkipDroppedColumns() {
+        OlapTable mockTable = Mockito.mock(OlapTable.class);
+        Mockito.when(mockTable.getColumn("dropped")).thenReturn(null);
+        Mockito.when(mockTable.getColumn("visible")).thenReturn(new 
Column("visible", PrimitiveType.INT));
+        Mockito.when(mockTable.getColumnIndexPairs(Mockito.any()))
+                .thenReturn(Collections.singleton(Pair.of("mockIndex", 
"visible")));
+
+        try (MockedStatic<StatisticsUtil> statisticsUtilStatic = 
Mockito.mockStatic(StatisticsUtil.class)) {
+            statisticsUtilStatic.when(() -> 
StatisticsUtil.needAnalyzeColumn(Mockito.any(), Mockito.any()))
+                    .thenReturn(true);
+            statisticsUtilStatic.when(() -> 
StatisticsUtil.findTable(Mockito.anyLong(), Mockito.anyLong(), 
Mockito.anyLong()))
+                    .thenReturn(mockTable);
+
+            QueryColumn droppedColumn = new QueryColumn(1, 2, 3, "dropped");
+            QueryColumn visibleQueryColumn = new QueryColumn(1, 2, 3, 
"visible");
+            Queue<QueryColumn> queue = new BlockingArrayQueue<>();
+            queue.add(droppedColumn);
+            queue.add(visibleQueryColumn);
+
+            FollowerColumnSender sender = new FollowerColumnSender();
+            Set<TQueryColumn> needAnalyzeColumns = 
sender.getNeedAnalyzeColumns(queue);
+            Assertions.assertEquals(1, needAnalyzeColumns.size());
+            
Assertions.assertFalse(needAnalyzeColumns.contains(droppedColumn.toThrift()));
+            
Assertions.assertTrue(needAnalyzeColumns.contains(visibleQueryColumn.toThrift()));
+        }
+    }
+
 }


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

Reply via email to