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

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


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new e4bad85a604 [feature](statistics)Support enable/disable auto analyze 
for table. (#39532) (#41836)
e4bad85a604 is described below

commit e4bad85a604be34fb940b9b8ec13d469cc991f68
Author: Jibing-Li <64681310+jibing...@users.noreply.github.com>
AuthorDate: Tue Oct 15 16:23:40 2024 +0800

    [feature](statistics)Support enable/disable auto analyze for table. 
(#39532) (#41836)
    
    backport: https://github.com/apache/doris/pull/39532
---
 .../main/java/org/apache/doris/alter/Alter.java    | 52 ++++++++++++---
 .../apache/doris/alter/SchemaChangeHandler.java    |  6 +-
 .../org/apache/doris/analysis/AlterTableStmt.java  |  3 -
 .../analysis/ModifyTablePropertiesClause.java      | 18 ++++++
 .../apache/doris/analysis/ShowTableStatsStmt.java  | 13 ++--
 .../main/java/org/apache/doris/catalog/Env.java    | 38 ++++++++++-
 .../java/org/apache/doris/catalog/OlapTable.java   | 15 +++++
 .../main/java/org/apache/doris/catalog/Table.java  |  5 ++
 .../java/org/apache/doris/catalog/TableIf.java     |  2 +
 .../org/apache/doris/catalog/TableProperty.java    | 10 +++
 .../cloud/alter/CloudSchemaChangeHandler.java      |  5 +-
 .../apache/doris/common/util/PropertyAnalyzer.java |  5 ++
 .../apache/doris/datasource/ExternalCatalog.java   | 16 +++++
 .../org/apache/doris/datasource/ExternalTable.java | 11 ++++
 .../persist/ModifyTablePropertyOperationLog.java   | 24 +++++++
 .../java/org/apache/doris/qe/ShowExecutor.java     |  6 +-
 .../doris/statistics/util/StatisticsUtil.java      |  7 +-
 .../doris/statistics/util/StatisticsUtilTest.java  | 62 ++++++++++--------
 .../hive/test_hive_statistics_p0.groovy            | 65 +++++++++++++++++++
 .../test_auto_analyze_black_white_list.groovy      | 75 ++++++++++++++++++++++
 20 files changed, 384 insertions(+), 54 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
index 1e1ebb40d9e..e6a2fe0229f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
@@ -44,6 +44,7 @@ import org.apache.doris.analysis.TableRenameClause;
 import org.apache.doris.catalog.Column;
 import org.apache.doris.catalog.DataProperty;
 import org.apache.doris.catalog.Database;
+import org.apache.doris.catalog.DatabaseIf;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.MTMV;
 import org.apache.doris.catalog.MysqlTable;
@@ -53,6 +54,7 @@ import org.apache.doris.catalog.Partition;
 import org.apache.doris.catalog.PartitionInfo;
 import org.apache.doris.catalog.ReplicaAllocation;
 import org.apache.doris.catalog.Table;
+import org.apache.doris.catalog.TableIf;
 import org.apache.doris.catalog.TableIf.TableType;
 import org.apache.doris.catalog.View;
 import org.apache.doris.cloud.alter.CloudSchemaChangeHandler;
@@ -65,6 +67,7 @@ import org.apache.doris.common.util.DynamicPartitionUtil;
 import org.apache.doris.common.util.MetaLockUtils;
 import org.apache.doris.common.util.PropertyAnalyzer;
 import org.apache.doris.common.util.PropertyAnalyzer.RewriteProperty;
+import org.apache.doris.datasource.ExternalTable;
 import org.apache.doris.nereids.trees.plans.commands.info.TableNameInfo;
 import org.apache.doris.persist.AlterMTMV;
 import org.apache.doris.persist.AlterViewInfo;
@@ -72,6 +75,7 @@ import org.apache.doris.persist.BatchModifyPartitionsInfo;
 import org.apache.doris.persist.ModifyCommentOperationLog;
 import org.apache.doris.persist.ModifyPartitionInfo;
 import org.apache.doris.persist.ModifyTableEngineOperationLog;
+import org.apache.doris.persist.ModifyTablePropertyOperationLog;
 import org.apache.doris.persist.ReplaceTableOperationLog;
 import org.apache.doris.policy.StoragePolicy;
 import org.apache.doris.qe.ConnectContext;
@@ -303,6 +307,24 @@ public class Alter {
         return needProcessOutsideTableLock;
     }
 
+    private void setExternalTableAutoAnalyzePolicy(ExternalTable table, 
List<AlterClause> alterClauses) {
+        Preconditions.checkState(alterClauses.size() == 1);
+        AlterClause alterClause = alterClauses.get(0);
+        Preconditions.checkState(alterClause instanceof 
ModifyTablePropertiesClause);
+        Map<String, String> properties = alterClause.getProperties();
+        Preconditions.checkState(properties.size() == 1);
+        
Preconditions.checkState(properties.containsKey(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY));
+        String value = 
properties.get(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY);
+        
Preconditions.checkState(PropertyAnalyzer.ENABLE_AUTO_ANALYZE_POLICY.equalsIgnoreCase(value)
+                || 
PropertyAnalyzer.DISABLE_AUTO_ANALYZE_POLICY.equalsIgnoreCase(value)
+                || 
PropertyAnalyzer.USE_CATALOG_AUTO_ANALYZE_POLICY.equalsIgnoreCase(value));
+        value = 
value.equalsIgnoreCase(PropertyAnalyzer.USE_CATALOG_AUTO_ANALYZE_POLICY) ? null 
: value;
+        
table.getCatalog().setAutoAnalyzePolicy(table.getDatabase().getFullName(), 
table.getName(), value);
+        ModifyTablePropertyOperationLog info = new 
ModifyTablePropertyOperationLog(table.getCatalog().getName(),
+                table.getDatabase().getFullName(), table.getName(), 
properties);
+        Env.getCurrentEnv().getEditLog().logModifyTableProperties(info);
+    }
+
     private boolean needChangeMTMVState(List<AlterClause> alterClauses) {
         for (AlterClause alterClause : alterClauses) {
             if (alterClause.needChangeMTMVState()) {
@@ -467,31 +489,45 @@ public class Alter {
 
     public void processAlterTable(AlterTableStmt stmt) throws UserException {
         TableName dbTableName = stmt.getTbl();
+        String ctlName = dbTableName.getCtl();
         String dbName = dbTableName.getDb();
         String tableName = dbTableName.getTbl();
-        Database db = 
Env.getCurrentInternalCatalog().getDbOrDdlException(dbName);
-        Table table = db.getTableOrDdlException(tableName);
+        DatabaseIf dbIf = Env.getCurrentEnv().getCatalogMgr()
+                .getCatalogOrException(ctlName, catalog -> new 
DdlException("Unknown catalog " + catalog))
+                .getDbOrDdlException(dbName);
+        TableIf tableIf = dbIf.getTableOrDdlException(tableName);
         List<AlterClause> alterClauses = Lists.newArrayList();
         // some operations will take long time to process, need to be done 
outside the table lock
         boolean needProcessOutsideTableLock = false;
-        switch (table.getType()) {
+        switch (tableIf.getType()) {
             case MATERIALIZED_VIEW:
             case OLAP:
-                OlapTable olapTable = (OlapTable) table;
-                needProcessOutsideTableLock = processAlterOlapTable(stmt, 
olapTable, alterClauses, db);
+                OlapTable olapTable = (OlapTable) tableIf;
+                needProcessOutsideTableLock = processAlterOlapTable(stmt, 
olapTable, alterClauses, (Database) dbIf);
                 break;
             case ODBC:
             case JDBC:
             case HIVE:
             case MYSQL:
             case ELASTICSEARCH:
-                processAlterExternalTable(stmt, table, db);
+                processAlterExternalTable(stmt, (Table) tableIf, (Database) 
dbIf);
+                return;
+            case HMS_EXTERNAL_TABLE:
+            case JDBC_EXTERNAL_TABLE:
+            case ICEBERG_EXTERNAL_TABLE:
+            case PAIMON_EXTERNAL_TABLE:
+            case MAX_COMPUTE_EXTERNAL_TABLE:
+            case HUDI_EXTERNAL_TABLE:
+            case TRINO_CONNECTOR_EXTERNAL_TABLE:
+                alterClauses.addAll(stmt.getOps());
+                setExternalTableAutoAnalyzePolicy((ExternalTable) tableIf, 
alterClauses);
                 return;
             default:
                 throw new DdlException("Do not support alter "
-                        + table.getType().toString() + " table[" + tableName + 
"]");
+                        + tableIf.getType().toString() + " table[" + tableName 
+ "]");
         }
 
+        Database db = (Database) dbIf;
         // the following ops should done outside table lock. because it 
contain synchronized create operation
         if (needProcessOutsideTableLock) {
             Preconditions.checkState(alterClauses.size() == 1);
@@ -514,7 +550,7 @@ public class Alter {
                 List<String> partitionNames = clause.getPartitionNames();
                 ((SchemaChangeHandler) 
schemaChangeHandler).updatePartitionsProperties(
                         db, tableName, partitionNames, properties);
-                OlapTable olapTable = (OlapTable) table;
+                OlapTable olapTable = (OlapTable) tableIf;
                 olapTable.writeLockOrDdlException();
                 try {
                     modifyPartitionsProperty(db, olapTable, partitionNames, 
properties, clause.isTempPartition());
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
index 99258bd205e..30fa6516b43 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
@@ -2280,7 +2280,8 @@ public class SchemaChangeHandler extends AlterHandler {
                 || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION)
                 || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_SKIP_WRITE_INDEX_ON_LOAD)
                 || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_EMPTY_ROWSETS_THRESHOLD)
-                || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_LEVEL_THRESHOLD));
+                || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_LEVEL_THRESHOLD)
+                || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY));
 
         
Env.getCurrentEnv().getAlterInstance().checkNoForceProperty(properties);
         List<Partition> partitions = Lists.newArrayList();
@@ -2356,7 +2357,8 @@ public class SchemaChangeHandler extends AlterHandler {
                 && 
!properties.containsKey(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION)
                 && 
!properties.containsKey(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_INTERVAL_MS)
                 && 
!properties.containsKey(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_DATA_BYTES)
-                && 
!properties.containsKey(PropertyAnalyzer.PROPERTIES_SKIP_WRITE_INDEX_ON_LOAD)) {
+                && 
!properties.containsKey(PropertyAnalyzer.PROPERTIES_SKIP_WRITE_INDEX_ON_LOAD)
+                && 
!properties.containsKey(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY)) {
             LOG.info("Properties already up-to-date");
             return;
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java
index a9e9c78d418..db51dfffd9f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStmt.java
@@ -29,7 +29,6 @@ import org.apache.doris.common.ErrorReport;
 import org.apache.doris.common.UserException;
 import org.apache.doris.common.util.InternalDatabaseUtil;
 import org.apache.doris.common.util.PropertyAnalyzer;
-import org.apache.doris.common.util.Util;
 import org.apache.doris.mysql.privilege.PrivPredicate;
 import org.apache.doris.qe.ConnectContext;
 
@@ -66,8 +65,6 @@ public class AlterTableStmt extends DdlStmt implements 
NotFallbackInParser {
             ErrorReport.reportAnalysisException(ErrorCode.ERR_NO_TABLES_USED);
         }
         tbl.analyze(analyzer);
-        // disallow external catalog
-        Util.prohibitExternalCatalog(tbl.getCtl(), 
this.getClass().getSimpleName());
         InternalDatabaseUtil.checkDatabase(tbl.getDb(), ConnectContext.get());
         if (!Env.getCurrentEnv().getAccessManager()
                 .checkTblPriv(ConnectContext.get(), tbl.getCtl(), tbl.getDb(), 
tbl.getTbl(),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java
 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java
index c7ea5c2ecca..2d3bc4ae05f 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java
@@ -29,6 +29,7 @@ import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.util.DynamicPartitionUtil;
 import org.apache.doris.common.util.PrintableMap;
 import org.apache.doris.common.util.PropertyAnalyzer;
+import org.apache.doris.datasource.InternalCatalog;
 
 import com.google.common.base.Strings;
 
@@ -350,6 +351,19 @@ public class ModifyTablePropertiesClause extends 
AlterTableClause {
             // do nothing, will be analyzed when creating alter job
         } else if 
(properties.containsKey(PropertyAnalyzer.PROPERTIES_ROW_STORE_COLUMNS)) {
             // do nothing, will be analyzed when creating alter job
+        } else if 
(properties.containsKey(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY)) {
+            String analyzePolicy = 
properties.getOrDefault(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY, "");
+            if (analyzePolicy != null
+                    && 
!analyzePolicy.equals(PropertyAnalyzer.ENABLE_AUTO_ANALYZE_POLICY)
+                    && 
!analyzePolicy.equals(PropertyAnalyzer.DISABLE_AUTO_ANALYZE_POLICY)
+                    && 
!analyzePolicy.equals(PropertyAnalyzer.USE_CATALOG_AUTO_ANALYZE_POLICY)) {
+                throw new AnalysisException(
+                    "Table auto analyze policy only support for " + 
PropertyAnalyzer.ENABLE_AUTO_ANALYZE_POLICY
+                        + " or " + PropertyAnalyzer.DISABLE_AUTO_ANALYZE_POLICY
+                        + " or " + 
PropertyAnalyzer.USE_CATALOG_AUTO_ANALYZE_POLICY);
+            }
+            this.needTableStable = false;
+            this.opType = AlterOpType.MODIFY_TABLE_PROPERTY_SYNC;
         } else {
             throw new AnalysisException("Unknown table property: " + 
properties.keySet());
         }
@@ -358,6 +372,10 @@ public class ModifyTablePropertiesClause extends 
AlterTableClause {
 
     private void analyzeForMTMV() throws AnalysisException {
         if (tableName != null) {
+            // Skip external catalog.
+            if 
(!(InternalCatalog.INTERNAL_CATALOG_NAME.equals(tableName.getCtl()))) {
+                return;
+            }
             Table table = 
Env.getCurrentInternalCatalog().getDbOrAnalysisException(tableName.getDb())
                     .getTableOrAnalysisException(tableName.getTbl());
             if (!(table instanceof MTMV)) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTableStatsStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTableStatsStmt.java
index 2e3f9e07cc0..54c8f652e12 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTableStatsStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowTableStatsStmt.java
@@ -61,6 +61,7 @@ public class ShowTableStatsStmt extends ShowStmt implements 
NotFallbackInParser
                     .add("trigger")
                     .add("new_partition")
                     .add("user_inject")
+                    .add("enable_auto_analyze")
                     .build();
 
     private static final ImmutableList<String> PARTITION_TITLE_NAMES =
@@ -197,12 +198,12 @@ public class ShowTableStatsStmt extends ShowStmt 
implements NotFallbackInParser
         return tableId;
     }
 
-    public ShowResultSet constructResultSet(TableStatsMeta tableStatistic) {
+    public ShowResultSet constructResultSet(TableStatsMeta tableStatistic, 
TableIf table) {
         if (indexName != null) {
             return constructIndexResultSet(tableStatistic);
         }
         if (partitionNames == null) {
-            return constructTableResultSet(tableStatistic);
+            return constructTableResultSet(tableStatistic, table);
         }
         if (columnNames == null) {
             return constructPartitionResultSet(tableStatistic);
@@ -215,7 +216,7 @@ public class ShowTableStatsStmt extends ShowStmt implements 
NotFallbackInParser
         return new ShowResultSet(getMetaData(), new ArrayList<>());
     }
 
-    public ShowResultSet constructResultSet(long rowCount) {
+    public ShowResultSet constructResultSet(TableIf table) {
         List<List<String>> result = Lists.newArrayList();
         if (partitionNames != null) {
             // For partition, return empty result if table stats not exist.
@@ -224,17 +225,18 @@ public class ShowTableStatsStmt extends ShowStmt 
implements NotFallbackInParser
         List<String> row = Lists.newArrayList();
         row.add("");
         row.add("");
-        row.add(String.valueOf(rowCount));
+        row.add(String.valueOf(table.getCachedRowCount()));
         row.add("");
         row.add("");
         row.add("");
         row.add("");
         row.add("");
+        row.add(String.valueOf(table.autoAnalyzeEnabled()));
         result.add(row);
         return new ShowResultSet(getMetaData(), result);
     }
 
-    public ShowResultSet constructTableResultSet(TableStatsMeta 
tableStatistic) {
+    public ShowResultSet constructTableResultSet(TableStatsMeta 
tableStatistic, TableIf table) {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 
HH:mm:ss");
         if (tableStatistic == null) {
             return new ShowResultSet(getMetaData(), new ArrayList<>());
@@ -253,6 +255,7 @@ public class ShowTableStatsStmt extends ShowStmt implements 
NotFallbackInParser
         row.add(tableStatistic.jobType.toString());
         row.add(String.valueOf(tableStatistic.partitionChanged.get()));
         row.add(String.valueOf(tableStatistic.userInjected));
+        row.add(table == null ? "N/A" : 
String.valueOf(table.autoAnalyzeEnabled()));
         result.add(row);
         return new ShowResultSet(getMetaData(), result);
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index b08ef17aac5..33e1f84980b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -132,6 +132,7 @@ import org.apache.doris.consistency.ConsistencyChecker;
 import org.apache.doris.cooldown.CooldownConfHandler;
 import org.apache.doris.datasource.CatalogIf;
 import org.apache.doris.datasource.CatalogMgr;
+import org.apache.doris.datasource.ExternalCatalog;
 import org.apache.doris.datasource.ExternalMetaCacheMgr;
 import org.apache.doris.datasource.ExternalMetaIdMgr;
 import org.apache.doris.datasource.InternalCatalog;
@@ -5335,7 +5336,8 @@ public class Env {
                 .buildEnableSingleReplicaCompaction()
                 .buildTimeSeriesCompactionEmptyRowsetsThreshold()
                 .buildTimeSeriesCompactionLevelThreshold()
-                .buildTTLSeconds();
+                .buildTTLSeconds()
+                .buildAutoAnalyzeProperty();
 
         // need to update partition info meta
         for (Partition partition : table.getPartitions()) {
@@ -5362,10 +5364,17 @@ public class Env {
 
     public void replayModifyTableProperty(short opCode, 
ModifyTablePropertyOperationLog info)
             throws MetaNotFoundException {
+        String ctlName = info.getCtlName();
         long dbId = info.getDbId();
         long tableId = info.getTableId();
         Map<String, String> properties = info.getProperties();
 
+        // Handle HMSExternalTable set auto analyze policy.
+        if (ctlName != null && 
!(InternalCatalog.INTERNAL_CATALOG_NAME.equalsIgnoreCase(ctlName))) {
+            setExternalTableAutoAnalyze(properties, info);
+            return;
+        }
+
         Database db = getInternalCatalog().getDbOrMetaException(dbId);
         OlapTable olapTable = (OlapTable) db.getTableOrMetaException(tableId, 
TableType.OLAP);
         olapTable.writeLock();
@@ -5405,6 +5414,33 @@ public class Env {
         }
     }
 
+    private void setExternalTableAutoAnalyze(Map<String, String> properties, 
ModifyTablePropertyOperationLog info) {
+        if (properties.size() != 1) {
+            LOG.warn("External table property should contain exactly 1 
entry.");
+            return;
+        }
+        if 
(!properties.containsKey(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY)) {
+            LOG.warn("External table property should only contain 
auto_analyze_policy");
+            return;
+        }
+        String value = 
properties.get(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY);
+        if 
(!PropertyAnalyzer.ENABLE_AUTO_ANALYZE_POLICY.equalsIgnoreCase(value)
+                && 
!PropertyAnalyzer.DISABLE_AUTO_ANALYZE_POLICY.equalsIgnoreCase(value)
+                && 
!PropertyAnalyzer.USE_CATALOG_AUTO_ANALYZE_POLICY.equalsIgnoreCase(value)) {
+            LOG.warn("External table property should be 'enable', 'disable' or 
'base_on_catalog'");
+            return;
+        }
+        try {
+            CatalogIf catalog = Env.getCurrentEnv().getCatalogMgr()
+                    .getCatalogOrException(info.getCtlName(),
+                        ctlName -> new DdlException("Unknown catalog " + 
ctlName));
+            value = 
value.equalsIgnoreCase(PropertyAnalyzer.USE_CATALOG_AUTO_ANALYZE_POLICY) ? null 
: value;
+            ((ExternalCatalog) catalog).setAutoAnalyzePolicy(info.getDbName(), 
info.getTableName(), value);
+        } catch (Exception e) {
+            LOG.warn("Failed to replay external table set property.", e);
+        }
+    }
+
     public void modifyDefaultDistributionBucketNum(Database db, OlapTable 
olapTable,
                                                    ModifyDistributionClause 
modifyDistributionClause)
             throws DdlException {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
index 090c58fcbed..4dfdff2468d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
@@ -3216,4 +3216,19 @@ public class OlapTable extends Table implements 
MTMVRelatedTableIf, GsonPostProc
             return false;
         }
     }
+
+    @Override
+    public boolean autoAnalyzeEnabled() {
+        if (tableProperty == null) {
+            return super.autoAnalyzeEnabled();
+        }
+        Map<String, String> properties = tableProperty.getProperties();
+        if (properties == null || 
!properties.containsKey(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY)
+                || 
properties.get(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY)
+                    
.equalsIgnoreCase(PropertyAnalyzer.USE_CATALOG_AUTO_ANALYZE_POLICY)) {
+            return super.autoAnalyzeEnabled();
+        }
+        return properties.get(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY)
+                .equalsIgnoreCase(PropertyAnalyzer.ENABLE_AUTO_ANALYZE_POLICY);
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
index 906a710f369..e9392deae4a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
@@ -634,4 +634,9 @@ public abstract class Table extends MetaObject implements 
Writable, TableIf, Gso
     public long getCachedRowCount() {
         return getRowCount();
     }
+
+    @Override
+    public boolean autoAnalyzeEnabled() {
+        return true;
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableIf.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableIf.java
index 1ddd083cff4..ed40840239a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableIf.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableIf.java
@@ -559,4 +559,6 @@ public interface TableIf {
     default boolean isPartitionedTable() {
         return false;
     }
+
+    boolean autoAnalyzeEnabled();
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
index 4b7d5e6a88b..1c1d7e35880 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
@@ -124,6 +124,9 @@ public class TableProperty implements Writable, 
GsonPostProcessable {
     private long timeSeriesCompactionLevelThreshold
                                     = 
PropertyAnalyzer.TIME_SERIES_COMPACTION_LEVEL_THRESHOLD_DEFAULT_VALUE;
 
+    private String autoAnalyzePolicy = 
PropertyAnalyzer.ENABLE_AUTO_ANALYZE_POLICY;
+
+
     private DataSortInfo dataSortInfo = new DataSortInfo();
 
     public TableProperty(Map<String, String> properties) {
@@ -163,6 +166,7 @@ public class TableProperty implements Writable, 
GsonPostProcessable {
                 buildTimeSeriesCompactionEmptyRowsetsThreshold();
                 buildTimeSeriesCompactionLevelThreshold();
                 buildTTLSeconds();
+                buildAutoAnalyzeProperty();
                 break;
             default:
                 break;
@@ -256,6 +260,12 @@ public class TableProperty implements Writable, 
GsonPostProcessable {
         return this;
     }
 
+    public TableProperty buildAutoAnalyzeProperty() {
+        autoAnalyzePolicy = 
properties.getOrDefault(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY,
+                PropertyAnalyzer.ENABLE_AUTO_ANALYZE_POLICY);
+        return this;
+    }
+
     public boolean disableAutoCompaction() {
         return disableAutoCompaction;
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/cloud/alter/CloudSchemaChangeHandler.java
 
b/fe/fe-core/src/main/java/org/apache/doris/cloud/alter/CloudSchemaChangeHandler.java
index e48b8a745a3..fa3bb96014c 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/cloud/alter/CloudSchemaChangeHandler.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/cloud/alter/CloudSchemaChangeHandler.java
@@ -100,7 +100,8 @@ public class CloudSchemaChangeHandler extends 
SchemaChangeHandler {
                 || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_EMPTY_ROWSETS_THRESHOLD)
                 || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_TIME_SERIES_COMPACTION_LEVEL_THRESHOLD)
                 || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION)
-                || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE));
+                || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_ENABLE_MOW_LIGHT_DELETE)
+                || 
properties.containsKey(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY));
 
         if (properties.size() != 1) {
             throw new UserException("Can only set one table property at a 
time");
@@ -316,6 +317,8 @@ public class CloudSchemaChangeHandler extends 
SchemaChangeHandler {
             }
             param.enableMowLightDelete = enableMowLightDelete;
             param.type = 
UpdatePartitionMetaParam.TabletMetaType.ENABLE_MOW_LIGHT_DELETE;
+        } else if 
(properties.containsKey(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY)) {
+            // Do nothing.
         } else {
             LOG.warn("invalid properties:{}", properties);
             throw new UserException("invalid properties");
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/common/util/PropertyAnalyzer.java 
b/fe/fe-core/src/main/java/org/apache/doris/common/util/PropertyAnalyzer.java
index 08e6f906222..43eda6cc189 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/common/util/PropertyAnalyzer.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/common/util/PropertyAnalyzer.java
@@ -223,6 +223,11 @@ public class PropertyAnalyzer {
     public static final boolean 
PROPERTIES_ENABLE_MOW_LIGHT_DELETE_DEFAULT_VALUE
             = Config.enable_mow_light_delete;
 
+    public static final String PROPERTIES_AUTO_ANALYZE_POLICY = 
"auto_analyze_policy";
+    public static final String ENABLE_AUTO_ANALYZE_POLICY = "enable";
+    public static final String DISABLE_AUTO_ANALYZE_POLICY = "disable";
+    public static final String USE_CATALOG_AUTO_ANALYZE_POLICY = 
"base_on_catalog";
+
     // compaction policy
     public static final String SIZE_BASED_COMPACTION_POLICY = "size_based";
     public static final String TIME_SERIES_COMPACTION_POLICY = "time_series";
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
index 0d854a9ecdc..37e44c63569 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java
@@ -33,6 +33,7 @@ import org.apache.doris.catalog.TableIf;
 import org.apache.doris.cluster.ClusterNamespace;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.DdlException;
+import org.apache.doris.common.Pair;
 import org.apache.doris.common.UserException;
 import org.apache.doris.common.Version;
 import org.apache.doris.common.io.Text;
@@ -127,6 +128,9 @@ public abstract class ExternalCatalog
     protected Map<Long, ExternalDatabase<? extends ExternalTable>> idToDb = 
Maps.newConcurrentMap();
     @SerializedName(value = "lastUpdateTime")
     protected long lastUpdateTime;
+    // <db name, table name> to tableAutoAnalyzePolicy
+    @SerializedName(value = "taap")
+    protected Map<Pair<String, String>, String> tableAutoAnalyzePolicy = 
Maps.newHashMap();
     // db name does not contains "default_cluster"
     protected Map<String, Long> dbNameToId = Maps.newConcurrentMap();
     private boolean objectCreated = false;
@@ -723,6 +727,9 @@ public abstract class ExternalCatalog
         this.propLock = new byte[0];
         this.initialized = false;
         setDefaultPropsIfMissing(true);
+        if (tableAutoAnalyzePolicy == null) {
+            tableAutoAnalyzePolicy = Maps.newHashMap();
+        }
     }
 
     public void addDatabaseForTest(ExternalDatabase<? extends ExternalTable> 
db) {
@@ -884,4 +891,13 @@ public abstract class ExternalCatalog
     public String getQualifiedName(String dbName) {
         return String.join(".", name, dbName);
     }
+
+    public void setAutoAnalyzePolicy(String dbName, String tableName, String 
policy) {
+        Pair<String, String> key = Pair.of(dbName, tableName);
+        if (policy == null) {
+            tableAutoAnalyzePolicy.remove(key);
+        } else {
+            tableAutoAnalyzePolicy.put(key, policy);
+        }
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalTable.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalTable.java
index 2d5689a5468..eedbe4e20da 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalTable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalTable.java
@@ -27,6 +27,7 @@ import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.Pair;
 import org.apache.doris.common.io.Text;
 import org.apache.doris.common.io.Writable;
+import org.apache.doris.common.util.PropertyAnalyzer;
 import org.apache.doris.common.util.Util;
 import org.apache.doris.persist.gson.GsonPostProcessable;
 import org.apache.doris.persist.gson.GsonUtils;
@@ -282,6 +283,16 @@ public class ExternalTable implements TableIf, Writable, 
GsonPostProcessable {
         return getFullSchema();
     }
 
+    @Override
+    public boolean autoAnalyzeEnabled() {
+        makeSureInitialized();
+        String policy = 
catalog.getTableAutoAnalyzePolicy().get(Pair.of(dbName, name));
+        if (policy == null) {
+            return catalog.enableAutoAnalyze();
+        }
+        return 
policy.equalsIgnoreCase(PropertyAnalyzer.ENABLE_AUTO_ANALYZE_POLICY);
+    }
+
     @Override
     public Optional<ColumnStatistic> getColumnStatistic(String colName) {
         return Optional.empty();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/persist/ModifyTablePropertyOperationLog.java
 
b/fe/fe-core/src/main/java/org/apache/doris/persist/ModifyTablePropertyOperationLog.java
index a782db9f9c0..50b49074ce1 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/persist/ModifyTablePropertyOperationLog.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/persist/ModifyTablePropertyOperationLog.java
@@ -35,6 +35,10 @@ public class ModifyTablePropertyOperationLog implements 
Writable {
     private long dbId;
     @SerializedName(value = "tableId")
     private long tableId;
+    @SerializedName(value = "ctlName")
+    private String ctlName;
+    @SerializedName(value = "dbName")
+    private String dbName;
     @SerializedName(value = "tableName")
     private String tableName;
     @SerializedName(value = "properties")
@@ -58,6 +62,14 @@ public class ModifyTablePropertyOperationLog implements 
Writable {
         this.sql = sb.toString();
     }
 
+    public ModifyTablePropertyOperationLog(String ctlName, String dbName, 
String tableName,
+                                           Map<String, String> properties) {
+        this.ctlName = ctlName;
+        this.dbName = dbName;
+        this.tableName = tableName;
+        this.properties = properties;
+    }
+
     public long getDbId() {
         return dbId;
     }
@@ -66,6 +78,18 @@ public class ModifyTablePropertyOperationLog implements 
Writable {
         return tableId;
     }
 
+    public String getCtlName() {
+        return ctlName;
+    }
+
+    public String getDbName() {
+        return dbName;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
     public Map<String, String> getProperties() {
         return properties;
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java
index cc0577b54d3..65a42730ebe 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java
@@ -2733,7 +2733,7 @@ public class ShowExecutor {
             if (tableStats == null) {
                 resultSet = showTableStatsStmt.constructEmptyResultSet();
             } else {
-                resultSet = showTableStatsStmt.constructResultSet(tableStats);
+                resultSet = showTableStatsStmt.constructResultSet(tableStats, 
tableIf);
             }
             return;
         }
@@ -2742,9 +2742,9 @@ public class ShowExecutor {
            tableStats == null means it's not analyzed, in this case show the 
estimated row count.
          */
         if (tableStats == null) {
-            resultSet = 
showTableStatsStmt.constructResultSet(tableIf.getCachedRowCount());
+            resultSet = showTableStatsStmt.constructResultSet(tableIf);
         } else {
-            resultSet = showTableStatsStmt.constructResultSet(tableStats);
+            resultSet = showTableStatsStmt.constructResultSet(tableStats, 
tableIf);
         }
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java 
b/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java
index ee79ec9e791..b4ba12a3f0d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java
@@ -998,12 +998,7 @@ public class StatisticsUtil {
         if (column == null) {
             return false;
         }
-        try {
-            if (!table.getDatabase().getCatalog().enableAutoAnalyze()) {
-                return false;
-            }
-        } catch (Throwable t) {
-            LOG.warn("Failed to get catalog property. {}", t.getMessage());
+        if (!table.autoAnalyzeEnabled()) {
             return false;
         }
         AnalysisManager manager = Env.getServingEnv().getAnalysisManager();
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/statistics/util/StatisticsUtilTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/statistics/util/StatisticsUtilTest.java
index 6dccd3af46e..32521882939 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/statistics/util/StatisticsUtilTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/statistics/util/StatisticsUtilTest.java
@@ -18,21 +18,21 @@
 package org.apache.doris.statistics.util;
 
 import org.apache.doris.catalog.Column;
-import org.apache.doris.catalog.Database;
-import org.apache.doris.catalog.DatabaseIf;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.PrimitiveType;
+import org.apache.doris.catalog.TableProperty;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.common.Pair;
-import org.apache.doris.datasource.CatalogIf;
+import org.apache.doris.common.util.PropertyAnalyzer;
 import org.apache.doris.datasource.ExternalCatalog;
 import org.apache.doris.datasource.ExternalTable;
 import org.apache.doris.datasource.hive.HMSExternalCatalog;
 import org.apache.doris.datasource.hive.HMSExternalTable;
 import org.apache.doris.datasource.hive.HMSExternalTable.DLAType;
+import org.apache.doris.datasource.jdbc.JdbcExternalCatalog;
 import org.apache.doris.datasource.jdbc.JdbcExternalTable;
 import org.apache.doris.qe.SessionVariable;
 import org.apache.doris.statistics.AnalysisManager;
@@ -51,7 +51,9 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.Base64;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 class StatisticsUtilTest {
     @Test
@@ -176,42 +178,46 @@ class StatisticsUtilTest {
         List<Column> schema = new ArrayList<>();
         schema.add(column);
         OlapTable table = new OlapTable(200, "testTable", schema, null, null, 
null);
-        Database db = new Database(111, "TestDb");
-        ExternalCatalog externalCatalog = new HMSExternalCatalog();
+        HMSExternalCatalog externalCatalog = new HMSExternalCatalog();
 
-        // Test get database/catalog exception
-        new MockUp<OlapTable>() {
-            @Mock
-            public DatabaseIf getDatabase() {
-                throw new RuntimeException();
-            }
-        };
+        // Test olap table auto analyze disabled.
+        Map<String, String> properties = new HashMap<>();
+        properties.put(PropertyAnalyzer.PROPERTIES_AUTO_ANALYZE_POLICY, 
"disable");
+        table.setTableProperty(new TableProperty(properties));
         Assertions.assertFalse(StatisticsUtil.needAnalyzeColumn(table, 
Pair.of("index", column.getName())));
+        table.setTableProperty(null);
 
-        // Test auto analyze disabled.
-        new MockUp<OlapTable>() {
+        new MockUp<HMSExternalTable>() {
             @Mock
-            public DatabaseIf getDatabase() {
-                return db;
+            protected synchronized void makeSureInitialized() {
             }
         };
-        new MockUp<Database>() {
+
+        // Test auto analyze catalog disabled.
+        HMSExternalTable hmsTable = new HMSExternalTable(1, "name", "dbName", 
externalCatalog);
+        Assertions.assertFalse(StatisticsUtil.needAnalyzeColumn(hmsTable, 
Pair.of("index", column.getName())));
+
+        // Test catalog auto analyze enabled.
+        new MockUp<AnalysisManager>() {
             @Mock
-            public CatalogIf getCatalog() {
-                return externalCatalog;
+            public TableStatsMeta findTableStatsStatus(long tblId) {
+                return null;
             }
         };
-        Assertions.assertFalse(StatisticsUtil.needAnalyzeColumn(table, 
Pair.of("index", column.getName())));
+        
externalCatalog.getCatalogProperty().addProperty(ExternalCatalog.ENABLE_AUTO_ANALYZE,
 "true");
+        Assertions.assertTrue(StatisticsUtil.needAnalyzeColumn(table, 
Pair.of("index", column.getName())));
 
-        // Test auto analyze enabled.
+        // Test external table auto analyze enabled.
         new MockUp<AnalysisManager>() {
             @Mock
             public TableStatsMeta findTableStatsStatus(long tblId) {
                 return null;
             }
         };
-        
externalCatalog.getCatalogProperty().addProperty(ExternalCatalog.ENABLE_AUTO_ANALYZE,
 "true");
-        Assertions.assertTrue(StatisticsUtil.needAnalyzeColumn(table, 
Pair.of("index", column.getName())));
+        
externalCatalog.getCatalogProperty().addProperty(ExternalCatalog.ENABLE_AUTO_ANALYZE,
 "false");
+        HMSExternalTable hmsTable1 = new HMSExternalTable(1, "name", "dbName", 
externalCatalog);
+        externalCatalog.setAutoAnalyzePolicy("dbName", "name", "enable");
+        Assertions.assertTrue(StatisticsUtil.needAnalyzeColumn(hmsTable1, 
Pair.of("index", column.getName())));
 
 
         // Test table stats meta is null.
@@ -256,8 +262,14 @@ class StatisticsUtilTest {
             }
         };
 
+        new MockUp<JdbcExternalTable>() {
+            @Mock
+            protected synchronized void makeSureInitialized() {
+            }
+        };
         // Test not supported external table type.
-        ExternalTable externalTable = new JdbcExternalTable(1, "jdbctable", 
"jdbcdb", null);
+        ExternalTable externalTable = new JdbcExternalTable(1, "jdbctable", 
"jdbcdb",
+                new JdbcExternalCatalog(1, "name", "resource", new 
HashMap<>(), ""));
         Assertions.assertFalse(StatisticsUtil.needAnalyzeColumn(externalTable, 
Pair.of("index", column.getName())));
 
         // Test hms external table not hive type.
@@ -267,7 +279,7 @@ class StatisticsUtilTest {
                 return DLAType.ICEBERG;
             }
         };
-        ExternalTable hmsExternalTable = new HMSExternalTable(1, "hmsTable", 
"hmsDb", null);
+        ExternalTable hmsExternalTable = new HMSExternalTable(1, "hmsTable", 
"hmsDb", externalCatalog);
         
Assertions.assertFalse(StatisticsUtil.needAnalyzeColumn(hmsExternalTable, 
Pair.of("index", column.getName())));
 
         // Test partition first load.
diff --git 
a/regression-test/suites/external_table_p0/hive/test_hive_statistics_p0.groovy 
b/regression-test/suites/external_table_p0/hive/test_hive_statistics_p0.groovy
index 71a43d2aec9..c11ff176d95 100644
--- 
a/regression-test/suites/external_table_p0/hive/test_hive_statistics_p0.groovy
+++ 
b/regression-test/suites/external_table_p0/hive/test_hive_statistics_p0.groovy
@@ -232,6 +232,71 @@ suite("test_hive_statistics_p0", 
"all_types,p0,external,hive,external_docker,ext
             assertEquals("N/A", result[0][7])
             assertEquals("N/A", result[0][8])
 
+
+            // Test auto analyze policy
+            sql """drop stats stats_test1"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("false", result[0][8])
+
+            sql """ALTER CATALOG `${catalog_name}` SET PROPERTIES 
('enable.auto.analyze'='true')"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("true", result[0][8])
+
+            sql """ALTER CATALOG `${catalog_name}` SET PROPERTIES 
('enable.auto.analyze'='false')"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("false", result[0][8])
+
+            sql """analyze table stats_test1 
PROPERTIES("use.auto.analyzer"="true")"""
+            result = sql """show auto analyze stats_test1"""
+            assertEquals(0, result.size())
+
+            sql """ALTER TABLE stats_test1 SET ("auto_analyze_policy" = 
"enable");"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("true", result[0][8])
+
+            sql """analyze table stats_test1 
PROPERTIES("use.auto.analyzer"="true")"""
+            result = sql """show auto analyze stats_test1"""
+            assertEquals(1, result.size())
+
+            sql """ALTER CATALOG `${catalog_name}` SET PROPERTIES 
('enable.auto.analyze'='true')"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("true", result[0][8])
+
+            sql """ALTER CATALOG `${catalog_name}` SET PROPERTIES 
('enable.auto.analyze'='false')"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("true", result[0][8])
+
+            sql """ALTER TABLE stats_test1 SET ("auto_analyze_policy" = 
"disable");"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("false", result[0][8])
+
+            sql """ALTER CATALOG `${catalog_name}` SET PROPERTIES 
('enable.auto.analyze'='true')"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("false", result[0][8])
+
+            sql """ALTER CATALOG `${catalog_name}` SET PROPERTIES 
('enable.auto.analyze'='false')"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("false", result[0][8])
+
+            sql """ALTER TABLE stats_test1 SET ("auto_analyze_policy" = 
"base_on_catalog");"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("false", result[0][8])
+
+            sql """ALTER CATALOG `${catalog_name}` SET PROPERTIES 
('enable.auto.analyze'='true')"""
+            result = sql """show table stats stats_test1"""
+            assertEquals(1, result.size())
+            assertEquals("true", result[0][8])
+
             sql """drop catalog if exists ${catalog_name}"""
 
         } finally {
diff --git 
a/regression-test/suites/statistics/test_auto_analyze_black_white_list.groovy 
b/regression-test/suites/statistics/test_auto_analyze_black_white_list.groovy
new file mode 100644
index 00000000000..8ba453b81f5
--- /dev/null
+++ 
b/regression-test/suites/statistics/test_auto_analyze_black_white_list.groovy
@@ -0,0 +1,75 @@
+// 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.
+
+suite("test_auto_analyze_black_white_list") {
+
+    sql """drop database if exists test_auto_analyze_black_white_list"""
+    sql """create database test_auto_analyze_black_white_list"""
+    sql """use test_auto_analyze_black_white_list"""
+    sql """set global force_sample_analyze=false"""
+    sql """set global enable_auto_analyze=false"""
+
+    sql """CREATE TABLE test_bw (
+            key1 bigint NOT NULL,
+            key2 bigint NOT NULL,
+            value1 int NOT NULL,
+            value2 int NOT NULL,
+            value3 int NOT NULL
+        )ENGINE=OLAP
+        DUPLICATE KEY(`key1`, `key2`)
+        COMMENT "OLAP"
+        DISTRIBUTED BY HASH(`key1`) BUCKETS 2
+        PROPERTIES (
+            "replication_num" = "1"
+        )
+    """
+
+    // Test show index row count
+    def result = sql """show table stats test_bw"""
+    assertEquals(1, result.size())
+    assertEquals("true", result[0][8])
+
+    sql """ALTER TABLE test_bw SET ("auto_analyze_policy" = "disable");"""
+    result = sql """show table stats test_bw"""
+    assertEquals(1, result.size())
+    assertEquals("false", result[0][8])
+
+    sql """analyze table test_bw PROPERTIES("use.auto.analyzer"="true")"""
+    result = sql """show auto analyze test_bw"""
+    assertEquals(0, result.size())
+
+    sql """ALTER TABLE test_bw SET ("auto_analyze_policy" = "enable");"""
+    result = sql """show table stats test_bw"""
+    assertEquals(1, result.size())
+    assertEquals("true", result[0][8])
+
+    sql """analyze table test_bw PROPERTIES("use.auto.analyzer"="true")"""
+    result = sql """show auto analyze test_bw"""
+    assertEquals(1, result.size())
+
+    sql """ALTER TABLE test_bw SET ("auto_analyze_policy" = "disable");"""
+    result = sql """show table stats test_bw"""
+    assertEquals(1, result.size())
+    assertEquals("false", result[0][8])
+    sql """ALTER TABLE test_bw SET ("auto_analyze_policy" = 
"base_on_catalog");"""
+    result = sql """show table stats test_bw"""
+    assertEquals(1, result.size())
+    assertEquals("true", result[0][8])
+
+    sql """drop database if exists test_auto_analyze_black_white_list"""
+}
+


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to