This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push:
new aa8b2f8 [Bug][Refactor] Fix the conflict of temp partition and
dynamic partition operations (#3201)
aa8b2f8 is described below
commit aa8b2f86c419710d5d39902c06bfaa6f07fe508e
Author: Mingyu Chen <[email protected]>
AuthorDate: Fri Mar 27 20:25:15 2020 +0800
[Bug][Refactor] Fix the conflict of temp partition and dynamic partition
operations (#3201)
The bug is described in issue: #3200.
This CL solve the problem by:
1. Refactor the alter operation conflict checking logic by introducing new
classes `AlterOperations` and `AlterOpType`.
2. Allow add/drop temporary partition when dynamic partition feature is
enabled.
3. Allow modifying table's property when there is temporary partition in
table.
4. Make the properties `dynamic_partition.enable` optional, and default is
true.
---
.../cn/administrator-guide/dynamic-partition.md | 2 +-
.../sql-statements/Data Definition/CREATE TABLE.md | 9 +-
fe/src/main/java/org/apache/doris/alter/Alter.java | 224 ++++-----------------
.../java/org/apache/doris/alter/AlterOpType.java | 62 ++++++
.../org/apache/doris/alter/AlterOperations.java | 103 ++++++++++
.../apache/doris/alter/SchemaChangeHandler.java | 63 +++++-
.../org/apache/doris/analysis/AddColumnClause.java | 2 +
.../apache/doris/analysis/AddColumnsClause.java | 2 +
.../apache/doris/analysis/AddPartitionClause.java | 4 +-
.../org/apache/doris/analysis/AddRollupClause.java | 9 +-
.../org/apache/doris/analysis/AlterClause.java | 12 ++
.../apache/doris/analysis/AlterClusterClause.java | 2 +
.../doris/analysis/AlterLoadErrorUrlClause.java | 2 +
.../apache/doris/analysis/AlterTableClause.java | 7 +
.../org/apache/doris/analysis/AlterUserClause.java | 11 +-
.../org/apache/doris/analysis/BackendClause.java | 3 +
.../apache/doris/analysis/ColumnRenameClause.java | 2 +
.../apache/doris/analysis/CreateIndexClause.java | 3 +-
.../apache/doris/analysis/DropColumnClause.java | 2 +
.../org/apache/doris/analysis/DropIndexClause.java | 3 +-
.../apache/doris/analysis/DropPartitionClause.java | 2 +
.../apache/doris/analysis/DropRollupClause.java | 2 +
.../org/apache/doris/analysis/FrontendClause.java | 2 +
.../java/org/apache/doris/analysis/IndexDef.java | 8 +-
.../apache/doris/analysis/ModifyBrokerClause.java | 3 +
.../apache/doris/analysis/ModifyColumnClause.java | 2 +
.../doris/analysis/ModifyPartitionClause.java | 4 +-
.../analysis/ModifyTablePropertiesClause.java | 3 +
.../doris/analysis/PartitionRenameClause.java | 2 +
.../doris/analysis/ReorderColumnsClause.java | 2 +
.../doris/analysis/ReplacePartitionClause.java | 2 +
.../apache/doris/analysis/RollupRenameClause.java | 2 +
.../apache/doris/analysis/TableRenameClause.java | 2 +
.../java/org/apache/doris/catalog/Catalog.java | 2 +-
.../doris/clone/DynamicPartitionScheduler.java | 1 -
.../java/org/apache/doris/common/ErrorCode.java | 2 +-
.../doris/common/util/DynamicPartitionUtil.java | 7 +-
.../java/org/apache/doris/alter/AlterTest.java | 190 +++++++++++++++++
.../doris/catalog/DynamicPartitionTableTest.java | 60 +-----
.../java/org/apache/doris/utframe/DemoTest.java | 4 +-
40 files changed, 552 insertions(+), 277 deletions(-)
diff --git a/docs/documentation/cn/administrator-guide/dynamic-partition.md
b/docs/documentation/cn/administrator-guide/dynamic-partition.md
index 0ca38ed..bf5d4f4 100644
--- a/docs/documentation/cn/administrator-guide/dynamic-partition.md
+++ b/docs/documentation/cn/administrator-guide/dynamic-partition.md
@@ -42,7 +42,7 @@ under the License.
### 动态分区属性参数说明:
-`dynamic_partition.enable`: 是否开启动态分区特性,可指定为 `TRUE` 或 `FALSE`。
+`dynamic_partition.enable`: 是否开启动态分区特性,可指定为 `TRUE` 或 `FALSE`。如果不填写,默认为 `TRUE`。
`dynamic_partition.time_unit`: 动态分区调度的单位,可指定为 `DAY` `WEEK` `MONTH`,当指定为 `DAY`
时,动态创建的分区名后缀格式为`yyyyMMdd`,例如`20200325`。当指定为 `WEEK`
时,动态创建的分区名后缀格式为`yyyy_ww`即当前日期属于这一年的第几周,例如 `2020-03-25` 创建的分区名后缀为 `2020_13`,
表明目前为2020年第13周。当指定为 `MONTH` 时,动态创建的分区名后缀格式为 `yyyyMM`,例如 `202003`。
diff --git a/docs/documentation/cn/sql-reference/sql-statements/Data
Definition/CREATE TABLE.md
b/docs/documentation/cn/sql-reference/sql-statements/Data Definition/CREATE
TABLE.md
index c0d575d..80afc16 100644
--- a/docs/documentation/cn/sql-reference/sql-statements/Data Definition/CREATE
TABLE.md
+++ b/docs/documentation/cn/sql-reference/sql-statements/Data Definition/CREATE
TABLE.md
@@ -257,13 +257,15 @@ under the License.
PROPERTIES (
"dynamic_partition.enable" = "true|false",
"dynamic_partition.time_unit" = "DAY|WEEK|MONTH",
+ "dynamic_partition.start" = "${integer_value}",
"dynamic_partitoin.end" = "${integer_value}",
"dynamic_partition.prefix" = "${string_value}",
"dynamic_partition.buckets" = "${integer_value}
```
- dynamic_partition.enable: 用于指定表级别的动态分区功能是否开启
+ dynamic_partition.enable: 用于指定表级别的动态分区功能是否开启。默认为 true。
dynamic_partition.time_unit: 用于指定动态添加分区的时间单位,可选择为DAY(天),WEEK(周),MONTH(月)
- dynamic_partition.end: 用于指定提前创建的分区数量
+ dynamic_partition.start: 用于指定向前删除多少个分区。值必须小于0。默认为 Integer.MIN_VALUE。
+ dynamic_partition.end: 用于指定提前创建的分区数量。值必须大于0。
dynamic_partition.prefix: 用于指定创建的分区名前缀,例如分区名前缀为p,则自动创建分区名为p20200108
dynamic_partition.buckets: 用于指定自动创建的分区分桶数量
@@ -524,7 +526,7 @@ under the License.
PROPERTIES ("storage_type"="column");
```
-11.
创建一个动态分区表(需要在FE配置中开启动态分区功能),该表每天提前创建3天的分区,例如今天为`2020-01-08`,则会创建分区名为`p20200108`,
`p20200109`, `p20200110`, `p20200111`的分区. 分区范围分别为:
+11.
创建一个动态分区表(需要在FE配置中开启动态分区功能),该表每天提前创建3天的分区,并删除3天前的分区。例如今天为`2020-01-08`,则会创建分区名为`p20200108`,
`p20200109`, `p20200110`, `p20200111`的分区. 分区范围分别为:
```
[types: [DATE]; keys: [2020-01-08]; ‥types: [DATE]; keys: [2020-01-09]; )
@@ -554,6 +556,7 @@ under the License.
PROPERTIES(
"storage_medium" = "SSD",
"dynamic_partition.time_unit" = "DAY",
+ "dynamic_partition.start" = "-3",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "32"
diff --git a/fe/src/main/java/org/apache/doris/alter/Alter.java
b/fe/src/main/java/org/apache/doris/alter/Alter.java
index 4edbbe1..8028023 100644
--- a/fe/src/main/java/org/apache/doris/alter/Alter.java
+++ b/fe/src/main/java/org/apache/doris/alter/Alter.java
@@ -17,29 +17,18 @@
package org.apache.doris.alter;
-import org.apache.doris.analysis.AddColumnClause;
-import org.apache.doris.analysis.AddColumnsClause;
import org.apache.doris.analysis.AddPartitionClause;
-import org.apache.doris.analysis.AddRollupClause;
import org.apache.doris.analysis.AlterClause;
import org.apache.doris.analysis.AlterSystemStmt;
-import org.apache.doris.analysis.AlterTableClause;
import org.apache.doris.analysis.AlterTableStmt;
import org.apache.doris.analysis.AlterViewStmt;
import org.apache.doris.analysis.ColumnRenameClause;
-import org.apache.doris.analysis.CreateIndexClause;
import org.apache.doris.analysis.CreateMaterializedViewStmt;
-import org.apache.doris.analysis.DropColumnClause;
-import org.apache.doris.analysis.DropIndexClause;
import org.apache.doris.analysis.DropMaterializedViewStmt;
import org.apache.doris.analysis.DropPartitionClause;
-import org.apache.doris.analysis.DropRollupClause;
-import org.apache.doris.analysis.IndexDef;
-import org.apache.doris.analysis.ModifyColumnClause;
import org.apache.doris.analysis.ModifyPartitionClause;
import org.apache.doris.analysis.ModifyTablePropertiesClause;
import org.apache.doris.analysis.PartitionRenameClause;
-import org.apache.doris.analysis.ReorderColumnsClause;
import org.apache.doris.analysis.ReplacePartitionClause;
import org.apache.doris.analysis.RollupRenameClause;
import org.apache.doris.analysis.TableName;
@@ -47,7 +36,6 @@ import org.apache.doris.analysis.TableRenameClause;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Database;
-import org.apache.doris.catalog.Index;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.OlapTable.OlapTableState;
import org.apache.doris.catalog.Table;
@@ -72,8 +60,6 @@ import org.apache.logging.log4j.Logger;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
public class Alter {
private static final Logger LOG = LogManager.getLogger(Alter.class);
@@ -167,141 +153,19 @@ public class Alter {
ErrorReport.reportDdlException(ErrorCode.ERR_BAD_DB_ERROR, dbName);
}
- // check cluster capacity
- Catalog.getCurrentSystemInfo().checkClusterCapacity(clusterName);
-
- // schema change ops can appear several in one alter stmt without
other alter ops entry
- boolean hasSchemaChange = false;
- // materialized view ops (include rollup), if has, should appear one
and only one add or drop mv entry
- boolean hasAddMaterializedView = false;
- boolean hasDropRollup = false;
- // partition ops, if has, should appear one and only one entry
- boolean hasPartition = false;
- // rename ops, if has, should appear one and only one entry
- boolean hasRename = false;
- // modify properties ops, if has, should appear one and only one entry
- boolean hasModifyProp = false;
-
// check conflict alter ops first
List<AlterClause> alterClauses = stmt.getOps();
- // check conflict alter ops first
-
- // if all alter clauses are DropPartitionClause or DropRollupClause,
no need to check quota.
- boolean allIsDropOps = true;
- for (AlterClause alterClause : alterClauses) {
- if (!(alterClause instanceof DropPartitionClause)
- && !(alterClause instanceof DropRollupClause)) {
- allIsDropOps = false;
- break;
- }
- }
+ AlterOperations currentAlterOps = new AlterOperations();
+ currentAlterOps.checkConflict(alterClauses);
- if (!allIsDropOps) {
- // check db quota
+ // check cluster capacity and db quota, only need to check once.
+ if (currentAlterOps.needCheckCapacity()) {
+ Catalog.getCurrentSystemInfo().checkClusterCapacity(clusterName);
db.checkQuota();
}
- // synchronized operation must handle outside db write lock
- boolean needSynchronized = false;
- boolean needTableStable = false;
- for (AlterClause alterClause : alterClauses) {
- if (!needTableStable) {
- needTableStable = ((AlterTableClause)
alterClause).isNeedTableStable();
- }
- if ((alterClause instanceof AddColumnClause
- || alterClause instanceof AddColumnsClause
- || alterClause instanceof DropColumnClause
- || alterClause instanceof ModifyColumnClause
- || alterClause instanceof ReorderColumnsClause
- || alterClause instanceof CreateIndexClause
- || alterClause instanceof DropIndexClause)
- && !hasAddMaterializedView && !hasDropRollup &&
!hasPartition && !hasRename) {
- hasSchemaChange = true;
- if (alterClause instanceof CreateIndexClause) {
- Table table = db.getTable(dbTableName.getTbl());
- if (!(table instanceof OlapTable)) {
- throw new AnalysisException("create index only support
in olap table at current version.");
- }
- List<Index> indexes = ((OlapTable) table).getIndexes();
- IndexDef indexDef = ((CreateIndexClause)
alterClause).getIndexDef();
- Set<String> newColset = new
TreeSet<>(String.CASE_INSENSITIVE_ORDER);
- newColset.addAll(indexDef.getColumns());
- for (Index idx : indexes) {
- if
(idx.getIndexName().equalsIgnoreCase(indexDef.getIndexName())) {
- throw new AnalysisException("index `" +
indexDef.getIndexName() + "` already exist.");
- }
- Set<String> idxSet = new
TreeSet<>(String.CASE_INSENSITIVE_ORDER);
- idxSet.addAll(idx.getColumns());
- if (newColset.equals(idxSet)) {
- throw new AnalysisException("index for columns ("
+ String
- .join(",", indexDef.getColumns()) + " )
already exist.");
- }
- }
- OlapTable olapTable = (OlapTable) table;
- for (String col : indexDef.getColumns()) {
- Column column = olapTable.getColumn(col);
- if (column != null) {
- indexDef.checkColumn(column,
olapTable.getKeysType());
- } else {
- throw new AnalysisException("BITMAP column does
not exist in table. invalid column: "
- + col);
- }
- }
- } else if (alterClause instanceof DropIndexClause) {
- Table table = db.getTable(dbTableName.getTbl());
- if (!(table instanceof OlapTable)) {
- throw new AnalysisException("drop index only support
in olap table at current version.");
- }
- String indexName = ((DropIndexClause)
alterClause).getIndexName();
- List<Index> indexes = ((OlapTable) table).getIndexes();
- Index found = null;
- for (Index idx : indexes) {
- if (idx.getIndexName().equalsIgnoreCase(indexName)) {
- found = idx;
- break;
- }
- }
- if (found == null) {
- throw new AnalysisException("index " + indexName +
" does not exist");
- }
- }
- } else if ((alterClause instanceof AddRollupClause)
- && !hasSchemaChange && !hasDropRollup
- && !hasPartition && !hasRename && !hasModifyProp) {
- hasAddMaterializedView = true;
- } else if (alterClause instanceof DropRollupClause &&
!hasSchemaChange && !hasAddMaterializedView
- && !hasPartition && !hasRename && !hasModifyProp) {
- hasDropRollup = true;
- } else if (alterClause instanceof AddPartitionClause &&
!hasSchemaChange && !hasAddMaterializedView
- && !hasDropRollup && !hasPartition && !hasRename &&
!hasModifyProp) {
- hasPartition = true;
- } else if (alterClause instanceof DropPartitionClause &&
!hasSchemaChange && !hasAddMaterializedView && !hasDropRollup
- && !hasPartition && !hasRename && !hasModifyProp) {
- hasPartition = true;
- } else if (alterClause instanceof ModifyPartitionClause &&
!hasSchemaChange && !hasAddMaterializedView
- && !hasDropRollup && !hasPartition && !hasRename &&
!hasModifyProp) {
- hasPartition = true;
- } else if ((alterClause instanceof TableRenameClause ||
alterClause instanceof RollupRenameClause
- || alterClause instanceof PartitionRenameClause ||
alterClause instanceof ColumnRenameClause)
- && !hasSchemaChange && !hasAddMaterializedView &&
!hasDropRollup && !hasPartition && !hasRename
- && !hasModifyProp) {
- hasRename = true;
- } else if (alterClause instanceof ReplacePartitionClause &&
!hasSchemaChange && !hasAddMaterializedView
- && !hasDropRollup && !hasPartition && !hasRename &&
!hasModifyProp) {
- hasPartition = true;
- } else if (alterClause instanceof ModifyTablePropertiesClause &&
!hasSchemaChange && !hasAddMaterializedView
- && !hasDropRollup && !hasPartition && !hasRename &&
!hasModifyProp) {
- Map<String, String> properties = alterClause.getProperties();
- if
(properties.containsKey(PropertyAnalyzer.PROPERTIES_INMEMORY)) {
- needSynchronized = true;
- } else {
- hasModifyProp = true;
- }
- } else {
- throw new DdlException("Conflicting alter clauses. see help
for more information");
- }
- } // end for alter clauses
-
+ // some operations will take long time to process, need to be done
outside the databse lock
+ boolean needProcessOutsideDatabaseLock = false;
String tableName = dbTableName.getTbl();
db.writeLock();
try {
@@ -313,44 +177,29 @@ public class Alter {
if (table.getType() != TableType.OLAP) {
throw new DdlException("Do not support alter non-OLAP table["
+ tableName + "]");
}
-
OlapTable olapTable = (OlapTable) table;
- if (olapTable.getPartitions().size() == 0 && !hasPartition) {
- throw new DdlException("table with empty parition cannot do
schema change. [" + tableName + "]");
+ if (olapTable.getPartitions().size() == 0 &&
!currentAlterOps.hasPartitionOp()) {
+ throw new DdlException("Table with empty parition cannot do
schema change. [" + tableName + "]");
}
if (olapTable.getState() != OlapTableState.NORMAL) {
- throw new DdlException("Table[" + table.getName() + "]'s state
is not NORMAL. Do not allow doing ALTER ops");
+ throw new DdlException(
+ "Table[" + table.getName() + "]'s state is not NORMAL.
Do not allow doing ALTER ops");
}
- // schema change job will wait until table become stable
- if (needTableStable && !hasSchemaChange &&
!hasAddMaterializedView) {
- // check if all tablets are healthy, and no tablet is in
tablet scheduler
- boolean isStable =
olapTable.isStable(Catalog.getCurrentSystemInfo(),
- Catalog.getCurrentCatalog().getTabletScheduler(),
- db.getClusterName());
- if (!isStable) {
- throw new DdlException("table [" + olapTable.getName() +
"] is not stable."
- + " Some tablets of this table may not be healthy
or are being scheduled."
- + " You need to repair the table first"
- + " or stop cluster balance. See 'help admin;'.");
- }
- }
-
- if (hasSchemaChange || hasModifyProp) {
+ if (currentAlterOps.hasSchemaChangeOp()) {
// if modify storage type to v2, do schema change to convert
all related tablets to segment v2 format
schemaChangeHandler.process(alterClauses, clusterName, db,
olapTable);
- } else if (hasAddMaterializedView || hasDropRollup) {
+ } else if (currentAlterOps.hasRollupOp()) {
materializedViewHandler.process(alterClauses, clusterName, db,
olapTable);
- } else if (hasPartition) {
+ } else if (currentAlterOps.hasPartitionOp()) {
Preconditions.checkState(alterClauses.size() == 1);
- // when this is a dynamic partition table, do not allow doing
partition operation.
- // TODO(cmy): although some of operation can be done with
dynamic partition,
- // but currently we check it strictly to avoid some unexpected
exception.
- DynamicPartitionUtil.checkAlterAllowed(olapTable);
AlterClause alterClause = alterClauses.get(0);
if (alterClause instanceof DropPartitionClause) {
+ if (!((DropPartitionClause)
alterClause).isTempPartition()) {
+ DynamicPartitionUtil.checkAlterAllowed((OlapTable)
db.getTable(tableName));
+ }
Catalog.getInstance().dropPartition(db, olapTable,
((DropPartitionClause) alterClause));
} else if (alterClause instanceof ReplacePartitionClause) {
Catalog.getCurrentCatalog().replaceTempPartition(db,
tableName, (ReplacePartitionClause) alterClause);
@@ -358,45 +207,50 @@ public class Alter {
ModifyPartitionClause clause = ((ModifyPartitionClause)
alterClause);
Map<String, String> properties = clause.getProperties();
if
(properties.containsKey(PropertyAnalyzer.PROPERTIES_INMEMORY)) {
- needSynchronized = true;
+ needProcessOutsideDatabaseLock = true;
} else {
String partitionName = clause.getPartitionName();
- Catalog.getInstance().modifyPartition(db, olapTable,
partitionName, properties);
+ Catalog.getInstance().modifyPartitionProperty(db,
olapTable, partitionName, properties);
}
+ } else if (alterClause instanceof AddPartitionClause) {
+ needProcessOutsideDatabaseLock = true;
} else {
- // add (temp) partition
- needSynchronized = true;
+ throw new DdlException("Invalid alter opertion: " +
alterClause.getOpType());
}
- } else if (hasRename) {
+ } else if (currentAlterOps.hasRenameOp()) {
processRename(db, olapTable, alterClauses);
+ } else if
(currentAlterOps.contains(AlterOpType.MODIFY_TABLE_PROPERTY_SYNC)) {
+ needProcessOutsideDatabaseLock = true;
+ } else {
+ throw new DdlException("Invalid alter operations: " +
currentAlterOps);
}
} finally {
db.writeUnlock();
}
// the following ops should done outside db lock. because it contain
synchronized create operation
- if (needSynchronized) {
+ if (needProcessOutsideDatabaseLock) {
Preconditions.checkState(alterClauses.size() == 1);
AlterClause alterClause = alterClauses.get(0);
if (alterClause instanceof AddPartitionClause) {
- DynamicPartitionUtil.checkAlterAllowed((OlapTable)
db.getTable(tableName));
- Catalog.getInstance().addPartition(db, tableName,
(AddPartitionClause) alterClause);
+ if (!((AddPartitionClause) alterClause).isTempPartition()) {
+ DynamicPartitionUtil.checkAlterAllowed((OlapTable)
db.getTable(tableName));
+ }
+ Catalog.getCurrentCatalog().addPartition(db, tableName,
(AddPartitionClause) alterClause);
} else if (alterClause instanceof ModifyPartitionClause) {
ModifyPartitionClause clause = ((ModifyPartitionClause)
alterClause);
Map<String, String> properties = clause.getProperties();
String partitionName = clause.getPartitionName();
// currently, only in memory property could reach here
Preconditions.checkState(properties.containsKey(PropertyAnalyzer.PROPERTIES_INMEMORY));
- if
(properties.containsKey(PropertyAnalyzer.PROPERTIES_INMEMORY)) {
- boolean isInMemory =
Boolean.parseBoolean(properties.get(PropertyAnalyzer.PROPERTIES_INMEMORY));
-
((SchemaChangeHandler)schemaChangeHandler).updatePartitionInMemoryMeta(
- db, tableName, partitionName, isInMemory);
- }
+ boolean isInMemory =
Boolean.parseBoolean(properties.get(PropertyAnalyzer.PROPERTIES_INMEMORY));
+ ((SchemaChangeHandler)
schemaChangeHandler).updatePartitionInMemoryMeta(
+ db, tableName, partitionName, isInMemory);
db.writeLock();
try {
- OlapTable olapTable = (OlapTable)db.getTable(tableName);
- Catalog.getInstance().modifyPartition(db, olapTable,
partitionName, properties);
+ OlapTable olapTable = (OlapTable) db.getTable(tableName);
+ Catalog.getCurrentCatalog().modifyPartitionProperty(db,
olapTable, partitionName, properties);
} finally {
db.writeUnlock();
}
@@ -404,9 +258,9 @@ public class Alter {
Map<String, String> properties = alterClause.getProperties();
// currently, only in memory property could reach here
Preconditions.checkState(properties.containsKey(PropertyAnalyzer.PROPERTIES_INMEMORY));
-
((SchemaChangeHandler)schemaChangeHandler).updateTableInMemoryMeta(db,
tableName, properties);
+ ((SchemaChangeHandler)
schemaChangeHandler).updateTableInMemoryMeta(db, tableName, properties);
} else {
- Preconditions.checkState(false);
+ throw new DdlException("Invalid alter opertion: " +
alterClause.getOpType());
}
}
}
diff --git a/fe/src/main/java/org/apache/doris/alter/AlterOpType.java
b/fe/src/main/java/org/apache/doris/alter/AlterOpType.java
new file mode 100644
index 0000000..6cf112e
--- /dev/null
+++ b/fe/src/main/java/org/apache/doris/alter/AlterOpType.java
@@ -0,0 +1,62 @@
+// 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.
+
+package org.apache.doris.alter;
+
+public enum AlterOpType {
+ // rollup
+ ADD_ROLLUP,
+ DROP_ROLLUP,
+ // schema change
+ SCHEMA_CHANGE,
+ // partition
+ ADD_PARTITION,
+ DROP_PARTITION,
+ REPLACE_PARTITION,
+ MODIFY_PARTITION,
+ // rename
+ RENAME,
+ // table property
+ MODIFY_TABLE_PROPERTY,
+ MODIFY_TABLE_PROPERTY_SYNC, // Some operations are performed
synchronously, so we distinguish them by suffix _SYNC
+ // others operation, such as add/drop backend. currently we do not care
about them
+ ALTER_OTHER,
+
+ INVALID_OP;
+
+ // true means 2 operations have no conflict.
+ public static Boolean[][] COMPATIBITLITY_MATRIX;
+ static {
+ COMPATIBITLITY_MATRIX = new Boolean[INVALID_OP.ordinal() +
1][INVALID_OP.ordinal() + 1];
+ for (int i = 0; i < INVALID_OP.ordinal(); i++) {
+ for (int j = 0; j < INVALID_OP.ordinal(); j++) {
+ COMPATIBITLITY_MATRIX[i][j] = false;
+ }
+ }
+
+ // rollup can be added or dropped in batch
+ COMPATIBITLITY_MATRIX[ADD_ROLLUP.ordinal()][ADD_ROLLUP.ordinal()] =
true;
+ COMPATIBITLITY_MATRIX[DROP_ROLLUP.ordinal()][DROP_ROLLUP.ordinal()] =
true;
+ // schema change, such as add/modify/drop columns can be processed in
batch
+
COMPATIBITLITY_MATRIX[SCHEMA_CHANGE.ordinal()][SCHEMA_CHANGE.ordinal()] = true;
+ }
+
+ public boolean needCheckCapacity() {
+ return this == ADD_ROLLUP || this == SCHEMA_CHANGE || this ==
ADD_PARTITION;
+ }
+
+}
diff --git a/fe/src/main/java/org/apache/doris/alter/AlterOperations.java
b/fe/src/main/java/org/apache/doris/alter/AlterOperations.java
new file mode 100644
index 0000000..ff3af4a
--- /dev/null
+++ b/fe/src/main/java/org/apache/doris/alter/AlterOperations.java
@@ -0,0 +1,103 @@
+// 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.
+
+package org.apache.doris.alter;
+
+import org.apache.doris.analysis.AlterClause;
+import org.apache.doris.common.DdlException;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Sets;
+
+import java.util.List;
+import java.util.Set;
+
+/*
+ * AlterOperations contains a set alter operations generated from a
AlterStmt's alter clause.
+ * This class is mainly used to integrate these operation types and check
whether they have conflicts.
+ */
+public class AlterOperations {
+ private Set<AlterOpType> currentOps = Sets.newHashSet();
+
+ public AlterOperations() {
+ }
+
+ public Set<AlterOpType> getCurrentOps() {
+ return currentOps;
+ }
+
+ // check the conflicts of the given list of alter clauses
+ public void checkConflict(List<AlterClause> alterClauses) throws
DdlException {
+ for (AlterClause alterClause : alterClauses) {
+ checkOp(alterClause.getOpType());
+ }
+ }
+
+ // some operations take up disk space. so we need to check the disk
capacity before processing.
+ // return true if we see these kind of opertions.
+ public boolean needCheckCapacity() {
+ for (AlterOpType currentOp : currentOps) {
+ if (currentOp.needCheckCapacity()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean hasPartitionOp() {
+ return currentOps.contains(AlterOpType.ADD_PARTITION) ||
currentOps.contains(AlterOpType.DROP_PARTITION)
+ || currentOps.contains(AlterOpType.REPLACE_PARTITION) ||
currentOps.contains(AlterOpType.MODIFY_PARTITION);
+ }
+
+ // MODIFY_TABLE_PROPERTY is also processed by SchemaChangeHandler
+ public boolean hasSchemaChangeOp() {
+ return currentOps.contains(AlterOpType.SCHEMA_CHANGE) ||
currentOps.contains(AlterOpType.MODIFY_TABLE_PROPERTY);
+ }
+
+ public boolean hasRollupOp() {
+ return currentOps.contains(AlterOpType.ADD_ROLLUP) ||
currentOps.contains(AlterOpType.DROP_ROLLUP);
+ }
+
+ public boolean hasRenameOp() {
+ return currentOps.contains(AlterOpType.RENAME);
+ }
+
+ public boolean contains(AlterOpType op) {
+ return currentOps.contains(op);
+ }
+
+ // throw exception if the given operation has conflict with current
operations.,
+ private void checkOp(AlterOpType opType) throws DdlException {
+ if (currentOps.isEmpty()) {
+ currentOps.add(opType);
+ return;
+ }
+
+ for (AlterOpType currentOp : currentOps) {
+ if
(!AlterOpType.COMPATIBITLITY_MATRIX[currentOp.ordinal()][opType.ordinal()]) {
+ throw new DdlException("Alter operation " + opType + "
conflicts with operation " + currentOp);
+ }
+ }
+
+ currentOps.add(opType);
+ }
+
+ @Override
+ public String toString() {
+ return Joiner.on(", ").join(currentOps);
+ }
+}
diff --git a/fe/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
b/fe/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
index ea3c67d..4279f71 100644
--- a/fe/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
+++ b/fe/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
@@ -27,6 +27,7 @@ import org.apache.doris.analysis.ColumnPosition;
import org.apache.doris.analysis.CreateIndexClause;
import org.apache.doris.analysis.DropColumnClause;
import org.apache.doris.analysis.DropIndexClause;
+import org.apache.doris.analysis.IndexDef;
import org.apache.doris.analysis.ModifyColumnClause;
import org.apache.doris.analysis.ModifyTablePropertiesClause;
import org.apache.doris.analysis.ReorderColumnsClause;
@@ -1324,10 +1325,6 @@ public class SchemaChangeHandler extends AlterHandler {
public void process(List<AlterClause> alterClauses, String clusterName,
Database db, OlapTable olapTable)
throws UserException {
- if (olapTable.existTempPartitions()) {
- throw new DdlException("Can not alter table when there are temp
partitions in table");
- }
-
// index id -> index schema
Map<Long, LinkedList<Column>> indexSchemaMap = new HashMap<>();
for (Map.Entry<Long, List<Column>> entry :
olapTable.getIndexIdToSchema().entrySet()) {
@@ -1369,6 +1366,11 @@ public class SchemaChangeHandler extends AlterHandler {
}
}
+ // the following operations can not be done when there are temp
partitions exist.
+ if (olapTable.existTempPartitions()) {
+ throw new DdlException("Can not alter table when there are
temp partitions in table");
+ }
+
if (alterClause instanceof AddColumnClause) {
// add column
processAddColumn((AddColumnClause) alterClause, olapTable,
indexSchemaMap);
@@ -1388,9 +1390,9 @@ public class SchemaChangeHandler extends AlterHandler {
// modify table properties
// do nothing, properties are already in propertyMap
} else if (alterClause instanceof CreateIndexClause) {
- processAddIndex((CreateIndexClause) alterClause, newIndexes);
+ processAddIndex((CreateIndexClause) alterClause, olapTable,
newIndexes);
} else if (alterClause instanceof DropIndexClause) {
- processDropIndex((DropIndexClause) alterClause, newIndexes);
+ processDropIndex((DropIndexClause) alterClause, olapTable,
newIndexes);
} else {
Preconditions.checkState(false);
}
@@ -1590,13 +1592,54 @@ public class SchemaChangeHandler extends AlterHandler {
}
}
- private void processAddIndex(CreateIndexClause alterClause, List<Index>
indexes) {
- if (alterClause.getIndex() != null) {
- indexes.add(alterClause.getIndex());
+ private void processAddIndex(CreateIndexClause alterClause, OlapTable
olapTable, List<Index> newIndexes)
+ throws UserException {
+ if (alterClause.getIndex() == null) {
+ return;
+ }
+
+ List<Index> existedIndexes = olapTable.getIndexes();
+ IndexDef indexDef = alterClause.getIndexDef();
+ Set<String> newColset = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
+ newColset.addAll(indexDef.getColumns());
+ for (Index existedIdx : existedIndexes) {
+ if
(existedIdx.getIndexName().equalsIgnoreCase(indexDef.getIndexName())) {
+ throw new DdlException("index `" + indexDef.getIndexName() +
"` already exist.");
+ }
+ Set<String> existedIdxColSet =
Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
+ existedIdxColSet.addAll(existedIdx.getColumns());
+ if (newColset.equals(existedIdxColSet)) {
+ throw new DdlException(
+ "index for columns (" + String.join(",",
indexDef.getColumns()) + " ) already exist.");
+ }
+ }
+
+ for (String col : indexDef.getColumns()) {
+ Column column = olapTable.getColumn(col);
+ if (column != null) {
+ indexDef.checkColumn(column, olapTable.getKeysType());
+ } else {
+ throw new DdlException("BITMAP column does not exist in table.
invalid column: " + col);
+ }
}
+
+ newIndexes.add(alterClause.getIndex());
}
- private void processDropIndex(DropIndexClause alterClause, List<Index>
indexes) {
+ private void processDropIndex(DropIndexClause alterClause, OlapTable
olapTable, List<Index> indexes) throws DdlException {
+ String indexName = alterClause.getIndexName();
+ List<Index> existedIndexes = olapTable.getIndexes();
+ Index found = null;
+ for (Index existedIdx : existedIndexes) {
+ if (existedIdx.getIndexName().equalsIgnoreCase(indexName)) {
+ found = existedIdx;
+ break;
+ }
+ }
+ if (found == null) {
+ throw new DdlException("index " + indexName + " does not exist");
+ }
+
Iterator<Index> itr = indexes.iterator();
while (itr.hasNext()) {
Index idx = itr.next();
diff --git a/fe/src/main/java/org/apache/doris/analysis/AddColumnClause.java
b/fe/src/main/java/org/apache/doris/analysis/AddColumnClause.java
index 16f162f..918baaa 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AddColumnClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AddColumnClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.catalog.Column;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
@@ -54,6 +55,7 @@ public class AddColumnClause extends AlterTableClause {
public AddColumnClause(ColumnDef columnDef, ColumnPosition colPos, String
rollupName,
Map<String, String> properties) {
+ super(AlterOpType.SCHEMA_CHANGE);
this.columnDef = columnDef;
this.colPos = colPos;
this.rollupName = rollupName;
diff --git a/fe/src/main/java/org/apache/doris/analysis/AddColumnsClause.java
b/fe/src/main/java/org/apache/doris/analysis/AddColumnsClause.java
index 4418ee8..c3c52a4 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AddColumnsClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AddColumnsClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.catalog.Column;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
@@ -46,6 +47,7 @@ public class AddColumnsClause extends AlterTableClause {
}
public AddColumnsClause(List<ColumnDef> columnDefs, String rollupName,
Map<String, String> properties) {
+ super(AlterOpType.SCHEMA_CHANGE);
this.columnDefs = columnDefs;
this.rollupName = rollupName;
this.properties = properties;
diff --git a/fe/src/main/java/org/apache/doris/analysis/AddPartitionClause.java
b/fe/src/main/java/org/apache/doris/analysis/AddPartitionClause.java
index 62b3da0..23f8a23 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AddPartitionClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AddPartitionClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import java.util.Map;
@@ -46,11 +47,12 @@ public class AddPartitionClause extends AlterTableClause {
DistributionDesc distributionDesc,
Map<String, String> properties,
boolean isTempPartition) {
+ super(AlterOpType.ADD_PARTITION);
this.partitionDesc = partitionDesc;
this.distributionDesc = distributionDesc;
this.properties = properties;
this.isTempPartition = isTempPartition;
-
+
this.needTableStable = false;
}
diff --git a/fe/src/main/java/org/apache/doris/analysis/AddRollupClause.java
b/fe/src/main/java/org/apache/doris/analysis/AddRollupClause.java
index 809d29a..36d5bcd 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AddRollupClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AddRollupClause.java
@@ -17,14 +17,13 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.FeNameFormat;
import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.List;
@@ -43,11 +42,6 @@ public class AddRollupClause extends AlterTableClause {
private Map<String, String> properties;
- public AddRollupClause() {
- columnNames = Lists.newArrayList();
- properties = Maps.newHashMap();
- }
-
public String getRollupName() {
return rollupName;
}
@@ -67,6 +61,7 @@ public class AddRollupClause extends AlterTableClause {
public AddRollupClause(String rollupName, List<String> columnNames,
List<String> dupKeys, String baseRollupName,
Map<String, String> properties) {
+ super(AlterOpType.ADD_ROLLUP);
this.rollupName = rollupName;
this.columnNames = columnNames;
this.dupKeys = dupKeys;
diff --git a/fe/src/main/java/org/apache/doris/analysis/AlterClause.java
b/fe/src/main/java/org/apache/doris/analysis/AlterClause.java
index 0c859a7..3213a6a 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AlterClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AlterClause.java
@@ -17,6 +17,8 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
+
import org.apache.commons.lang.NotImplementedException;
import java.util.Map;
@@ -24,7 +26,17 @@ import java.util.Map;
// Alter clause.
public abstract class AlterClause implements ParseNode {
+ protected AlterOpType opType;
+
+ public AlterClause(AlterOpType opType) {
+ this.opType = opType;
+ }
+
public Map<String, String> getProperties() {
throw new NotImplementedException();
}
+
+ public AlterOpType getOpType() {
+ return opType;
+ }
}
diff --git a/fe/src/main/java/org/apache/doris/analysis/AlterClusterClause.java
b/fe/src/main/java/org/apache/doris/analysis/AlterClusterClause.java
index 5e92d4f..2984a52 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AlterClusterClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AlterClusterClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.ErrorCode;
@@ -34,6 +35,7 @@ public class AlterClusterClause extends AlterClause {
private String password;
public AlterClusterClause(AlterClusterType type, Map<String, String>
properties) {
+ super(AlterOpType.ALTER_OTHER);
this.type = type;
this.properties = properties;
instanceNum = 0;
diff --git
a/fe/src/main/java/org/apache/doris/analysis/AlterLoadErrorUrlClause.java
b/fe/src/main/java/org/apache/doris/analysis/AlterLoadErrorUrlClause.java
index 633ed85..376c4cf 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AlterLoadErrorUrlClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AlterLoadErrorUrlClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.util.PrintableMap;
import org.apache.doris.load.LoadErrorHub;
@@ -38,6 +39,7 @@ public class AlterLoadErrorUrlClause extends AlterClause {
private LoadErrorHub.Param param;
public AlterLoadErrorUrlClause(Map<String, String> properties) {
+ super(AlterOpType.ALTER_OTHER);
this.properties = properties;
}
diff --git a/fe/src/main/java/org/apache/doris/analysis/AlterTableClause.java
b/fe/src/main/java/org/apache/doris/analysis/AlterTableClause.java
index a35291a..7a223be 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AlterTableClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AlterTableClause.java
@@ -17,8 +17,15 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
+
// alter table clause
public abstract class AlterTableClause extends AlterClause {
+
+ public AlterTableClause(AlterOpType opType) {
+ super(opType);
+ }
+
// if set to true, the corresponding table should be stable before
processing this operation on it.
protected boolean needTableStable = true;
diff --git a/fe/src/main/java/org/apache/doris/analysis/AlterUserClause.java
b/fe/src/main/java/org/apache/doris/analysis/AlterUserClause.java
index debfbf4..07a2e95 100644
--- a/fe/src/main/java/org/apache/doris/analysis/AlterUserClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/AlterUserClause.java
@@ -17,11 +17,9 @@
package org.apache.doris.analysis;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
+
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -30,6 +28,10 @@ import org.apache.commons.lang.NotImplementedException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
public class AlterUserClause extends AlterClause {
private static final Logger LOG =
LogManager.getLogger(AlterUserClause.class);
private List<String> hostOrIps;
@@ -40,6 +42,7 @@ public class AlterUserClause extends AlterClause {
private AlterUserType type;
public AlterUserClause(AlterUserType type, List<String> hostOrIps) {
+ super(AlterOpType.ALTER_OTHER);
this.type = type;
this.hostOrIps = hostOrIps;
this.ips = Lists.newArrayList();
diff --git a/fe/src/main/java/org/apache/doris/analysis/BackendClause.java
b/fe/src/main/java/org/apache/doris/analysis/BackendClause.java
index 31f3ce0..c09ef49 100644
--- a/fe/src/main/java/org/apache/doris/analysis/BackendClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/BackendClause.java
@@ -17,9 +17,11 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Pair;
import org.apache.doris.system.SystemInfoService;
+
import com.google.common.base.Preconditions;
import org.apache.commons.lang.NotImplementedException;
@@ -34,6 +36,7 @@ public class BackendClause extends AlterClause {
protected List<Pair<String, Integer>> hostPortPairs;
protected BackendClause(List<String> hostPorts) {
+ super(AlterOpType.ALTER_OTHER);
this.hostPorts = hostPorts;
this.hostPortPairs = new LinkedList<Pair<String, Integer>>();
}
diff --git a/fe/src/main/java/org/apache/doris/analysis/ColumnRenameClause.java
b/fe/src/main/java/org/apache/doris/analysis/ColumnRenameClause.java
index c6a67b7..e3d9d69 100644
--- a/fe/src/main/java/org/apache/doris/analysis/ColumnRenameClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/ColumnRenameClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.FeNameFormat;
@@ -30,6 +31,7 @@ public class ColumnRenameClause extends AlterTableClause {
private String newColName;
public ColumnRenameClause(String colName, String newColName) {
+ super(AlterOpType.SCHEMA_CHANGE);
this.colName = colName;
this.newColName = newColName;
this.needTableStable = false;
diff --git a/fe/src/main/java/org/apache/doris/analysis/CreateIndexClause.java
b/fe/src/main/java/org/apache/doris/analysis/CreateIndexClause.java
index 97187f4..d1ff400 100644
--- a/fe/src/main/java/org/apache/doris/analysis/CreateIndexClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/CreateIndexClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.catalog.Index;
import org.apache.doris.common.AnalysisException;
@@ -36,10 +37,10 @@ public class CreateIndexClause extends AlterTableClause {
private Index index;
public CreateIndexClause(TableName tableName, IndexDef indexDef, boolean
alter) {
+ super(AlterOpType.SCHEMA_CHANGE);
this.tableName = tableName;
this.indexDef = indexDef;
this.alter = alter;
- this.needTableStable = true;
}
@Override
diff --git a/fe/src/main/java/org/apache/doris/analysis/DropColumnClause.java
b/fe/src/main/java/org/apache/doris/analysis/DropColumnClause.java
index 14f7061..911a7f5 100644
--- a/fe/src/main/java/org/apache/doris/analysis/DropColumnClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/DropColumnClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
@@ -41,6 +42,7 @@ public class DropColumnClause extends AlterTableClause {
}
public DropColumnClause(String colName, String rollupName, Map<String,
String> properties) {
+ super(AlterOpType.SCHEMA_CHANGE);
this.colName = colName;
this.rollupName = rollupName;
this.properties = properties;
diff --git a/fe/src/main/java/org/apache/doris/analysis/DropIndexClause.java
b/fe/src/main/java/org/apache/doris/analysis/DropIndexClause.java
index 40d5665..f5f4a20 100644
--- a/fe/src/main/java/org/apache/doris/analysis/DropIndexClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/DropIndexClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.UserException;
@@ -30,10 +31,10 @@ public class DropIndexClause extends AlterTableClause {
private boolean alter;
public DropIndexClause(String indexName, TableName tableName, boolean
alter) {
+ super(AlterOpType.SCHEMA_CHANGE);
this.indexName = indexName;
this.tableName = tableName;
this.alter = alter;
- this.needTableStable = true;
}
public String getIndexName() {
diff --git
a/fe/src/main/java/org/apache/doris/analysis/DropPartitionClause.java
b/fe/src/main/java/org/apache/doris/analysis/DropPartitionClause.java
index 90ca887..543bcea 100644
--- a/fe/src/main/java/org/apache/doris/analysis/DropPartitionClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/DropPartitionClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
@@ -33,6 +34,7 @@ public class DropPartitionClause extends AlterTableClause {
private boolean isTempPartition;
public DropPartitionClause(boolean ifExists, String partitionName, boolean
isTempPartition) {
+ super(AlterOpType.DROP_PARTITION);
this.ifExists = ifExists;
this.partitionName = partitionName;
this.isTempPartition = isTempPartition;
diff --git a/fe/src/main/java/org/apache/doris/analysis/DropRollupClause.java
b/fe/src/main/java/org/apache/doris/analysis/DropRollupClause.java
index f8f24e2..5929136 100644
--- a/fe/src/main/java/org/apache/doris/analysis/DropRollupClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/DropRollupClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import com.google.common.base.Strings;
@@ -29,6 +30,7 @@ public class DropRollupClause extends AlterTableClause {
private Map<String, String> properties;
public DropRollupClause(String rollupName, Map<String, String> properties)
{
+ super(AlterOpType.DROP_ROLLUP);
this.rollupName = rollupName;
this.properties = properties;
this.needTableStable = false;
diff --git a/fe/src/main/java/org/apache/doris/analysis/FrontendClause.java
b/fe/src/main/java/org/apache/doris/analysis/FrontendClause.java
index ab631e1..4bfcfef 100644
--- a/fe/src/main/java/org/apache/doris/analysis/FrontendClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/FrontendClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
@@ -41,6 +42,7 @@ public class FrontendClause extends AlterClause {
protected FrontendNodeType role;
protected FrontendClause(String hostPort, FrontendNodeType role) {
+ super(AlterOpType.ALTER_OTHER);
this.hostPort = hostPort;
this.role = role;
}
diff --git a/fe/src/main/java/org/apache/doris/analysis/IndexDef.java
b/fe/src/main/java/org/apache/doris/analysis/IndexDef.java
index 683cfd6..19a63a9 100644
--- a/fe/src/main/java/org/apache/doris/analysis/IndexDef.java
+++ b/fe/src/main/java/org/apache/doris/analysis/IndexDef.java
@@ -17,9 +17,6 @@
package org.apache.doris.analysis;
-import java.util.List;
-import java.util.TreeSet;
-
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.KeysType;
import org.apache.doris.catalog.PrimitiveType;
@@ -27,6 +24,9 @@ import org.apache.doris.common.AnalysisException;
import com.google.common.base.Strings;
+import java.util.List;
+import java.util.TreeSet;
+
public class IndexDef {
private String indexName;
private List<String> columns;
@@ -136,6 +136,8 @@ public class IndexDef {
"BITMAP index only used in columns of DUP_KEYS table
or key columns of"
+ " UNIQUE_KEYS/AGG_KEYS table. invalid
column: " + indexColName);
}
+ } else {
+ throw new AnalysisException("Unsupported index type: " +
indexType);
}
}
diff --git a/fe/src/main/java/org/apache/doris/analysis/ModifyBrokerClause.java
b/fe/src/main/java/org/apache/doris/analysis/ModifyBrokerClause.java
index 7e00586..c073d5f 100644
--- a/fe/src/main/java/org/apache/doris/analysis/ModifyBrokerClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/ModifyBrokerClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Pair;
import org.apache.doris.system.SystemInfoService;
@@ -24,6 +25,7 @@ import org.apache.doris.system.SystemInfoService;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
+
import org.apache.commons.lang.NotImplementedException;
import java.util.List;
@@ -44,6 +46,7 @@ public class ModifyBrokerClause extends AlterClause {
protected Set<Pair<String, Integer>> hostPortPairs;
public ModifyBrokerClause(ModifyOp op, String brokerName, List<String>
hostPorts) {
+ super(AlterOpType.ALTER_OTHER);
this.op = op;
this.brokerName = brokerName;
this.hostPorts = hostPorts;
diff --git a/fe/src/main/java/org/apache/doris/analysis/ModifyColumnClause.java
b/fe/src/main/java/org/apache/doris/analysis/ModifyColumnClause.java
index 9f0ace6..9783396 100644
--- a/fe/src/main/java/org/apache/doris/analysis/ModifyColumnClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/ModifyColumnClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.catalog.Column;
import org.apache.doris.common.AnalysisException;
@@ -48,6 +49,7 @@ public class ModifyColumnClause extends AlterTableClause {
public ModifyColumnClause(ColumnDef columnDef, ColumnPosition colPos,
String rollup,
Map<String, String> properties) {
+ super(AlterOpType.SCHEMA_CHANGE);
this.columnDef = columnDef;
this.colPos = colPos;
this.rollupName = rollup;
diff --git
a/fe/src/main/java/org/apache/doris/analysis/ModifyPartitionClause.java
b/fe/src/main/java/org/apache/doris/analysis/ModifyPartitionClause.java
index 5d95ed6..6f9c21f 100644
--- a/fe/src/main/java/org/apache/doris/analysis/ModifyPartitionClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/ModifyPartitionClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.util.PrintableMap;
@@ -35,13 +36,14 @@ public class ModifyPartitionClause extends AlterTableClause
{
}
public ModifyPartitionClause(String partitionName, Map<String, String>
properties) {
+ super(AlterOpType.MODIFY_PARTITION);
this.partitionName = partitionName;
this.properties = properties;
// ATTN: currently, modify partition only allow 3 kinds of operations:
// 1. modify replication num
// 2. modify data property
// 3. modify in memory
- // And these 2 operations does not require table to be stable.
+ // And these 3 operations does not require table to be stable.
// If other kinds of operations be added later, "needTableStable" may
be changed.
this.needTableStable = false;
}
diff --git
a/fe/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java
b/fe/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java
index 71fa4cb..63de337 100644
---
a/fe/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java
+++
b/fe/src/main/java/org/apache/doris/analysis/ModifyTablePropertiesClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.catalog.TableProperty;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
@@ -32,6 +33,7 @@ public class ModifyTablePropertiesClause extends
AlterTableClause {
private Map<String, String> properties;
public ModifyTablePropertiesClause(Map<String, String> properties) {
+ super(AlterOpType.MODIFY_TABLE_PROPERTY);
this.properties = properties;
}
@@ -87,6 +89,7 @@ public class ModifyTablePropertiesClause extends
AlterTableClause {
properties.remove(defaultReplicationNumName);
} else if
(properties.containsKey(PropertyAnalyzer.PROPERTIES_INMEMORY)) {
this.needTableStable = false;
+ this.opType = AlterOpType.MODIFY_TABLE_PROPERTY_SYNC;
} else {
throw new AnalysisException("Unknown table property: " +
properties.keySet());
}
diff --git
a/fe/src/main/java/org/apache/doris/analysis/PartitionRenameClause.java
b/fe/src/main/java/org/apache/doris/analysis/PartitionRenameClause.java
index c19dae9..e3cf839 100644
--- a/fe/src/main/java/org/apache/doris/analysis/PartitionRenameClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/PartitionRenameClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.FeNameFormat;
@@ -30,6 +31,7 @@ public class PartitionRenameClause extends AlterTableClause {
private String newPartitionName;
public PartitionRenameClause(String partitionName, String
newPartitionName) {
+ super(AlterOpType.RENAME);
this.partitionName = partitionName;
this.newPartitionName = newPartitionName;
this.needTableStable = false;
diff --git
a/fe/src/main/java/org/apache/doris/analysis/ReorderColumnsClause.java
b/fe/src/main/java/org/apache/doris/analysis/ReorderColumnsClause.java
index d16498b..0d63072 100644
--- a/fe/src/main/java/org/apache/doris/analysis/ReorderColumnsClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/ReorderColumnsClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import com.google.common.base.Strings;
@@ -40,6 +41,7 @@ public class ReorderColumnsClause extends AlterTableClause {
}
public ReorderColumnsClause(List<String> cols, String rollup, Map<String,
String> properties) {
+ super(AlterOpType.SCHEMA_CHANGE);
this.columnsByPos = cols;
this.rollupName = rollup;
this.properties = properties;
diff --git
a/fe/src/main/java/org/apache/doris/analysis/ReplacePartitionClause.java
b/fe/src/main/java/org/apache/doris/analysis/ReplacePartitionClause.java
index a7002ad..ddb347e 100644
--- a/fe/src/main/java/org/apache/doris/analysis/ReplacePartitionClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/ReplacePartitionClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.util.PropertyAnalyzer;
@@ -53,6 +54,7 @@ public class ReplacePartitionClause extends AlterTableClause {
public ReplacePartitionClause(PartitionNames partitionNames,
PartitionNames tempPartitionNames,
Map<String, String> properties) {
+ super(AlterOpType.REPLACE_PARTITION);
this.partitionNames = partitionNames;
this.tempPartitionNames = tempPartitionNames;
this.needTableStable = false;
diff --git a/fe/src/main/java/org/apache/doris/analysis/RollupRenameClause.java
b/fe/src/main/java/org/apache/doris/analysis/RollupRenameClause.java
index f7a6918..a51dff3 100644
--- a/fe/src/main/java/org/apache/doris/analysis/RollupRenameClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/RollupRenameClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.FeNameFormat;
@@ -30,6 +31,7 @@ public class RollupRenameClause extends AlterTableClause {
private String newRollupName;
public RollupRenameClause(String rollupName, String newRollupName) {
+ super(AlterOpType.RENAME);
this.rollupName = rollupName;
this.newRollupName = newRollupName;
this.needTableStable = false;
diff --git a/fe/src/main/java/org/apache/doris/analysis/TableRenameClause.java
b/fe/src/main/java/org/apache/doris/analysis/TableRenameClause.java
index 08bf4ba..e35eff7 100644
--- a/fe/src/main/java/org/apache/doris/analysis/TableRenameClause.java
+++ b/fe/src/main/java/org/apache/doris/analysis/TableRenameClause.java
@@ -17,6 +17,7 @@
package org.apache.doris.analysis;
+import org.apache.doris.alter.AlterOpType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.FeNameFormat;
@@ -29,6 +30,7 @@ public class TableRenameClause extends AlterTableClause {
private String newTableName;
public TableRenameClause(String newTableName) {
+ super(AlterOpType.RENAME);
this.newTableName = newTableName;
this.needTableStable = false;
}
diff --git a/fe/src/main/java/org/apache/doris/catalog/Catalog.java
b/fe/src/main/java/org/apache/doris/catalog/Catalog.java
index f719e9e..2cbcee2 100644
--- a/fe/src/main/java/org/apache/doris/catalog/Catalog.java
+++ b/fe/src/main/java/org/apache/doris/catalog/Catalog.java
@@ -3229,7 +3229,7 @@ public class Catalog {
}
}
- public void modifyPartition(Database db, OlapTable olapTable, String
partitionName, Map<String, String> properties)
+ public void modifyPartitionProperty(Database db, OlapTable olapTable,
String partitionName, Map<String, String> properties)
throws DdlException {
Preconditions.checkArgument(db.isWriteLockHeldByCurrentThread());
if (olapTable.getState() != OlapTableState.NORMAL) {
diff --git
a/fe/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java
b/fe/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java
index 106ed9c..4df2ed8 100644
--- a/fe/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java
+++ b/fe/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java
@@ -84,7 +84,6 @@ public class DynamicPartitionScheduler extends MasterDaemon {
ERROR
}
-
public DynamicPartitionScheduler(String name, long intervalMs) {
super(name, intervalMs);
this.initialize = false;
diff --git a/fe/src/main/java/org/apache/doris/common/ErrorCode.java
b/fe/src/main/java/org/apache/doris/common/ErrorCode.java
index f3b32dd..9a6ecc8 100644
--- a/fe/src/main/java/org/apache/doris/common/ErrorCode.java
+++ b/fe/src/main/java/org/apache/doris/common/ErrorCode.java
@@ -210,7 +210,7 @@ public enum ErrorCode {
"Table %s is not a colocated table"),
ERR_INVALID_OPERATION(5065, new byte[] { '4', '2', '0', '0', '0' },
"Operation %s is invalid"),
ERROR_DYNAMIC_PARTITION_TIME_UNIT(5065, new byte[] {'4', '2', '0', '0',
'0'},
- "Unsupported time unit %s. Expect DAY WEEK MONTH."),
+ "Unsupported time unit %s. Expect DAY/WEEK/MONTH."),
ERROR_DYNAMIC_PARTITION_START_ZERO(5066, new byte[] {'4', '2', '0', '0',
'0'},
"Dynamic partition start must less than 0"),
ERROR_DYNAMIC_PARTITION_START_FORMAT(5066, new byte[] {'4', '2', '0', '0',
'0'},
diff --git
a/fe/src/main/java/org/apache/doris/common/util/DynamicPartitionUtil.java
b/fe/src/main/java/org/apache/doris/common/util/DynamicPartitionUtil.java
index 3e45110..03c41d9 100644
--- a/fe/src/main/java/org/apache/doris/common/util/DynamicPartitionUtil.java
+++ b/fe/src/main/java/org/apache/doris/common/util/DynamicPartitionUtil.java
@@ -36,9 +36,10 @@ import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.FeNameFormat;
+import com.google.common.base.Strings;
+
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import com.google.common.base.Strings;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -145,7 +146,7 @@ public class DynamicPartitionUtil {
Strings.isNullOrEmpty(end) &&
Strings.isNullOrEmpty(buckets)))) {
if (Strings.isNullOrEmpty(enable)) {
- throw new DdlException("Must assign dynamic_partition.enable
properties");
+ properties.put(DynamicPartitionProperty.ENABLE, "true");
}
if (Strings.isNullOrEmpty(timeUnit)) {
throw new DdlException("Must assign
dynamic_partition.time_unit properties");
@@ -225,7 +226,7 @@ public class DynamicPartitionUtil {
if (tableProperty != null &&
tableProperty.getDynamicPartitionProperty() != null &&
tableProperty.getDynamicPartitionProperty().isExist() &&
tableProperty.getDynamicPartitionProperty().getEnable()) {
- throw new DdlException("Cannot modify partition on a Dynamic
Partition Table, set `dynamic_partition.enable` to false firstly.");
+ throw new DdlException("Cannot add/drop partition on a Dynamic
Partition Table, set `dynamic_partition.enable` to false firstly.");
}
}
diff --git a/fe/src/test/java/org/apache/doris/alter/AlterTest.java
b/fe/src/test/java/org/apache/doris/alter/AlterTest.java
new file mode 100644
index 0000000..a129162
--- /dev/null
+++ b/fe/src/test/java/org/apache/doris/alter/AlterTest.java
@@ -0,0 +1,190 @@
+// 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.
+
+package org.apache.doris.alter;
+
+import org.apache.doris.analysis.AlterTableStmt;
+import org.apache.doris.analysis.CreateDbStmt;
+import org.apache.doris.analysis.CreateTableStmt;
+import org.apache.doris.catalog.Catalog;
+import org.apache.doris.catalog.Database;
+import org.apache.doris.catalog.OlapTable;
+import org.apache.doris.common.Config;
+import org.apache.doris.common.FeConstants;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.utframe.UtFrameUtils;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.Map;
+import java.util.UUID;
+
+public class AlterTest {
+
+ private static String runningDir = "fe/mocked/AlterTest/" +
UUID.randomUUID().toString() + "/";
+
+ private static ConnectContext connectContext;
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ FeConstants.runningUnitTest = true;
+ FeConstants.default_scheduler_interval_millisecond = 100;
+ Config.dynamic_partition_enable = true;
+ UtFrameUtils.createMinDorisCluster(runningDir);
+
+ // create connect context
+ connectContext = UtFrameUtils.createDefaultCtx();
+ // create database
+ String createDbStmtStr = "create database test;";
+ CreateDbStmt createDbStmt = (CreateDbStmt)
UtFrameUtils.parseAndAnalyzeStmt(createDbStmtStr, connectContext);
+ Catalog.getCurrentCatalog().createDb(createDbStmt);
+
+ createTable("CREATE TABLE test.tbl1\n" +
+ "(\n" +
+ " k1 date,\n" +
+ " k2 int,\n" +
+ " v1 int sum\n" +
+ ")\n" +
+ "PARTITION BY RANGE(k1)\n" +
+ "(\n" +
+ " PARTITION p1 values less than('2020-02-01'),\n" +
+ " PARTITION p2 values less than('2020-03-01')\n" +
+ ")\n" +
+ "DISTRIBUTED BY HASH(k2) BUCKETS 3\n" +
+ "PROPERTIES('replication_num' = '1');");
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ File file = new File(runningDir);
+ file.delete();
+ }
+
+ private static void createTable(String sql) throws Exception {
+ CreateTableStmt createTableStmt = (CreateTableStmt)
UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
+ Catalog.getCurrentCatalog().createTable(createTableStmt);
+ }
+
+ private static void alterTable(String sql, boolean expectedException)
throws Exception {
+ AlterTableStmt alterTableStmt = (AlterTableStmt)
UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
+ try {
+ Catalog.getCurrentCatalog().alterTable(alterTableStmt);
+ if (expectedException) {
+ Assert.fail();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ if (!expectedException) {
+ Assert.fail();
+ }
+ }
+ }
+
+ @Test
+ public void testConflictAlterOperations() throws Exception {
+ String stmt = "alter table test.tbl1 add partition p3 values less
than('2020-04-01'), add partition p4 values less than('2020-05-01')";
+ alterTable(stmt, true);
+
+ stmt = "alter table test.tbl1 add partition p3 values less
than('2020-04-01'), drop partition p4";
+ alterTable(stmt, true);
+
+ stmt = "alter table test.tbl1 drop partition p3, drop partition p4";
+ alterTable(stmt, true);
+
+ stmt = "alter table test.tbl1 drop partition p3, add column k3 int";
+ alterTable(stmt, true);
+
+ // no conflict
+ stmt = "alter table test.tbl1 add column k3 int, add column k4 int";
+ alterTable(stmt, false);
+ waitSchemaChangeJobDone(false);
+
+ stmt = "alter table test.tbl1 add rollup r1 (k1)";
+ alterTable(stmt, false);
+ waitSchemaChangeJobDone(true);
+
+ stmt = "alter table test.tbl1 add rollup r2 (k1), r3 (k1)";
+ alterTable(stmt, false);
+ waitSchemaChangeJobDone(true);
+
+ // enable dynamic partition
+ stmt = "alter table test.tbl1 set (\n" +
+ "'dynamic_partition.enable' = 'true',\n" +
+ "'dynamic_partition.time_unit' = 'DAY',\n" +
+ "'dynamic_partition.start' = '-3',\n" +
+ "'dynamic_partition.end' = '3',\n" +
+ "'dynamic_partition.prefix' = 'p',\n" +
+ "'dynamic_partition.buckets' = '3'\n" +
+ " );";
+ alterTable(stmt, false);
+ Database db =
Catalog.getCurrentCatalog().getDb("default_cluster:test");
+ OlapTable tbl = (OlapTable)db.getTable("tbl1");
+
Assert.assertTrue(tbl.getTableProperty().getDynamicPartitionProperty().getEnable());
+ Assert.assertEquals(4, tbl.getIndexIdToSchema().size());
+
+ // add partition when dynamic partition is enable
+ stmt = "alter table test.tbl1 add partition p3 values less
than('2020-04-01') distributed by hash(k2) buckets 4 PROPERTIES
('replication_num' = '1')";
+ alterTable(stmt, true);
+
+ // add temp partition when dynamic partition is enable
+ stmt = "alter table test.tbl1 add temporary partition tp3 values less
than('2020-04-01') distributed by hash(k2) buckets 4 PROPERTIES
('replication_num' = '1')";
+ alterTable(stmt, false);
+ Assert.assertEquals(1, tbl.getTempPartitions().size());
+
+ // disable the dynamic partition
+ stmt = "alter table test.tbl1 set ('dynamic_partition.enable' =
'false')";
+ alterTable(stmt, false);
+
Assert.assertFalse(tbl.getTableProperty().getDynamicPartitionProperty().getEnable());
+
+ // add partition when dynamic partition is disable
+ stmt = "alter table test.tbl1 add partition p3 values less
than('2020-04-01') distributed by hash(k2) buckets 4";
+ alterTable(stmt, false);
+
+ // set table's default replication num
+ Assert.assertEquals(Short.valueOf("1"),
tbl.getDefaultReplicationNum());
+ stmt = "alter table test.tbl1 set ('default.replication_num' = '3');";
+ alterTable(stmt, false);
+ Assert.assertEquals(Short.valueOf("3"),
tbl.getDefaultReplicationNum());
+
+ // add partition without set replication num
+ stmt = "alter table test.tbl1 add partition p4 values less
than('2020-05-01')";
+ alterTable(stmt, true);
+
+ // add partition when dynamic partition is disable
+ stmt = "alter table test.tbl1 add partition p4 values less
than('2020-05-01') ('replication_num' = '1')";
+ alterTable(stmt, false);
+ }
+
+ private void waitSchemaChangeJobDone(boolean rollupJob) throws
InterruptedException {
+ Map<Long, AlterJobV2> alterJobs =
Catalog.getCurrentCatalog().getSchemaChangeHandler().getAlterJobsV2();
+ if (rollupJob) {
+ alterJobs =
Catalog.getCurrentCatalog().getRollupHandler().getAlterJobsV2();
+ }
+ for (AlterJobV2 alterJobV2 : alterJobs.values()) {
+ while (!alterJobV2.getJobState().isFinalState()) {
+ System.out.println("alter job " + alterJobV2.getJobId() + " is
running. state: " + alterJobV2.getJobState());
+ Thread.sleep(1000);
+ }
+ System.out.println(alterJobV2.getType() + " alter job " +
alterJobV2.getJobId() + " is done. state: " + alterJobV2.getJobState());
+ Assert.assertEquals(AlterJobV2.JobState.FINISHED,
alterJobV2.getJobState());
+ }
+ }
+}
diff --git
a/fe/src/test/java/org/apache/doris/catalog/DynamicPartitionTableTest.java
b/fe/src/test/java/org/apache/doris/catalog/DynamicPartitionTableTest.java
index 318e282..c65277e 100644
--- a/fe/src/test/java/org/apache/doris/catalog/DynamicPartitionTableTest.java
+++ b/fe/src/test/java/org/apache/doris/catalog/DynamicPartitionTableTest.java
@@ -1,10 +1,5 @@
package org.apache.doris.catalog;
-import com.google.common.collect.Lists;
-import mockit.Expectations;
-import mockit.Injectable;
-import mockit.Mock;
-import mockit.MockUp;
import org.apache.doris.analysis.Analyzer;
import org.apache.doris.analysis.ColumnDef;
import org.apache.doris.analysis.CreateTableStmt;
@@ -24,6 +19,9 @@ import org.apache.doris.persist.EditLog;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.system.SystemInfoService;
import org.apache.doris.task.AgentBatchTask;
+
+import com.google.common.collect.Lists;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -36,6 +34,11 @@ import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import mockit.Expectations;
+import mockit.Injectable;
+import mockit.Mock;
+import mockit.MockUp;
+
public class DynamicPartitionTableTest {
private TableName dbTableName;
private String dbName = "testDb";
@@ -154,53 +157,6 @@ public class DynamicPartitionTableTest {
}
@Test
- public void testMissEnable(@Injectable SystemInfoService systemInfoService,
- @Injectable PaloAuth paloAuth,
- @Injectable EditLog editLog) throws
UserException {
- new Expectations(catalog) {
- {
- catalog.getDb(dbTableName.getDb());
- minTimes = 0;
- result = db;
-
- Catalog.getCurrentSystemInfo();
- minTimes = 0;
- result = systemInfoService;
-
- systemInfoService.checkClusterCapacity(anyString);
- minTimes = 0;
- systemInfoService.seqChooseBackendIds(anyInt, true, true,
anyString);
- minTimes = 0;
- result = beIds;
-
- catalog.getAuth();
- minTimes = 0;
- result = paloAuth;
- paloAuth.checkTblPriv((ConnectContext) any, anyString,
anyString, PrivPredicate.CREATE);
- minTimes = 0;
- result = true;
-
- catalog.getEditLog();
- minTimes = 0;
- result = editLog;
- }
- };
-
- properties.remove(DynamicPartitionProperty.ENABLE);
-
- CreateTableStmt stmt = new CreateTableStmt(false, false, dbTableName,
columnDefs, "olap",
- new KeysDesc(KeysType.AGG_KEYS, columnNames),
- new RangePartitionDesc(Lists.newArrayList("key1"),
singleRangePartitionDescs),
- new HashDistributionDesc(1, Lists.newArrayList("key1")),
properties, null, "");
- stmt.analyze(analyzer);
-
- expectedEx.expect(DdlException.class);
- expectedEx.expectMessage("Must assign dynamic_partition.enable
properties");
-
- catalog.createTable(stmt);
- }
-
- @Test
public void testMissPrefix(@Injectable SystemInfoService systemInfoService,
@Injectable PaloAuth paloAuth,
@Injectable EditLog editLog) throws
UserException {
diff --git a/fe/src/test/java/org/apache/doris/utframe/DemoTest.java
b/fe/src/test/java/org/apache/doris/utframe/DemoTest.java
index dfa293b..499f959 100644
--- a/fe/src/test/java/org/apache/doris/utframe/DemoTest.java
+++ b/fe/src/test/java/org/apache/doris/utframe/DemoTest.java
@@ -109,10 +109,10 @@ public class DemoTest {
Assert.assertEquals(1, alterJobs.size());
for (AlterJobV2 alterJobV2 : alterJobs.values()) {
while (!alterJobV2.getJobState().isFinalState()) {
- System.out.println("alter job " + alterJobV2.getDbId() + " is
running. state: " + alterJobV2.getJobState());
+ System.out.println("alter job " + alterJobV2.getJobId() + " is
running. state: " + alterJobV2.getJobState());
Thread.sleep(1000);
}
- System.out.println("alter job " + alterJobV2.getDbId() + " is
done. state: " + alterJobV2.getJobState());
+ System.out.println("alter job " + alterJobV2.getJobId() + " is
done. state: " + alterJobV2.getJobState());
Assert.assertEquals(AlterJobV2.JobState.FINISHED,
alterJobV2.getJobState());
}
db.readLock();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]