@Override
  public void validate() throws SemanticException {
    boolean wasAcidChecked = false;
    // Validate inputs and outputs have right protectmode to execute the query
    for (ReadEntity readEntity : getInputs()) {
      ReadEntity.Type type = readEntity.getType();

      if (type != ReadEntity.Type.TABLE &&
          type != ReadEntity.Type.PARTITION) {
        // In current implementation it will never happen, but we leave it
        // here to make the logic complete.
        continue;
      }

      Table tbl = readEntity.getTable();
      Partition p = readEntity.getPartition();

      if (p != null) {
        tbl = p.getTable();
      }
      if (tbl != null && AcidUtils.isTransactionalTable(tbl)) {
        transactionalInQuery = true;
        if (!wasAcidChecked) {
          checkAcidTxnManager(tbl);
        }
        wasAcidChecked = true;
      }
    }

    for (WriteEntity writeEntity : getOutputs()) {
      WriteEntity.Type type = writeEntity.getType();

      if (type == WriteEntity.Type.PARTITION || type == WriteEntity.Type.DUMMYPARTITION) {
        String conflictingArchive = null;
        try {
          Partition usedp = writeEntity.getPartition();
          Table tbl = usedp.getTable();
          if (AcidUtils.isTransactionalTable(tbl)) {
            transactionalInQuery = true;
            if (!wasAcidChecked) {
              checkAcidTxnManager(tbl);
            }
            wasAcidChecked = true;
          }

          LOG.debug("validated " + usedp.getName());
          LOG.debug(usedp.getTable().getTableName());
          if (!AcidUtils.isTransactionalTable(tbl) && conf.getBoolVar(HIVE_ARCHIVE_ENABLED)) {
            // Do not check for ACID; it does not create new parts and this is expensive as hell.
            // TODO: add an API to get table name list for archived parts with a single call;
            //       nobody uses this so we could skip the whole thing.
            conflictingArchive = ArchiveUtils
                .conflictingArchiveNameOrNull(db, tbl, usedp.getSpec());
          }
        } catch (HiveException e) {
          throw new SemanticException(e);
        }
        if (conflictingArchive != null) {
          String message = String.format("Insert conflict with existing archive: %s",
              conflictingArchive);
          throw new SemanticException(message);
        }
      } else if (type == WriteEntity.Type.TABLE) {
        Table tbl = writeEntity.getTable();
        if (AcidUtils.isTransactionalTable(tbl)) {
          transactionalInQuery = true;
          if (!wasAcidChecked) {
            checkAcidTxnManager(tbl);
          }
          wasAcidChecked = true;
        }
      }

      if (type != WriteEntity.Type.TABLE &&
          type != WriteEntity.Type.PARTITION) {
        LOG.debug("not validating writeEntity, because entity is neither table nor partition");
        continue;
      }
    }

    boolean reworkMapredWork = HiveConf.getBoolVar(this.conf,
        HiveConf.ConfVars.HIVE_REWORK_MAPREDWORK);

    // validate all tasks
    for (Task<?> rootTask : rootTasks) {
      validate(rootTask, reworkMapredWork);
    }
  }
Generates all of the expression node descriptors for the expression and children of it
passed in the arguments. This function uses the row resolver and the metadata information
that are passed as arguments to resolve the column names to internal names.

@param expr
         The expression
@param input
         The row resolver
@param tcCtx
         Customized type-checking context
@return expression to exprNodeDesc mapping
@throws SemanticException Failed to evaluate expression
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java