Pair<Boolean, String> canCBOHandleAst(ASTNode ast, QB qb, PreCboCtx cboCtx) {
    int root = ast.getToken().getType();
    boolean needToLogMessage = STATIC_LOG.isInfoEnabled();
    boolean isSupportedRoot = root == HiveParser.TOK_QUERY || root == HiveParser.TOK_EXPLAIN
        || qb.isCTAS() || qb.isMaterializedView();
    // Queries without a source table currently are not supported by CBO
    boolean isSupportedType = (qb.getIsQuery())
        || qb.isCTAS() || qb.isMaterializedView() || cboCtx.type == PreCboCtx.Type.INSERT
        || cboCtx.type == PreCboCtx.Type.MULTI_INSERT;
    Pair<Boolean, String> unsupportedFeatures = HiveCalciteUtil.unsupportedFeaturesPresentInASTorQB(ast, qb);
    boolean result = isSupportedRoot && isSupportedType && Boolean.FALSE.equals(unsupportedFeatures.getKey());

    String msg = "";
    if (!result) {
      if (!isSupportedRoot) {
        msg += "doesn't have QUERY or EXPLAIN as root and not a CTAS; ";
      }
      if (!isSupportedType) {
        msg += "is not a query with at least one source table "
            + " or there is a subquery without a source table, or CTAS, or insert; ";
      }
      if (Boolean.TRUE.equals(unsupportedFeatures.getKey())) {
        msg += "has unsupported feature [" + unsupportedFeatures.getValue() + "]; ";
      }
      msg = msg.substring(0, msg.length() - 2);
      if (needToLogMessage) {
        STATIC_LOG.info("Not invoking CBO because the statement " + msg);
      }
      return Pair.of(false, msg);
    }

    // Now check QB in more detail. canHandleQbForCbo returns null if query can
    // be handled.
    msg = CalcitePlanner.canHandleQbForCbo(queryProperties, conf, true);
    if (msg == null) {
      return Pair.of(true, msg);
    }

    if (needToLogMessage) {
      STATIC_LOG.info("Not invoking CBO because the statement " + msg);
    }
    return Pair.of(false, msg);
  }
Can CBO handle the given AST?

@param ast
         Top level AST
@param qb
         top level QB corresponding to the AST
@param cboCtx
@return boolean

        Assumption:<br>
        If top level QB is query then everything below it must also be
        Query.
ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java