weizhengte commented on code in PR #11030:
URL: https://github.com/apache/doris/pull/11030#discussion_r938407214
##########
fe/fe-core/src/main/java/org/apache/doris/analysis/AlterTableStatsStmt.java:
##########
@@ -35,61 +39,125 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
+/**
+ * Manually inject statistics for tables or partitions.
+ * Only OLAP table statistics are supported.
+ * e.g.
+ * ALTER TABLE table_name
+ * SET STATS ('k1' = 'v1', ...) [ PARTITIONS(p_name1, p_name2...) ]
+ */
public class AlterTableStatsStmt extends DdlStmt {
private static final ImmutableSet<StatsType> CONFIGURABLE_PROPERTIES_SET =
new ImmutableSet.Builder<StatsType>()
.add(TableStats.DATA_SIZE)
.add(TableStats.ROW_COUNT)
.build();
- private TableName tableName;
- private Map<String, String> properties;
- public final Map<StatsType, String> statsTypeToValue = Maps.newHashMap();
+ private final TableName tableName;
+ private final PartitionNames optPartitionNames;
+ private final Map<String, String> properties;
- public AlterTableStatsStmt(TableName tableName, Map<String, String>
properties) {
+ private final List<String> partitionNames = Lists.newArrayList();
+ private final Map<StatsType, String> statsTypeToValue = Maps.newHashMap();
+
+ public AlterTableStatsStmt(TableName tableName, Map<String, String>
properties,
+ PartitionNames optPartitionNames) {
this.tableName = tableName;
- this.properties = properties;
+ this.properties = properties == null ? Maps.newHashMap() : properties;
+ this.optPartitionNames = optPartitionNames;
+ }
+
+ public TableName getTableName() {
+ return tableName;
+ }
+
+ public List<String> getPartitionNames() {
+ return partitionNames;
+ }
+
+ public Map<StatsType, String> getStatsTypeToValue() {
+ return statsTypeToValue;
}
@Override
public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);
+
// check table name
tableName.analyze(analyzer);
+
// disallow external catalog
Util.prohibitExternalCatalog(tableName.getCtl(),
this.getClass().getSimpleName());
+
+ // check partition
+ checkPartitionNames();
+
// check properties
Optional<StatsType> optional =
properties.keySet().stream().map(StatsType::fromString)
- .filter(statsType ->
!CONFIGURABLE_PROPERTIES_SET.contains(statsType)).findFirst();
+ .filter(statsType ->
!CONFIGURABLE_PROPERTIES_SET.contains(statsType))
+ .findFirst();
if (optional.isPresent()) {
- throw new AnalysisException(optional.get() + " is invalid
statistic");
+ throw new AnalysisException(optional.get() + " is invalid
statistics");
}
+
// check auth
- if (!Env.getCurrentEnv().getAuth().checkTblPriv(
- ConnectContext.get(), tableName.getDb(), tableName.getTbl(),
PrivPredicate.ALTER)) {
+ if (!Env.getCurrentEnv().getAuth()
+ .checkTblPriv(ConnectContext.get(), tableName.getDb(),
tableName.getTbl(), PrivPredicate.ALTER)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR,
"ALTER TABLE STATS",
- ConnectContext.get().getQualifiedUser(),
- ConnectContext.get().getRemoteIP(),
+ ConnectContext.get().getQualifiedUser(),
ConnectContext.get().getRemoteIP(),
tableName.getDb() + ": " + tableName.getTbl());
}
+
// get statsTypeToValue
properties.forEach((key, value) -> {
StatsType statsType = StatsType.fromString(key);
statsTypeToValue.put(statsType, value);
});
}
- public TableName getTableName() {
- return tableName;
- }
+ private void checkPartitionNames() throws AnalysisException {
+ if (optPartitionNames != null) {
+ optPartitionNames.analyze(analyzer);
+ Database db = analyzer.getEnv().getInternalDataSource()
+ .getDbOrAnalysisException(tableName.getDb());
+ Table table = db.getTableOrAnalysisException(tableName.getTbl());
- public Map<StatsType, String> getStatsTypeToValue() {
- return statsTypeToValue;
+ if (table.getType() != Table.TableType.OLAP) {
+ throw new AnalysisException("Only OLAP table statistics are
supported");
+ }
+
+ OlapTable olapTable = (OlapTable) table;
+
+ if (olapTable.isPartitioned()) {
+ List<String> names = optPartitionNames.getPartitionNames();
+ Set<String> olapPartitionNames = olapTable.getPartitionNames();
+ Optional<String> optional = names.stream()
+ .filter(name ->
!olapPartitionNames.contains(name)).findFirst();
+ if (optional.isPresent()) {
+ throw new AnalysisException("Partition does not exist: " +
optional.get());
+ }
+ partitionNames.addAll(optPartitionNames.getPartitionNames());
+ } else {
+ throw new AnalysisException("Not a partitioned table: " +
olapTable.getName());
+ }
+ }
Review Comment:
There are table level and partition level statistics. For a partitioned
table, if a partition is specified by the user, the statistics of the
corresponding partition will be updated, and if no partition is specified, the
statistics of the table level will be updated.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]