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 afbc93f44dd [fix](drop table) Improve error prompts when deleting materialized views (#35437) afbc93f44dd is described below commit afbc93f44dd4defc45a1b001aceebd4a321cb339 Author: HB <hubia...@corp.netease.com> AuthorDate: Sat Jun 1 23:42:49 2024 +0800 [fix](drop table) Improve error prompts when deleting materialized views (#35437) --- .../apache/doris/datasource/InternalCatalog.java | 16 +-- .../doris/catalog/DropMaterializedViewTest.java | 158 +++++++++++++++++++++ .../org/apache/doris/common/util/UnitTestUtil.java | 1 + 3 files changed, 167 insertions(+), 8 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java index 5f589ad1c66..7addc8053f2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java @@ -887,21 +887,21 @@ public class InternalCatalog implements CatalogIf<Database> { if (stmt.isView()) { if (!(table instanceof View)) { ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_OBJECT, dbName, tableName, "VIEW", - genDropHint(table)); + genDropHint(dbName, table)); } } else { if (table instanceof View) { ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_OBJECT, dbName, tableName, "TABLE", - genDropHint(table)); + genDropHint(dbName, table)); } } if (!stmt.isMaterializedView() && table instanceof MTMV) { ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_OBJECT, dbName, tableName, "TABLE", - genDropHint(table)); + genDropHint(dbName, table)); } else if (stmt.isMaterializedView() && !(table instanceof MTMV)) { ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_OBJECT, dbName, tableName, "MTMV", - genDropHint(table)); + genDropHint(dbName, table)); } if (!stmt.isForceDrop()) { @@ -964,16 +964,16 @@ public class InternalCatalog implements CatalogIf<Database> { tableName, dbName, stmt.isForceDrop(), costTimes); } - private static String genDropHint(TableIf table) { + private static String genDropHint(String dbName, TableIf table) { String type = ""; if (table instanceof View) { type = "VIEW"; - } else if (table instanceof OlapTable) { - type = "TABLE"; } else if (table instanceof MTMV) { type = "MATERIALIZED VIEW"; + } else if (table instanceof OlapTable) { + type = "TABLE"; } - return "Use 'DROP " + type + " " + table.getName(); + return String.format("Use 'DROP %s %s.%s'", type, dbName, table.getName()); } public boolean unprotectDropTable(Database db, Table table, boolean isForceDrop, boolean isReplay, diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/DropMaterializedViewTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/DropMaterializedViewTest.java new file mode 100644 index 00000000000..2edd5380378 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/DropMaterializedViewTest.java @@ -0,0 +1,158 @@ +// 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.catalog; + +import org.apache.doris.alter.AlterJobV2; +import org.apache.doris.analysis.CreateDbStmt; +import org.apache.doris.analysis.CreateTableStmt; +import org.apache.doris.analysis.DropTableStmt; +import org.apache.doris.analysis.TableName; +import org.apache.doris.common.DdlException; +import org.apache.doris.common.ExceptionChecker; +import org.apache.doris.common.MetaNotFoundException; +import org.apache.doris.common.util.UnitTestUtil; +import org.apache.doris.datasource.InternalCatalog; +import org.apache.doris.nereids.parser.NereidsParser; +import org.apache.doris.nereids.trees.plans.commands.CreateMTMVCommand; +import org.apache.doris.nereids.trees.plans.commands.DropMTMVCommand; +import org.apache.doris.nereids.trees.plans.logical.LogicalPlan; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.StmtExecutor; +import org.apache.doris.utframe.UtFrameUtils; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import java.io.File; +import java.util.Map; +import java.util.UUID; + +public class DropMaterializedViewTest { + private static String runningDir = "fe/mocked/DropMaterializedViewTest/" + UUID.randomUUID() + "/"; + + private static ConnectContext connectContext; + + @BeforeClass + public static void beforeClass() throws Exception { + UtFrameUtils.createDorisCluster(runningDir); + + // create connect context + connectContext = UtFrameUtils.createDefaultCtx(); + + String createDbStmtStr = String.format("CREATE DATABASE %s;", UnitTestUtil.DB_NAME); + String createTableStr1 = String.format("CREATE TABLE %s.%s(k1 int, k2 bigint) DUPLICATE KEY(k1) DISTRIBUTED BY " + + "HASH(k2) BUCKETS 1 PROPERTIES('replication_num' = '1');", UnitTestUtil.DB_NAME, UnitTestUtil.TABLE_NAME); + String createMVStr1 = String.format("CREATE MATERIALIZED VIEW %s.%s BUILD IMMEDIATE REFRESH AUTO ON MANUAL " + + "DISTRIBUTED BY RANDOM BUCKETS 1 PROPERTIES ('replication_num' = '1') AS SELECT k1, sum(k2) as k3 from %s.%s" + + " GROUP BY k1;", UnitTestUtil.DB_NAME, UnitTestUtil.MV_NAME, UnitTestUtil.DB_NAME, UnitTestUtil.TABLE_NAME); + createDb(createDbStmtStr); + createTable(createTableStr1); + createMvByNereids(createMVStr1); + } + + @AfterClass + public static void tearDown() { + File file = new File(runningDir); + file.delete(); + } + + private static void createMvByNereids(String sql) throws Exception { + NereidsParser nereidsParser = new NereidsParser(); + LogicalPlan parsed = nereidsParser.parseSingle(sql); + StmtExecutor stmtExecutor = new StmtExecutor(connectContext, sql); + if (parsed instanceof CreateMTMVCommand) { + ((CreateMTMVCommand) parsed).run(connectContext, stmtExecutor); + } + checkAlterJob(); + // waiting table state to normal + Thread.sleep(1000); + } + + private static void dropMvByNereids(String sql) throws Exception { + NereidsParser nereidsParser = new NereidsParser(); + LogicalPlan parsed = nereidsParser.parseSingle(sql); + StmtExecutor stmtExecutor = new StmtExecutor(connectContext, sql); + if (parsed instanceof DropMTMVCommand) { + ((DropMTMVCommand) parsed).run(connectContext, stmtExecutor); + } + checkAlterJob(); + // waiting table state to normal + Thread.sleep(1000); + } + + private static void createDb(String sql) throws Exception { + CreateDbStmt createDbStmt = (CreateDbStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Env.getCurrentEnv().createDb(createDbStmt); + } + + private static void createTable(String sql) throws Exception { + CreateTableStmt createTableStmt = (CreateTableStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Env.getCurrentEnv().createTable(createTableStmt); + } + + private static void dropTable(String db, String tbl, boolean isMaterializedView) throws Exception { + DropTableStmt dropTableStmt = new DropTableStmt(false, + new TableName(InternalCatalog.INTERNAL_CATALOG_NAME, db, tbl), false, false); + if (isMaterializedView) { + dropTableStmt.setMaterializedView(true); + } + Env.getCurrentEnv().dropTable(dropTableStmt); + } + + private static void checkAlterJob() throws InterruptedException { + // check alter job + Map<Long, AlterJobV2> alterJobs = Env.getCurrentEnv().getMaterializedViewHandler().getAlterJobsV2(); + for (AlterJobV2 alterJobV2 : alterJobs.values()) { + while (!alterJobV2.getJobState().isFinalState()) { + System.out.println("alter job " + alterJobV2.getDbId() + + " is running. state: " + alterJobV2.getJobState()); + Thread.sleep(100); + } + System.out.println("alter job " + alterJobV2.getDbId() + " is done. state: " + alterJobV2.getJobState()); + Assertions.assertEquals(AlterJobV2.JobState.FINISHED, alterJobV2.getJobState()); + + try { + // Add table state check in case of below Exception: + // there is still a short gap between "job finish" and "table become normal", + // so if user send next alter job right after the "job finish", + // it may encounter "table's state not NORMAL" error. + Database db = Env.getCurrentInternalCatalog().getDbOrMetaException(alterJobV2.getDbId()); + OlapTable tbl = (OlapTable) db.getTableOrMetaException(alterJobV2.getTableId(), Table.TableType.OLAP); + while (tbl.getState() != OlapTable.OlapTableState.NORMAL) { + Thread.sleep(1000); + } + } catch (MetaNotFoundException e) { + // Sometimes table could be dropped by tests, but the corresponding alter job is not deleted yet. + // Ignore this error. + System.out.println(e.getMessage()); + } + } + } + + @Test + public void testDropMv() throws Exception { + ExceptionChecker.expectThrowsWithMsg(DdlException.class, + String.format("'%s.%s' is not TABLE. Use 'DROP MATERIALIZED VIEW %s.%s'", + UnitTestUtil.DB_NAME, UnitTestUtil.MV_NAME, UnitTestUtil.DB_NAME, UnitTestUtil.MV_NAME), + () -> dropTable(UnitTestUtil.DB_NAME, UnitTestUtil.MV_NAME, false)); + ExceptionChecker.expectThrowsNoException(() -> dropMvByNereids(String.format("DROP MATERIALIZED VIEW %s.%s", + UnitTestUtil.DB_NAME, UnitTestUtil.MV_NAME))); + } +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/common/util/UnitTestUtil.java b/fe/fe-core/src/test/java/org/apache/doris/common/util/UnitTestUtil.java index b16879625cd..9963479f6b8 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/common/util/UnitTestUtil.java +++ b/fe/fe-core/src/test/java/org/apache/doris/common/util/UnitTestUtil.java @@ -60,6 +60,7 @@ import java.util.Map; public class UnitTestUtil { public static final String DB_NAME = "testDb"; public static final String TABLE_NAME = "testTable"; + public static final String MV_NAME = "testMv"; public static final String PARTITION_NAME = "testTable"; public static final int SCHEMA_HASH = 0; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org