// implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    final FilterRelBase filterRel = call.rel(0);
    final ProjectRelBase projRel = call.rel(1);

    // convert the filter to one that references the child of the project
    RexNode newCondition = RelOptUtil.pushFilterPastProject(filterRel.getCondition(), projRel);

    RelNode newFilterRel =
        filterFactory == null
            ? filterRel.copy(filterRel.getTraitSet(), projRel.getChild(), newCondition)
            : filterFactory.createFilter(projRel.getChild(), newCondition);

    RelNode newProjRel =
        projectFactory == null
            ? projRel.copy(
                projRel.getTraitSet(), newFilterRel, projRel.getProjects(), projRel.getRowType())
            : projectFactory.createProject(
                newFilterRel, projRel.getProjects(), projRel.getRowType().getFieldNames());

    call.transformTo(newProjRel);
  }
 public Boolean areColumnsUnique(FilterRelBase rel, BitSet columns, boolean ignoreNulls) {
   return RelMetadataQuery.areColumnsUnique(rel.getChild(), columns, ignoreNulls);
 }