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 c88dbc8..9961b29 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 @@ -2134,20 +2134,25 @@ private void getMetaData(QB qb, ReadEntity parentInput) ctx.setResDir(null); ctx.setResFile(null); - // allocate a temporary output dir on the location of the table - String tableName = getUnescapedName((ASTNode) ast.getChild(0)); - String[] names = Utilities.getDbTableName(tableName); Path location; - try { - Warehouse wh = new Warehouse(conf); - //Use destination table's db location. - String destTableDb = qb.getTableDesc() != null? qb.getTableDesc().getDatabaseName(): null; - if (destTableDb == null) { - destTableDb = names[0]; + // If the CTAS query does specify a location, use the table location, else use the db location + if (qb.getTableDesc() != null && qb.getTableDesc().getLocation() != null) { + location = new Path(qb.getTableDesc().getLocation()); + } else { + // allocate a temporary output dir on the location of the table + String tableName = getUnescapedName((ASTNode) ast.getChild(0)); + String[] names = Utilities.getDbTableName(tableName); + try { + Warehouse wh = new Warehouse(conf); + //Use destination table's db location. + String destTableDb = qb.getTableDesc() != null ? qb.getTableDesc().getDatabaseName() : null; + if (destTableDb == null) { + destTableDb = names[0]; + } + location = wh.getDatabasePath(db.getDatabase(destTableDb)); + } catch (MetaException e) { + throw new SemanticException(e); } - location = wh.getDatabasePath(db.getDatabase(destTableDb)); - } catch (MetaException e) { - throw new SemanticException(e); } try { fname = ctx.getExtTmpPathRelTo( @@ -2174,6 +2179,7 @@ private void getMetaData(QB qb, ReadEntity parentInput) if (ast.getChildCount() >= 2 && ast.getChild(1).getText().toLowerCase().equals("local")) { isDfsFile = false; } + // Set the destination for the SELECT query inside the CTAS qb.getMetaData().setDestForAlias(name, fname, isDfsFile); CreateTableDesc directoryDesc = new CreateTableDesc(); @@ -11683,6 +11689,7 @@ ASTNode analyzeCreateTable( break; case HiveParser.TOK_TABLELOCATION: location = unescapeSQLString(child.getChild(0).getText()); + location = EximUtil.relativeToAbsolutePath(conf, location); inputs.add(toReadEntity(location)); break; @@ -11850,7 +11857,12 @@ ASTNode analyzeCreateTable( if(locStats != null && locStats.isDir()) { FileStatus[] lStats = curFs.listStatus(locPath); if(lStats != null && lStats.length != 0) { - throw new SemanticException(ErrorMsg.CTAS_LOCATION_NONEMPTY.getMsg(location)); + // Don't throw an exception if the target location only contains the staging-dirs + for (FileStatus lStat : lStats) { + if (!lStat.getPath().getName().startsWith(HiveConf.getVar(conf, HiveConf.ConfVars.STAGINGDIR))) { + throw new SemanticException(ErrorMsg.CTAS_LOCATION_NONEMPTY.getMsg(location)); + } + } } } } catch (FileNotFoundException nfe) {