public static void handleCreateGraph()

in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/util/GraphStatementHandlingUtil.java [100:221]


    public static void handleCreateGraph(CreateGraphStatement cgs, MetadataProvider metadataProvider,
            IStatementExecutor statementExecutor, DataverseName activeDataverseName) throws Exception {
        MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
        metadataProvider.setMetadataTxnContext(mdTxnCtx);

        // Ensure that our active dataverse exists.
        Dataverse dataverse = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, activeDataverseName);
        if (dataverse == null) {
            throw new CompilationException(ErrorCode.UNKNOWN_DATAVERSE, cgs.getSourceLocation(), activeDataverseName);
        }

        // If a graph already exists, skip.
        Graph existingGraph = GraphixMetadataExtension.getGraph(mdTxnCtx, activeDataverseName, cgs.getGraphName());
        if (existingGraph != null) {
            if (cgs.isIfNotExists()) {
                MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
                return;

            } else if (!cgs.isReplaceIfExists()) {
                throw new CompilationException(ErrorCode.COMPILATION_ERROR, cgs.getSourceLocation(),
                        "Graph " + existingGraph.getGraphName() + " already exists.");
            }
        }
        IEntityRequirements existingRequirements = null;
        if (existingGraph != null) {
            existingRequirements = GraphixMetadataExtension.getAllEntityRequirements(mdTxnCtx).stream()
                    .filter(r -> r.getDataverseName().equals(activeDataverseName))
                    .filter(r -> r.getEntityName().equals(cgs.getGraphName()))
                    .filter(r -> r.getDependentKind().equals(IEntityRequirements.DependentKind.GRAPH)).findFirst()
                    .orElseThrow(() -> new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE,
                            cgs.getSourceLocation(), "Graph dependencies for " + cgs.getGraphName()
                                    + " exist, but the graph itself does not."));
        }

        // Build the graph schema.
        GraphIdentifier graphIdentifier = new GraphIdentifier(activeDataverseName, cgs.getGraphName());
        Schema.Builder schemaBuilder = new Schema.Builder(graphIdentifier);
        List<GraphElementDeclaration> graphElementDeclarations = new ArrayList<>();
        for (GraphConstructor.VertexConstructor vertex : cgs.getVertexElements()) {
            Vertex schemaVertex =
                    schemaBuilder.addVertex(vertex.getLabel(), vertex.getPrimaryKeyFields(), vertex.getDefinition());
            switch (schemaBuilder.getLastError()) {
                case NO_ERROR:
                    VertexIdentifier id = schemaVertex.getIdentifier();
                    GraphElementDeclaration decl = new GraphElementDeclaration(id, vertex.getExpression());
                    decl.setSourceLocation(vertex.getSourceLocation());
                    graphElementDeclarations.add(decl);
                    break;

                case VERTEX_LABEL_CONFLICT:
                    throw new CompilationException(ErrorCode.COMPILATION_ERROR, vertex.getSourceLocation(),
                            "Conflicting vertex label found: " + vertex.getLabel());

                default:
                    throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, vertex.getSourceLocation(),
                            "Constructor vertex was not returned, but the error is not a vertex label conflict!");
            }
        }
        for (GraphConstructor.EdgeConstructor edge : cgs.getEdgeElements()) {
            Edge schemaEdge =
                    schemaBuilder.addEdge(edge.getEdgeLabel(), edge.getDestinationLabel(), edge.getSourceLabel(),
                            edge.getDestinationKeyFields(), edge.getSourceKeyFields(), edge.getDefinition());
            switch (schemaBuilder.getLastError()) {
                case NO_ERROR:
                    EdgeIdentifier id = schemaEdge.getIdentifier();
                    GraphElementDeclaration decl = new GraphElementDeclaration(id, edge.getExpression());
                    decl.setSourceLocation(edge.getSourceLocation());
                    graphElementDeclarations.add(decl);
                    break;

                case SOURCE_VERTEX_NOT_FOUND:
                    throw new CompilationException(ErrorCode.COMPILATION_ERROR, edge.getSourceLocation(),
                            "Source vertex " + edge.getSourceLabel() + " not found in the edge " + edge.getEdgeLabel()
                                    + ".");

                case DESTINATION_VERTEX_NOT_FOUND:
                    throw new CompilationException(ErrorCode.COMPILATION_ERROR, edge.getSourceLocation(),
                            "Destination vertex " + edge.getDestinationLabel() + " not found in the edge "
                                    + edge.getEdgeLabel() + ".");

                case EDGE_LABEL_CONFLICT:
                    throw new CompilationException(ErrorCode.COMPILATION_ERROR, edge.getSourceLocation(),
                            "Conflicting edge label found: " + edge.getEdgeLabel());

                default:
                    throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, edge.getSourceLocation(),
                            "Edge constructor was not returned, and an unexpected error encountered");
            }
        }

        GraphixQueryRewriter graphixQueryRewriter = ((GraphixQueryTranslator) statementExecutor).getQueryRewriter();
        metadataProvider.setDefaultDataverse(dataverse);
        DataverseName dataverseName = (cgs.getDataverseName() != null) ? cgs.getDataverseName() : activeDataverseName;
        GraphRequirements requirements = new GraphRequirements(dataverseName, cgs.getGraphName());
        for (GraphElementDeclaration graphElementDeclaration : graphElementDeclarations) {
            // Determine the graph dependencies using the raw body.
            Set<DependencyIdentifier> graphDependencies = new HashSet<>();
            collectDependenciesOnGraph(graphElementDeclaration.getRawBody(), activeDataverseName, graphDependencies);
            requirements.loadGraphDependencies(graphDependencies);

            // Verify that each element definition is usable.
            ((GraphixQueryTranslator) statementExecutor).setGraphElementNormalizedBody(metadataProvider,
                    graphElementDeclaration, graphixQueryRewriter);

            // Determine the non-graph dependencies using the normalized body.
            requirements.loadNonGraphDependencies(graphElementDeclaration.getNormalizedBody(), graphixQueryRewriter);
        }

        // Add / upsert our graph + requirements to our metadata.
        Graph newGraph = new Graph(graphIdentifier, schemaBuilder.build());
        if (existingGraph == null) {
            MetadataManager.INSTANCE.addEntity(mdTxnCtx, newGraph);
            MetadataManager.INSTANCE.addEntity(mdTxnCtx, requirements);

        } else {
            requirements.setPrimaryKeyValue(existingRequirements.getPrimaryKeyValue());
            MetadataManager.INSTANCE.upsertEntity(mdTxnCtx, newGraph);
            MetadataManager.INSTANCE.upsertEntity(mdTxnCtx, requirements);
        }

        MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
    }