[feature](multi-catalog)support catalog name when create/drop db (#33116)
Issue Number: #31442
This commit is contained in:
@ -772,6 +772,7 @@ nonterminal ArrayList<Long> opt_tablet_list, tablet_list;
|
||||
nonterminal TableSample opt_table_sample, table_sample;
|
||||
nonterminal TableSnapshot opt_table_snapshot, table_snapshot;
|
||||
nonterminal TableName table_name, opt_table_name;
|
||||
nonterminal DbName db_name;
|
||||
nonterminal FunctionName function_name;
|
||||
nonterminal EncryptKeyName encryptkey_name;
|
||||
nonterminal Expr pre_filter_clause;
|
||||
@ -1766,11 +1767,11 @@ opt_intermediate_type ::=
|
||||
// Create Statement
|
||||
create_stmt ::=
|
||||
/* Database */
|
||||
KW_CREATE KW_DATABASE opt_if_not_exists:ifNotExists ident:db opt_properties:properties
|
||||
KW_CREATE KW_DATABASE opt_if_not_exists:ifNotExists db_name:db opt_properties:properties
|
||||
{:
|
||||
RESULT = new CreateDbStmt(ifNotExists, db, properties);
|
||||
:}
|
||||
| KW_CREATE KW_SCHEMA opt_if_not_exists:ifNotExists ident:db
|
||||
| KW_CREATE KW_SCHEMA opt_if_not_exists:ifNotExists db_name:db
|
||||
{:
|
||||
RESULT = new CreateDbStmt(ifNotExists, db, null);
|
||||
:}
|
||||
@ -2989,11 +2990,11 @@ revoke_stmt ::=
|
||||
// Drop statement
|
||||
drop_stmt ::=
|
||||
/* Database */
|
||||
KW_DROP KW_DATABASE opt_if_exists:ifExists ident:db opt_force:force
|
||||
KW_DROP KW_DATABASE opt_if_exists:ifExists db_name:db opt_force:force
|
||||
{:
|
||||
RESULT = new DropDbStmt(ifExists, db, force);
|
||||
:}
|
||||
| KW_DROP KW_SCHEMA opt_if_exists:ifExists ident:db opt_force:force
|
||||
| KW_DROP KW_SCHEMA opt_if_exists:ifExists db_name:db opt_force:force
|
||||
{:
|
||||
RESULT = new DropDbStmt(ifExists, db, force);
|
||||
:}
|
||||
@ -5793,6 +5794,13 @@ table_name ::=
|
||||
{: RESULT = new TableName(ctl, db, tbl); :}
|
||||
;
|
||||
|
||||
db_name ::=
|
||||
ident:db
|
||||
{: RESULT = new DbName(null, db); :}
|
||||
| ident:ctl DOT ident:db
|
||||
{: RESULT = new DbName(ctl, db); :}
|
||||
;
|
||||
|
||||
colocate_group_name ::=
|
||||
ident:group
|
||||
{:
|
||||
|
||||
@ -27,17 +27,21 @@ import org.apache.doris.common.util.PrintableMap;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CreateDbStmt extends DdlStmt {
|
||||
private boolean ifNotExists;
|
||||
private String ctlName;
|
||||
private String dbName;
|
||||
private Map<String, String> properties;
|
||||
|
||||
public CreateDbStmt(boolean ifNotExists, String dbName, Map<String, String> properties) {
|
||||
public CreateDbStmt(boolean ifNotExists, DbName dbName, Map<String, String> properties) {
|
||||
this.ifNotExists = ifNotExists;
|
||||
this.dbName = dbName;
|
||||
this.ctlName = dbName.getCtl();
|
||||
this.dbName = dbName.getDb();
|
||||
this.properties = properties == null ? new HashMap<>() : properties;
|
||||
}
|
||||
|
||||
@ -45,6 +49,10 @@ public class CreateDbStmt extends DdlStmt {
|
||||
return dbName;
|
||||
}
|
||||
|
||||
public String getCtlName() {
|
||||
return ctlName;
|
||||
}
|
||||
|
||||
public boolean isSetIfNotExists() {
|
||||
return ifNotExists;
|
||||
}
|
||||
@ -56,6 +64,10 @@ public class CreateDbStmt extends DdlStmt {
|
||||
@Override
|
||||
public void analyze(Analyzer analyzer) throws UserException {
|
||||
super.analyze(analyzer);
|
||||
if (StringUtils.isEmpty(ctlName)) {
|
||||
ctlName = Env.getCurrentEnv().getCurrentCatalog().getName();
|
||||
}
|
||||
FeNameFormat.checkCatalogName(ctlName);
|
||||
FeNameFormat.checkDbName(dbName);
|
||||
InternalDatabaseUtil.checkDatabase(dbName, ConnectContext.get());
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(), dbName, PrivPredicate.CREATE)) {
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
// 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.
|
||||
// This file is copied from
|
||||
// https://github.com/apache/impala/blob/branch-2.9.0/fe/src/main/java/org/apache/impala/TableName.java
|
||||
// and modified by Doris
|
||||
|
||||
package org.apache.doris.analysis;
|
||||
|
||||
import org.apache.doris.datasource.InternalCatalog;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class DbName {
|
||||
private String ctl;
|
||||
private String db;
|
||||
|
||||
public DbName(String ctl, String db) {
|
||||
this.ctl = ctl;
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public String getCtl() {
|
||||
return ctl;
|
||||
}
|
||||
|
||||
public void setCtl(String ctl) {
|
||||
this.ctl = ctl;
|
||||
}
|
||||
|
||||
public String getDb() {
|
||||
return db;
|
||||
}
|
||||
|
||||
public void setDb(String db) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (ctl != null && !ctl.equals(InternalCatalog.INTERNAL_CATALOG_NAME)) {
|
||||
stringBuilder.append(ctl).append(".");
|
||||
}
|
||||
stringBuilder.append(db);
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other instanceof DbName) {
|
||||
return toString().equals(other.toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(ctl, db);
|
||||
}
|
||||
|
||||
public String toSql() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (ctl != null && !ctl.equals(InternalCatalog.INTERNAL_CATALOG_NAME)) {
|
||||
stringBuilder.append("`").append(ctl).append("`.");
|
||||
}
|
||||
stringBuilder.append("`").append(db).append("`");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
@ -32,12 +32,14 @@ import com.google.common.base.Strings;
|
||||
// DROP DB表达式
|
||||
public class DropDbStmt extends DdlStmt {
|
||||
private boolean ifExists;
|
||||
private String ctlName;
|
||||
private String dbName;
|
||||
private boolean forceDrop;
|
||||
|
||||
public DropDbStmt(boolean ifExists, String dbName, boolean forceDrop) {
|
||||
public DropDbStmt(boolean ifExists, DbName dbName, boolean forceDrop) {
|
||||
this.ifExists = ifExists;
|
||||
this.dbName = dbName;
|
||||
this.ctlName = dbName.getCtl();
|
||||
this.dbName = dbName.getDb();
|
||||
this.forceDrop = forceDrop;
|
||||
}
|
||||
|
||||
@ -45,6 +47,10 @@ public class DropDbStmt extends DdlStmt {
|
||||
return ifExists;
|
||||
}
|
||||
|
||||
public String getCtlName() {
|
||||
return ctlName;
|
||||
}
|
||||
|
||||
public String getDbName() {
|
||||
return this.dbName;
|
||||
}
|
||||
|
||||
@ -2967,7 +2967,13 @@ public class Env {
|
||||
|
||||
// The interface which DdlExecutor needs.
|
||||
public void createDb(CreateDbStmt stmt) throws DdlException {
|
||||
getCurrentCatalog().createDb(stmt);
|
||||
CatalogIf<?> catalogIf;
|
||||
if (StringUtils.isEmpty(stmt.getCtlName())) {
|
||||
catalogIf = getCurrentCatalog();
|
||||
} else {
|
||||
catalogIf = catalogMgr.getCatalog(stmt.getCtlName());
|
||||
}
|
||||
catalogIf.createDb(stmt);
|
||||
}
|
||||
|
||||
// For replay edit log, need't lock metadata
|
||||
@ -2980,7 +2986,13 @@ public class Env {
|
||||
}
|
||||
|
||||
public void dropDb(DropDbStmt stmt) throws DdlException {
|
||||
getCurrentCatalog().dropDb(stmt);
|
||||
CatalogIf<?> catalogIf;
|
||||
if (StringUtils.isEmpty(stmt.getCtlName())) {
|
||||
catalogIf = getCurrentCatalog();
|
||||
} else {
|
||||
catalogIf = catalogMgr.getCatalog(stmt.getCtlName());
|
||||
}
|
||||
catalogIf.dropDb(stmt);
|
||||
}
|
||||
|
||||
public void replayDropDb(String dbName, boolean isForceDrop, Long recycleTime) throws DdlException {
|
||||
|
||||
@ -21,6 +21,7 @@ import org.apache.doris.analysis.AlterClause;
|
||||
import org.apache.doris.analysis.AlterTableStmt;
|
||||
import org.apache.doris.analysis.CreateDbStmt;
|
||||
import org.apache.doris.analysis.CreateTableStmt;
|
||||
import org.apache.doris.analysis.DbName;
|
||||
import org.apache.doris.analysis.DistributionDesc;
|
||||
import org.apache.doris.analysis.DropTableStmt;
|
||||
import org.apache.doris.analysis.HashDistributionDesc;
|
||||
@ -164,8 +165,8 @@ public class InternalSchemaInitializer extends Thread {
|
||||
|
||||
@VisibleForTesting
|
||||
public static void createDb() {
|
||||
CreateDbStmt createDbStmt = new CreateDbStmt(true, FeConstants.INTERNAL_DB_NAME,
|
||||
null);
|
||||
CreateDbStmt createDbStmt = new CreateDbStmt(true,
|
||||
new DbName("internal", FeConstants.INTERNAL_DB_NAME), null);
|
||||
try {
|
||||
Env.getCurrentEnv().createDb(createDbStmt);
|
||||
} catch (DdlException e) {
|
||||
|
||||
@ -48,7 +48,7 @@ public class CreateDbStmtTest {
|
||||
|
||||
@Test
|
||||
public void testAnalyzeNormal() throws UserException {
|
||||
CreateDbStmt dbStmt = new CreateDbStmt(false, "test", null);
|
||||
CreateDbStmt dbStmt = new CreateDbStmt(false, new DbName(null, "test"), null);
|
||||
dbStmt.analyze(analyzer);
|
||||
Assert.assertEquals("test", dbStmt.getFullDbName());
|
||||
Assert.assertEquals("CREATE DATABASE `test`", dbStmt.toString());
|
||||
@ -56,7 +56,7 @@ public class CreateDbStmtTest {
|
||||
|
||||
@Test(expected = AnalysisException.class)
|
||||
public void testAnalyzeWithException() throws UserException {
|
||||
CreateDbStmt stmt = new CreateDbStmt(false, "", null);
|
||||
CreateDbStmt stmt = new CreateDbStmt(false, new DbName("", ""), null);
|
||||
stmt.analyze(analyzer);
|
||||
Assert.fail("no exception");
|
||||
}
|
||||
@ -66,8 +66,9 @@ public class CreateDbStmtTest {
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.put("iceberg.database", "doris");
|
||||
properties.put("iceberg.hive.metastore.uris", "thrift://127.0.0.1:9087");
|
||||
CreateDbStmt stmt = new CreateDbStmt(false, "test", properties);
|
||||
CreateDbStmt stmt = new CreateDbStmt(false, new DbName("ctl", "test"), properties);
|
||||
stmt.analyze(analyzer);
|
||||
Assert.assertEquals("ctl", stmt.getCtlName());
|
||||
Assert.assertEquals("test", stmt.getFullDbName());
|
||||
Assert.assertEquals("CREATE DATABASE `test`\n"
|
||||
+ "PROPERTIES (\n"
|
||||
@ -81,7 +82,7 @@ public class CreateDbStmtTest {
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.put("iceberg.database", "doris");
|
||||
properties.put("iceberg.hive.metastore.uris", "thrift://127.0.0.1:9087");
|
||||
CreateDbStmt stmt = new CreateDbStmt(false, "", properties);
|
||||
CreateDbStmt stmt = new CreateDbStmt(false, new DbName("", ""), properties);
|
||||
stmt.analyze(analyzer);
|
||||
Assert.fail("No exception throws.");
|
||||
}
|
||||
|
||||
@ -45,16 +45,17 @@ public class DropDbStmtTest {
|
||||
|
||||
@Test
|
||||
public void testNormal() throws UserException, AnalysisException {
|
||||
DropDbStmt stmt = new DropDbStmt(false, "test", true);
|
||||
DropDbStmt stmt = new DropDbStmt(false, new DbName("test", "test"), true);
|
||||
|
||||
stmt.analyze(analyzer);
|
||||
Assert.assertEquals("test", stmt.getCtlName());
|
||||
Assert.assertEquals("test", stmt.getDbName());
|
||||
Assert.assertEquals("DROP DATABASE `test`", stmt.toString());
|
||||
}
|
||||
|
||||
@Test(expected = AnalysisException.class)
|
||||
public void testFailed() throws UserException, AnalysisException {
|
||||
DropDbStmt stmt = new DropDbStmt(false, "", true);
|
||||
DropDbStmt stmt = new DropDbStmt(false, new DbName("", ""), true);
|
||||
|
||||
stmt.analyze(analyzer);
|
||||
Assert.fail("no exception");
|
||||
@ -62,7 +63,7 @@ public class DropDbStmtTest {
|
||||
|
||||
@Test
|
||||
public void testNoPriv() {
|
||||
DropDbStmt stmt = new DropDbStmt(false, "", true);
|
||||
DropDbStmt stmt = new DropDbStmt(false, new DbName("", ""), true);
|
||||
try {
|
||||
stmt.analyze(AccessTestUtil.fetchBlockAnalyzer());
|
||||
} catch (AnalysisException e) {
|
||||
|
||||
@ -20,6 +20,7 @@ package org.apache.doris.datasource.hive;
|
||||
import org.apache.doris.analysis.CreateCatalogStmt;
|
||||
import org.apache.doris.analysis.CreateDbStmt;
|
||||
import org.apache.doris.analysis.CreateTableStmt;
|
||||
import org.apache.doris.analysis.DbName;
|
||||
import org.apache.doris.analysis.HashDistributionDesc;
|
||||
import org.apache.doris.analysis.SwitchStmt;
|
||||
import org.apache.doris.catalog.Column;
|
||||
@ -140,7 +141,7 @@ public class HiveDDLAndDMLPlanTest extends TestWithFeService {
|
||||
}
|
||||
}
|
||||
};
|
||||
CreateDbStmt createDbStmt = new CreateDbStmt(true, mockedDbName, dbProps);
|
||||
CreateDbStmt createDbStmt = new CreateDbStmt(true, new DbName("hive", mockedDbName), dbProps);
|
||||
Env.getCurrentEnv().createDb(createDbStmt);
|
||||
useDatabase(mockedDbName);
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ package org.apache.doris.datasource.hive;
|
||||
|
||||
import org.apache.doris.analysis.CreateDbStmt;
|
||||
import org.apache.doris.analysis.CreateTableStmt;
|
||||
import org.apache.doris.analysis.DbName;
|
||||
import org.apache.doris.analysis.DistributionDesc;
|
||||
import org.apache.doris.analysis.DropDbStmt;
|
||||
import org.apache.doris.analysis.DropTableStmt;
|
||||
@ -99,12 +100,12 @@ public class HiveMetadataOpsTest {
|
||||
}
|
||||
|
||||
private void createDb(String dbName, Map<String, String> props) throws DdlException {
|
||||
CreateDbStmt createDbStmt = new CreateDbStmt(true, dbName, props);
|
||||
CreateDbStmt createDbStmt = new CreateDbStmt(true, new DbName("hive", dbName), props);
|
||||
metadataOps.createDb(createDbStmt);
|
||||
}
|
||||
|
||||
private void dropDb(String dbName, boolean forceDrop) throws DdlException {
|
||||
DropDbStmt dropDbStmt = new DropDbStmt(true, dbName, forceDrop);
|
||||
DropDbStmt dropDbStmt = new DropDbStmt(true, new DbName("hive", dbName), forceDrop);
|
||||
metadataOps.dropDb(dropDbStmt);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user