protected static RelNode recreateProjectOperator(RelBuilder builder, RexBuilder rexBuilder,
      int[] adjustments, Project topProject, RelNode newInputOperator, boolean force) {
    List<RexNode> newProjects = new ArrayList<>();

    List<RelDataTypeField> swappedJoinFields = newInputOperator.getRowType().getFieldList();
    for(RexNode project : topProject.getProjects()) {
      RexNode newProject = project.accept(
          new RelOptUtil.RexInputConverter(rexBuilder, swappedJoinFields, swappedJoinFields, adjustments));
      newProjects.add(newProject);
    }
    return builder
        .push(newInputOperator)
        .project(newProjects, ImmutableList.of(), force)
        .build();
  }
Rule that matches an Aggregate on top of a Join and tries to transform it
into a SemiJoin swapping its inputs.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveSemiJoinRule.java