You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2020/06/22 01:24:31 UTC
[incubator-doris] branch master updated: [Bug] Can not use non-key
column as partition column in duplicate table (#3916)
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 56bb218 [Bug] Can not use non-key column as partition column in duplicate table (#3916)
56bb218 is described below
commit 56bb218148d02fb1db4cea60ac193da0b6600cec
Author: Mingyu Chen <mo...@gmail.com>
AuthorDate: Mon Jun 22 09:24:21 2020 +0800
[Bug] Can not use non-key column as partition column in duplicate table (#3916)
The following statement will throw error:
```
create table test.tbl2
(k1 int, k2 int, k3 float)
duplicate key(k1)
partition by range(k2)
(partition p1 values less than("10"))
distributed by hash(k3) buckets 1
properties('replication_num' = '1');
```
Error: `Only key column can be partition column`
But in duplicate key table, columns can be partition or distribution column
even if they are not in duplicate keys.
This bug is introduced by #3812
---
.../doris/analysis/HashDistributionDesc.java | 9 +-
.../apache/doris/analysis/RangePartitionDesc.java | 17 +-
.../org/apache/doris/catalog/CreateTableTest.java | 509 +++++----------------
.../org/apache/doris/common/ExceptionChecker.java | 44 +-
.../org/apache/doris/http/DorisHttpTestCase.java | 9 +-
.../org/apache/doris/planner/QueryPlanTest.java | 2 +-
6 files changed, 169 insertions(+), 421 deletions(-)
diff --git a/fe/src/main/java/org/apache/doris/analysis/HashDistributionDesc.java b/fe/src/main/java/org/apache/doris/analysis/HashDistributionDesc.java
index e779f20..31e1d3b 100644
--- a/fe/src/main/java/org/apache/doris/analysis/HashDistributionDesc.java
+++ b/fe/src/main/java/org/apache/doris/analysis/HashDistributionDesc.java
@@ -17,10 +17,11 @@
package org.apache.doris.analysis;
+import org.apache.doris.catalog.AggregateType;
import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.DistributionInfo;
import org.apache.doris.catalog.DistributionInfo.DistributionInfoType;
import org.apache.doris.catalog.HashDistributionInfo;
-import org.apache.doris.catalog.DistributionInfo;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.io.Text;
@@ -102,10 +103,14 @@ public class HashDistributionDesc extends DistributionDesc {
boolean find = false;
for (Column column : columns) {
if (column.getName().equalsIgnoreCase(colName)) {
- if (!column.isKey()) {
+ if (!column.isKey() && column.getAggregationType() != AggregateType.NONE) {
throw new DdlException("Distribution column[" + colName + "] is not key column");
}
+ if (column.getType().isFloatingPointType()) {
+ throw new DdlException("Floating point type column can not be distribution column");
+ }
+
distributionColumns.add(column);
find = true;
break;
diff --git a/fe/src/main/java/org/apache/doris/analysis/RangePartitionDesc.java b/fe/src/main/java/org/apache/doris/analysis/RangePartitionDesc.java
index 8f49d2e..771e208 100644
--- a/fe/src/main/java/org/apache/doris/analysis/RangePartitionDesc.java
+++ b/fe/src/main/java/org/apache/doris/analysis/RangePartitionDesc.java
@@ -18,6 +18,7 @@
package org.apache.doris.analysis;
import org.apache.doris.analysis.PartitionKeyDesc.PartitionRangeType;
+import org.apache.doris.catalog.AggregateType;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.PartitionInfo;
import org.apache.doris.catalog.PartitionType;
@@ -71,8 +72,11 @@ public class RangePartitionDesc extends PartitionDesc {
boolean found = false;
for (ColumnDef columnDef : columnDefs) {
if (columnDef.getName().equals(partitionCol)) {
- if (!columnDef.isKey()) {
- throw new AnalysisException("Only key column can be partition column");
+ if (!columnDef.isKey() && columnDef.getAggregateType() != AggregateType.NONE) {
+ throw new AnalysisException("The partition column could not be aggregated column");
+ }
+ if (columnDef.getType().isFloatingPointType()) {
+ throw new AnalysisException("Floating point type column can not be partition column");
}
found = true;
break;
@@ -145,9 +149,14 @@ public class RangePartitionDesc extends PartitionDesc {
boolean find = false;
for (Column column : schema) {
if (column.getName().equalsIgnoreCase(colName)) {
- if (!column.isKey()) {
- throw new DdlException("Partition column[" + colName + "] is not key column");
+ if (!column.isKey() && column.getAggregationType() != AggregateType.NONE) {
+ throw new DdlException("The partition column could not be aggregated column");
+ }
+
+ if (column.getType().isFloatingPointType()) {
+ throw new DdlException("Floating point type column can not be partition column");
}
+
try {
RangePartitionInfo.checkRangeColumnType(column);
} catch (AnalysisException e) {
diff --git a/fe/src/test/java/org/apache/doris/catalog/CreateTableTest.java b/fe/src/test/java/org/apache/doris/catalog/CreateTableTest.java
index 17b3648..4ee95a5 100644
--- a/fe/src/test/java/org/apache/doris/catalog/CreateTableTest.java
+++ b/fe/src/test/java/org/apache/doris/catalog/CreateTableTest.java
@@ -17,426 +17,135 @@
package org.apache.doris.catalog;
-import org.apache.doris.analysis.Analyzer;
-import org.apache.doris.analysis.ColumnDef;
+import org.apache.doris.analysis.CreateDbStmt;
import org.apache.doris.analysis.CreateTableStmt;
-import org.apache.doris.analysis.HashDistributionDesc;
-import org.apache.doris.analysis.KeysDesc;
-import org.apache.doris.analysis.TableName;
-import org.apache.doris.analysis.TypeDef;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
-import org.apache.doris.common.util.PropertyAnalyzer;
-import org.apache.doris.mysql.privilege.PaloAuth;
-import org.apache.doris.mysql.privilege.PrivPredicate;
-import org.apache.doris.persist.EditLog;
+import org.apache.doris.common.ExceptionChecker;
import org.apache.doris.qe.ConnectContext;
-import org.apache.doris.system.SystemInfoService;
-import org.apache.doris.task.AgentBatchTask;
+import org.apache.doris.utframe.UtFrameUtils;
-import com.google.common.collect.Lists;
-
-import org.junit.Before;
-import org.junit.Rule;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import java.util.HashMap;
-import java.util.List;
-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;
+import java.io.File;
+import java.util.UUID;
public class CreateTableTest {
+ private static String runningDir = "fe/mocked/CreateTableTest2/" + UUID.randomUUID().toString() + "/";
- private TableName dbTableName;
- private String dbName = "testDb";
- private String tableName = "testTable";
- private String clusterName = "default";
- private List<Long> beIds = Lists.newArrayList();
- private List<String> columnNames = Lists.newArrayList();
- private List<ColumnDef> columnDefs = Lists.newArrayList();
-
- private Catalog catalog = Catalog.getCurrentCatalog();
- private Database db = new Database();
- private Analyzer analyzer;
-
- @Injectable
- ConnectContext connectContext;
-
- @Rule
- public ExpectedException expectedEx = ExpectedException.none();
-
- @Before
- public void setUp() throws AnalysisException {
- dbTableName = new TableName(dbName, tableName);
-
- beIds.add(1L);
- beIds.add(2L);
- beIds.add(3L);
-
- columnNames.add("key1");
- columnNames.add("key2");
-
- columnDefs.add(new ColumnDef("key1", new TypeDef(ScalarType.createType(PrimitiveType.INT))));
- columnDefs.add(new ColumnDef("key2", new TypeDef(ScalarType.createVarchar(10))));
-
- analyzer = new Analyzer(catalog, connectContext);
-
- new Expectations(analyzer) {
- {
- analyzer.getClusterName();
- minTimes = 0;
- result = clusterName;
- }
- };
-
- new Expectations(catalog) {
- {
- Catalog.getCurrentCatalog();
- minTimes = 0;
- result = catalog;
-
- Catalog.getCurrentCatalog();
- minTimes = 0;
- result = catalog;
- }
- };
-
- dbTableName.analyze(analyzer);
- }
-
- @Test
- public void testNormalOlap(@Injectable SystemInfoService systemInfoService, @Injectable PaloAuth paloAuth,
- @Injectable EditLog editLog) throws Exception {
- new Expectations(catalog) {
- {
- catalog.getDb(dbTableName.getDb());
- minTimes = 0;
- result = db;
-
- Catalog.getCurrentSystemInfo();
- minTimes = 0;
- result = systemInfoService;
-
- catalog.getAuth();
- minTimes = 0;
- result = paloAuth;
-
- catalog.getEditLog();
- minTimes = 0;
- result = editLog;
- }
- };
-
- new Expectations() {
- {
- systemInfoService.checkClusterCapacity(anyString);
- minTimes = 0;
-
- systemInfoService.seqChooseBackendIds(anyInt, true, true, anyString);
- minTimes = 0;
- result = beIds;
-
- paloAuth.checkTblPriv((ConnectContext) any, anyString, anyString, PrivPredicate.CREATE);
- minTimes = 0;
- result = true;
- }
- };
-
- new MockUp<AgentBatchTask>() {
- @Mock
- void run() {
- return;
- }
- };
-
- new MockUp<CountDownLatch>() {
- @Mock
- boolean await(long timeout, TimeUnit unit) {
- return true;
- }
- };
-
- CreateTableStmt stmt = new CreateTableStmt(false, false, dbTableName, columnDefs, "olap",
- new KeysDesc(KeysType.AGG_KEYS, columnNames), null,
- new HashDistributionDesc(1, Lists.newArrayList("key1")), null, null, "");
- stmt.analyze(analyzer);
-
- catalog.createTable(stmt);
- }
-
- @Test
- public void testUnknownDatabase(@Injectable PaloAuth paloAuth) throws Exception {
- new Expectations(catalog) {
- {
- catalog.getAuth();
- minTimes = 0;
- result = paloAuth;
- }
- };
-
- new Expectations() {
- {
- paloAuth.checkTblPriv((ConnectContext) any, anyString, anyString, PrivPredicate.CREATE);
- minTimes = 0;
- result = true;
- }
- };
-
- CreateTableStmt stmt = new CreateTableStmt(false, false, dbTableName, columnDefs, "olap",
- new KeysDesc(KeysType.AGG_KEYS, columnNames), null,
- new HashDistributionDesc(1, Lists.newArrayList("key1")), null, null, "");
-
- stmt.analyze(analyzer);
-
- expectedEx.expect(DdlException.class);
- expectedEx.expectMessage("Unknown database 'default:testDb'");
-
- catalog.createTable(stmt);
- }
-
- @Test
- public void testShortKeyTooLarge(@Injectable SystemInfoService systemInfoService, @Injectable PaloAuth paloAuth)
- throws Exception {
- new Expectations(catalog) {
- {
- catalog.getDb(dbTableName.getDb());
- minTimes = 0;
- result = db;
-
- Catalog.getCurrentSystemInfo();
- minTimes = 0;
- result = systemInfoService;
-
- catalog.getAuth();
- minTimes = 0;
- result = paloAuth;
-
- }
- };
-
- new Expectations() {
- {
- systemInfoService.checkClusterCapacity(anyString);
- minTimes = 0;
-
- paloAuth.checkTblPriv((ConnectContext) any, anyString, anyString, PrivPredicate.CREATE);
- minTimes = 0;
- result = true;
- }
- };
+ private static ConnectContext connectContext;
- Map<String, String> properties = new HashMap<String, String>();
- //larger then indexColumns size
- properties.put(PropertyAnalyzer.PROPERTIES_SHORT_KEY, "3");
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ UtFrameUtils.createMinDorisCluster(runningDir);
- CreateTableStmt stmt = new CreateTableStmt(false, false, dbTableName, columnDefs, "olap",
- new KeysDesc(KeysType.AGG_KEYS, columnNames), null,
- new HashDistributionDesc(1, Lists.newArrayList("key1")), properties, null, "");
- stmt.analyze(analyzer);
-
- expectedEx.expect(DdlException.class);
- expectedEx.expectMessage("Short key is too large. should less than: 2");
-
- catalog.createTable(stmt);
+ // create connect context
+ connectContext = UtFrameUtils.createDefaultCtx();
+ // create database
+ String createDbStmtStr = "create database test;";
+ CreateDbStmt createDbStmt = (CreateDbStmt) UtFrameUtils.parseAndAnalyzeStmt(createDbStmtStr, connectContext);
+ Catalog.getCurrentCatalog().createDb(createDbStmt);
}
-
- @Test
- public void testShortKeyVarcharMiddle(@Injectable SystemInfoService systemInfoService,
- @Injectable PaloAuth paloAuth) throws Exception {
- columnDefs.clear();
- columnDefs.add(new ColumnDef("key1", new TypeDef(ScalarType.createVarchar(10))));
- columnDefs.add(new ColumnDef("key2", new TypeDef(ScalarType.createType(PrimitiveType.INT))));
-
- new Expectations(catalog) {
- {
- catalog.getDb(dbTableName.getDb());
- minTimes = 0;
- result = db;
-
- Catalog.getCurrentSystemInfo();
- minTimes = 0;
- result = systemInfoService;
-
- catalog.getAuth();
- minTimes = 0;
- result = paloAuth;
-
- }
- };
-
- new Expectations() {
- {
- systemInfoService.checkClusterCapacity(anyString);
- minTimes = 0;
-
- paloAuth.checkTblPriv((ConnectContext) any, anyString, anyString, PrivPredicate.CREATE);
- minTimes = 0;
- result = true;
- }
- };
-
- Map<String, String> properties = new HashMap<String, String>();
- properties.put(PropertyAnalyzer.PROPERTIES_SHORT_KEY, "2");
-
- CreateTableStmt stmt = new CreateTableStmt(false, false, dbTableName, columnDefs, "olap",
- new KeysDesc(KeysType.AGG_KEYS, columnNames), null,
- new HashDistributionDesc(1, Lists.newArrayList("key1")), properties, null, "");
- stmt.analyze(analyzer);
-
- expectedEx.expect(DdlException.class);
- expectedEx.expectMessage("Varchar should not in the middle of short keys.");
-
- catalog.createTable(stmt);
+
+ @AfterClass
+ public static void tearDown() {
+ File file = new File(runningDir);
+ file.delete();
}
- @Test
- public void testNotEnoughBackend(@Injectable SystemInfoService systemInfoService, @Injectable PaloAuth paloAuth)
- throws Exception {
- new Expectations(catalog) {
- {
- catalog.getDb(dbTableName.getDb());
- minTimes = 0;
- result = db;
-
- Catalog.getCurrentSystemInfo();
- minTimes = 0;
- result = systemInfoService;
-
- catalog.getAuth();
- minTimes = 0;
- result = paloAuth;
-
- }
- };
-
- new Expectations() {
- {
- systemInfoService.checkClusterCapacity(anyString);
- minTimes = 0;
-
- systemInfoService.seqChooseBackendIds(anyInt, true, true, anyString);
- minTimes = 0;
- result = null;
-
- paloAuth.checkTblPriv((ConnectContext) any, anyString, anyString, PrivPredicate.CREATE);
- minTimes = 0;
- result = true;
- }
- };
-
- CreateTableStmt stmt = new CreateTableStmt(false, false, dbTableName, columnDefs, "olap",
- new KeysDesc(KeysType.AGG_KEYS, columnNames), null,
- new HashDistributionDesc(1, Lists.newArrayList("key1")), null, null, "");
- stmt.analyze(analyzer);
-
- expectedEx.expect(DdlException.class);
- expectedEx.expectMessage("Failed to find enough host in all backends. need: 3");
-
- catalog.createTable(stmt);
+ private static void createTable(String sql) throws Exception {
+ CreateTableStmt createTableStmt = (CreateTableStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
+ Catalog.getCurrentCatalog().createTable(createTableStmt);
}
@Test
- public void testOlapTableExists(@Injectable SystemInfoService systemInfoService, @Injectable PaloAuth paloAuth)
- throws Exception {
- Table olapTable = new OlapTable();
- new Expectations(db) {
- {
- db.getTable(tableName);
- minTimes = 0;
- result = olapTable;
- }
- };
-
- new Expectations(catalog) {
- {
-
- catalog.getDb(dbTableName.getDb());
- minTimes = 0;
- result = db;
-
- Catalog.getCurrentSystemInfo();
- minTimes = 0;
- result = systemInfoService;
-
- catalog.getAuth();
- minTimes = 0;
- result = paloAuth;
-
- }
- };
-
- new Expectations() {
- {
- systemInfoService.checkClusterCapacity(anyString);
- minTimes = 0;
-
- paloAuth.checkTblPriv((ConnectContext) any, anyString, anyString, PrivPredicate.CREATE);
- minTimes = 0;
- result = true;
- }
- };
-
- CreateTableStmt stmt = new CreateTableStmt(false, false, dbTableName, columnDefs, "olap",
- new KeysDesc(KeysType.AGG_KEYS, columnNames), null,
- new HashDistributionDesc(1, Lists.newArrayList("key1")), null, null, "");
- stmt.analyze(analyzer);
-
- expectedEx.expect(DdlException.class);
- expectedEx.expectMessage("Table 'testTable' already exists");
-
- catalog.createTable(stmt);
+ public void testNormal() {
+ ExceptionChecker.expectThrowsNoException(
+ () -> createTable("create table test.tbl1\n" + "(k1 int, k2 int)\n" + "duplicate key(k1)\n"
+ + "distributed by hash(k2) buckets 1\n" + "properties('replication_num' = '1'); "));
+
+ ExceptionChecker.expectThrowsNoException(() -> createTable("create table test.tbl2\n" + "(k1 int, k2 int)\n"
+ + "duplicate key(k1)\n" + "partition by range(k2)\n" + "(partition p1 values less than(\"10\"))\n"
+ + "distributed by hash(k2) buckets 1\n" + "properties('replication_num' = '1'); "));
+
+ ExceptionChecker.expectThrowsNoException(
+ () -> createTable("create table test.tbl3\n" + "(k1 varchar(40), k2 int)\n" + "duplicate key(k1)\n"
+ + "partition by range(k2)\n" + "(partition p1 values less than(\"10\"))\n"
+ + "distributed by hash(k2) buckets 1\n" + "properties('replication_num' = '1');"));
+
+ ExceptionChecker.expectThrowsNoException(
+ () -> createTable("create table test.tbl4\n" + "(k1 varchar(40), k2 int, v1 int sum)\n"
+ + "partition by range(k2)\n" + "(partition p1 values less than(\"10\"))\n"
+ + "distributed by hash(k1) buckets 1\n" + "properties('replication_num' = '1');"));
+
+ ExceptionChecker.expectThrowsNoException(() -> createTable(
+ "create table test.tbl5\n" + "(k1 varchar(40), k2 int, v1 int sum)\n" + "aggregate key(k1,k2)\n"
+ + "partition by range(k2)\n" + "(partition p1 values less than(\"10\"))\n"
+ + "distributed by hash(k1) buckets 1\n" + "properties('replication_num' = '1');"));
+
+ ExceptionChecker.expectThrowsNoException(() -> createTable(
+ "create table test.tbl6\n" + "(k1 varchar(40), k2 int, k3 int)\n" + "duplicate key(k1, k2, k3)\n"
+ + "partition by range(k2)\n" + "(partition p1 values less than(\"10\"))\n"
+ + "distributed by hash(k1) buckets 1\n" + "properties('replication_num' = '1');"));
+
+ ExceptionChecker
+ .expectThrowsNoException(() -> createTable("create table test.tbl7\n" + "(k1 varchar(40), k2 int)\n"
+ + "partition by range(k2)\n" + "(partition p1 values less than(\"10\"))\n"
+ + "distributed by hash(k2) buckets 1\n" + "properties('replication_num' = '1');"));
+
+ Database db = Catalog.getCurrentCatalog().getDb("default_cluster:test");
+ OlapTable tbl6 = (OlapTable) db.getTable("tbl6");
+ Assert.assertTrue(tbl6.getColumn("k1").isKey());
+ Assert.assertTrue(tbl6.getColumn("k2").isKey());
+ Assert.assertTrue(tbl6.getColumn("k3").isKey());
+
+ OlapTable tbl7 = (OlapTable) db.getTable("tbl7");
+ Assert.assertTrue(tbl7.getColumn("k1").isKey());
+ Assert.assertFalse(tbl7.getColumn("k2").isKey());
+ Assert.assertTrue(tbl7.getColumn("k2").getAggregationType() == AggregateType.NONE);
}
@Test
- public void testOlapTimeOut(@Injectable SystemInfoService systemInfoService, @Injectable PaloAuth paloAuth)
- throws Exception {
- new Expectations(catalog) {
- {
- catalog.getDb(dbTableName.getDb());
- minTimes = 0;
- result = db;
-
- Catalog.getCurrentSystemInfo();
- minTimes = 0;
- result = systemInfoService;
-
- catalog.getAuth();
- minTimes = 0;
- result = paloAuth;
-
- }
- };
-
- new Expectations() {
- {
- systemInfoService.checkClusterCapacity(anyString);
- minTimes = 0;
-
- systemInfoService.seqChooseBackendIds(anyInt, true, true, anyString);
- minTimes = 0;
- result = beIds;
-
- paloAuth.checkTblPriv((ConnectContext) any, anyString, anyString, PrivPredicate.CREATE);
- minTimes = 0;
- result = true;
- }
- };
-
- CreateTableStmt stmt = new CreateTableStmt(false, false, dbTableName, columnDefs, "olap",
- new KeysDesc(KeysType.AGG_KEYS, columnNames), null,
- new HashDistributionDesc(1, Lists.newArrayList("key1")), null, null, "");
- stmt.analyze(analyzer);
-
- expectedEx.expect(DdlException.class);
- expectedEx.expectMessage("Failed to create partition[testTable]. Timeout");
-
- catalog.createTable(stmt);
+ public void testAbormal() {
+ ExceptionChecker.expectThrowsWithMsg(DdlException.class,
+ "Floating point type column can not be distribution column",
+ () -> createTable("create table test.atbl1\n" + "(k1 int, k2 float)\n" + "duplicate key(k1)\n"
+ + "distributed by hash(k2) buckets 1\n" + "properties('replication_num' = '1'); "));
+
+ ExceptionChecker.expectThrowsWithMsg(AnalysisException.class,
+ "Floating point type column can not be partition column",
+ () -> createTable("create table test.atbl3\n" + "(k1 int, k2 int, k3 float)\n" + "duplicate key(k1)\n"
+ + "partition by range(k3)\n" + "(partition p1 values less than(\"10\"))\n"
+ + "distributed by hash(k2) buckets 1\n" + "properties('replication_num' = '1'); "));
+
+ ExceptionChecker.expectThrowsWithMsg(DdlException.class,
+ "Varchar should not in the middle of short keys",
+ () -> createTable("create table test.atbl3\n" + "(k1 varchar(40), k2 int, k3 int)\n"
+ + "duplicate key(k1, k2, k3)\n" + "distributed by hash(k1) buckets 1\n"
+ + "properties('replication_num' = '1', 'short_key' = '3');"));
+
+ ExceptionChecker.expectThrowsWithMsg(DdlException.class, "Short key is too large. should less than: 3",
+ () -> createTable("create table test.atbl4\n" + "(k1 int, k2 int, k3 int)\n"
+ + "duplicate key(k1, k2, k3)\n" + "distributed by hash(k1) buckets 1\n"
+ + "properties('replication_num' = '1', 'short_key' = '4');"));
+
+ ExceptionChecker
+ .expectThrowsWithMsg(DdlException.class, "Failed to find enough host in all backends. need: 3",
+ () -> createTable("create table test.atbl5\n" + "(k1 int, k2 int, k3 int)\n"
+ + "duplicate key(k1, k2, k3)\n" + "distributed by hash(k1) buckets 1\n"
+ + "properties('replication_num' = '3');"));
+
+ ExceptionChecker.expectThrowsNoException(
+ () -> createTable("create table test.atbl6\n" + "(k1 int, k2 int)\n" + "duplicate key(k1)\n"
+ + "distributed by hash(k2) buckets 1\n" + "properties('replication_num' = '1'); "));
+
+ ExceptionChecker
+ .expectThrowsWithMsg(DdlException.class, "Table 'atbl6' already exists",
+ () -> createTable("create table test.atbl6\n" + "(k1 int, k2 int, k3 int)\n"
+ + "duplicate key(k1, k2, k3)\n" + "distributed by hash(k1) buckets 1\n"
+ + "properties('replication_num' = '1');"));
}
}
diff --git a/fe/src/test/java/org/apache/doris/common/ExceptionChecker.java b/fe/src/test/java/org/apache/doris/common/ExceptionChecker.java
index 128a8b8..62a0030 100644
--- a/fe/src/test/java/org/apache/doris/common/ExceptionChecker.java
+++ b/fe/src/test/java/org/apache/doris/common/ExceptionChecker.java
@@ -17,12 +17,21 @@
package org.apache.doris.common;
-import org.apache.doris.http.DorisHttpTestCase;
+import com.google.common.base.Strings;
+
import junit.framework.AssertionFailedError;
public class ExceptionChecker {
- public static void expectThrowsNoException(DorisHttpTestCase.ThrowingRunnable runnable) {
+ /**
+ * A runnable that can throw any checked exception.
+ */
+ @FunctionalInterface
+ public interface ThrowingRunnable {
+ void run() throws Throwable;
+ }
+
+ public static void expectThrowsNoException(ThrowingRunnable runnable) {
try {
runnable.run();
} catch (Throwable e) {
@@ -33,21 +42,44 @@ public class ExceptionChecker {
/**
* Checks a specific exception class is thrown by the given runnable, and returns it.
*/
- public static <T extends Throwable> T expectThrows(Class<T> expectedType, DorisHttpTestCase.ThrowingRunnable runnable) {
- return expectThrows(expectedType, "Expected exception " + expectedType.getSimpleName() + " but no exception was thrown", runnable);
+ public static <T extends Throwable> T expectThrows(Class<T> expectedType, ThrowingRunnable runnable) {
+ return expectThrows(expectedType,
+ "Expected exception " + expectedType.getSimpleName() + " but no exception was thrown", null, runnable);
+ }
+
+ /**
+ * Checks a specific exception class is thrown by the given runnable, and
+ * returns it.
+ * Will also check if the given `exceptionMsg` is with exception.
+ */
+ public static <T extends Throwable> T expectThrowsWithMsg(Class<T> expectedType, String exceptionMsg,
+ ThrowingRunnable runnable) {
+ return expectThrows(expectedType,
+ "Expected exception " + expectedType.getSimpleName() + " but no exception was thrown", exceptionMsg,
+ runnable);
}
/**
* Checks a specific exception class is thrown by the given runnable, and returns it.
*/
- public static <T extends Throwable> T expectThrows(Class<T> expectedType, String noExceptionMessage, DorisHttpTestCase.ThrowingRunnable runnable) {
+ public static <T extends Throwable> T expectThrows(Class<T> expectedType, String noExceptionMessage,
+ String exceptionMsg, ThrowingRunnable runnable) {
try {
runnable.run();
} catch (Throwable e) {
if (expectedType.isInstance(e)) {
+ if (!Strings.isNullOrEmpty(exceptionMsg)) {
+ if (!e.getMessage().contains(exceptionMsg)) {
+ AssertionFailedError assertion = new AssertionFailedError(
+ "expceted msg: " + exceptionMsg + ", actual: " + e.getMessage());
+ assertion.initCause(e);
+ throw assertion;
+ }
+ }
return expectedType.cast(e);
}
- AssertionFailedError assertion = new AssertionFailedError("Unexpected exception type, expected " + expectedType.getSimpleName() + " but got " + e);
+ AssertionFailedError assertion = new AssertionFailedError(
+ "Unexpected exception type, expected " + expectedType.getSimpleName() + " but got " + e);
assertion.initCause(e);
throw assertion;
}
diff --git a/fe/src/test/java/org/apache/doris/http/DorisHttpTestCase.java b/fe/src/test/java/org/apache/doris/http/DorisHttpTestCase.java
index f9c24d1..94fa7f0 100644
--- a/fe/src/test/java/org/apache/doris/http/DorisHttpTestCase.java
+++ b/fe/src/test/java/org/apache/doris/http/DorisHttpTestCase.java
@@ -38,6 +38,7 @@ import org.apache.doris.catalog.TabletInvertedIndex;
import org.apache.doris.catalog.TabletMeta;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
+import org.apache.doris.common.ExceptionChecker.ThrowingRunnable;
import org.apache.doris.common.jmockit.Deencapsulation;
import org.apache.doris.load.Load;
import org.apache.doris.mysql.privilege.PaloAuth;
@@ -345,14 +346,6 @@ abstract public class DorisHttpTestCase {
}
- /**
- * A runnable that can throw any checked exception.
- */
- @FunctionalInterface
- public interface ThrowingRunnable {
- void run() throws Throwable;
- }
-
public void expectThrowsNoException(ThrowingRunnable runnable) {
try {
runnable.run();
diff --git a/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java b/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
index 9195490..8e6f4d3 100644
--- a/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
+++ b/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
@@ -70,8 +70,8 @@ public class QueryPlanTest {
createTable("create table test.test1\n" +
"(\n" +
- " time datetime not null comment \"Query start time\",\n" +
" query_id varchar(48) comment \"Unique query id\",\n" +
+ " time datetime not null comment \"Query start time\",\n" +
" client_ip varchar(32) comment \"Client IP\",\n" +
" user varchar(64) comment \"User name\",\n" +
" db varchar(96) comment \"Database of this query\",\n" +
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org