private void handleInsertStatementSpecPhase1(ASTNode ast, QBParseInfo qbp, Phase1Ctx ctx_1) throws SemanticException {
    ASTNode tabColName = (ASTNode)ast.getChild(1);
    boolean hasSpecificColumns = tabColName != null && tabColName.getType() == HiveParser.TOK_TABCOLNAME;
    if(ast.getType() == HiveParser.TOK_INSERT_INTO) {
      //we have "insert into foo(a,b)..."; parser will enforce that 1+ columns are listed if TOK_TABCOLNAME is present
      String fullTableName = getUnescapedName((ASTNode) ast.getChild(0).getChild(0),
          SessionState.get().getCurrentDatabase());
      List<String> targetColumnNames = hasSpecificColumns ? processTableColumnNames(tabColName, fullTableName) : new ArrayList<>();
      if (hasSpecificColumns) {
        qbp.setDestSchemaForClause(ctx_1.dest, targetColumnNames);
      }
      Table targetTable;
      try {
        targetTable = getTableObjectByName(fullTableName);
      } catch (HiveException ex) {
        LOG.error("Error processing HiveParser.TOK_DESTINATION: " + ex.getMessage(), ex);
        throw new SemanticException(ex);
      }
      if(targetTable == null) {
        throw new SemanticException(generateErrorMessage(ast,
            "Unable to access metadata for table " + fullTableName));
      }
      ColumnAccessInfo cai = new ColumnAccessInfo();
      if (!hasSpecificColumns) {
        for (FieldSchema col : targetTable.getCols()) {
          targetColumnNames.add(col.getName());
        }
      }
      String completeTableName = targetTable.getCompleteName();
      for (String colName : targetColumnNames) {
        cai.add(completeTableName, colName);
      }
      setUpdateColumnAccessInfo(cai);
      Set<String> targetColumns = new HashSet<>(targetColumnNames);
      for(FieldSchema f : targetTable.getCols()) {
        //parser only allows foo(a,b), not foo(foo.a, foo.b)
        targetColumns.remove(f.getName());
      }
      if(!targetColumns.isEmpty()) {//here we need to see if remaining columns are dynamic partition columns
            /* We just checked the user specified schema columns among regular table column and found some which are not
            'regular'.  Now check is they are dynamic partition columns
              For dynamic partitioning,
              Given "create table multipart(a int, b int) partitioned by (c int, d int);"
              for "insert into multipart partition(c='1',d)(d,a) values(2,3);" we expect parse tree to look like this
               (TOK_INSERT_INTO
                (TOK_TAB
                  (TOK_TABNAME multipart)
                  (TOK_PARTSPEC
                    (TOK_PARTVAL c '1')
                    (TOK_PARTVAL d)
                  )
                )
                (TOK_TABCOLNAME d a)
               )*/
        List<String> dynamicPartitionColumns = new ArrayList<String>();
        if(ast.getChild(0) != null && ast.getChild(0).getType() == HiveParser.TOK_TAB) {
          ASTNode tokTab = (ASTNode)ast.getChild(0);
          ASTNode tokPartSpec = (ASTNode)tokTab.getFirstChildWithType(HiveParser.TOK_PARTSPEC);
          if(tokPartSpec != null) {
            for(Node n : tokPartSpec.getChildren()) {
              ASTNode tokPartVal = null;
              if(n instanceof ASTNode) {
                tokPartVal = (ASTNode)n;
              }
              if(tokPartVal != null && tokPartVal.getType() == HiveParser.TOK_PARTVAL && tokPartVal.getChildCount() == 1) {
                assert tokPartVal.getChild(0).getType() == HiveParser.Identifier :
                    "Expected column name; found tokType=" + tokPartVal.getType();
                dynamicPartitionColumns.add(tokPartVal.getChild(0).getText());
              }
            }
            for(String colName : dynamicPartitionColumns) {
              targetColumns.remove(colName);
            }
          } else  {
            // partition spec is not specified but column schema can have partitions specified
            for(FieldSchema f : targetTable.getPartCols()) {
              //parser only allows foo(a,b), not foo(foo.a, foo.b)
              targetColumns.remove(f.getName());
            }
          }
        }

        if(!targetColumns.isEmpty()) {
          //Found some columns in user specified schema which are neither regular not dynamic partition columns
          throw new SemanticException(generateErrorMessage(tabColName,
              "'" + (targetColumns.size() == 1 ? targetColumns.iterator().next() : targetColumns) +
                  "' in insert schema specification " + (targetColumns.size() == 1 ? "is" : "are") +
                  " not found among regular columns of " +
                  fullTableName + " nor dynamic partition columns."));
        }
      }
    }
  }
This is phase1 of supporting specifying schema in insert statement
insert into foo(z,y) select a,b from bar;
@see #handleInsertStatementSpec(java.util.List, String, RowResolver, QB, ASTNode)
@throws SemanticException
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java