private Pattern visit()

in interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/GraphIOProcessor.java [203:442]


        private Pattern visit(List<RelNode> sentences, boolean optional) {
            RelVisitor visitor =
                    new RelVisitor() {
                        PatternVertex lastVisited = null;

                        @Override
                        public void visit(RelNode node, int ordinal, @Nullable RelNode parent) {
                            super.visit(node, ordinal, parent);
                            if (node instanceof GraphLogicalSource) {
                                GraphLogicalSource source = (GraphLogicalSource) node;
                                lastVisited = visitAndAddVertex(source);
                            } else if (node instanceof GraphLogicalExpand) {
                                Preconditions.checkArgument(
                                        parent instanceof GraphLogicalGetV,
                                        "there should be a getV operator after expand since edge in"
                                                + " patten should have two endpoints");
                                PatternVertex vertex = visitAndAddVertex((GraphLogicalGetV) parent);
                                visitAndAddEdge((GraphLogicalExpand) node, lastVisited, vertex);
                                lastVisited = vertex;
                            } else if (node instanceof GraphLogicalPathExpand) {
                                Preconditions.checkArgument(
                                        parent instanceof GraphLogicalGetV,
                                        "there should be a getV operator after path expand since"
                                                + " edge in patten should have two endpoints");
                                Preconditions.checkArgument(
                                        ((GraphLogicalPathExpand) node).getUntilCondition() == null,
                                        "cannot apply optimization if path expand has until"
                                                + " conditions");
                                PatternVertex vertex = visitAndAddVertex((GraphLogicalGetV) parent);
                                visitAndAddPxdEdge(
                                        (GraphLogicalPathExpand) node, lastVisited, vertex);
                                lastVisited = vertex;
                            }
                            if (parent != null
                                    && (node instanceof GraphLogicalSource
                                            || node instanceof GraphLogicalGetV)) {
                                DataValue value = vertexOrEdgeDetails.get(lastVisited);
                                if (value != null
                                        && (value.getAlias() == null
                                                || value.getAlias()
                                                        == AliasInference.DEFAULT_NAME)) {
                                    vertexOrEdgeDetails.put(
                                            lastVisited,
                                            new DataValue(
                                                    generateAlias(lastVisited), value.getFilter()));
                                }
                            }
                        }

                        private String generateAlias(PatternVertex vertex) {
                            return "PATTERN_VERTEX$" + vertex.getId();
                        }

                        private PatternVertex visitAndAddVertex(
                                AbstractBindableTableScan tableScan) {
                            String alias = tableScan.getAliasName();
                            PatternVertex existVertex = aliasNameToVertex.get(alias);
                            RexNode filters = getFilters(tableScan);
                            if (existVertex == null) {
                                int vertexId = idGenerator.getAndIncrement();
                                List<Integer> typeIds =
                                        com.alibaba.graphscope.common.ir.meta.glogue.Utils
                                                .getVertexTypeIds(tableScan);
                                double selectivity = mq.getSelectivity(tableScan, filters);
                                existVertex =
                                        (typeIds.size() == 1)
                                                ? new SinglePatternVertex(
                                                        typeIds.get(0),
                                                        vertexId,
                                                        new ElementDetails(selectivity))
                                                : new FuzzyPatternVertex(
                                                        typeIds,
                                                        vertexId,
                                                        new ElementDetails(selectivity));
                                inputPattern.addVertex(existVertex);
                                if (alias != AliasInference.DEFAULT_NAME) {
                                    aliasNameToVertex.put(alias, existVertex);
                                }
                                vertexOrEdgeDetails.put(existVertex, new DataValue(alias, filters));
                            } else if (filters != null) {
                                DataValue value = vertexOrEdgeDetails.get(existVertex);
                                // reset condition
                                RexNode newCondition =
                                        (value.getFilter() == null)
                                                ? filters
                                                : RexUtil.composeConjunction(
                                                        builder.getRexBuilder(),
                                                        ImmutableList.of(
                                                                filters, value.getFilter()));
                                vertexOrEdgeDetails.put(
                                        existVertex,
                                        new DataValue(
                                                value.getAlias(),
                                                newCondition,
                                                value.getParentAlias()));
                            }
                            return existVertex;
                        }

                        private PatternEdge visitAndAddEdge(
                                GraphLogicalExpand expand,
                                PatternVertex left,
                                PatternVertex right) {
                            PatternVertex src, dst;
                            switch (expand.getOpt()) {
                                case OUT:
                                case BOTH:
                                    src = left;
                                    dst = right;
                                    break;
                                case IN:
                                default:
                                    src = right;
                                    dst = left;
                            }
                            PatternEdge edge = visitEdge(expand, src, dst);
                            boolean added = inputPattern.addEdge(src, dst, edge);
                            if (!added) {
                                throw new UnsupportedOperationException(
                                        "edge "
                                                + edge
                                                + " already exists in the pattern, and pattern with"
                                                + " multi-edges are not supported yet");
                            }

                            vertexOrEdgeDetails.put(
                                    edge, new DataValue(expand.getAliasName(), getFilters(expand)));
                            return edge;
                        }

                        private PatternEdge visitAndAddPxdEdge(
                                GraphLogicalPathExpand pxd,
                                PatternVertex left,
                                PatternVertex right) {
                            GraphLogicalExpand expand = (GraphLogicalExpand) pxd.getExpand();
                            PatternVertex src, dst;
                            switch (expand.getOpt()) {
                                case OUT:
                                case BOTH:
                                    src = left;
                                    dst = right;
                                    break;
                                case IN:
                                default:
                                    src = right;
                                    dst = left;
                            }
                            PatternEdge expandEdge = visitEdge(expand, src, dst);
                            int offset =
                                    (pxd.getOffset() == null)
                                            ? 0
                                            : ((RexLiteral) pxd.getOffset())
                                                    .getValueAs(Number.class)
                                                    .intValue();
                            int fetch =
                                    (pxd.getFetch() == null)
                                            ? (Integer.MAX_VALUE - offset)
                                            : ((RexLiteral) pxd.getFetch())
                                                    .getValueAs(Number.class)
                                                    .intValue();
                            GraphPathType pathType =
                                    (GraphPathType)
                                            pxd.getRowType().getFieldList().get(0).getType();
                            GraphLabelType labelType =
                                    ((GraphSchemaType) pathType.getComponentType().getGetVType())
                                            .getLabelType();
                            List<Integer> innerGetVTypes =
                                    labelType.getLabelsEntry().stream()
                                            .map(k -> k.getLabelId())
                                            .collect(Collectors.toList());
                            ElementDetails newDetails =
                                    new ElementDetails(
                                            expandEdge.getElementDetails().getSelectivity(),
                                            new PathExpandRange(offset, fetch),
                                            innerGetVTypes,
                                            pxd.getResultOpt(),
                                            pxd.getPathOpt(),
                                            expandEdge.getElementDetails().isOptional());
                            expandEdge =
                                    (expandEdge instanceof SinglePatternEdge)
                                            ? new SinglePatternEdge(
                                                    expandEdge.getSrcVertex(),
                                                    expandEdge.getDstVertex(),
                                                    expandEdge.getEdgeTypeIds().get(0),
                                                    expandEdge.getId(),
                                                    expandEdge.isBoth(),
                                                    newDetails)
                                            : new FuzzyPatternEdge(
                                                    expandEdge.getSrcVertex(),
                                                    expandEdge.getDstVertex(),
                                                    expandEdge.getEdgeTypeIds(),
                                                    expandEdge.getId(),
                                                    expandEdge.isBoth(),
                                                    newDetails);
                            boolean added = inputPattern.addEdge(src, dst, expandEdge);
                            if (!added) {
                                throw new UnsupportedOperationException(
                                        "edge "
                                                + expandEdge
                                                + " already exists in the pattern, and pattern with"
                                                + " multi-edges are not supported yet");
                            }
                            vertexOrEdgeDetails.put(
                                    expandEdge,
                                    new DataValue(pxd.getAliasName(), getFilters(expand)));
                            return expandEdge;
                        }

                        private PatternEdge visitEdge(
                                GraphLogicalExpand expand, PatternVertex src, PatternVertex dst) {
                            boolean isBoth = expand.getOpt() == GraphOpt.Expand.BOTH;
                            List<EdgeTypeId> edgeTypeIds =
                                    com.alibaba.graphscope.common.ir.meta.glogue.Utils
                                            .getEdgeTypeIds(expand);
                            int edgeId = idGenerator.getAndIncrement();
                            double selectivity = mq.getSelectivity(expand, getFilters(expand));
                            PatternEdge edge =
                                    (edgeTypeIds.size() == 1)
                                            ? new SinglePatternEdge(
                                                    src,
                                                    dst,
                                                    edgeTypeIds.get(0),
                                                    edgeId,
                                                    isBoth,
                                                    new ElementDetails(selectivity, optional))
                                            : new FuzzyPatternEdge(
                                                    src,
                                                    dst,
                                                    edgeTypeIds,
                                                    edgeId,
                                                    isBoth,
                                                    new ElementDetails(selectivity, optional));
                            return edge;
                        }
                    };
            for (RelNode sentence : sentences) {
                visitor.go(sentence);
            }
            return inputPattern;
        }