@Override
  public void runInternal() throws HiveSQLException {
    setState(OperationState.PENDING);

    final boolean doRunAsync = shouldRunAsync();
    final boolean asyncPrepare = doRunAsync
      && HiveConf.getBoolVar(queryState.getConf(),
        HiveConf.ConfVars.HIVE_SERVER2_ASYNC_EXEC_ASYNC_COMPILE);
    if (!asyncPrepare) {
      prepare(queryState);
    }
    if (!doRunAsync) {
      runQuery();
    } else {
      // We'll pass ThreadLocals in the background thread from the foreground (handler) thread.
      // 1) ThreadLocal Hive object needs to be set in background thread
      // 2) The metastore client in Hive is associated with right user.
      // 3) Current UGI will get used by metastore when metastore is in embedded mode
      Runnable work =
          new BackgroundWork(getCurrentUGI(), parentSession.getSessionHive(), SessionState.get(),
              asyncPrepare);

      try {
        // This submit blocks if no background threads are available to run this operation
        Future<?> backgroundHandle = getParentSession().submitBackgroundOperation(work);
        setBackgroundHandle(backgroundHandle);
      } catch (RejectedExecutionException rejected) {
        setState(OperationState.ERROR);
        throw new HiveSQLException("The background threadpool cannot accept" +
            " new task for execution, please retry the operation", rejected, queryState.getQueryId());
      }
    }
  }
If the operation was cancelled by another thread, or the execution timed out, Driver#run
may return a non-zero response code. We will simply return if the operation state is
CANCELED, TIMEDOUT, CLOSED or FINISHED, otherwise throw an exception
service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java