@VisibleForTesting
    public List<ProjectionContext> planRemoteAssignments(Assignments assignments, VariableAllocator variableAllocator)
    {
        ImmutableList.Builder<List<ProjectionContext>> assignmentProjections = ImmutableList.builder();
        for (Map.Entry<VariableReferenceExpression, RowExpression> entry : assignments.getMap().entrySet()) {
            List<ProjectionContext> rewritten = entry.getValue().accept(new Visitor(functionAndTypeManager, variableAllocator), null);
            if (rewritten.isEmpty()) {
                assignmentProjections.add(ImmutableList.of(new ProjectionContext(ImmutableMap.of(entry.getKey(), entry.getValue()), false)));
            }
            else {
                checkState(rewritten.get(rewritten.size() - 1).getProjections().size() == 1, "Expect at most 1 assignment from last projection in rewrite");
                ProjectionContext last = rewritten.get(rewritten.size() - 1);
                ImmutableList.Builder<ProjectionContext> projectionContextBuilder = ImmutableList.builder();
                projectionContextBuilder.addAll(rewritten.subList(0, rewritten.size() - 1));
                projectionContextBuilder.add(new ProjectionContext(ImmutableMap.of(entry.getKey(), getOnlyElement(last.getProjections().values())), last.isRemote()));
                assignmentProjections.add(projectionContextBuilder.build());
            }
        }
        List<ProjectionContext> mergedProjectionContexts = mergeProjectionContexts(assignmentProjections.build());
        return dedupVariables(mergedProjectionContexts);
    }
@Test
    void testSpecialForm()
    {
        PlanBuilder planBuilder = new PlanBuilder(TEST_SESSION, new PlanNodeIdAllocator(), getMetadata());
        planBuilder.variable("x", INTEGER);
        planBuilder.variable("y", INTEGER);

        PlanRemoteProjections rule = new PlanRemoteProjections(getFunctionAndTypeManager());
        List<ProjectionContext> rewritten = rule.planRemoteAssignments(Assignments.builder()
                .put(planBuilder.variable("a"), planBuilder.rowExpression("unittest.memory.remote_foo(x, y + unittest.memory.remote_foo(x))"))
                .put(planBuilder.variable("b"), planBuilder.rowExpression("x IS NULL OR y IS NULL"))
                .put(planBuilder.variable("c"), planBuilder.rowExpression("IF(abs(unittest.memory.remote_foo()) > 0, x, y)"))
                .put(planBuilder.variable("d"), planBuilder.rowExpression("unittest.memory.remote_foo(x + y, abs(x))"))
                .put(planBuilder.variable("e"), planBuilder.rowExpression("TRUE OR FALSE"))
                .build(), new VariableAllocator(planBuilder.getTypes().allVariables()));
        assertEquals(rewritten.size(), 4);
        assertEquals(rewritten.get(3).getProjections().size(), 5);
    }