diff --git ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java index f02c828..516671a 100644 --- ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java +++ ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java @@ -2359,17 +2359,47 @@ private static boolean destExists(List> result, Path proposed) { return false; } - private static boolean isSubDir(Path srcf, Path destf, FileSystem fs){ + private static boolean isSubDir(Path srcf, Path destf, FileSystem fs, boolean isSrcLocal){ if (srcf == null) { return false; } - Path currentWorkingDir = fs.getWorkingDirectory(); - String fullF1 = srcf.makeQualified(srcf.toUri(), currentWorkingDir).toString(); - String fullF2 = destf.makeQualified(destf.toUri(), currentWorkingDir).toString(); - LOG.debug("The source path is " + fullF1 + " and destination path is " + fullF2); + + // schema is diff, return false + String schemaSrcf = srcf.toUri().getScheme(); + String schemaDestf = destf.toUri().getScheme(); + + String fullF1 = getQualifiedPathWithoutSchemeAndAuthority(srcf, fs); + String fullF2 = getQualifiedPathWithoutSchemeAndAuthority(srcf, fs); + + boolean isInTest = Boolean.valueOf(HiveConf.getBoolVar(fs.getConf(), ConfVars.HIVE_IN_TEST)); + // In the automation, the data warehouse is the local file system based. + if (isInTest) { + return fullF1.startsWith(fullF2); + } + + // if the schemaDestf is null, it means the destination is not in the local file system + if (schemaDestf == null && isSrcLocal) { + LOG.debug("The source file is in the local while the dest not."); + return false; + } + + // If both schema information are provided, they should be the same. + if (schemaSrcf != null && schemaDestf != null && !schemaSrcf.equals(schemaDestf)) { + LOG.debug("The source path's schema is " + schemaSrcf + + " and the destination path's schema is " + schemaDestf + "."); + return false; + } + + LOG.debug("The source path is " + fullF1 + " and the destination path is " + fullF2); return fullF1.startsWith(fullF2); } + private static String getQualifiedPathWithoutSchemeAndAuthority(Path srcf, FileSystem fs) { + Path currentWorkingDir = fs.getWorkingDirectory(); + Path path = Path.getPathWithoutSchemeAndAuthority(srcf); + return path.makeQualified(path.toUri(), currentWorkingDir).toString(); + } + //it is assumed that parent directory of the destf should already exist when this //method is called. when the replace value is true, this method works a little different //from mv command if the destf is a directory, it replaces the destf instead of moving under @@ -2391,7 +2421,7 @@ public static boolean moveFile(HiveConf conf, Path srcf, Path destf, // (1) Do not delete the dest dir before doing the move operation. // (2) It is assumed that subdir and dir are in same encryption zone. // (3) Move individual files from scr dir to dest dir. - boolean destIsSubDir = isSubDir(srcf, destf, fs); + boolean destIsSubDir = isSubDir(srcf, destf, fs, isSrcLocal); try { if (inheritPerms || replace) { try{ @@ -2402,6 +2432,7 @@ public static boolean moveFile(HiveConf conf, Path srcf, Path destf, //if destf is an existing file, rename is actually a replace, and do not need // to delete the file first if (replace && !destIsSubDir) { + LOG.debug("===== xc ===== The path " + destf.toString() + " is deleted"); fs.delete(destf, true); } } catch (FileNotFoundException ignore) {