Skip to content

Commit

Permalink
DRILL-5238: CTTAS: unable to resolve temporary table if workspace is …
Browse files Browse the repository at this point in the history
…indicated without schema

This closes #736
  • Loading branch information
arina-ielchiieva authored and parthchandra committed Feb 4, 2017
1 parent c8fbc38 commit 1ec3edf
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 17 deletions.
@@ -1,4 +1,4 @@
/**
/*
* 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
Expand Down Expand Up @@ -93,7 +93,7 @@ public QueryContext(final UserSession session, final DrillbitContext drillbitCon
plannerSettings.setNumEndPoints(drillbitContext.getBits().size());
table = new DrillOperatorTable(getFunctionRegistry(), drillbitContext.getOptionManager());

queryContextInfo = Utilities.createQueryContextInfo(session.getDefaultSchemaName(), session.getSessionId());
queryContextInfo = Utilities.createQueryContextInfo(session.getDefaultSchemaPath(), session.getSessionId());
contextInformation = new ContextInformation(session.getCredentials(), queryContextInfo);

allocator = drillbitContext.getAllocator().newChildAllocator(
Expand Down
Expand Up @@ -480,25 +480,27 @@ private class DrillCalciteCatalogReader extends CalciteCatalogReader {
private boolean allowTemporaryTables;

DrillCalciteCatalogReader(CalciteSchema rootSchema,
boolean caseSensitive,
List<String> defaultSchema,
JavaTypeFactory typeFactory,
DrillConfig drillConfig,
UserSession session) {
boolean caseSensitive,
List<String> defaultSchema,
JavaTypeFactory typeFactory,
DrillConfig drillConfig,
UserSession session) {
super(rootSchema, caseSensitive, defaultSchema, typeFactory);
this.drillConfig = drillConfig;
this.session = session;
this.allowTemporaryTables = true;
}

/** Disallow temporary tables presence in sql statement (ex: in view definitions) */
/**
* Disallow temporary tables presence in sql statement (ex: in view definitions)
*/
public void disallowTemporaryTables() {
this.allowTemporaryTables = false;
}

/**
* If schema is not indicated (only one element in the list) or schema is default temporary workspace,
* we need to check among session temporary tables first in default temporary workspace.
* we need to check among session temporary tables in default temporary workspace first.
* If temporary table is found and temporary tables usage is allowed, its table instance will be returned,
* otherwise search will be conducted in original workspace.
*
Expand All @@ -509,8 +511,8 @@ public void disallowTemporaryTables() {
@Override
public RelOptTableImpl getTable(final List<String> names) {
RelOptTableImpl temporaryTable = null;
String schemaPath = SchemaUtilites.getSchemaPath(names.subList(0, names.size() - 1));
if (names.size() == 1 || SchemaUtilites.isTemporaryWorkspace(schemaPath, drillConfig)) {

if (mightBeTemporaryTable(names, session.getDefaultSchemaPath(), drillConfig)) {
String temporaryTableName = session.resolveTemporaryTableName(names.get(names.size() - 1));
if (temporaryTableName != null) {
List<String> temporaryNames = Lists.newArrayList(temporarySchema, temporaryTableName);
Expand All @@ -528,5 +530,31 @@ public RelOptTableImpl getTable(final List<String> names) {
}
return super.getTable(names);
}

/**
* We should check if passed table is temporary or not if:
* <li>schema is not indicated (only one element in the names list)<li/>
* <li>current schema or indicated schema is default temporary workspace<li/>
*
* Examples (where dfs.tmp is default temporary workspace):
* <li>select * from t<li/>
* <li>select * from dfs.tmp.t<li/>
* <li>use dfs; select * from tmp.t<li/>
*
* @param names list of schema and table names, table name is always the last element
* @param defaultSchemaPath current schema path set using USE command
* @param drillConfig drill config
* @return true if check for temporary table should be done, false otherwise
*/
private boolean mightBeTemporaryTable(List<String> names, String defaultSchemaPath, DrillConfig drillConfig) {
if (names.size() == 1) {
return true;
}

String schemaPath = SchemaUtilites.getSchemaPath(names.subList(0, names.size() - 1));
return SchemaUtilites.isTemporaryWorkspace(schemaPath, drillConfig) ||
SchemaUtilites.isTemporaryWorkspace(
SchemaUtilites.SCHEMA_PATH_JOINER.join(defaultSchemaPath, schemaPath), drillConfig);
}
}
}
Expand Up @@ -65,8 +65,8 @@ public class UserSession implements Closeable {

private boolean supportComplexTypes = false;
private UserCredentials credentials;
private Map<String, String> properties;
private OptionManager sessionOptions;
private final Map<String, String> properties;
private final AtomicInteger queryCount;
private final String sessionId;

Expand Down Expand Up @@ -121,7 +121,6 @@ public Builder withOptionManager(OptionManager systemOptions) {
}

public Builder withUserProperties(UserProperties properties) {
userSession.properties = Maps.newHashMap();
if (properties != null) {
for (int i = 0; i < properties.getPropertiesCount(); i++) {
final Property property = properties.getProperties(i);
Expand Down Expand Up @@ -157,6 +156,7 @@ private UserSession() {
sessionId = UUID.randomUUID().toString();
temporaryTables = Maps.newConcurrentMap();
temporaryLocations = Maps.newConcurrentMap();
properties = Maps.newHashMap();
}

public boolean isSupportComplexTypes() {
Expand Down Expand Up @@ -189,10 +189,6 @@ public String getTargetUserName() {
return properties.get(IMPERSONATION_TARGET);
}

public String getDefaultSchemaName() {
return getProp(SCHEMA);
}

public void incrementQueryCount(final QueryCountIncrementer incrementer) {
assert incrementer != null;
queryCount.incrementAndGet();
Expand Down
Expand Up @@ -142,6 +142,20 @@ public void testTemporaryTablesCaseInsensitivity() throws Exception {
}
}

@Test
public void testResolveTemporaryTableWithPartialSchema() throws Exception {
String temporaryTableName = "temporary_table_with_partial_schema";
test("use %s", test_schema);
test("create temporary table tmp.%s as select 'A' as c1 from (values(1))", temporaryTableName);

testBuilder()
.sqlQuery("select * from tmp.%s", temporaryTableName)
.unOrdered()
.baselineColumns("c1")
.baselineValues("A")
.go();
}

@Test
public void testPartitionByWithTemporaryTables() throws Exception {
String temporaryTableName = "temporary_table_with_partitions";
Expand Down

0 comments on commit 1ec3edf

Please sign in to comment.