[fix](statistics)Refresh follower FE cache after alter column stats. Support alter index column stats (#31108)

1. Refresh follower FE cache after alter column stats. So that follower could update the cached stats too.
2. Support alter index column stats.
This commit is contained in:
Jibing-Li
2024-02-20 11:52:11 +08:00
committed by yiguolei
parent 54e8354fc6
commit 4aaab6fb44
5 changed files with 93 additions and 6 deletions

View File

@ -73,6 +73,7 @@ public class AlterColumnStatsStmt extends DdlStmt {
.build();
private final TableName tableName;
private final String indexName;
private final String columnName;
private final Map<String, String> properties;
private final PartitionNames optPartitionNames;
@ -80,9 +81,12 @@ public class AlterColumnStatsStmt extends DdlStmt {
private final List<Long> partitionIds = Lists.newArrayList();
private final Map<StatsType, String> statsTypeToValue = Maps.newHashMap();
public AlterColumnStatsStmt(TableName tableName, String columnName,
private long indexId = -1;
public AlterColumnStatsStmt(TableName tableName, String indexName, String columnName,
Map<String, String> properties, PartitionNames optPartitionNames) {
this.tableName = tableName;
this.indexName = indexName;
this.columnName = columnName;
this.properties = properties == null ? Collections.emptyMap() : properties;
this.optPartitionNames = optPartitionNames;
@ -96,6 +100,10 @@ public class AlterColumnStatsStmt extends DdlStmt {
return columnName;
}
public long getIndexId() {
return indexId;
}
public List<Long> getPartitionIds() {
return partitionIds;
}
@ -148,6 +156,19 @@ public class AlterColumnStatsStmt extends DdlStmt {
DatabaseIf db = catalog.getDbOrAnalysisException(tableName.getDb());
TableIf table = db.getTableOrAnalysisException(tableName.getTbl());
if (indexName != null) {
if (!(table instanceof OlapTable)) {
throw new AnalysisException("Only OlapTable support alter index stats. "
+ "Table " + table.getName() + " is not OlapTable.");
}
OlapTable olapTable = (OlapTable) table;
Long idxId = olapTable.getIndexIdByName(indexName);
if (idxId == null) {
throw new AnalysisException("Index " + indexName + " not exist in table " + table.getName());
}
indexId = idxId;
}
if (table.getColumn(columnName) == null) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_WRONG_COLUMN_NAME,
columnName, FeNameFormat.getColumnNameRegex());
@ -176,6 +197,10 @@ public class AlterColumnStatsStmt extends DdlStmt {
StringBuilder sb = new StringBuilder();
sb.append("ALTER TABLE ");
sb.append(tableName.toSql());
if (indexName != null) {
sb.append(" INDEX ");
sb.append(indexName);
}
sb.append(" MODIFY COLUMN ");
sb.append(columnName);
sb.append(" SET STATS ");

View File

@ -101,6 +101,18 @@ public class ColStatsData {
this.updateTime = row.get(13);
}
public ColStatsData(String id, long catalogId, long dbId, long tblId, long idxId, String colId, String partId,
ColumnStatistic columnStatistic) {
this.statsId = new StatsId(id, catalogId, dbId, tblId, idxId, colId, partId);
this.count = Math.round(columnStatistic.count);
this.ndv = Math.round(columnStatistic.ndv);
this.nullCount = Math.round(columnStatistic.numNulls);
this.minLit = columnStatistic.minExpr == null ? null : columnStatistic.minExpr.getStringValue();
this.maxLit = columnStatistic.maxExpr == null ? null : columnStatistic.maxExpr.getStringValue();
this.dataSizeInBytes = Math.round(columnStatistic.dataSize);
this.updateTime = columnStatistic.updatedTime;
}
public String toSQL(boolean roundByParentheses) {
StringJoiner sj = null;
if (roundByParentheses) {

View File

@ -247,6 +247,7 @@ public class StatisticsRepository {
String min = alterColumnStatsStmt.getValue(StatsType.MIN_VALUE);
String max = alterColumnStatsStmt.getValue(StatsType.MAX_VALUE);
String dataSize = alterColumnStatsStmt.getValue(StatsType.DATA_SIZE);
long indexId = alterColumnStatsStmt.getIndexId();
ColumnStatisticBuilder builder = new ColumnStatisticBuilder();
String colName = alterColumnStatsStmt.getColumnName();
Column column = objects.table.getColumn(colName);
@ -282,10 +283,10 @@ public class StatisticsRepository {
ColumnStatistic columnStatistic = builder.build();
Map<String, String> params = new HashMap<>();
params.put("id", constructId(objects.table.getId(), -1, colName));
params.put("id", constructId(objects.table.getId(), indexId, colName));
params.put("catalogId", String.valueOf(objects.catalog.getId()));
params.put("dbId", String.valueOf(objects.db.getId()));
params.put("idxId", "-1");
params.put("idxId", String.valueOf(indexId));
params.put("tblId", String.valueOf(objects.table.getId()));
params.put("colId", String.valueOf(colName));
params.put("count", String.valueOf(columnStatistic.count));
@ -299,8 +300,10 @@ public class StatisticsRepository {
// update table granularity statistics
params.put("partId", "NULL");
StatisticsUtil.execUpdate(INSERT_INTO_COLUMN_STATISTICS, params);
Env.getCurrentEnv().getStatisticsCache()
.updateColStatsCache(objects.table.getId(), -1, colName, columnStatistic);
ColStatsData data = new ColStatsData(constructId(objects.table.getId(), indexId, colName),
objects.catalog.getId(), objects.db.getId(), objects.table.getId(), indexId, colName,
null, columnStatistic);
Env.getCurrentEnv().getStatisticsCache().syncColStats(data);
AnalysisInfo mockedJobInfo = new AnalysisInfoBuilder()
.setTblUpdateTime(System.currentTimeMillis())
.setColName("")