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/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 13780e4827d [fix](nereids)(create-table) fix bug that replication num
is not set when create table with no property (#25651)
13780e4827d is described below
commit 13780e4827db38494f2f3fb168f3195163a18fc1
Author: Mingyu Chen <[email protected]>
AuthorDate: Sat Oct 21 23:15:08 2023 +0800
[fix](nereids)(create-table) fix bug that replication num is not set when
create table with no property (#25651)
When executing create partitioned table with Nereids, and replication_num
property is not set,
the replication number will be 0, so the tablet will has no replica.
---
.../org/apache/doris/analysis/CreateTableStmt.java | 75 +-------------
.../apache/doris/common/util/PropertyAnalyzer.java | 72 ++++++++++++++
.../doris/nereids/parser/LogicalPlanBuilder.java | 11 ++-
.../trees/plans/commands/info/CreateTableInfo.java | 45 ++++++---
.../plans/commands/info/FixedRangePartition.java | 10 +-
.../trees/plans/commands/info/InPartition.java | 9 +-
.../plans/commands/info/LessThanPartition.java | 10 +-
.../plans/commands/info/PartitionDefinition.java | 22 ++++-
.../trees/plans/commands/info/StepPartition.java | 9 +-
.../org/apache/doris/catalog/CreateTableTest.java | 110 +++++++++++++--------
.../org/apache/doris/common/ExceptionChecker.java | 1 +
.../apache/doris/utframe/TestWithFeService.java | 37 +++++--
12 files changed, 240 insertions(+), 171 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableStmt.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableStmt.java
index a03884f5c6e..f56de294d98 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableStmt.java
@@ -20,13 +20,11 @@ package org.apache.doris.analysis;
import org.apache.doris.analysis.IndexDef.IndexType;
import org.apache.doris.catalog.AggregateType;
import org.apache.doris.catalog.Column;
-import org.apache.doris.catalog.DatabaseIf;
import org.apache.doris.catalog.DistributionInfo;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.Index;
import org.apache.doris.catalog.KeysType;
import org.apache.doris.catalog.PrimitiveType;
-import org.apache.doris.catalog.ReplicaAllocation;
import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
@@ -41,7 +39,6 @@ import org.apache.doris.common.util.ParseUtil;
import org.apache.doris.common.util.PrintableMap;
import org.apache.doris.common.util.PropertyAnalyzer;
import org.apache.doris.common.util.Util;
-import org.apache.doris.datasource.CatalogIf;
import org.apache.doris.external.elasticsearch.EsUtil;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;
@@ -51,7 +48,6 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -559,7 +555,8 @@ public class CreateTableStmt extends DdlStmt {
if (engineName.equals("olap")) {
// before analyzing partition, handle the replication allocation
info
- properties = rewriteReplicaAllocationProperties(properties);
+ properties = PropertyAnalyzer.rewriteReplicaAllocationProperties(
+ tableName.getCtl(), tableName.getDb(), properties);
// analyze partition
if (partitionDesc != null) {
if (partitionDesc instanceof ListPartitionDesc ||
partitionDesc instanceof RangePartitionDesc
@@ -650,74 +647,6 @@ public class CreateTableStmt extends DdlStmt {
}
}
- private Map<String, String> rewriteReplicaAllocationProperties(Map<String,
String> properties)
- throws AnalysisException {
- if (Config.force_olap_table_replication_num <= 0) {
- return rewriteReplicaAllocationPropertiesByDatabase(properties);
- }
- // if force_olap_table_replication_num is set, use this value to
rewrite the replication_num or
- // replication_allocation properties
- Map<String, String> newProperties = properties;
- if (newProperties == null) {
- newProperties = Maps.newHashMap();
- }
- boolean rewrite = false;
- if
(newProperties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM)) {
- newProperties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM,
- String.valueOf(Config.force_olap_table_replication_num));
- rewrite = true;
- }
- if
(newProperties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION))
{
-
newProperties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION,
- new ReplicaAllocation((short)
Config.force_olap_table_replication_num).toCreateStmt());
- rewrite = true;
- }
- if (!rewrite) {
- newProperties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM,
- String.valueOf(Config.force_olap_table_replication_num));
- }
- return newProperties;
- }
-
- private Map<String, String>
rewriteReplicaAllocationPropertiesByDatabase(Map<String, String> properties)
- throws AnalysisException {
- // if table contain `replication_allocation` or
`replication_allocation`,not need rewrite by db
- if (properties != null &&
(properties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION)
- ||
properties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM))) {
- return properties;
- }
- CatalogIf catalog =
Env.getCurrentEnv().getCatalogMgr().getCatalogNullable(tableName.getCtl());
- if (catalog == null) {
- return properties;
- }
- DatabaseIf db = catalog.getDbNullable(tableName.getDb());
- if (db == null) {
- return properties;
- }
- // if db not have properties,not need rewrite
- if (db.getDbProperties() == null) {
- return properties;
- }
- Map<String, String> dbProperties =
db.getDbProperties().getProperties();
- if (dbProperties == null) {
- return properties;
- }
- if (properties == null) {
- properties = Maps.newHashMap();
- }
- if
(dbProperties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION)
&& StringUtils
-
.isNotEmpty(dbProperties.get(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION)))
{
- properties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION,
-
dbProperties.get(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION));
- }
- if
(dbProperties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM) &&
StringUtils
-
.isNotEmpty(dbProperties.get(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM))) {
- properties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM,
-
dbProperties.get(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM));
- }
- return properties;
- }
-
private void analyzeEngineName() throws AnalysisException {
if (Strings.isNullOrEmpty(engineName)) {
engineName = "olap";
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 a3f2202246f..5e037c2e3b8 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
@@ -21,6 +21,7 @@ import org.apache.doris.analysis.DataSortInfo;
import org.apache.doris.analysis.DateLiteral;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.DataProperty;
+import org.apache.doris.catalog.DatabaseIf;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.EsResource;
import org.apache.doris.catalog.KeysType;
@@ -32,6 +33,7 @@ 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.datasource.CatalogIf;
import org.apache.doris.datasource.CatalogMgr;
import org.apache.doris.policy.Policy;
import org.apache.doris.policy.StoragePolicy;
@@ -48,6 +50,7 @@ import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -1176,4 +1179,73 @@ public class PropertyAnalyzer {
}
}
}
+
+ public static Map<String, String> rewriteReplicaAllocationProperties(
+ String ctl, String db, Map<String, String> properties) {
+ if (Config.force_olap_table_replication_num <= 0) {
+ return rewriteReplicaAllocationPropertiesByDatabase(ctl, db,
properties);
+ }
+ // if force_olap_table_replication_num is set, use this value to
rewrite the replication_num or
+ // replication_allocation properties
+ Map<String, String> newProperties = properties;
+ if (newProperties == null) {
+ newProperties = Maps.newHashMap();
+ }
+ boolean rewrite = false;
+ if
(newProperties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM)) {
+ newProperties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM,
+ String.valueOf(Config.force_olap_table_replication_num));
+ rewrite = true;
+ }
+ if
(newProperties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION))
{
+
newProperties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION,
+ new ReplicaAllocation((short)
Config.force_olap_table_replication_num).toCreateStmt());
+ rewrite = true;
+ }
+ if (!rewrite) {
+ newProperties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM,
+ String.valueOf(Config.force_olap_table_replication_num));
+ }
+ return newProperties;
+ }
+
+ private static Map<String, String>
rewriteReplicaAllocationPropertiesByDatabase(
+ String ctl, String database, Map<String, String> properties) {
+ // if table contain `replication_allocation` or
`replication_allocation`,not need rewrite by db
+ if (properties != null &&
(properties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION)
+ ||
properties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM))) {
+ return properties;
+ }
+ CatalogIf catalog =
Env.getCurrentEnv().getCatalogMgr().getCatalogNullable(ctl);
+ if (catalog == null) {
+ return properties;
+ }
+ DatabaseIf db = catalog.getDbNullable(database);
+ if (db == null) {
+ return properties;
+ }
+ // if db not have properties,not need rewrite
+ if (db.getDbProperties() == null) {
+ return properties;
+ }
+ Map<String, String> dbProperties =
db.getDbProperties().getProperties();
+ if (dbProperties == null) {
+ return properties;
+ }
+ if (properties == null) {
+ properties = Maps.newHashMap();
+ }
+ if
(dbProperties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION)
&& StringUtils
+
.isNotEmpty(dbProperties.get(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION)))
{
+ properties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION,
+
dbProperties.get(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION));
+ }
+ if
(dbProperties.containsKey(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM) &&
StringUtils
+
.isNotEmpty(dbProperties.get(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM))) {
+ properties.put(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM,
+
dbProperties.get(PropertyAnalyzer.PROPERTIES_REPLICATION_NUM));
+ }
+ return properties;
+ }
+
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index 734a215888b..b817803f23c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -1865,8 +1865,9 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
@Override
public LogicalPlan visitCreateTable(CreateTableContext ctx) {
+ String ctlName = null;
String dbName = null;
- String tableName;
+ String tableName = null;
List<String> nameParts = visitMultipartIdentifier(ctx.name);
// TODO: support catalog
if (nameParts.size() == 1) {
@@ -1874,8 +1875,12 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
} else if (nameParts.size() == 2) {
dbName = nameParts.get(0);
tableName = nameParts.get(1);
+ } else if (nameParts.size() == 3) {
+ ctlName = nameParts.get(0);
+ dbName = nameParts.get(1);
+ tableName = nameParts.get(2);
} else {
- throw new AnalysisException("nameParts in create table should be 1
or 2");
+ throw new AnalysisException("nameParts in create table should be
[ctl.][db.]tbl");
}
KeysType keysType = null;
if (ctx.DUPLICATE() != null) {
@@ -1906,6 +1911,7 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
}
return new CreateTableCommand(Optional.empty(), new
CreateTableInfo(
ctx.EXISTS() != null,
+ ctlName,
dbName,
tableName,
visitColumnDefs(ctx.columnDefs()),
@@ -1923,6 +1929,7 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
} else if (ctx.AS() != null) {
return new
CreateTableCommand(Optional.of(visitQuery(ctx.query())), new CreateTableInfo(
ctx.EXISTS() != null,
+ ctlName,
dbName,
tableName,
ctx.ctasCols != null ? visitIdentifierList(ctx.ctasCols) :
null,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
index f398c7b7d12..af11d4944cd 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
@@ -30,17 +30,21 @@ import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.Index;
import org.apache.doris.catalog.KeysType;
+import org.apache.doris.catalog.PartitionType;
import org.apache.doris.catalog.Type;
import org.apache.doris.cluster.ClusterNamespace;
import org.apache.doris.common.Config;
import org.apache.doris.common.FeConstants;
import org.apache.doris.common.FeNameFormat;
import org.apache.doris.common.util.PropertyAnalyzer;
+import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.util.Utils;
import org.apache.doris.qe.ConnectContext;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -57,6 +61,7 @@ import java.util.stream.Collectors;
*/
public class CreateTableInfo {
private final boolean ifNotExists;
+ private String ctlName;
private String dbName;
private final String tableName;
private List<ColumnDefinition> columns;
@@ -77,11 +82,13 @@ public class CreateTableInfo {
/**
* constructor for create table
*/
- public CreateTableInfo(boolean ifNotExists, String dbName, String
tableName, List<ColumnDefinition> columns,
- List<IndexDefinition> indexes, String engineName, KeysType
keysType, List<String> keys, String comment,
+ public CreateTableInfo(boolean ifNotExists, String ctlName, String dbName,
String tableName,
+ List<ColumnDefinition> columns, List<IndexDefinition> indexes,
String engineName,
+ KeysType keysType, List<String> keys, String comment,
String partitionType, List<String> partitionColumns,
List<PartitionDefinition> partitions,
DistributionDescriptor distribution, List<RollupDefinition>
rollups, Map<String, String> properties) {
this.ifNotExists = ifNotExists;
+ this.ctlName = ctlName;
this.dbName = dbName;
this.tableName = tableName;
this.ctasColumns = null;
@@ -102,11 +109,12 @@ public class CreateTableInfo {
/**
* constructor for create table as select
*/
- public CreateTableInfo(boolean ifNotExists, String dbName, String
tableName, List<String> cols,
+ public CreateTableInfo(boolean ifNotExists, String ctlName, String dbName,
String tableName, List<String> cols,
String engineName, KeysType keysType, List<String> keys, String
comment,
String partitionType, List<String> partitionColumns,
List<PartitionDefinition> partitions,
DistributionDescriptor distribution, List<RollupDefinition>
rollups, Map<String, String> properties) {
this.ifNotExists = ifNotExists;
+ this.ctlName = ctlName;
this.dbName = dbName;
this.tableName = tableName;
this.ctasColumns = cols;
@@ -128,6 +136,10 @@ public class CreateTableInfo {
return ctasColumns;
}
+ public String getCtlName() {
+ return ctlName;
+ }
+
public String getDbName() {
return dbName;
}
@@ -163,20 +175,30 @@ public class CreateTableInfo {
try {
FeNameFormat.checkTableName(tableName);
- if (dbName != null) {
- FeNameFormat.checkDbName(dbName);
- }
} catch (Exception e) {
throw new AnalysisException(e.getMessage(), e);
}
+ // analyze catalog name
+ if (Strings.isNullOrEmpty(ctlName)) {
+ if (ctx.getCurrentCatalog() != null) {
+ ctlName = ctx.getCurrentCatalog().getName();
+ } else {
+ ctlName = InternalCatalog.INTERNAL_CATALOG_NAME;
+ }
+ }
+
// analyze table name
- if (dbName == null) {
+ if (Strings.isNullOrEmpty(dbName)) {
dbName = ClusterNamespace.getFullName(ctx.getClusterName(),
ctx.getDatabase());
} else {
dbName = ClusterNamespace.getFullName(ctx.getClusterName(),
dbName);
}
+ Preconditions.checkState(!Strings.isNullOrEmpty(ctlName), "catalog
name is null or empty");
+ Preconditions.checkState(!Strings.isNullOrEmpty(dbName), "database
name is null or empty");
+ properties =
PropertyAnalyzer.rewriteReplicaAllocationProperties(ctlName, dbName,
properties);
+
boolean enableDuplicateWithoutKeysByDefault = false;
if (properties != null) {
try {
@@ -367,14 +389,15 @@ public class CreateTableInfo {
* check partitions types.
*/
private boolean checkPartitionsTypes() {
- if (partitionType.equalsIgnoreCase("RANGE")) {
+ if (partitionType.equalsIgnoreCase(PartitionType.RANGE.name())) {
if (partitions.stream().allMatch(p -> p instanceof StepPartition))
{
return true;
}
return partitions.stream().allMatch(p -> (p instanceof
LessThanPartition)
|| (p instanceof FixedRangePartition));
}
- return partitionType.equalsIgnoreCase("LIST") &&
partitions.stream().allMatch(p -> p instanceof InPartition);
+ return partitionType.equalsIgnoreCase(PartitionType.LIST.name())
+ && partitions.stream().allMatch(p -> p instanceof InPartition);
}
private void validatePartitionColumn(ColumnDefinition column,
ConnectContext ctx) {
@@ -395,7 +418,7 @@ public class CreateTableInfo {
if (!ctx.getSessionVariable().isAllowPartitionColumnNullable() &&
column.isNullable()) {
throw new AnalysisException("The partition column must be NOT
NULL");
}
- if (partitionType.equalsIgnoreCase("LIST") && column.isNullable()) {
+ if (partitionType.equalsIgnoreCase(PartitionType.LIST.name()) &&
column.isNullable()) {
throw new AnalysisException("The list partition column must be NOT
NULL");
}
}
@@ -415,7 +438,7 @@ public class CreateTableInfo {
List<AllPartitionDesc> partitionDescs = partitions.stream()
.map(PartitionDefinition::translateToCatalogStyle).collect(Collectors.toList());
try {
- if (partitionType.equals("RANGE")) {
+ if (partitionType.equals(PartitionType.RANGE.name())) {
partitionDesc = new RangePartitionDesc(partitionColumns,
partitionDescs);
} else {
partitionDesc = new ListPartitionDesc(partitionColumns,
partitionDescs);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/FixedRangePartition.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/FixedRangePartition.java
index 634f5c235dc..a1d74d20691 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/FixedRangePartition.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/FixedRangePartition.java
@@ -20,9 +20,6 @@ package org.apache.doris.nereids.trees.plans.commands.info;
import org.apache.doris.analysis.PartitionKeyDesc;
import org.apache.doris.analysis.PartitionValue;
import org.apache.doris.analysis.SinglePartitionDesc;
-import org.apache.doris.catalog.ReplicaAllocation;
-import org.apache.doris.common.util.PropertyAnalyzer;
-import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.types.DataType;
@@ -39,7 +36,6 @@ public class FixedRangePartition extends PartitionDefinition {
private final String partitionName;
private List<Expression> lowerBounds;
private List<Expression> upperBounds;
- private ReplicaAllocation replicaAllocation =
ReplicaAllocation.DEFAULT_ALLOCATION;
public FixedRangePartition(String partitionName, List<Expression>
lowerBounds, List<Expression> upperBounds) {
this.partitionName = partitionName;
@@ -49,11 +45,7 @@ public class FixedRangePartition extends PartitionDefinition
{
@Override
public void validate(Map<String, String> properties) {
- try {
- replicaAllocation =
PropertyAnalyzer.analyzeReplicaAllocation(properties, "");
- } catch (Exception e) {
- throw new AnalysisException(e.getMessage(), e.getCause());
- }
+ super.validate(properties);
final DataType type = partitionTypes.get(0);
lowerBounds = lowerBounds.stream().map(e ->
e.castTo(type)).collect(Collectors.toList());
upperBounds = upperBounds.stream().map(e ->
e.castTo(type)).collect(Collectors.toList());
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/InPartition.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/InPartition.java
index 900f521cabc..84821d99212 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/InPartition.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/InPartition.java
@@ -21,8 +21,6 @@ import org.apache.doris.analysis.AllPartitionDesc;
import org.apache.doris.analysis.PartitionKeyDesc;
import org.apache.doris.analysis.PartitionValue;
import org.apache.doris.analysis.SinglePartitionDesc;
-import org.apache.doris.catalog.ReplicaAllocation;
-import org.apache.doris.common.util.PropertyAnalyzer;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
@@ -38,7 +36,6 @@ import java.util.stream.Collectors;
public class InPartition extends PartitionDefinition {
private final String partitionName;
private final List<List<Expression>> values;
- private ReplicaAllocation replicaAllocation =
ReplicaAllocation.DEFAULT_ALLOCATION;
public InPartition(String partitionName, List<List<Expression>> values) {
this.partitionName = partitionName;
@@ -47,11 +44,7 @@ public class InPartition extends PartitionDefinition {
@Override
public void validate(Map<String, String> properties) {
- try {
- replicaAllocation =
PropertyAnalyzer.analyzeReplicaAllocation(properties, "");
- } catch (Exception e) {
- throw new AnalysisException(e.getMessage(), e.getCause());
- }
+ super.validate(properties);
if (values.stream().anyMatch(l ->
l.stream().anyMatch(MaxValue.class::isInstance))) {
throw new AnalysisException("MAXVALUE cannot be used in 'in
partition'");
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/LessThanPartition.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/LessThanPartition.java
index 2537c5d1a1a..11a6f4f50da 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/LessThanPartition.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/LessThanPartition.java
@@ -20,9 +20,6 @@ package org.apache.doris.nereids.trees.plans.commands.info;
import org.apache.doris.analysis.PartitionKeyDesc;
import org.apache.doris.analysis.PartitionValue;
import org.apache.doris.analysis.SinglePartitionDesc;
-import org.apache.doris.catalog.ReplicaAllocation;
-import org.apache.doris.common.util.PropertyAnalyzer;
-import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import com.google.common.collect.Maps;
@@ -37,7 +34,6 @@ import java.util.stream.Collectors;
public class LessThanPartition extends PartitionDefinition {
private final String partitionName;
private final List<Expression> values;
- private ReplicaAllocation replicaAllocation =
ReplicaAllocation.DEFAULT_ALLOCATION;
public LessThanPartition(String partitionName, List<Expression> values) {
this.partitionName = partitionName;
@@ -46,11 +42,7 @@ public class LessThanPartition extends PartitionDefinition {
@Override
public void validate(Map<String, String> properties) {
- try {
- replicaAllocation =
PropertyAnalyzer.analyzeReplicaAllocation(properties, "");
- } catch (Exception e) {
- throw new AnalysisException(e.getMessage(), e.getCause());
- }
+ super.validate(properties);
}
public String getPartitionName() {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/PartitionDefinition.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/PartitionDefinition.java
index a6edda1b83d..2d89ed94909 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/PartitionDefinition.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/PartitionDefinition.java
@@ -19,6 +19,8 @@ package org.apache.doris.nereids.trees.plans.commands.info;
import org.apache.doris.analysis.AllPartitionDesc;
import org.apache.doris.analysis.PartitionValue;
+import org.apache.doris.catalog.ReplicaAllocation;
+import org.apache.doris.common.util.PropertyAnalyzer;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
@@ -34,16 +36,30 @@ import java.util.Map;
*/
public abstract class PartitionDefinition {
protected List<DataType> partitionTypes;
- protected Map<String, String> propreties;
+ protected Map<String, String> properties;
+ protected ReplicaAllocation replicaAllocation =
ReplicaAllocation.DEFAULT_ALLOCATION;
public PartitionDefinition withProperties(Map<String, String> properties) {
- this.propreties = properties;
+ this.properties = properties;
return this;
}
public abstract AllPartitionDesc translateToCatalogStyle();
- public abstract void validate(Map<String, String> properties);
+ /**
+ * Validate the properties.
+ * Derived class can override this method to do more validation.
+ */
+ public void validate(Map<String, String> properties) {
+ try {
+ replicaAllocation =
PropertyAnalyzer.analyzeReplicaAllocation(properties, "");
+ if (replicaAllocation.isNotSet()) {
+ replicaAllocation = ReplicaAllocation.DEFAULT_ALLOCATION;
+ }
+ } catch (Exception e) {
+ throw new AnalysisException(e.getMessage(), e.getCause());
+ }
+ }
/**
* get partition name
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/StepPartition.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/StepPartition.java
index 6588ad1dc35..a02013d3770 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/StepPartition.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/StepPartition.java
@@ -20,8 +20,6 @@ package org.apache.doris.nereids.trees.plans.commands.info;
import org.apache.doris.analysis.MultiPartitionDesc;
import org.apache.doris.analysis.PartitionKeyDesc;
import org.apache.doris.analysis.PartitionValue;
-import org.apache.doris.catalog.ReplicaAllocation;
-import org.apache.doris.common.util.PropertyAnalyzer;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
@@ -39,7 +37,6 @@ public class StepPartition extends PartitionDefinition {
private final List<Expression> toExpression;
private final long unit;
private final String unitString;
- private ReplicaAllocation replicaAllocation =
ReplicaAllocation.DEFAULT_ALLOCATION;
public StepPartition(List<Expression> fromExpression, List<Expression>
toExpression, long unit,
String unitString) {
@@ -51,15 +48,11 @@ public class StepPartition extends PartitionDefinition {
@Override
public void validate(Map<String, String> properties) {
+ super.validate(properties);
if (fromExpression.stream().anyMatch(MaxValue.class::isInstance)
|| toExpression.stream().anyMatch(MaxValue.class::isInstance))
{
throw new AnalysisException("MAXVALUE cannot be used in step
partition");
}
- try {
- replicaAllocation =
PropertyAnalyzer.analyzeReplicaAllocation(properties, "");
- } catch (Exception e) {
- throw new AnalysisException(e.getMessage(), e.getCause());
- }
}
/**
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/catalog/CreateTableTest.java
b/fe/fe-core/src/test/java/org/apache/doris/catalog/CreateTableTest.java
index f8b37973214..3bf6af35c2a 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/catalog/CreateTableTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/CreateTableTest.java
@@ -17,9 +17,6 @@
package org.apache.doris.catalog;
-import org.apache.doris.analysis.AlterTableStmt;
-import org.apache.doris.analysis.CreateDbStmt;
-import org.apache.doris.analysis.CreateTableStmt;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.ConfigBase;
@@ -27,51 +24,27 @@ import org.apache.doris.common.ConfigException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.ExceptionChecker;
import org.apache.doris.common.UserException;
-import org.apache.doris.qe.ConnectContext;
-import org.apache.doris.utframe.UtFrameUtils;
+import org.apache.doris.utframe.TestWithFeService;
-import org.junit.AfterClass;
import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
-import java.io.File;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
-public class CreateTableTest {
+public class CreateTableTest extends TestWithFeService {
private static String runningDir = "fe/mocked/CreateTableTest2/" +
UUID.randomUUID().toString() + "/";
- private static ConnectContext connectContext;
-
- @BeforeClass
- public static void beforeClass() throws Exception {
- Config.disable_storage_medium_check = true;
- UtFrameUtils.createDorisClusterWithMultiTag(runningDir, 3);
-
- // create connect context
- connectContext = UtFrameUtils.createDefaultCtx();
- // create database
- String createDbStmtStr = "create database test;";
- CreateDbStmt createDbStmt = (CreateDbStmt)
UtFrameUtils.parseAndAnalyzeStmt(createDbStmtStr, connectContext);
- Env.getCurrentEnv().createDb(createDbStmt);
+ @Override
+ protected int backendNum() {
+ return 3;
}
- @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);
- Env.getCurrentEnv().createTable(createTableStmt);
- }
-
- private static void alterTable(String sql) throws Exception {
- AlterTableStmt alterTableStmt = (AlterTableStmt)
UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
- Env.getCurrentEnv().alterTable(alterTableStmt);
+ @Override
+ protected void runBeforeAll() throws Exception {
+ Config.allow_replica_on_same_host = true;
+ createDatabase("test");
}
@Test
@@ -761,7 +734,7 @@ public class CreateTableTest {
// can still set replication_num manually.
ExceptionChecker.expectThrowsWithMsg(UserException.class, "Failed
to find enough host with tag",
() -> {
- alterTable("alter table test.test_replica modify
partition p1 set ('replication_num' = '4')");
+ alterTableSync("alter table test.test_replica modify
partition p1 set ('replication_num' = '4')");
});
Database db =
Env.getCurrentInternalCatalog().getDbOrDdlException("default_cluster:test");
@@ -792,17 +765,17 @@ public class CreateTableTest {
Assert.assertEquals(2, (int)
tbl1.getDefaultReplicaAllocation().getTotalReplicaNum());
ExceptionChecker.expectThrowsNoException(
- () -> alterTable("alter table
test.tbl_min_load_replica_num_1\n"
+ () -> alterTableSync("alter table
test.tbl_min_load_replica_num_1\n"
+ " set ( 'min_load_replica_num' = '2');"));
Assert.assertEquals(2, tbl1.getMinLoadReplicaNum());
ExceptionChecker.expectThrowsWithMsg(DdlException.class, "Failed to
check min load replica num",
- () -> alterTable("alter table
test.tbl_min_load_replica_num_1\n"
+ () -> alterTableSync("alter table
test.tbl_min_load_replica_num_1\n"
+ " set ( 'min_load_replica_num' = '3');"));
Assert.assertEquals(2, tbl1.getMinLoadReplicaNum());
ExceptionChecker.expectThrowsWithMsg(DdlException.class,
"min_load_replica_num should > 0 or =-1",
- () -> alterTable("alter table
test.tbl_min_load_replica_num_1\n"
+ () -> alterTableSync("alter table
test.tbl_min_load_replica_num_1\n"
+ " set ( 'min_load_replica_num' = '-3');"));
ExceptionChecker.expectThrowsWithMsg(DdlException.class, "Failed to
check min load replica num",
@@ -881,7 +854,7 @@ public class CreateTableTest {
+ ");\n"));
ExceptionChecker.expectThrowsWithMsg(DdlException.class, "Failed to
check min load replica num",
- () -> alterTable("alter table
test.tbl_min_load_replica_num_6\n"
+ () -> alterTableSync("alter table
test.tbl_min_load_replica_num_6\n"
+ " set ( 'min_load_replica_num' = '3');"));
ExceptionChecker.expectThrowsWithMsg(DdlException.class, "Failed to
check min load replica num",
@@ -905,4 +878,57 @@ public class CreateTableTest {
+ "\"dynamic_partition.start\" = \"-3\"\n"
+ ");\n"));
}
+
+ @Test
+ public void testCreateTableWithNerieds() throws Exception {
+
ExceptionChecker.expectThrowsWithMsg(org.apache.doris.nereids.exceptions.AnalysisException.class,
+ "Failed to check min load replica num",
+ () -> createTable("create table
test.tbl_min_load_replica_num_2_nereids\n"
+ + "(k1 int, k2 int)\n"
+ + "duplicate key(k1)\n"
+ + "distributed by hash(k1) buckets 1\n"
+ + "properties(\n"
+ + " 'replication_num' = '2',\n"
+ + " 'min_load_replica_num' = '3'\n"
+ + ");", true));
+
+ ExceptionChecker.expectThrowsNoException(
+ () -> createTable("create table test.tbl_no_properties\n"
+ + "(k1 int, k2 int)\n"
+ + "duplicate key(k1)\n"
+ + "distributed by hash(k1) buckets 1", true));
+
+ ExceptionChecker.expectThrowsNoException(
+ () -> createTable("create table
test.tbl_range_part_no_properties\n"
+ + "(k1 int not null, k2 int)\n"
+ + "partition by range(k1)\n"
+ + "(partition p1 values less than ('100'),"
+ + "partition p2 values less than ('200'))\n"
+ + "distributed by hash(k1) buckets 1", true));
+
+ ExceptionChecker.expectThrowsNoException(
+ () -> createTable("create table
test.tbl_in_part_no_properties\n"
+ + "(k1 int not null, k2 int)\n"
+ + "partition by list(k1)\n"
+ + "(partition p1 values in ('100'),"
+ + "partition p2 values in ('200'))\n"
+ + "distributed by hash(k1) buckets 3", true));
+
+ ExceptionChecker.expectThrowsNoException(
+ () -> createTable("create table
test.tbl_fixed_part_no_properties\n"
+ + "(k1 int not null, k2 int)\n"
+ + "partition by range(k1)\n"
+ + "(partition p1 values [('100'),('200')),"
+ + "partition p2 values [('200'),('300')))\n"
+ + "distributed by hash(k1) buckets 10", true));
+
+ createDatabaseWithSql("create database db2
properties('replication_num' = '4')");
+
ExceptionChecker.expectThrowsWithMsg(org.apache.doris.nereids.exceptions.AnalysisException.class,
+ "replication num should be less than the number of available
backends. "
+ + "replication num is 4, available backend num is 3",
+ () -> createTable("create table db2.tbl_4_replica\n"
+ + "(k1 int, k2 int)\n"
+ + "duplicate key(k1)\n"
+ + "distributed by hash(k1) buckets 1\n", true));
+ }
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/common/ExceptionChecker.java
b/fe/fe-core/src/test/java/org/apache/doris/common/ExceptionChecker.java
index 26d5d1dc47a..5353cfd0274 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/common/ExceptionChecker.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/common/ExceptionChecker.java
@@ -34,6 +34,7 @@ public class ExceptionChecker {
try {
runnable.run();
} catch (Throwable e) {
+ e.printStackTrace();
throw new AssertionFailedError(e.getMessage());
}
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java
b/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java
index 5237909dd46..160bdee462e 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java
@@ -59,8 +59,10 @@ import org.apache.doris.common.util.SqlParserUtils;
import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.StatementContext;
import org.apache.doris.nereids.glue.LogicalPlanAdapter;
+import org.apache.doris.nereids.parser.NereidsParser;
import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.trees.expressions.StatementScopeIdGenerator;
+import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.util.MemoTestUtils;
import org.apache.doris.planner.Planner;
@@ -101,7 +103,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
-import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -562,6 +563,11 @@ public abstract class TestWithFeService {
Env.getCurrentEnv().createDb(createDbStmt);
}
+ public void createDatabaseWithSql(String createDbSql) throws Exception {
+ CreateDbStmt createDbStmt = (CreateDbStmt)
parseAndAnalyzeStmt(createDbSql);
+ Env.getCurrentEnv().createDb(createDbStmt);
+ }
+
public void dropDatabase(String db) throws Exception {
String createDbStmtStr = "DROP DATABASE " + db;
DropDbStmt createDbStmt = (DropDbStmt)
parseAndAnalyzeStmt(createDbStmtStr);
@@ -597,10 +603,14 @@ public abstract class TestWithFeService {
}
public void createTable(String sql) throws Exception {
+ createTable(sql, false);
+ }
+
+ public void createTable(String sql, boolean enableNerieds) throws
Exception {
try {
Config.enable_odbc_table = true;
- createTables(sql);
- } catch (ConcurrentModificationException e) {
+ createTables(enableNerieds, sql);
+ } catch (Exception e) {
e.printStackTrace();
throw e;
}
@@ -624,9 +634,24 @@ public abstract class TestWithFeService {
}
public void createTables(String... sqls) throws Exception {
- for (String sql : sqls) {
- CreateTableStmt stmt = (CreateTableStmt) parseAndAnalyzeStmt(sql);
- Env.getCurrentEnv().createTable(stmt);
+ createTables(false, sqls);
+ }
+
+ public void createTables(boolean enableNereids, String... sqls) throws
Exception {
+ if (enableNereids) {
+ for (String sql : sqls) {
+ NereidsParser nereidsParser = new NereidsParser();
+ LogicalPlan parsed = nereidsParser.parseSingle(sql);
+ StmtExecutor stmtExecutor = new StmtExecutor(connectContext,
sql);
+ if (parsed instanceof CreateTableCommand) {
+ ((CreateTableCommand) parsed).run(connectContext,
stmtExecutor);
+ }
+ }
+ } else {
+ for (String sql : sqls) {
+ CreateTableStmt stmt = (CreateTableStmt)
parseAndAnalyzeStmt(sql);
+ Env.getCurrentEnv().createTable(stmt);
+ }
}
updateReplicaPathHash();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]