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);
}