diff --git a/ql/src/java/org/apache/hadoop/hive/ql/metadata/SessionHiveMetaStoreClient.java b/ql/src/java/org/apache/hadoop/hive/ql/metadata/SessionHiveMetaStoreClient.java index 51ff262..6091c3f 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/metadata/SessionHiveMetaStoreClient.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/metadata/SessionHiveMetaStoreClient.java @@ -515,7 +515,7 @@ private void dropTempTable(org.apache.hadoop.hive.metastore.api.Table table, boo return newCopy; } - private Map getTempTablesForDatabase(String dbName) { + public static Map getTempTablesForDatabase(String dbName) { SessionState ss = SessionState.get(); if (ss == null) { LOG.debug("No current SessionState, skipping temp tables"); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index 4bec228..7a54aec 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -112,6 +112,7 @@ import org.apache.hadoop.hive.ql.metadata.HiveUtils; import org.apache.hadoop.hive.ql.metadata.InvalidTableException; import org.apache.hadoop.hive.ql.metadata.Partition; +import org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient; import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.ql.metadata.VirtualColumn; import org.apache.hadoop.hive.ql.optimizer.Optimizer; @@ -10943,14 +10944,30 @@ ASTNode analyzeCreateTable( case CTAS: // create table as select - // Verify that the table does not already exist - try { - Table dumpTable = db.newTable(dbDotTab); - if (null != db.getTable(dumpTable.getDbName(), dumpTable.getTableName(), false)) { - throw new SemanticException(ErrorMsg.TABLE_ALREADY_EXISTS.getMsg(dbDotTab)); + if (isTemporary) { + String dbName = qualifiedTabName[0]; + String tblName = qualifiedTabName[1]; + SessionState ss = SessionState.get(); + if (ss == null) { + throw new SemanticException("No current SessionState, cannot create temporary table " + + dbName + "." + tblName); + } + Map tables = SessionHiveMetaStoreClient.getTempTablesForDatabase(dbName); + if (tables != null && tables.containsKey(tblName)) { + throw new SemanticException("Temporary table " + dbName + "." + tblName + + " already exists"); + } + } else { + // Verify that the table does not already exist + // dumpTable is only used to check the conflict for non-temporary tables + try { + Table dumpTable = db.newTable(dbDotTab); + if (null != db.getTable(dumpTable.getDbName(), dumpTable.getTableName(), false)) { + throw new SemanticException(ErrorMsg.TABLE_ALREADY_EXISTS.getMsg(dbDotTab)); + } + } catch (HiveException e) { + throw new SemanticException(e); } - } catch (HiveException e) { - throw new SemanticException(e); } if(location != null && location.length() != 0) { diff --git a/ql/src/test/queries/clientpositive/temp_table.q b/ql/src/test/queries/clientpositive/temp_table.q index e587f3f..65f3eb4 100644 --- a/ql/src/test/queries/clientpositive/temp_table.q +++ b/ql/src/test/queries/clientpositive/temp_table.q @@ -42,3 +42,29 @@ use default; DROP DATABASE two CASCADE; DROP TABLE bay; + +create table s as select * from src limit 10; + +select count(*) from s; + +create temporary table s as select * from s limit 2; + +select count(*) from s; + +with s as ( select * from src limit 1) +select count(*) from s; + +with src as ( select * from s) +select count(*) from src; + +drop table s; + +select count(*) from s; + +with s as ( select * from src limit 1) +select count(*) from s; + +with src as ( select * from s) +select count(*) from src; + +drop table s; diff --git a/ql/src/test/results/clientpositive/spark/temp_table.q.out b/ql/src/test/results/clientpositive/spark/temp_table.q.out index 65e256d..718a8a4 100644 --- a/ql/src/test/results/clientpositive/spark/temp_table.q.out +++ b/ql/src/test/results/clientpositive/spark/temp_table.q.out @@ -448,3 +448,110 @@ POSTHOOK: query: DROP TABLE bay POSTHOOK: type: DROPTABLE POSTHOOK: Input: default@bay POSTHOOK: Output: default@bay +PREHOOK: query: create table s as select * from src limit 10 +PREHOOK: type: CREATETABLE_AS_SELECT +PREHOOK: Input: default@src +PREHOOK: Output: database:default +PREHOOK: Output: default@s +POSTHOOK: query: create table s as select * from src limit 10 +POSTHOOK: type: CREATETABLE_AS_SELECT +POSTHOOK: Input: default@src +POSTHOOK: Output: database:default +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: create temporary table s as select * from s limit 2 +PREHOOK: type: CREATETABLE_AS_SELECT +PREHOOK: Input: default@s +PREHOOK: Output: database:default +PREHOOK: Output: default@s +POSTHOOK: query: create temporary table s as select * from s limit 2 +POSTHOOK: type: CREATETABLE_AS_SELECT +POSTHOOK: Input: default@s +POSTHOOK: Output: database:default +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +2 +PREHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +1 +PREHOOK: query: with src as ( select * from s) +select count(*) from src +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: with src as ( select * from s) +select count(*) from src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +2 +PREHOOK: query: drop table s +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@s +PREHOOK: Output: default@s +POSTHOOK: query: drop table s +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@s +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +1 +PREHOOK: query: with src as ( select * from s) +select count(*) from src +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: with src as ( select * from s) +select count(*) from src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: drop table s +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@s +PREHOOK: Output: default@s +POSTHOOK: query: drop table s +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@s +POSTHOOK: Output: default@s diff --git a/ql/src/test/results/clientpositive/temp_table.q.out b/ql/src/test/results/clientpositive/temp_table.q.out index e2987fe..a9f2bae 100644 --- a/ql/src/test/results/clientpositive/temp_table.q.out +++ b/ql/src/test/results/clientpositive/temp_table.q.out @@ -520,3 +520,110 @@ POSTHOOK: query: DROP TABLE bay POSTHOOK: type: DROPTABLE POSTHOOK: Input: default@bay POSTHOOK: Output: default@bay +PREHOOK: query: create table s as select * from src limit 10 +PREHOOK: type: CREATETABLE_AS_SELECT +PREHOOK: Input: default@src +PREHOOK: Output: database:default +PREHOOK: Output: default@s +POSTHOOK: query: create table s as select * from src limit 10 +POSTHOOK: type: CREATETABLE_AS_SELECT +POSTHOOK: Input: default@src +POSTHOOK: Output: database:default +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: create temporary table s as select * from s limit 2 +PREHOOK: type: CREATETABLE_AS_SELECT +PREHOOK: Input: default@s +PREHOOK: Output: database:default +PREHOOK: Output: default@s +POSTHOOK: query: create temporary table s as select * from s limit 2 +POSTHOOK: type: CREATETABLE_AS_SELECT +POSTHOOK: Input: default@s +POSTHOOK: Output: database:default +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +2 +PREHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +1 +PREHOOK: query: with src as ( select * from s) +select count(*) from src +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: with src as ( select * from s) +select count(*) from src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +2 +PREHOOK: query: drop table s +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@s +PREHOOK: Output: default@s +POSTHOOK: query: drop table s +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@s +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +1 +PREHOOK: query: with src as ( select * from s) +select count(*) from src +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: with src as ( select * from s) +select count(*) from src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: drop table s +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@s +PREHOOK: Output: default@s +POSTHOOK: query: drop table s +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@s +POSTHOOK: Output: default@s diff --git a/ql/src/test/results/clientpositive/tez/temp_table.q.out b/ql/src/test/results/clientpositive/tez/temp_table.q.out index 49f57c2..200ccdd 100644 --- a/ql/src/test/results/clientpositive/tez/temp_table.q.out +++ b/ql/src/test/results/clientpositive/tez/temp_table.q.out @@ -460,3 +460,110 @@ POSTHOOK: query: DROP TABLE bay POSTHOOK: type: DROPTABLE POSTHOOK: Input: default@bay POSTHOOK: Output: default@bay +PREHOOK: query: create table s as select * from src limit 10 +PREHOOK: type: CREATETABLE_AS_SELECT +PREHOOK: Input: default@src +PREHOOK: Output: database:default +PREHOOK: Output: default@s +POSTHOOK: query: create table s as select * from src limit 10 +POSTHOOK: type: CREATETABLE_AS_SELECT +POSTHOOK: Input: default@src +POSTHOOK: Output: database:default +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: create temporary table s as select * from s limit 2 +PREHOOK: type: CREATETABLE_AS_SELECT +PREHOOK: Input: default@s +PREHOOK: Output: database:default +PREHOOK: Output: default@s +POSTHOOK: query: create temporary table s as select * from s limit 2 +POSTHOOK: type: CREATETABLE_AS_SELECT +POSTHOOK: Input: default@s +POSTHOOK: Output: database:default +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +2 +PREHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +1 +PREHOOK: query: with src as ( select * from s) +select count(*) from src +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: with src as ( select * from s) +select count(*) from src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +2 +PREHOOK: query: drop table s +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@s +PREHOOK: Output: default@s +POSTHOOK: query: drop table s +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@s +POSTHOOK: Output: default@s +PREHOOK: query: select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: with s as ( select * from src limit 1) +select count(*) from s +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +1 +PREHOOK: query: with src as ( select * from s) +select count(*) from src +PREHOOK: type: QUERY +PREHOOK: Input: default@s +#### A masked pattern was here #### +POSTHOOK: query: with src as ( select * from s) +select count(*) from src +POSTHOOK: type: QUERY +POSTHOOK: Input: default@s +#### A masked pattern was here #### +10 +PREHOOK: query: drop table s +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@s +PREHOOK: Output: default@s +POSTHOOK: query: drop table s +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@s +POSTHOOK: Output: default@s