public static Pair<RelOptTable, List<Integer>> getColumnOriginSet(RelNode rel, ImmutableBitSet colSet) {
    RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
    RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
    Map<RelTableRef, List<Integer>> tabToOriginColumns = new HashMap<>();
    for(int col:colSet) {
      final RexInputRef tempColRef =  rexBuilder.makeInputRef(rel, col);
      Set<RexNode> columnOrigins = mq.getExpressionLineage(rel, tempColRef);
      if (null == columnOrigins || columnOrigins.isEmpty()) {
        // if even on
        return null;
      }
      // we have either one or multiple origins of the column, we need to make sure that all of the column
      for (RexNode orgCol : columnOrigins) {
        RexTableInputRef inputRef = extractTableInputRef(orgCol);
        if(inputRef == null) {
          return null;
        }
        List<Integer> cols = tabToOriginColumns.get(inputRef.getTableRef());
        if (cols == null) {
          cols = new ArrayList<>();
        }
        cols.add(inputRef.getIndex());
        tabToOriginColumns.put(inputRef.getTableRef(), cols);
      }
    }

    // return the first table which has same number of backtracked columns as colSet
    // ideally we should return all, in case one doesn't work we can fall back to another
    for(Entry<RelTableRef, List<Integer>> mapEntries: tabToOriginColumns.entrySet()) {
      RelTableRef tblRef = mapEntries.getKey();
      List<Integer> mapColList = mapEntries.getValue();
      if(mapColList.size() == colSet.cardinality()) {
        RelOptTable tbl = tblRef.getTable();
        return Pair.of(tbl, mapColList);
      }
    }
    return null;
  }
Class representing an equivalence class, i.e., a set of equivalent columns

TODO: This is a subset of a private class in materialized view rewriting
in Calcite. It should be moved to its own class in Calcite so it can be
accessible here.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/HiveRelOptUtil.java