@Override
    public PlanNode visitIndexJoin(IndexJoinNode node, RewriteContext<Set<Symbol>> context) {
      ImmutableSet.Builder<Symbol> probeInputsBuilder = ImmutableSet.builder();
      probeInputsBuilder
          .addAll(context.get())
          .addAll(Iterables.transform(node.getCriteria(), IndexJoinNode.EquiJoinClause::getProbe));
      if (node.getProbeHashSymbol().isPresent()) {
        probeInputsBuilder.add(node.getProbeHashSymbol().get());
      }
      Set<Symbol> probeInputs = probeInputsBuilder.build();

      ImmutableSet.Builder<Symbol> indexInputBuilder = ImmutableSet.builder();
      indexInputBuilder
          .addAll(context.get())
          .addAll(Iterables.transform(node.getCriteria(), IndexJoinNode.EquiJoinClause::getIndex));
      if (node.getIndexHashSymbol().isPresent()) {
        indexInputBuilder.add(node.getIndexHashSymbol().get());
      }
      Set<Symbol> indexInputs = indexInputBuilder.build();

      PlanNode probeSource = context.rewrite(node.getProbeSource(), probeInputs);
      PlanNode indexSource = context.rewrite(node.getIndexSource(), indexInputs);

      return new IndexJoinNode(
          node.getId(),
          node.getType(),
          probeSource,
          indexSource,
          node.getCriteria(),
          node.getProbeHashSymbol(),
          node.getIndexHashSymbol());
    }
    @Override
    public PlanNode visitIndexJoin(IndexJoinNode node, RewriteContext<Context> context) {
      // Lookup symbols can only be passed through the probe side of an index join
      Set<Symbol> probeLookupSymbols =
          context
              .get()
              .getLookupSymbols()
              .stream()
              .filter(node.getProbeSource().getOutputSymbols()::contains)
              .collect(toImmutableSet());

      if (probeLookupSymbols.isEmpty()) {
        return node;
      }

      PlanNode rewrittenProbeSource =
          context.rewrite(
              node.getProbeSource(), new Context(probeLookupSymbols, context.get().getSuccess()));

      PlanNode source = node;
      if (rewrittenProbeSource != node.getProbeSource()) {
        source =
            new IndexJoinNode(
                node.getId(),
                node.getType(),
                rewrittenProbeSource,
                node.getIndexSource(),
                node.getCriteria(),
                node.getProbeHashSymbol(),
                node.getIndexHashSymbol());
      }

      return source;
    }