private BaseSemanticAnalyzer analyze() throws Exception {
    perfLogger.perfLogBegin(CLASS_NAME, PerfLogger.ANALYZE);

    driverContext.getHookRunner().runBeforeCompileHook(context.getCmd());

    // clear CurrentFunctionsInUse set, to capture new set of functions
    // that SemanticAnalyzer finds are in use
    SessionState.get().getCurrentFunctionsInUse().clear();

    // Flush the metastore cache.  This assures that we don't pick up objects from a previous
    // query running in this same thread.  This has to be done after we get our semantic
    // analyzer (this is when the connection to the metastore is made) but before we analyze,
    // because at that point we need access to the objects.
    Hive.get().getMSC().flushCache();

    boolean executeHooks = driverContext.getHookRunner().hasPreAnalyzeHooks();

    HiveSemanticAnalyzerHookContext hookCtx = new HiveSemanticAnalyzerHookContextImpl();
    if (executeHooks) {
      hookCtx.setConf(driverContext.getConf());
      hookCtx.setUserName(SessionState.get().getUserName());
      hookCtx.setIpAddress(SessionState.get().getUserIpAddress());
      hookCtx.setCommand(context.getCmd());
      hookCtx.setHiveOperation(queryState.getHiveOperation());

      tree = driverContext.getHookRunner().runPreAnalyzeHooks(hookCtx, tree);
    }
    
    // SemanticAnalyzerFactory also sets the hive operation in query state
    BaseSemanticAnalyzer sem = SemanticAnalyzerFactory.get(queryState, tree);

    if (HiveOperation.REPLDUMP == queryState.getHiveOperation() && !driverContext.isRetrial()) {
      setLastReplIdForDump(queryState.getConf());
    }
    driverContext.setValidTxnListsGenerated(false);

    // Do semantic analysis and plan generation
    try {
      sem.startAnalysis();
      sem.analyze(tree, context);
    } finally {
      sem.endAnalysis(tree);
    }

    if (executeHooks) {
      hookCtx.update(sem);
      driverContext.getHookRunner().runPostAnalyzeHooks(hookCtx, sem.getAllRootTasks());
    }

    LOG.info("Semantic Analysis Completed (retrial = {})", driverContext.isRetrial());

    // Retrieve information about cache usage for the query.
    if (driverContext.getConf().getBoolVar(HiveConf.ConfVars.HIVE_QUERY_RESULTS_CACHE_ENABLED)) {
      driverContext.setCacheUsage(sem.getCacheUsage());
    }

    // validate the plan
    sem.validate();

    perfLogger.perfLogEnd(CLASS_NAME, PerfLogger.ANALYZE);
    return sem;
  }
@param deferClose indicates if the close/destroy should be deferred when the process has been interrupted
            it should be set to true if the compile method is called within another method like runInternal,
            which defers the close to the called in that method.
ql/src/java/org/apache/hadoop/hive/ql/Compiler.java