diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertStmt.java index 36be17c9266445..a8da7d3af8cc5d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/InsertStmt.java @@ -336,6 +336,10 @@ private void analyzeTargetTable(Analyzer analyzer) throws AnalysisException { for (Partition partition : olapTable.getPartitions()) { targetPartitionIds.add(partition.getId()); } + if (targetPartitionIds.isEmpty()) { + ErrorReport.reportAnalysisException( + ErrorCode.ERR_EMPTY_PARTITION_IN_TABLE, targetTable.getName()); + } } // need a descriptor DescriptorTable descTable = analyzer.getDescTbl(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java b/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java index 75ae600b48741b..a5609c55bc37ec 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java @@ -103,7 +103,8 @@ public enum ErrorCode { ERR_PARTITION_CLAUSE_ON_NONPARTITIONED(1747, new byte[] {'H', 'Y', '0', '0', '0'}, "PARTITION () clause on non partitioned table"), ERR_EMPTY_PARTITION_IN_TABLE(1748, new byte[] {'H', 'Y', '0', '0', '0'}, - "data cannot be inserted into table with emtpy partition. [%s]"), + "data cannot be inserted into table with empty partition. " + + "Use `SHOW PARTITIONS FROM %s` to see the currently partitions of this table. "), ERR_NO_SUCH_PARTITION(1749, new byte[] {'H', 'Y', '0', '0', '0'}, "partition '%s' doesn't exist"), // Following is Palo's error code, which start from 5000 ERR_NOT_OLAP_TABLE(5000, new byte[] {'H', 'Y', '0', '0', '0'}, "Table '%s' is not a OLAP table"), diff --git a/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/LoadingTaskPlanner.java b/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/LoadingTaskPlanner.java index 803e4352b16315..ab46d8caeb71cd 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/LoadingTaskPlanner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/LoadingTaskPlanner.java @@ -182,6 +182,13 @@ private List getAllPartitionIds() throws LoadException, MetaNotFoundExcept } } + // If this is a dynamic partitioned table, it will take some time to create the partition after the + // table is created, a exception needs to be thrown here + if (partitionIds.isEmpty()) { + throw new LoadException("data cannot be inserted into table with empty partition. " + + "Use `SHOW PARTITIONS FROM " + table.getName() + "` to see the currently partitions of this table. "); + } + return Lists.newArrayList(partitionIds); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/StreamLoadPlanner.java b/fe/fe-core/src/main/java/org/apache/doris/planner/StreamLoadPlanner.java index 9e779b6d674640..2559c1eaddd6e0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/StreamLoadPlanner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/StreamLoadPlanner.java @@ -47,7 +47,6 @@ import org.apache.doris.thrift.TScanRangeLocations; import org.apache.doris.thrift.TScanRangeParams; import org.apache.doris.thrift.TUniqueId; - import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -213,7 +212,11 @@ private List getAllPartitionIds() throws DdlException { for (Partition partition : destTable.getPartitions()) { partitionIds.add(partition.getId()); } + if (partitionIds.isEmpty()) { + ErrorReport.reportDdlException(ErrorCode.ERR_EMPTY_PARTITION_IN_TABLE, destTable.getName()); + } } + return partitionIds; } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/DynamicPartitionTableTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/DynamicPartitionTableTest.java index 8084ae4c10e257..dd1f18775a1db6 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/catalog/DynamicPartitionTableTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/DynamicPartitionTableTest.java @@ -19,6 +19,7 @@ import org.apache.doris.analysis.CreateDbStmt; import org.apache.doris.analysis.CreateTableStmt; +import org.apache.doris.common.AnalysisException; import org.apache.doris.common.DdlException; import org.apache.doris.common.FeConstants; import org.apache.doris.qe.ConnectContext; @@ -438,4 +439,35 @@ public void testSetDynamicPartitionReplicationNum() throws Exception { OlapTable table = (OlapTable) db.getTable(tableName); Assert.assertEquals(table.getTableProperty().getDynamicPartitionProperty().getReplicationNum(), 2); } + + @Test + public void testEmptyDynamicPartition() throws Exception { + String createOlapTblStmt = "CREATE TABLE test.`empty_dynamic_partition` (\n" + + " `k1` date NULL COMMENT \"\",\n" + + " `k2` int NULL COMMENT \"\",\n" + + " `k3` smallint NULL COMMENT \"\",\n" + + " `v1` varchar(2048) NULL COMMENT \"\",\n" + + " `v2` datetime NULL COMMENT \"\"\n" + + ") ENGINE=OLAP\n" + + "DUPLICATE KEY(`k1`, `k2`, `k3`)\n" + + "COMMENT \"OLAP\"\n" + + "PARTITION BY RANGE(`k1`)\n" + + "()\n" + + "DISTRIBUTED BY HASH(`k1`) BUCKETS 32\n" + + "PROPERTIES (\n" + + "\"replication_num\" = \"1\",\n" + + "\"dynamic_partition.enable\" = \"true\",\n" + + "\"dynamic_partition.start\" = \"-3\",\n" + + "\"dynamic_partition.end\" = \"3\",\n" + + "\"dynamic_partition.time_unit\" = \"day\",\n" + + "\"dynamic_partition.prefix\" = \"p\",\n" + + "\"dynamic_partition.buckets\" = \"1\"\n" + + ");"; + String insertStmt = "insert into test.`empty_dynamic_partition` values ('2020-09-10', 1000, 100, 'test', '2020-09-10 23:59:59');"; + createTable(createOlapTblStmt); + expectedException.expect(AnalysisException.class); + expectedException.expectMessage("errCode = 2, detailMessage = data cannot be inserted into table with empty partition. " + + "Use `SHOW PARTITIONS FROM empty_dynamic_partition` to see the currently partitions of this table. "); + UtFrameUtils.parseAndAnalyzeStmt("explain " + insertStmt, connectContext); + } }