@Override
    public PhysicalOperator visitJoin(Join join, Object value) throws OptimizerException {
      PhysicalOperator leftOp = join.getLeft().accept(this, value);
      List<OrderDef> leftOrderDefs = Lists.newArrayList();
      for (JoinCondition jc : join.getConditions()) {
        leftOrderDefs.add(new OrderDef(Direction.ASC, jc.getLeft()));
      }
      leftOp = new Sort(leftOp, leftOrderDefs, false);
      leftOp = new SelectionVectorRemover(leftOp);

      PhysicalOperator rightOp = join.getRight().accept(this, value);
      List<OrderDef> rightOrderDefs = Lists.newArrayList();
      for (JoinCondition jc : join.getConditions()) {
        rightOrderDefs.add(new OrderDef(Direction.ASC, jc.getRight()));
      }
      rightOp = new Sort(rightOp, rightOrderDefs, false);
      rightOp = new SelectionVectorRemover(rightOp);

      MergeJoinPOP mjp =
          new MergeJoinPOP(
              leftOp, rightOp, Arrays.asList(join.getConditions()), join.getJointType());
      return new SelectionVectorRemover(mjp);
    }