aboutsummaryrefslogtreecommitdiff
path: root/exec/java-exec/src/main/java/org/apache/drill
diff options
context:
space:
mode:
authorArina Ielchiieva <arina.yelchiyeva@gmail.com>2017-02-22 18:13:14 +0000
committerSudheesh Katkam <sudheesh@apache.org>2017-02-24 19:01:40 -0800
commit5db557c66b3d3b1a01ff6a8d1c0081205c8b6ef3 (patch)
treeca635740bbce47605dd69b9c19860af8be3fedf7 /exec/java-exec/src/main/java/org/apache/drill
parent456e26cf0113088a4089226bf088f49cdccf6821 (diff)
DRILL-5255: Remove default temporary workspace check at drillbit start up
closes #759
Diffstat (limited to 'exec/java-exec/src/main/java/org/apache/drill')
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/SchemaUtilites.java90
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java27
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DropTableHandler.java5
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java21
-rw-r--r--exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java21
5 files changed, 88 insertions, 76 deletions
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/SchemaUtilites.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/SchemaUtilites.java
index 20c92c753..51c3cb107 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/SchemaUtilites.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/SchemaUtilites.java
@@ -21,9 +21,7 @@ import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.apache.calcite.schema.SchemaPlus;
-import org.apache.calcite.tools.ValidationException;
import org.apache.drill.common.config.DrillConfig;
-import org.apache.drill.common.exceptions.DrillRuntimeException;
import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.store.AbstractSchema;
@@ -70,10 +68,9 @@ public class SchemaUtilites {
/**
* Same utility as {@link #findSchema(SchemaPlus, List)} except the search schema path given here is complete path
* instead of list. Use "." separator to divided the schema into nested schema names.
- * @param defaultSchema
- * @param schemaPath
- * @return
- * @throws ValidationException
+ * @param defaultSchema default schema
+ * @param schemaPath current schema path
+ * @return found schema path
*/
public static SchemaPlus findSchema(final SchemaPlus defaultSchema, final String schemaPath) {
final List<String> schemaPathAsList = Lists.newArrayList(schemaPath.split("\\."));
@@ -92,9 +89,8 @@ public class SchemaUtilites {
}
/**
- * Returns true if the given <i>schema</i> is root schema. False otherwise.
- * @param schema
- * @return
+ * @param schema current schema
+ * @return true if the given <i>schema</i> is root schema. False otherwise.
*/
public static boolean isRootSchema(SchemaPlus schema) {
return schema.getParentSchema() == null;
@@ -128,7 +124,7 @@ public class SchemaUtilites {
/** Utility method to get the schema path as list for given schema instance. */
public static List<String> getSchemaPathAsList(SchemaPlus schema) {
if (isRootSchema(schema)) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
List<String> path = Lists.newArrayListWithCapacity(5);
@@ -156,12 +152,13 @@ public class SchemaUtilites {
/**
* Given reference to default schema in schema tree, search for schema with given <i>schemaPath</i>. Once a schema is
* found resolve it into a mutable <i>AbstractDrillSchema</i> instance. A {@link UserException} is throws when:
- * 1. No schema for given <i>schemaPath</i> is found,
- * 2. Schema found for given <i>schemaPath</i> is a root schema
- * 3. Resolved schema is not a mutable schema.
- * @param defaultSchema
- * @param schemaPath
- * @return
+ * <li>No schema for given <i>schemaPath</i> is found.</li>
+ * <li>Schema found for given <i>schemaPath</i> is a root schema.</li>
+ * <li>Resolved schema is not a mutable schema.</li>
+ *
+ * @param defaultSchema default schema
+ * @param schemaPath current schema path
+ * @return mutable schema, exception otherwise
*/
public static AbstractSchema resolveToMutableDrillSchema(final SchemaPlus defaultSchema, List<String> schemaPath) {
final SchemaPlus schema = findSchema(defaultSchema, schemaPath);
@@ -171,7 +168,7 @@ public class SchemaUtilites {
}
if (isRootSchema(schema)) {
- throw UserException.parseError()
+ throw UserException.validationError()
.message("Root schema is immutable. Creating or dropping tables/views is not allowed in root schema." +
"Select a schema using 'USE schema' command.")
.build(logger);
@@ -179,7 +176,7 @@ public class SchemaUtilites {
final AbstractSchema drillSchema = unwrapAsDrillSchemaInstance(schema);
if (!drillSchema.isMutable()) {
- throw UserException.parseError()
+ throw UserException.validationError()
.message("Unable to create or drop tables/views. Schema [%s] is immutable.", getSchemaPath(schema))
.build(logger);
}
@@ -189,21 +186,16 @@ public class SchemaUtilites {
/**
* Looks in schema tree for default temporary workspace instance.
- * Makes sure that temporary workspace is mutable and file-based
- * (instance of {@link WorkspaceSchemaFactory.WorkspaceSchema}).
*
* @param defaultSchema default schema
* @param config drill config
- * @return default temporary workspace
+ * @return default temporary workspace, null if workspace was not found
*/
public static AbstractSchema getTemporaryWorkspace(SchemaPlus defaultSchema, DrillConfig config) {
- List<String> temporarySchemaPath = Lists.newArrayList(config.getString(ExecConstants.DEFAULT_TEMPORARY_WORKSPACE));
- AbstractSchema temporarySchema = resolveToMutableDrillSchema(defaultSchema, temporarySchemaPath);
- if (!(temporarySchema instanceof WorkspaceSchemaFactory.WorkspaceSchema)) {
- DrillRuntimeException.format("Temporary workspace [%s] must be file-based, instance of " +
- "WorkspaceSchemaFactory.WorkspaceSchema", temporarySchemaPath);
- }
- return temporarySchema;
+ String temporarySchema = config.getString(ExecConstants.DEFAULT_TEMPORARY_WORKSPACE);
+ List<String> temporarySchemaPath = Lists.newArrayList(temporarySchema);
+ SchemaPlus schema = findSchema(defaultSchema, temporarySchemaPath);
+ return schema == null ? null : unwrapAsDrillSchemaInstance(schema);
}
/**
@@ -217,4 +209,46 @@ public class SchemaUtilites {
public static boolean isTemporaryWorkspace(String schemaPath, DrillConfig config) {
return schemaPath.equals(config.getString(ExecConstants.DEFAULT_TEMPORARY_WORKSPACE));
}
+
+ /**
+ * Makes sure that passed workspace exists, is default temporary workspace, mutable and file-based
+ * (instance of {@link WorkspaceSchemaFactory.WorkspaceSchema}).
+ *
+ * @param schema drill schema
+ * @param config drill config
+ * @return mutable & file-based workspace instance, otherwise throws validation error
+ */
+ public static WorkspaceSchemaFactory.WorkspaceSchema resolveToValidTemporaryWorkspace(AbstractSchema schema,
+ DrillConfig config) {
+ if (schema == null) {
+ throw UserException.validationError()
+ .message("Default temporary workspace is not found")
+ .build(logger);
+ }
+
+ if (!isTemporaryWorkspace(schema.getFullSchemaName(), config)) {
+ throw UserException
+ .validationError()
+ .message(String.format("Temporary tables are not allowed to be created / dropped " +
+ "outside of default temporary workspace [%s].",
+ config.getString(ExecConstants.DEFAULT_TEMPORARY_WORKSPACE)))
+ .build(logger);
+ }
+
+ if (!schema.isMutable()) {
+ throw UserException.validationError()
+ .message("Unable to create or drop temporary table. Schema [%s] is immutable.", schema.getFullSchemaName())
+ .build(logger);
+ }
+
+ if (schema instanceof WorkspaceSchemaFactory.WorkspaceSchema) {
+ return (WorkspaceSchemaFactory.WorkspaceSchema) schema;
+ } else {
+ throw UserException.validationError()
+ .message("Temporary workspace [%s] must be file-based, instance of " +
+ "WorkspaceSchemaFactory.WorkspaceSchema", schema)
+ .build(logger);
+ }
+ }
+
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
index 07a364492..d50391c88 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/CreateTableHandler.java
@@ -97,7 +97,7 @@ public class CreateTableHandler extends DefaultSqlHandler {
// Generated table name is unique, UUID.randomUUID() is used for its generation.
// Original table name is stored in temporary tables cache, so it can be substituted to generated one during querying.
String newTableName = sqlCreateTable.isTemporary() ?
- context.getSession().registerTemporaryTable(drillSchema, originalTableName) : originalTableName;
+ context.getSession().registerTemporaryTable(drillSchema, originalTableName, drillConfig) : originalTableName;
DrillRel drel = convertToDrel(newTblRelNodeWithPCol, drillSchema, newTableName,
sqlCreateTable.getPartitionColumns(), newTblRelNode.getRowType(), storageStrategy);
@@ -263,8 +263,7 @@ public class CreateTableHandler extends DefaultSqlHandler {
* returns temporary workspace.
*
* If schema path is indicated, resolves to mutable drill schema.
- * Though if table to be created is temporary table, checks if resolved schema is temporary,
- * since temporary table are allowed to be created only in temporary workspace.
+ * Though if table to be created is temporary table, checks if resolved schema is valid default temporary workspace.
*
* @param sqlCreateTable create table call
* @param defaultSchema default schema
@@ -273,21 +272,19 @@ public class CreateTableHandler extends DefaultSqlHandler {
* @throws UserException if attempted to create temporary table outside of temporary workspace
*/
private AbstractSchema resolveSchema(SqlCreateTable sqlCreateTable, SchemaPlus defaultSchema, DrillConfig config) {
+ AbstractSchema resolvedSchema;
if (sqlCreateTable.isTemporary() && sqlCreateTable.getSchemaPath().size() == 0) {
- return SchemaUtilites.getTemporaryWorkspace(defaultSchema, config);
+ resolvedSchema = SchemaUtilites.getTemporaryWorkspace(defaultSchema, config);
} else {
- AbstractSchema resolvedSchema = SchemaUtilites.resolveToMutableDrillSchema(defaultSchema, sqlCreateTable.getSchemaPath());
- boolean isTemporaryWorkspace = SchemaUtilites.isTemporaryWorkspace(resolvedSchema.getFullSchemaName(), config);
-
- if (sqlCreateTable.isTemporary() && !isTemporaryWorkspace) {
- throw UserException
- .validationError()
- .message(String.format("Temporary tables are not allowed to be created " +
- "outside of default temporary workspace [%s].", config.getString(ExecConstants.DEFAULT_TEMPORARY_WORKSPACE)))
- .build(logger);
- }
- return resolvedSchema;
+ resolvedSchema = SchemaUtilites.resolveToMutableDrillSchema(
+ defaultSchema, sqlCreateTable.getSchemaPath());
+ }
+
+ if (sqlCreateTable.isTemporary()) {
+ return SchemaUtilites.resolveToValidTemporaryWorkspace(resolvedSchema, config);
}
+
+ return resolvedSchema;
}
/**
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DropTableHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DropTableHandler.java
index a9895dba2..c17ac2084 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DropTableHandler.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DropTableHandler.java
@@ -52,9 +52,6 @@ public class DropTableHandler extends DefaultSqlHandler {
* @param sqlNode - SqlDropTable (SQL parse tree of drop table [if exists] query)
* @return - Single row indicating drop succeeded or table is not found while IF EXISTS statement is used,
* raise exception otherwise
- * @throws ValidationException
- * @throws RelConversionException
- * @throws IOException
*/
@Override
public PhysicalPlan getPlan(SqlNode sqlNode) throws ValidationException, RelConversionException, IOException {
@@ -69,7 +66,7 @@ public class DropTableHandler extends DefaultSqlHandler {
boolean isTemporaryTable = session.isTemporaryTable(temporarySchema, drillConfig, originalTableName);
if (isTemporaryTable) {
- session.removeTemporaryTable(temporarySchema, originalTableName);
+ session.removeTemporaryTable(temporarySchema, originalTableName, drillConfig);
} else {
AbstractSchema drillSchema = SchemaUtilites.resolveToMutableDrillSchema(defaultSchema, tableSchema);
Table tableToDrop = SqlHandlerUtil.getTableFromSchema(drillSchema, originalTableName);
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java b/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java
index c1e577df9..61429f275 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java
@@ -259,6 +259,7 @@ public class UserSession implements Closeable {
/**
* Creates and adds session temporary location if absent using schema configuration.
+ * Before any actions, checks if passed table schema is valid default temporary workspace.
* Generates temporary table name and stores it's original name as key
* and generated name as value in session temporary tables cache.
* Original temporary name is converted to lower case to achieve case-insensitivity.
@@ -268,14 +269,15 @@ public class UserSession implements Closeable {
*
* @param schema table schema
* @param tableName original table name
+ * @param config drill config
* @return generated temporary table name
* @throws IOException if error during session temporary location creation
*/
- public String registerTemporaryTable(AbstractSchema schema, String tableName) throws IOException {
- addTemporaryLocation((WorkspaceSchemaFactory.WorkspaceSchema) schema);
- String temporaryTableName = new Path(sessionId, UUID.randomUUID().toString()).toUri().getPath();
- String oldTemporaryTableName = temporaryTables.putIfAbsent(tableName.toLowerCase(), temporaryTableName);
- return oldTemporaryTableName == null ? temporaryTableName : oldTemporaryTableName;
+ public String registerTemporaryTable(AbstractSchema schema, String tableName, DrillConfig config) throws IOException {
+ addTemporaryLocation(SchemaUtilites.resolveToValidTemporaryWorkspace(schema, config));
+ String temporaryTableName = new Path(sessionId, UUID.randomUUID().toString()).toUri().getPath();
+ String oldTemporaryTableName = temporaryTables.putIfAbsent(tableName.toLowerCase(), temporaryTableName);
+ return oldTemporaryTableName == null ? temporaryTableName : oldTemporaryTableName;
}
/**
@@ -305,7 +307,7 @@ public class UserSession implements Closeable {
* @return true if temporary table exists in schema, false otherwise
*/
public boolean isTemporaryTable(AbstractSchema drillSchema, DrillConfig config, String tableName) {
- if (!SchemaUtilites.isTemporaryWorkspace(drillSchema.getFullSchemaName(), config)) {
+ if (drillSchema == null || !SchemaUtilites.isTemporaryWorkspace(drillSchema.getFullSchemaName(), config)) {
return false;
}
String temporaryTableName = resolveTemporaryTableName(tableName);
@@ -321,15 +323,18 @@ public class UserSession implements Closeable {
/**
* Removes temporary table name from the list of session temporary tables.
* Original temporary name is converted to lower case to achieve case-insensitivity.
+ * Before temporary table drop, checks if passed table schema is valid default temporary workspace.
*
+ * @param schema table schema
* @param tableName original table name
+ * @param config drill config
*/
- public void removeTemporaryTable(AbstractSchema drillSchema, String tableName) {
+ public void removeTemporaryTable(AbstractSchema schema, String tableName, DrillConfig config) {
String temporaryTable = resolveTemporaryTableName(tableName);
if (temporaryTable == null) {
return;
}
- SqlHandlerUtil.dropTableFromSchema(drillSchema, temporaryTable);
+ SqlHandlerUtil.dropTableFromSchema(SchemaUtilites.resolveToValidTemporaryWorkspace(schema, config), temporaryTable);
temporaryTables.remove(tableName.toLowerCase());
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java
index 77532e10c..b4300e0bc 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/Drillbit.java
@@ -20,7 +20,6 @@ package org.apache.drill.exec.server;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.calcite.schema.SchemaPlus;
import org.apache.drill.common.AutoCloseables;
import org.apache.drill.common.StackTrace;
import org.apache.drill.common.config.DrillConfig;
@@ -31,17 +30,13 @@ import org.apache.drill.exec.coord.ClusterCoordinator;
import org.apache.drill.exec.coord.ClusterCoordinator.RegistrationHandle;
import org.apache.drill.exec.coord.zk.ZKClusterCoordinator;
import org.apache.drill.exec.exception.DrillbitStartupException;
-import org.apache.drill.exec.planner.sql.SchemaUtilites;
import org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint;
import org.apache.drill.exec.server.options.OptionManager;
import org.apache.drill.exec.server.options.OptionValue;
import org.apache.drill.exec.server.options.OptionValue.OptionType;
import org.apache.drill.exec.server.rest.WebServer;
import org.apache.drill.exec.service.ServiceEngine;
-import org.apache.drill.exec.store.AbstractSchema;
-import org.apache.drill.exec.store.SchemaTreeProvider;
import org.apache.drill.exec.store.StoragePluginRegistry;
-import org.apache.drill.exec.store.dfs.WorkspaceSchemaFactory;
import org.apache.drill.exec.store.sys.store.provider.CachingPersistentStoreProvider;
import org.apache.drill.exec.store.sys.PersistentStoreProvider;
import org.apache.drill.exec.store.sys.PersistentStoreRegistry;
@@ -128,7 +123,6 @@ public class Drillbit implements AutoCloseable {
storageRegistry.init();
drillbitContext.getOptionManager().init();
javaPropertiesToSystemOptions();
- validateTemporaryWorkspace(manager.getContext());
manager.getContext().getRemoteFunctionRegistry().init(context.getConfig(), storeProvider, coord);
registrationHandle = coord.register(md);
webServer.start();
@@ -221,21 +215,6 @@ public class Drillbit implements AutoCloseable {
}
/**
- * Validates that temporary workspace indicated in configuration is
- * mutable and file-based (instance of {@link WorkspaceSchemaFactory.WorkspaceSchema}).
- *
- * @param context drillbit context
- * @throws Exception in case when temporary table schema is not mutable or
- * not file-based (instance of WorkspaceSchemaFactory.WorkspaceSchema)
- */
- private void validateTemporaryWorkspace(DrillbitContext context) throws Exception {
- try (SchemaTreeProvider schemaTreeProvider = new SchemaTreeProvider(context)) {
- final SchemaPlus rootSchema = schemaTreeProvider.createRootSchema(context.getOptionManager());
- SchemaUtilites.getTemporaryWorkspace(rootSchema, context.getConfig());
- }
- }
-
- /**
* Shutdown hook for Drillbit. Closes the drillbit, and reports on errors that
* occur during closure, as well as the location the drillbit was started from.
*/