| // 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.impala.analysis; |
| |
| import com.google.common.base.Preconditions; |
| import org.apache.hadoop.fs.permission.FsAction; |
| import org.apache.impala.authorization.Privilege; |
| import org.apache.impala.catalog.FeDb; |
| import org.apache.impala.common.AnalysisException; |
| import org.apache.impala.compat.MetastoreShim; |
| import org.apache.impala.thrift.TCreateDbParams; |
| import org.apache.impala.util.CatalogBlacklistUtils; |
| |
| /** |
| * Represents a CREATE DATABASE statement |
| */ |
| public class CreateDbStmt extends StatementBase { |
| private final String dbName_; |
| private final HdfsUri location_; |
| private final String comment_; |
| private final boolean ifNotExists_; |
| // Database owner. Set during analysis. |
| private String owner_; |
| |
| // Server name needed for privileges. Set during analysis. |
| private String serverName_; |
| |
| /** |
| * Creates a database with the given name. |
| */ |
| public CreateDbStmt(String dbName) { |
| this(dbName, null, null, false); |
| } |
| |
| /** |
| * Creates a database with the given name, comment, and HDFS table storage location. |
| * New tables created in the database inherit the location property for their default |
| * storage location. Create database will throw an error if the database already exists |
| * unless the ifNotExists is true. |
| */ |
| public CreateDbStmt(String dbName, String comment, HdfsUri location, |
| boolean ifNotExists) { |
| this.dbName_ = dbName; |
| this.comment_ = comment; |
| this.location_ = location; |
| this.ifNotExists_ = ifNotExists; |
| } |
| |
| public String getComment() { return comment_; } |
| public String getDb() { return dbName_; } |
| public boolean getIfNotExists() { return ifNotExists_; } |
| |
| @Override |
| public String toSql(ToSqlOptions options) { |
| StringBuilder sb = new StringBuilder("CREATE DATABASE "); |
| if (ifNotExists_) sb.append("IF NOT EXISTS"); |
| sb.append(dbName_); |
| if (comment_ != null) sb.append(" COMMENT '" + comment_ + "'"); |
| if (location_ != null) sb.append(" LOCATION '" + location_ + "'"); |
| return sb.toString(); |
| } |
| |
| public TCreateDbParams toThrift() { |
| TCreateDbParams params = new TCreateDbParams(); |
| params.setDb(getDb()); |
| params.setComment(getComment()); |
| params.setLocation(location_ == null ? null : location_.toString()); |
| params.setIf_not_exists(getIfNotExists()); |
| params.setOwner(getOwner()); |
| params.setServer_name(serverName_); |
| return params; |
| } |
| |
| @Override |
| public void analyze(Analyzer analyzer) throws AnalysisException { |
| // Check whether the db name meets the Metastore's requirements. |
| if (!MetastoreShim.validateName(dbName_)) { |
| throw new AnalysisException("Invalid database name: " + dbName_); |
| } |
| CatalogBlacklistUtils.verifyDbName(dbName_); |
| |
| // Note: It is possible that a database with the same name was created external to |
| // this Impala instance. If that happens, the caller will not get an |
| // AnalysisException when creating the database, they will get a Hive |
| // AlreadyExistsException once the request has been sent to the metastore. |
| FeDb db = analyzer.getDb(getDb(), Privilege.CREATE, false); |
| if (db != null && !ifNotExists_) { |
| throw new AnalysisException(Analyzer.DB_ALREADY_EXISTS_ERROR_MSG + getDb()); |
| } |
| |
| if (location_ != null) { |
| location_.analyze(analyzer, Privilege.ALL, FsAction.READ_WRITE); |
| } |
| owner_ = analyzer.getUserShortName(); |
| // Set the servername here if authorization is enabled because analyzer_ is not |
| // available in the toThrift() method. |
| serverName_ = analyzer.getServerName(); |
| } |
| |
| /** |
| * Can only be called after analysis, returns the owner of this database (the user from |
| * the current session). |
| */ |
| public String getOwner() { return Preconditions.checkNotNull(owner_); } |
| } |