Skip to content

Commit

Permalink
[feature-wip](multi-catalog) support to switch catalog
Browse files Browse the repository at this point in the history
  • Loading branch information
AshinGau committed Jun 23, 2022
1 parent 3370c10 commit 5fa0b5e
Show file tree
Hide file tree
Showing 22 changed files with 452 additions and 65 deletions.
15 changes: 13 additions & 2 deletions fe/fe-core/src/main/cup/sql_parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@ terminal String KW_ADD, KW_ADMIN, KW_AFTER, KW_AGGREGATE, KW_ALIAS, KW_ALL, KW_A
KW_WARNINGS, KW_WEEK, KW_WHEN, KW_WHITELIST, KW_WHERE, KW_WITH, KW_WORK, KW_WRITE,
KW_YEAR,
KW_NOT_NULL,
KW_CATALOG, KW_CATALOGS;
KW_CATALOG, KW_CATALOGS,
KW_SWITCH;

terminal COMMA, COLON, DOT, DOTDOTDOT, AT, STAR, LPAREN, RPAREN, SEMICOLON, LBRACKET, RBRACKET, DIVIDE, MOD, ADD, SUBTRACT;
terminal BITAND, BITOR, BITXOR, BITNOT;
Expand All @@ -301,7 +302,7 @@ nonterminal StatementBase stmt, show_stmt, show_param, help_stmt, load_stmt,
show_routine_load_stmt, show_routine_load_task_stmt, show_create_routine_load_stmt,
describe_stmt, alter_stmt,
use_stmt, kill_stmt, drop_stmt, recover_stmt, grant_stmt, revoke_stmt, create_stmt, set_stmt, sync_stmt, cancel_stmt, cancel_param, delete_stmt,
link_stmt, migrate_stmt, enter_stmt, transaction_stmt, unsupported_stmt, export_stmt, admin_stmt, truncate_stmt,
link_stmt, migrate_stmt, switch_stmt, enter_stmt, transaction_stmt, unsupported_stmt, export_stmt, admin_stmt, truncate_stmt,
import_columns_stmt, import_delete_on_stmt, import_sequence_stmt, import_where_stmt, install_plugin_stmt, uninstall_plugin_stmt,
import_preceding_filter_stmt, unlock_tables_stmt, lock_tables_stmt, refresh_stmt;

Expand Down Expand Up @@ -670,6 +671,8 @@ stmt ::=
{: RESULT = query; :}
| migrate_stmt:query
{: RESULT = query; :}
| switch_stmt:stmt
{: RESULT = stmt; :}
| enter_stmt:enter
{: RESULT = enter; :}
| query_stmt:query
Expand Down Expand Up @@ -3422,6 +3425,14 @@ opt_set_qualifier ::=
{: RESULT = Qualifier.ALL; :}
;

// Change catalog
switch_stmt ::=
KW_SWITCH ident:catalog
{:
RESULT = new SwitchStmt(catalog);
:}
;

// Change cluster
enter_stmt ::=
KW_ENTER ident:cluster
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,14 @@

package org.apache.doris.analysis;


import org.apache.doris.analysis.CompoundPredicate.Operator;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.FeNameFormat;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.InternalDataSource;
import org.apache.doris.mysql.privilege.PaloPrivilege;
import org.apache.doris.mysql.privilege.PrivBitSet;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;

Expand Down Expand Up @@ -57,21 +53,15 @@ public String getNewCatalogName() {
@Override
public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);
if (!Config.enable_multi_catalog) {
throw new AnalysisException("The multi-catalog feature is still in experiment, and you can enable it "
+ "manually by set fe configuration named `enable_multi_catalog` to be ture.");
}
if (Strings.isNullOrEmpty(catalogName)) {
throw new AnalysisException("Datasource name is not set");
}
Util.checkCatalogAllRules(catalogName);

if (catalogName.equals(InternalDataSource.INTERNAL_DS_NAME)) {
throw new AnalysisException("Internal catalog can't be alter.");
}

if (!Catalog.getCurrentCatalog().getAuth().checkGlobalPriv(ConnectContext.get(),
PrivPredicate.of(PrivBitSet.of(PaloPrivilege.ADMIN_PRIV, PaloPrivilege.ALTER_PRIV), Operator.OR))) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
if (!Catalog.getCurrentCatalog().getAuth().checkCtlPriv(
ConnectContext.get(), catalogName, PrivPredicate.ALTER)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_CATALOG_ACCESS_DENIED,
analyzer.getQualifiedUser(), catalogName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@

package org.apache.doris.analysis;

import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.FeNameFormat;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.PrintableMap;
import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.InternalDataSource;

import com.google.common.base.Strings;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;

import java.util.Map;

Expand All @@ -51,12 +54,11 @@ public Map<String, String> getNewProperties() {
@Override
public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);
if (!Config.enable_multi_catalog) {
throw new AnalysisException("The multi-catalog feature is still in experiment, and you can enable it "
+ "manually by set fe configuration named `enable_multi_catalog` to be ture.");
}
if (Strings.isNullOrEmpty(catalogName)) {
throw new AnalysisException("Datasource name is not set");
Util.checkCatalogAllRules(catalogName);
if (!Catalog.getCurrentCatalog().getAuth().checkCtlPriv(
ConnectContext.get(), catalogName, PrivPredicate.ALTER)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_CATALOG_ACCESS_DENIED,
analyzer.getQualifiedUser(), catalogName);
}

if (catalogName.equals(InternalDataSource.INTERNAL_DS_NAME)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@

import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.FeNameFormat;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.PrintableMap;
import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.InternalDataSource;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;
Expand Down Expand Up @@ -64,17 +64,14 @@ public boolean isSetIfNotExists() {
@Override
public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);
if (!Config.enable_multi_catalog) {
throw new AnalysisException("The multi-catalog feature is still in experiment, and you can enable it "
+ "manually by set fe configuration named `enable_multi_catalog` to be ture.");
}
Util.checkCatalogAllRules(catalogName);
if (catalogName.equals(InternalDataSource.INTERNAL_DS_NAME)) {
throw new AnalysisException("Internal catalog name can't be create.");
}
FeNameFormat.checkCommonName("catalog", catalogName);

if (!Catalog.getCurrentCatalog().getAuth().checkGlobalPriv(ConnectContext.get(), PrivPredicate.CREATE)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
if (!Catalog.getCurrentCatalog().getAuth().checkCtlPriv(
ConnectContext.get(), catalogName, PrivPredicate.CREATE)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_CATALOG_ACCESS_DENIED,
analyzer.getQualifiedUser(), catalogName);
}
FeNameFormat.checkCatalogProperties(properties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@

import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.InternalDataSource;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;

import com.google.common.base.Strings;

/**
* Statement for drop a catalog.
*/
Expand All @@ -52,21 +50,16 @@ public String getCatalogName() {
@Override
public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);
if (!Config.enable_multi_catalog) {
throw new AnalysisException("The multi-catalog feature is still in experiment, and you can enable it "
+ "manually by set fe configuration named `enable_multi_catalog` to be ture.");
}
if (Strings.isNullOrEmpty(catalogName)) {
throw new AnalysisException("Datasource name is not set");
}
Util.checkCatalogAllRules(catalogName);

if (catalogName.equals(InternalDataSource.INTERNAL_DS_NAME)) {
throw new AnalysisException("Internal catalog can't be drop.");
}

if (!Catalog.getCurrentCatalog().getAuth().checkGlobalPriv(ConnectContext.get(), PrivPredicate.DROP)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
ConnectContext.get().getQualifiedUser(), catalogName);
if (!Catalog.getCurrentCatalog().getAuth().checkCtlPriv(
ConnectContext.get(), catalogName, PrivPredicate.DROP)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_CATALOG_ACCESS_DENIED,
analyzer.getQualifiedUser(), catalogName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,21 @@ public static void checkPrivileges(Analyzer analyzer, List<PaloPrivilege> privil
if (!Catalog.getCurrentCatalog().getAuth().checkGlobalPriv(ConnectContext.get(), PrivPredicate.GRANT)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "GRANT");
}
} else if (tblPattern.getPrivLevel() == PrivLevel.CATALOG) {
if (!Catalog.getCurrentCatalog().getAuth().checkCtlPriv(ConnectContext.get(),
tblPattern.getQualifiedCtl(), PrivPredicate.GRANT)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "GRANT");
}
} else if (tblPattern.getPrivLevel() == PrivLevel.DATABASE) {
if (!Catalog.getCurrentCatalog().getAuth().checkDbPriv(ConnectContext.get(),
tblPattern.getQualifiedDb(), PrivPredicate.GRANT)) {
tblPattern.getQualifiedCtl(), tblPattern.getQualifiedDb(), PrivPredicate.GRANT)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "GRANT");
}
} else {
// table level
if (!Catalog.getCurrentCatalog().getAuth().checkTblPriv(ConnectContext.get(),
tblPattern.getQualifiedDb(), tblPattern.getTbl(), PrivPredicate.GRANT)) {
tblPattern.getQualifiedCtl(), tblPattern.getQualifiedDb(),
tblPattern.getTbl(), PrivPredicate.GRANT)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "GRANT");
}
}
Expand Down
65 changes: 65 additions & 0 deletions fe/fe-core/src/main/java/org/apache/doris/analysis/SwitchStmt.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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.analysis;

import org.apache.doris.catalog.Catalog;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.Util;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;

public class SwitchStmt extends StatementBase {
private final String catalogName;

public SwitchStmt(String catalogName) {
this.catalogName = catalogName;
}

public String getCatalogName() {
return catalogName;
}

@Override
public String toSql() {
return "SWITCH `" + catalogName + "`";
}

@Override
public String toString() {
return toSql();
}

public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);

Util.checkCatalogAllRules(catalogName);

if (!Catalog.getCurrentCatalog().getAuth().checkCtlPriv(
ConnectContext.get(), catalogName, PrivPredicate.SHOW)) {
ErrorReport.reportAnalysisException(
ErrorCode.ERR_CATALOG_ACCESS_DENIED, analyzer.getQualifiedUser(), catalogName);
}
}

@Override
public RedirectStatus getRedirectStatus() {
return RedirectStatus.NO_FORWARD;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4218,6 +4218,15 @@ public void cancelAlterCluster(CancelAlterSystemStmt stmt) throws DdlException {
this.alter.getClusterHandler().cancel(stmt);
}

// Switch catalog of this sesseion.
public void changeCatalog(ConnectContext ctx, String catalogName) throws DdlException {
if (dataSourceMgr.getCatalogNullable(catalogName) == null) {
throw new DdlException(ErrorCode.ERR_UNKNOWN_CATALOG.formatErrorMsg(
catalogName), ErrorCode.ERR_UNKNOWN_CATALOG);
}
ctx.changeDefaultCatalog(catalogName);
}

// Change current database of this session.
public void changeDb(ConnectContext ctx, String qualifiedDb) throws DdlException {
if (!auth.checkDbPriv(ctx, qualifiedDb, PrivPredicate.SHOW)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1686,7 +1686,10 @@ public enum ErrorCode {
+ "Use `SHOW PARTITIONS FROM %s` to see the currently partitions of this table. "),
ERROR_SQL_AND_LIMITATIONS_SET_IN_ONE_RULE(5084, new byte[]{'4', '2', '0', '0', '0'},
"sql/sqlHash and partition_num/tablet_num/cardinality cannot be set in one rule."),
ERR_WRONG_CATALOG_NAME(5085, new byte[]{'4', '2', '0', '0', '0'}, "Incorrect catalog name '%s'");
ERR_WRONG_CATALOG_NAME(5085, new byte[]{'4', '2', '0', '0', '0'}, "Incorrect catalog name '%s'"),
ERR_UNKNOWN_CATALOG(5086, new byte[]{'4', '2', '0', '0', '0'}, "Unknown catalog '%s'"),
ERR_CATALOG_ACCESS_DENIED(5087, new byte[]{'4', '2', '0', '0', '0'},
"Access denied for user '%s' to catalog '%s'");

// This is error code
private final int code;
Expand Down
28 changes: 28 additions & 0 deletions fe/fe-core/src/main/java/org/apache/doris/common/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.FeNameFormat;
import org.apache.doris.datasource.InternalDataSource;
import org.apache.doris.qe.ConnectContext;

import com.google.common.base.Preconditions;
Expand Down Expand Up @@ -457,4 +460,29 @@ public static String escapeSingleRegex(String s) {
}
return s;
}

/**
* Multi-catalog feature is in experiment, and should be enabled by user manually.
*/
public static void checkCatalogEnabled() throws AnalysisException {
if (!Config.enable_multi_catalog) {
throw new AnalysisException("The multi-catalog feature is still in experiment, and you can enable it "
+ "manually by set fe configuration named `enable_multi_catalog` to be ture.");
}
}

/**
* Check all rules of catalog.
*/
public static void checkCatalogAllRules(String catalog) throws AnalysisException {
checkCatalogEnabled();

if (Strings.isNullOrEmpty(catalog)) {
throw new AnalysisException("Catalog name is empty.");
}

if (!catalog.equals(InternalDataSource.INTERNAL_DS_NAME)) {
FeNameFormat.checkCommonName("catalog", catalog);
}
}
}
Loading

0 comments on commit 5fa0b5e

Please sign in to comment.