public static List<Path> getInputPaths(JobConf job, MapWork work, Path hiveScratchDir,
      Context ctx, boolean skipDummy) throws Exception {

    PerfLogger perfLogger = SessionState.getPerfLogger();
    perfLogger.perfLogBegin(CLASS_NAME, PerfLogger.INPUT_PATHS);

    Set<Path> pathsProcessed = new HashSet<Path>();
    List<Path> pathsToAdd = new LinkedList<Path>();
    DriverState driverState = DriverState.getDriverState();
    if (work.isUseInputPathsDirectly() && work.getInputPaths() != null) {
      return work.getInputPaths();
    }
    // AliasToWork contains all the aliases
    Collection<String> aliasToWork = work.getAliasToWork().keySet();
    if (!skipDummy) {
      // ConcurrentModification otherwise if adding dummy.
      aliasToWork = new ArrayList<>(aliasToWork);
    }
    for (String alias : aliasToWork) {
      LOG.info("Processing alias {}", alias);

      // The alias may not have any path
      Collection<Map.Entry<Path, List<String>>> pathToAliases = work.getPathToAliases().entrySet();
      if (!skipDummy) {
        // ConcurrentModification otherwise if adding dummy.
        pathToAliases = new ArrayList<>(pathToAliases);
      }
      boolean isEmptyTable = true;
      boolean hasLogged = false;

      for (Map.Entry<Path, List<String>> e : pathToAliases) {
        if (driverState != null && driverState.isAborted()) {
          throw new IOException("Operation is Canceled.");
        }

        Path file = e.getKey();
        List<String> aliases = e.getValue();
        if (aliases.contains(alias)) {
          if (file != null) {
            isEmptyTable = false;
          } else {
            LOG.warn("Found a null path for alias {}", alias);
            continue;
          }

          // Multiple aliases can point to the same path - it should be
          // processed only once
          if (pathsProcessed.contains(file)) {
            continue;
          }

          StringInternUtils.internUriStringsInPath(file);
          pathsProcessed.add(file);
          LOG.debug("Adding input file {}", file);
          if (!hasLogged) {
            hasLogged = true;
            LOG.info("Adding {} inputs; the first input is {}",
              work.getPathToAliases().size(), file);
          }

          pathsToAdd.add(file);
        }
      }

      // If the query references non-existent partitions
      // We need to add a empty file, it is not acceptable to change the
      // operator tree
      // Consider the query:
      // select * from (select count(1) from T union all select count(1) from
      // T2) x;
      // If T is empty and T2 contains 100 rows, the user expects: 0, 100 (2
      // rows)
      if (isEmptyTable && !skipDummy) {
        pathsToAdd.add(createDummyFileForEmptyTable(job, work, hiveScratchDir, alias));
      }
    }

    List<Path> finalPathsToAdd = new LinkedList<>();

    int numExecutors = getMaxExecutorsForInputListing(job, pathsToAdd.size());
    if (numExecutors > 1) {
      ExecutorService pool = Executors.newFixedThreadPool(numExecutors,
              new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Get-Input-Paths-%d").build());

      finalPathsToAdd.addAll(getInputPathsWithPool(job, work, hiveScratchDir, ctx, skipDummy, pathsToAdd, pool));
    } else {
      for (final Path path : pathsToAdd) {
        if (driverState != null && driverState.isAborted()) {
          throw new IOException("Operation is Canceled.");
        }
        Path newPath = new GetInputPathsCallable(path, job, work, hiveScratchDir, ctx, skipDummy).call();
        updatePathForMapWork(newPath, work, path);
        finalPathsToAdd.add(newPath);
      }
    }

    perfLogger.perfLogEnd(CLASS_NAME, PerfLogger.INPUT_PATHS);

    return finalPathsToAdd;
  }
Computes a list of all input paths needed to compute the given MapWork. All aliases
are considered and a merged list of input paths is returned. If any input path points
to an empty table or partition a dummy file in the scratch dir is instead created and
added to the list. This is needed to avoid special casing the operator pipeline for
these cases.

@param job JobConf used to run the job
@param work MapWork encapsulating the info about the task
@param hiveScratchDir The tmp dir used to create dummy files if needed
@param ctx Context object
@return List of paths to process for the given MapWork
@throws Exception
ql/src/java/org/apache/hadoop/hive/ql/exec/Utilities.java