presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ExtractSpatialJoins.java/ExtractSpatialJoins/addPartitioningNodes
class ExtractSpatialJoins:    private static PlanNode addPartitioningNodes(Metadata metadata, Context context, PlanNode node, Symbol partitionSymbol, KdbTree kdbTree, Expression geometry, Optional<Expression> radius)
    {
        Assignments.Builder projections = Assignments.builder();
        for (Symbol outputSymbol : node.getOutputSymbols()) {
            projections.putIdentity(outputSymbol);
        }

        TypeSignature typeSignature = new TypeSignature(KDB_TREE_TYPENAME);
        FunctionCallBuilder spatialPartitionsCall = new FunctionCallBuilder(metadata)
                .setName(QualifiedName.of("spatial_partitions"))
                .addArgument(typeSignature, new Cast(new StringLiteral(KdbTreeUtils.toJson(kdbTree)), toSqlType(metadata.getType(typeSignature))))
                .addArgument(GEOMETRY_TYPE_SIGNATURE, geometry);
        radius.map(value -> spatialPartitionsCall.addArgument(DOUBLE, value));
        FunctionCall partitioningFunction = spatialPartitionsCall.build();

        Symbol partitionsSymbol = context.getSymbolAllocator().newSymbol(partitioningFunction, new ArrayType(INTEGER));
        projections.put(partitionsSymbol, partitioningFunction);

        return new UnnestNode(
                context.getIdAllocator().getNextId(),
                new ProjectNode(context.getIdAllocator().getNextId(), node, projections.build()),
                node.getOutputSymbols(),
                ImmutableMap.of(partitionsSymbol, ImmutableList.of(partitionSymbol)),
                Optional.empty(),
                INNER,
                Optional.empty());
    }