diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java index 0cb6ab58d1..0219d4be49 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java @@ -230,16 +230,6 @@ public class Alter { List alterClauses = Lists.newArrayList(); // some operations will take long time to process, need to be done outside the table lock boolean needProcessOutsideTableLock = false; - - // check conflict alter ops first - AlterOperations currentAlterOps = new AlterOperations(); - currentAlterOps.checkConflict(alterClauses); - // check cluster capacity and db quota outside table lock to escape dead lock, only need to check once. - if (currentAlterOps.needCheckCapacity()) { - Catalog.getCurrentSystemInfo().checkClusterCapacity(clusterName); - db.checkQuota(); - } - switch (table.getType()) { case OLAP: OlapTable olapTable = (OlapTable) table; diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/DropDbTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/DropDbTest.java new file mode 100644 index 0000000000..8a75300fac --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/DropDbTest.java @@ -0,0 +1,124 @@ +// 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.analysis.CreateDbStmt; +import org.apache.doris.analysis.CreateTableStmt; +import org.apache.doris.analysis.DropDbStmt; +import org.apache.doris.analysis.RecoverDbStmt; +import org.apache.doris.common.DdlException; +import org.apache.doris.common.ExceptionChecker; +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.List; +import java.util.UUID; + +public class DropDbTest { + private static String runningDir = "fe/mocked/DropDbTest/" + UUID.randomUUID().toString() + "/"; + + private static ConnectContext connectContext; + + @BeforeClass + public static void beforeClass() throws Exception { + UtFrameUtils.createMinDorisCluster(runningDir); + + // create connect context + connectContext = UtFrameUtils.createDefaultCtx(); + // create database + String createDbStmtStr1 = "create database test1;"; + String createDbStmtStr2 = "create database test2;"; + String createTablleStr1 = "create table test1.tbl1(k1 int, k2 bigint) duplicate key(k1) " + + "distributed by hash(k2) buckets 1" + " properties('replication_num' = '1');"; + String createTablleStr2 = "create table test2.tbl1" + "(k1 int, k2 bigint)" + " duplicate key(k1) " + + "distributed by hash(k2) buckets 1 " + "properties('replication_num' = '1');"; + createDb(createDbStmtStr1); + createDb(createDbStmtStr2); + createTable(createTablleStr1); + createTable(createTablleStr2); + } + + @AfterClass + public static void tearDown() { + File file = new File(runningDir); + file.delete(); + } + + private static void createDb(String sql) throws Exception { + CreateDbStmt createDbStmt = (CreateDbStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().createDb(createDbStmt); + } + + private static void dropDb(String sql) throws Exception { + DropDbStmt dropDbStmt = (DropDbStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().dropDb(dropDbStmt); + } + + private static void createTable(String sql) throws Exception { + CreateTableStmt createTableStmt = (CreateTableStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().createTable(createTableStmt); + } + + @Test + public void testNormalDropDb() throws Exception { + Database db = Catalog.getCurrentCatalog().getDb("default_cluster:test1"); + OlapTable table = (OlapTable) db.getTable("tbl1"); + Partition partition = table.getAllPartitions().iterator().next(); + long tabletId = partition.getBaseIndex().getTablets().get(0).getId(); + String dropDbSql = "drop database test1"; + dropDb(dropDbSql); + db = Catalog.getCurrentCatalog().getDb("default_cluster:test1"); + List replicaList = Catalog.getCurrentCatalog().getTabletInvertedIndex().getReplicasByTabletId(tabletId); + Assert.assertNull(db); + Assert.assertEquals(1, replicaList.size()); + String recoverDbSql = "recover database test1"; + RecoverDbStmt recoverDbStmt = (RecoverDbStmt) UtFrameUtils.parseAndAnalyzeStmt(recoverDbSql, connectContext); + Catalog.getCurrentCatalog().recoverDatabase(recoverDbStmt); + db = Catalog.getCurrentCatalog().getDb("default_cluster:test1"); + Assert.assertNotNull(db); + Assert.assertEquals("default_cluster:test1", db.getFullName()); + table = (OlapTable) db.getTable("tbl1"); + Assert.assertNotNull(table); + Assert.assertEquals("tbl1", table.getName()); + } + + @Test + public void testForceDropDb() throws Exception { + String dropDbSql = "drop database test2 force"; + Database db = Catalog.getCurrentCatalog().getDb("default_cluster:test2"); + OlapTable table = (OlapTable) db.getTable("tbl1"); + Partition partition = table.getAllPartitions().iterator().next(); + long tabletId = partition.getBaseIndex().getTablets().get(0).getId(); + dropDb(dropDbSql); + db = Catalog.getCurrentCatalog().getDb("default_cluster:test2"); + List replicaList = Catalog.getCurrentCatalog().getTabletInvertedIndex().getReplicasByTabletId(tabletId); + Assert.assertNull(db); + Assert.assertTrue(replicaList.isEmpty()); + String recoverDbSql = "recover database test2"; + RecoverDbStmt recoverDbStmt = (RecoverDbStmt) UtFrameUtils.parseAndAnalyzeStmt(recoverDbSql, connectContext); + ExceptionChecker.expectThrowsWithMsg(DdlException.class, + "Unknown database 'default_cluster:test2'", + () -> Catalog.getCurrentCatalog().recoverDatabase(recoverDbStmt)); + } +} diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/DropPartitionTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/DropPartitionTest.java new file mode 100644 index 0000000000..1464fd1d63 --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/DropPartitionTest.java @@ -0,0 +1,117 @@ +// 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.analysis.AlterTableStmt; +import org.apache.doris.analysis.CreateDbStmt; +import org.apache.doris.analysis.CreateTableStmt; +import org.apache.doris.analysis.RecoverPartitionStmt; +import org.apache.doris.common.DdlException; +import org.apache.doris.common.ExceptionChecker; +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.List; +import java.util.UUID; + +public class DropPartitionTest { + private static String runningDir = "fe/mocked/DropPartitionTest/" + UUID.randomUUID().toString() + "/"; + + private static ConnectContext connectContext; + + @BeforeClass + public static void beforeClass() throws Exception { + UtFrameUtils.createMinDorisCluster(runningDir); + + // create connect context + connectContext = UtFrameUtils.createDefaultCtx(); + // create database + String createDbStmtStr = "create database test;"; + String createTablleStr = "create table test.tbl1(d1 date, k1 int, k2 bigint) duplicate key(d1, k1) " + + "PARTITION BY RANGE(d1) (PARTITION p20210201 VALUES [('2021-02-01'), ('2021-02-02'))," + + "PARTITION p20210202 VALUES [('2021-02-02'), ('2021-02-03'))) distributed by hash(k1) " + + "buckets 1 properties('replication_num' = '1');"; + createDb(createDbStmtStr); + createTable(createTablleStr); + } + + @AfterClass + public static void tearDown() { + File file = new File(runningDir); + file.delete(); + } + + private static void createDb(String sql) throws Exception { + CreateDbStmt createDbStmt = (CreateDbStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().createDb(createDbStmt); + } + + private static void createTable(String sql) throws Exception { + CreateTableStmt createTableStmt = (CreateTableStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().createTable(createTableStmt); + } + + private static void dropPartition(String sql) throws Exception { + AlterTableStmt alterTableStmt = (AlterTableStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().alterTable(alterTableStmt); + } + + @Test + public void testNormalDropPartition() throws Exception { + Database db = Catalog.getCurrentCatalog().getDb("default_cluster:test"); + OlapTable table = (OlapTable) db.getTable("tbl1"); + Partition partition = table.getPartition("p20210201"); + long tabletId = partition.getBaseIndex().getTablets().get(0).getId(); + String dropPartitionSql = " alter table test.tbl1 drop partition p20210201;"; + dropPartition(dropPartitionSql); + List replicaList = Catalog.getCurrentCatalog().getTabletInvertedIndex().getReplicasByTabletId(tabletId); + partition = table.getPartition("p20210201"); + Assert.assertEquals(1, replicaList.size()); + Assert.assertNull(partition); + String recoverPartitionSql = "recover partition p20210201 from test.tbl1"; + RecoverPartitionStmt recoverPartitionStmt = (RecoverPartitionStmt) UtFrameUtils.parseAndAnalyzeStmt(recoverPartitionSql, connectContext); + Catalog.getCurrentCatalog().recoverPartition(recoverPartitionStmt); + partition = table.getPartition("p20210201"); + Assert.assertNotNull(partition); + Assert.assertEquals("p20210201", partition.getName()); + } + + @Test + public void testForceDropPartition() throws Exception { + Database db = Catalog.getCurrentCatalog().getDb("default_cluster:test"); + OlapTable table = (OlapTable) db.getTable("tbl1"); + Partition partition = table.getPartition("p20210202"); + long tabletId = partition.getBaseIndex().getTablets().get(0).getId(); + String dropPartitionSql = " alter table test.tbl1 drop partition p20210202 force;"; + dropPartition(dropPartitionSql); + List replicaList = Catalog.getCurrentCatalog().getTabletInvertedIndex().getReplicasByTabletId(tabletId); + partition = table.getPartition("p20210202"); + Assert.assertTrue(replicaList.isEmpty()); + Assert.assertNull(partition); + String recoverPartitionSql = "recover partition p20210202 from test.tbl1"; + RecoverPartitionStmt recoverPartitionStmt = (RecoverPartitionStmt) UtFrameUtils.parseAndAnalyzeStmt(recoverPartitionSql, connectContext); + ExceptionChecker.expectThrowsWithMsg(DdlException.class, + "No partition named p20210202 in table tbl1", + () -> Catalog.getCurrentCatalog().recoverPartition(recoverPartitionStmt)); + } +} \ No newline at end of file diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/DropTableTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/DropTableTest.java new file mode 100644 index 0000000000..4c12e5380e --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/DropTableTest.java @@ -0,0 +1,114 @@ +// 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.analysis.CreateDbStmt; +import org.apache.doris.analysis.CreateTableStmt; +import org.apache.doris.analysis.DropTableStmt; +import org.apache.doris.analysis.RecoverTableStmt; +import org.apache.doris.common.DdlException; +import org.apache.doris.common.ExceptionChecker; +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.List; +import java.util.UUID; + +public class DropTableTest { + private static String runningDir = "fe/mocked/DropTableTest/" + UUID.randomUUID().toString() + "/"; + + private static ConnectContext connectContext; + + @BeforeClass + public static void beforeClass() throws Exception { + UtFrameUtils.createMinDorisCluster(runningDir); + + // create connect context + connectContext = UtFrameUtils.createDefaultCtx(); + // create database + String createDbStmtStr = "create database test;"; + String createTablleStr1 = "create table test.tbl1(k1 int, k2 bigint) duplicate key(k1) " + + "distributed by hash(k2) buckets 1 properties('replication_num' = '1');"; + String createTablleStr2 = "create table test.tbl2(k1 int, k2 bigint)" + "duplicate key(k1) " + + "distributed by hash(k2) buckets 1 " + "properties('replication_num' = '1');"; + createDb(createDbStmtStr); + createTable(createTablleStr1); + createTable(createTablleStr2); + } + + @AfterClass + public static void tearDown() { + File file = new File(runningDir); + file.delete(); + } + + private static void createDb(String sql) throws Exception { + CreateDbStmt createDbStmt = (CreateDbStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().createDb(createDbStmt); + } + + private static void createTable(String sql) throws Exception { + CreateTableStmt createTableStmt = (CreateTableStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().createTable(createTableStmt); + } + + private static void dropTable(String sql) throws Exception { + DropTableStmt dropTableStmt = (DropTableStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext); + Catalog.getCurrentCatalog().dropTable(dropTableStmt); + } + + @Test + public void testNormalDropTable() throws Exception { + Database db = Catalog.getCurrentCatalog().getDb("default_cluster:test"); + OlapTable table = (OlapTable) db.getTable("tbl1"); + Partition partition = table.getAllPartitions().iterator().next(); + long tabletId = partition.getBaseIndex().getTablets().get(0).getId(); + String dropTableSql = "drop table test.tbl1"; + dropTable(dropTableSql); + List replicaList = Catalog.getCurrentCatalog().getTabletInvertedIndex().getReplicasByTabletId(tabletId); + Assert.assertEquals(1, replicaList.size()); + String recoverDbSql = "recover table test.tbl1"; + RecoverTableStmt recoverTableStmt = (RecoverTableStmt) UtFrameUtils.parseAndAnalyzeStmt(recoverDbSql, connectContext); + Catalog.getCurrentCatalog().recoverTable(recoverTableStmt); + table = (OlapTable) db.getTable("tbl1"); + Assert.assertNotNull(table); + Assert.assertEquals("tbl1", table.getName()); + } + + @Test + public void testForceDropTable() throws Exception { + Database db = Catalog.getCurrentCatalog().getDb("default_cluster:test"); + OlapTable table = (OlapTable) db.getTable("tbl2"); + Partition partition = table.getAllPartitions().iterator().next(); + long tabletId = partition.getBaseIndex().getTablets().get(0).getId(); + String dropTableSql = "drop table test.tbl2 force"; + dropTable(dropTableSql); + List replicaList = Catalog.getCurrentCatalog().getTabletInvertedIndex().getReplicasByTabletId(tabletId); + Assert.assertTrue(replicaList.isEmpty()); + String recoverDbSql = "recover table test.tbl2"; + RecoverTableStmt recoverTableStmt = (RecoverTableStmt) UtFrameUtils.parseAndAnalyzeStmt(recoverDbSql, connectContext); + ExceptionChecker.expectThrowsWithMsg(DdlException.class, + "Unknown table 'tbl2'", + () -> Catalog.getCurrentCatalog().recoverTable(recoverTableStmt)); + } +}