public IEnvironmentAction buildBoundVertexAction()

in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/lower/EnvironmentActionFactory.java [546:691]


    public IEnvironmentAction buildBoundVertexAction(VertexPatternExpr vertexPatternExpr,
            EdgePatternExpr edgePatternExpr, Function<EdgeIdentifier, List<List<String>>> edgeKeyAccess)
            throws CompilationException {
        VariableExpr edgeVar = edgePatternExpr.getEdgeDescriptor().getVariableExpr();
        VariableExpr vertexVar = vertexPatternExpr.getVariableExpr();
        VariableExpr iterationVar = graphixRewritingContext.getGraphixVariableCopy(vertexVar);
        VariableExpr intermediateVar = graphixRewritingContext.getGraphixVariableCopy(vertexVar);

        // We should only be working with one edge identifier...
        List<EdgeIdentifier> edgeElementIDs = edgePatternExpr.generateIdentifiers(graphIdentifier);
        if (edgeElementIDs.size() != 1) {
            throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, "Found non-canonical edge pattern!");
        }
        EdgeIdentifier edgeIdentifier = edgeElementIDs.get(0);

        // ...and only one vertex identifier (given that we only have one label).
        List<VertexIdentifier> vertexElementIDs = vertexPatternExpr.generateIdentifiers(graphIdentifier);
        if (vertexElementIDs.size() != 1) {
            throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, "Found non-canonical vertex pattern!");
        }
        VertexIdentifier vertexIdentifier = vertexElementIDs.get(0);
        ElementBodyAnalysisContext vertexAnalysisContext = analysisContextMap.get(vertexIdentifier);
        Expression datasetCallExpression = vertexAnalysisContext.getDatasetCallExpression();
        if (vertexAnalysisContext.isExpressionInline() && vertexAnalysisContext.isSelectClauseInline()) {
            return new AbstractInlineAction(graphixRewritingContext, vertexAnalysisContext, iterationVar) {
                @Override
                public void apply(LoweringEnvironment loweringEnvironment) throws CompilationException {
                    // Join our vertex iteration variable to our edge variable.
                    loweringEnvironment.acceptTransformer(lowerList -> {
                        VariableExpr edgeJoinExpr = aliasLookupTable.getJoinAlias(edgeVar);
                        VariableExpr edgeJoinCopy = graphixDeepCopyVisitor.visit(edgeJoinExpr, null);
                        VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
                        VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
                        Expression vertexEdgeJoin = buildVertexEdgeJoin(
                                buildAccessorList(iterationVarCopy1, elementLookupTable.getVertexKey(vertexIdentifier)),
                                buildAccessorList(edgeJoinCopy, edgeKeyAccess.apply(edgeIdentifier)));
                        JoinClause joinClause = new JoinClause(JoinType.INNER, datasetCallExpression, iterationVarCopy2,
                                null, vertexEdgeJoin, null);
                        joinClause.setSourceLocation(vertexPatternExpr.getSourceLocation());
                        lowerList.addNonRepresentativeClause(joinClause);
                    });

                    // Inline our vertex body.
                    super.apply(loweringEnvironment);

                    // If we have a filter expression, add it as a WHERE clause here.
                    final Expression filterExpr = vertexPatternExpr.getFilterExpr();
                    if (filterExpr != null) {
                        loweringEnvironment.acceptAction(buildFilterExprAction(filterExpr, vertexVar, iterationVar));
                    }

                    // Bind our intermediate (join) variable and vertex variable.
                    loweringEnvironment.acceptTransformer(lowerList -> {
                        VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
                        VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
                        VariableExpr intermediateVarCopy = graphixDeepCopyVisitor.visit(intermediateVar, null);
                        LetClause nonRepresentativeBinding = new LetClause(intermediateVarCopy, iterationVarCopy1);
                        lowerList.addNonRepresentativeClause(nonRepresentativeBinding);
                        lowerList.addVertexBinding(vertexVar, iterationVarCopy2);
                    });
                    aliasLookupTable.addIterationAlias(vertexVar, iterationVar);
                    aliasLookupTable.addJoinAlias(vertexVar, intermediateVar);
                }
            };

        } else if (vertexAnalysisContext.isExpressionInline()) {
            return new AbstractInlineAction(graphixRewritingContext, vertexAnalysisContext, iterationVar) {
                @Override
                public void apply(LoweringEnvironment loweringEnvironment) throws CompilationException {
                    // Join our vertex iteration variable to our edge variable.
                    loweringEnvironment.acceptTransformer(lowerList -> {
                        VariableExpr edgeJoinExpr = aliasLookupTable.getJoinAlias(edgeVar);
                        VariableExpr edgeJoinCopy = graphixDeepCopyVisitor.visit(edgeJoinExpr, null);
                        VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
                        VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
                        Expression vertexEdgeJoin = buildVertexEdgeJoin(
                                buildAccessorList(iterationVarCopy1, elementLookupTable.getVertexKey(vertexIdentifier)),
                                buildAccessorList(edgeJoinCopy, edgeKeyAccess.apply(edgeIdentifier)));
                        JoinClause joinClause = new JoinClause(JoinType.INNER, datasetCallExpression, iterationVarCopy2,
                                null, vertexEdgeJoin, null);
                        joinClause.setSourceLocation(vertexPatternExpr.getSourceLocation());
                        lowerList.addNonRepresentativeClause(joinClause);
                    });

                    // Inline our vertex body.
                    super.apply(loweringEnvironment);

                    // If we have a filter expression, add it as a WHERE clause here.
                    final Expression filterExpr = vertexPatternExpr.getFilterExpr();
                    if (filterExpr != null) {
                        loweringEnvironment.acceptAction(buildFilterExprAction(filterExpr, vertexVar, iterationVar));
                    }

                    // Build a record constructor from our context to bind to our vertex variable.
                    loweringEnvironment.acceptTransformer(lowerList -> {
                        VariableExpr intermediateVarCopy = graphixDeepCopyVisitor.visit(intermediateVar, null);
                        RecordConstructor recordConstructor1 = buildRecordConstructor();
                        RecordConstructor recordConstructor2 = buildRecordConstructor();
                        LetClause nonRepresentativeBinding = new LetClause(intermediateVarCopy, recordConstructor1);
                        lowerList.addNonRepresentativeClause(nonRepresentativeBinding);
                        lowerList.addVertexBinding(vertexVar, recordConstructor2);
                    });
                    aliasLookupTable.addIterationAlias(vertexVar, iterationVar);
                    aliasLookupTable.addJoinAlias(vertexVar, intermediateVar);
                }
            };

        } else {
            GraphElementDeclaration elementDeclaration = elementLookupTable.getElementDecl(vertexIdentifier);
            return loweringEnvironment -> {
                // Join our vertex body to our edge variable.
                loweringEnvironment.acceptTransformer(lowerList -> {
                    VariableExpr edgeJoinExpr = aliasLookupTable.getJoinAlias(edgeVar);
                    VariableExpr edgeJoinCopy = graphixDeepCopyVisitor.visit(edgeJoinExpr, null);
                    VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
                    VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
                    Expression vertexEdgeJoin = buildVertexEdgeJoin(
                            buildAccessorList(iterationVarCopy1, elementLookupTable.getVertexKey(vertexIdentifier)),
                            buildAccessorList(edgeJoinCopy, edgeKeyAccess.apply(edgeIdentifier)));
                    ILangExpression declBodyCopy = SqlppRewriteUtil.deepCopy(elementDeclaration.getNormalizedBody());
                    JoinClause joinClause = new JoinClause(JoinType.INNER, (Expression) declBodyCopy, iterationVarCopy2,
                            null, vertexEdgeJoin, null);
                    joinClause.setSourceLocation(vertexPatternExpr.getSourceLocation());
                    lowerList.addNonRepresentativeClause(joinClause);
                });

                // If we have a filter expression, add it as a WHERE clause here.
                final Expression filterExpr = vertexPatternExpr.getFilterExpr();
                if (filterExpr != null) {
                    loweringEnvironment.acceptAction(buildFilterExprAction(filterExpr, vertexVar, iterationVar));
                }

                // Bind our intermediate (join) variable and vertex variable.
                loweringEnvironment.acceptTransformer(lowerList -> {
                    VariableExpr iterationVarCopy1 = graphixDeepCopyVisitor.visit(iterationVar, null);
                    VariableExpr iterationVarCopy2 = graphixDeepCopyVisitor.visit(iterationVar, null);
                    VariableExpr intermediateVarCopy = graphixDeepCopyVisitor.visit(intermediateVar, null);
                    LetClause nonRepresentativeBinding = new LetClause(intermediateVarCopy, iterationVarCopy1);
                    lowerList.addNonRepresentativeClause(nonRepresentativeBinding);
                    lowerList.addVertexBinding(vertexVar, iterationVarCopy2);
                });
                aliasLookupTable.addIterationAlias(vertexVar, iterationVar);
                aliasLookupTable.addJoinAlias(vertexVar, intermediateVar);
            };
        }
    }