Skip to content

Intermediate translation to IR #108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@
import org.opencypher.gremlin.extension.TestProcedures;
import org.opencypher.gremlin.groups.SkipWithBytecode;
import org.opencypher.gremlin.groups.SkipWithGremlinGroovy;
import org.opencypher.gremlin.translation.CypherAstWrapper;
import org.opencypher.gremlin.translation.CypherAst;
import org.opencypher.gremlin.translation.ir.TranslationWriter;
import org.opencypher.gremlin.translation.ir.model.GremlinStep;
import org.opencypher.gremlin.translation.translator.Translator;
import org.opencypher.gremlin.translation.translator.TranslatorFlavor;
import org.opencypher.gremlin.traversal.ProcedureContext;
import org.opencypher.gremlin.traversal.ReturnNormalizer;
import scala.collection.Seq;

/**
* @see TestProcedures
Expand All @@ -47,20 +52,21 @@
public class ProcedureTest {

private GraphTraversalSource gts = TinkerGraph.open().traversal();
private TestProcedures testProcedures = new TestProcedures();
private ProcedureContext procedureContext = new ProcedureContext(new TestProcedures().get());
private TranslatorFlavor flavor = TranslatorFlavor.gremlinServer();

private List<Map<String, Object>> submitAndGet(String cypher) {
return submitAndGet(cypher, emptyMap());
}

private List<Map<String, Object>> submitAndGet(String cypher, Map<String, ?> parameters) {
private List<Map<String, Object>> submitAndGet(String cypher, Map<String, Object> parameters) {
DefaultGraphTraversal g = new DefaultGraphTraversal(gts);
Translator<GraphTraversal, P> translator = Translator.builder()
.traversal(g)
.procedures(testProcedures.get())
.build();
CypherAstWrapper ast = CypherAstWrapper.parse(cypher, parameters);
GraphTraversal<?, ?> traversal = ast.buildTranslation(translator);
CypherAst ast = CypherAst.parse(cypher, parameters);
Seq<GremlinStep> ir = ast.translate(flavor, procedureContext);
GraphTraversal<?, ?> traversal = TranslationWriter.write(ir, translator, parameters);
ReturnNormalizer returnNormalizer = ReturnNormalizer.create(ast.getReturnTypes());
return traversal.toStream()
.map(returnNormalizer::normalize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import org.opencypher.gremlin.neo4j.driver.GremlinDatabase;
import org.opencypher.gremlin.rules.GremlinServerExternalResource;

public class CypherGremlinNeo4jDriver {
public class CypherGremlinNeo4jDriverSnippets {

@ClassRule
public static final GremlinServerExternalResource gremlinServer = new GremlinServerExternalResource();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import org.opencypher.gremlin.client.CypherResultSet;
import org.opencypher.gremlin.rules.GremlinServerExternalResource;

public class CypherGremlinServerClient {
public class CypherGremlinServerClientSnippets {

@ClassRule
public static final GremlinServerExternalResource gremlinServer = new GremlinServerExternalResource();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import org.junit.ClassRule;
import org.junit.Test;
import org.opencypher.gremlin.rules.GremlinServerExternalResource;
import org.opencypher.gremlin.translation.CypherAstWrapper;
import org.opencypher.gremlin.translation.CypherAst;
import org.opencypher.gremlin.translation.TranslationFacade;
import org.opencypher.gremlin.translation.groovy.GroovyGremlinBindings;
import org.opencypher.gremlin.translation.groovy.GroovyGremlinPredicates;
Expand All @@ -31,7 +31,7 @@
import org.opencypher.gremlin.translation.translator.Translator;
import org.opencypher.gremlin.translation.translator.TranslatorFlavor;

public class Translation {
public class TranslationSnippets {

@ClassRule
public static final GremlinServerExternalResource gremlinServer = new GremlinServerExternalResource();
Expand All @@ -51,7 +51,7 @@ public void translate() throws Exception {
public void translateVerbose() throws Exception {
// freshReadmeSnippet: verbose
String cypher = "MATCH (p:Person) WHERE p.age > 25 RETURN p.name";
CypherAstWrapper ast = CypherAstWrapper.parse(cypher);
CypherAst ast = CypherAst.parse(cypher);
Translator<String, GroovyPredicate> translator = Translator.builder().gremlinGroovy().build();
String gremlin = ast.buildTranslation(translator);
// freshReadmeSnippet: verbose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.opencypher.gremlin.translation.CypherAstWrapper;
import org.opencypher.gremlin.translation.CypherAst;
import org.opencypher.gremlin.translation.translator.Translator;
import org.openjdk.jmh.infra.Blackhole;

Expand All @@ -32,7 +32,7 @@ public TranslationOnlyClient(Blackhole blackhole) {

@Override
public void run(String cypher) {
CypherAstWrapper ast = CypherAstWrapper.parse(cypher);
CypherAst ast = CypherAst.parse(cypher);
DefaultGraphTraversal g = new DefaultGraphTraversal();
Translator<GraphTraversal, P> translator = Translator.builder().traversal(g).build();
blackhole.consume(ast.buildTranslation(translator));
Expand Down
8 changes: 4 additions & 4 deletions tinkerpop/cypher-gremlin-neo4j-driver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Driver driver = GremlinDatabase.driver("//localhost:8182");

It is also possible to create a driver from a `org.apache.tinkerpop.gremlin.driver.Cluster` instance:

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinNeo4jDriver.java#createDriver) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinNeo4jDriverSnippets.java#createDriver) -->
```java
Cluster cluster1 = Cluster.build()
.enableSsl(true)
Expand All @@ -60,7 +60,7 @@ Driver driver2 = GremlinDatabase.driver(cluster2);

By default Cypher queries will be sent without translation, expecting [Cypher plugin](../cypher-gremlin-server-plugin) to be installed on the server. If the target Gremlin Server does not have the plugin installed, translation can be done on the client's thread:

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinNeo4jDriver.java#createConfiguration) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinNeo4jDriverSnippets.java#createConfiguration) -->
```java
Config config = Config.build()
.withTranslation()
Expand All @@ -72,7 +72,7 @@ Driver driver = GremlinDatabase.driver(uri, config);

You can also execute Cypher directly against a [`GraphTraversalSource`](https://tinkerpop.apache.org/docs/current/reference/#the-graph-process):

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinNeo4jDriver.java#inMemory) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinNeo4jDriverSnippets.java#inMemory) -->
```java
TinkerGraph graph = TinkerFactory.createModern();
GraphTraversalSource traversal = graph.traversal();
Expand All @@ -81,7 +81,7 @@ Driver driver = GremlinDatabase.driver(traversal);

Otherwise, the API is the same:

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinNeo4jDriver.java#useDriver) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinNeo4jDriverSnippets.java#useDriver) -->
```java
try (Session session = driver.session()) {
StatementResult result = session.run("CREATE (a:Greeting) " +
Expand Down
10 changes: 5 additions & 5 deletions tinkerpop/cypher-gremlin-server-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ You can also [build the snapshot](../README.md#development) from source.

To send Cypher queries to a Cypher-enabled Gremlin Server and get Cypher-style results:

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClient.java#gremlinStyle) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClientSnippets.java#gremlinStyle) -->
```java
Cluster cluster = Cluster.open(configuration);
Client gremlinClient = cluster.connect();
Expand All @@ -45,7 +45,7 @@ List<Map<String, Object>> results = resultSet.all();

Result sets can be consumed in various ways (all share the same iterator, so pick _one_):

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClient.java#workingWithCypherGremlinClient) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClientSnippets.java#workingWithCypherGremlinClient) -->
```java
List<Map<String, Object>> list = cypherGremlinClient.submit(cypher).all(); // as a list
Stream<Map<String, Object>> stream = cypherGremlinClient.submit(cypher).stream(); // as a stream
Expand All @@ -55,7 +55,7 @@ Iterable<Map<String, Object>> iterable = cypherGremlinClient.submit(cypher); //

Queries can be submitted asynchronously:

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClient.java#async) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClientSnippets.java#async) -->
```java
String cypher = "MATCH (p:person) WHERE p.age > 25 RETURN p.name";
CompletableFuture<CypherResultSet> future = cypherGremlinClient.submitAsync(cypher);
Expand All @@ -68,14 +68,14 @@ future

If the target Gremlin Server does not have the [Cypher plugin](../cypher-gremlin-server-plugin) installed, translation can be done on the client's thread:

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClient.java#translating) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClientSnippets.java#translating) -->
```java
CypherGremlinClient cypherGremlinClient = CypherGremlinClient.translating(gremlinClient);
```

You can also execute Cypher directly against a [`GraphTraversalSource`](https://tinkerpop.apache.org/docs/current/reference/#the-graph-process):

<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClient.java#inMemory) -->
<!-- [freshReadmeSource](../../testware/integration-tests/src/test/java/org/opencypher/gremlin/snippets/CypherGremlinServerClientSnippets.java#inMemory) -->
```java
TinkerGraph graph = TinkerFactory.createModern();
GraphTraversalSource traversal = graph.traversal();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.apache.tinkerpop.gremlin.driver.ResultSet;
import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.opencypher.gremlin.translation.CypherAstWrapper;
import org.opencypher.gremlin.translation.CypherAst;
import org.opencypher.gremlin.translation.translator.Translator;
import org.opencypher.gremlin.translation.translator.TranslatorFlavor;
import org.opencypher.gremlin.traversal.ParameterNormalizer;
Expand All @@ -50,9 +50,9 @@ public void close() {
@Override
public CompletableFuture<CypherResultSet> submitAsync(String cypher, Map<String, ?> parameters) {
Map<String, Object> normalizedParameters = ParameterNormalizer.normalize(parameters);
CypherAstWrapper ast;
CypherAst ast;
try {
ast = CypherAstWrapper.parse(cypher, normalizedParameters);
ast = CypherAst.parse(cypher, normalizedParameters);
} catch (Exception e) {
return completedFuture(exceptional(e));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@
import java.util.NoSuchElementException;
import java.util.function.Supplier;
import org.apache.tinkerpop.gremlin.driver.Result;
import org.opencypher.gremlin.translation.CypherAstWrapper;
import org.opencypher.gremlin.translation.CypherAst;
import org.opencypher.gremlin.translation.groovy.GroovyPredicate;
import org.opencypher.gremlin.translation.translator.Translator;

final class CommonResultSets {
private CommonResultSets() {
}

static CypherResultSet explain(CypherAstWrapper ast) {
static CypherResultSet explain(CypherAst ast) {
Map<String, Object> explanation = new LinkedHashMap<>();
Translator<String, GroovyPredicate> translator = Translator.builder()
.gremlinGroovy()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import java.util.concurrent.CompletableFuture;
import org.apache.tinkerpop.gremlin.driver.Client;
import org.apache.tinkerpop.gremlin.driver.ResultSet;
import org.opencypher.gremlin.translation.CypherAstWrapper;
import org.opencypher.gremlin.translation.CypherAst;
import org.opencypher.gremlin.translation.groovy.GroovyPredicate;
import org.opencypher.gremlin.translation.translator.Translator;
import org.opencypher.gremlin.translation.translator.TranslatorFlavor;
Expand All @@ -49,9 +49,9 @@ public void close() {
@Override
public CompletableFuture<CypherResultSet> submitAsync(String cypher, Map<String, ?> parameters) {
Map<String, Object> normalizedParameters = ParameterNormalizer.normalize(parameters);
CypherAstWrapper ast;
CypherAst ast;
try {
ast = CypherAstWrapper.parse(cypher, normalizedParameters);
ast = CypherAst.parse(cypher, normalizedParameters);
} catch (Exception e) {
return completedFuture(exceptional(e));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.opencypher.gremlin.translation.CypherAstWrapper;
import org.opencypher.gremlin.translation.CypherAst;
import org.opencypher.gremlin.translation.translator.Translator;
import org.opencypher.gremlin.traversal.ParameterNormalizer;
import org.opencypher.gremlin.traversal.ReturnNormalizer;
Expand All @@ -50,9 +50,9 @@ public void close() {
@Override
public CompletableFuture<CypherResultSet> submitAsync(String cypher, Map<String, ?> parameters) {
Map<String, Object> normalizedParameters = ParameterNormalizer.normalize(parameters);
CypherAstWrapper ast;
CypherAst ast;
try {
ast = CypherAstWrapper.parse(cypher, normalizedParameters);
ast = CypherAst.parse(cypher, normalizedParameters);
} catch (Exception e) {
return completedFuture(exceptional(e));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@
import org.apache.tinkerpop.gremlin.server.op.OpProcessorException;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.util.function.ThrowingConsumer;
import org.opencypher.gremlin.translation.CypherAstWrapper;
import org.opencypher.gremlin.translation.CypherAst;
import org.opencypher.gremlin.translation.groovy.GroovyPredicate;
import org.opencypher.gremlin.translation.ir.TranslationWriter;
import org.opencypher.gremlin.translation.ir.model.GremlinStep;
import org.opencypher.gremlin.translation.translator.Translator;
import org.opencypher.gremlin.translation.translator.TranslatorFlavor;
import org.opencypher.gremlin.traversal.ParameterNormalizer;
import org.opencypher.gremlin.traversal.ProcedureContext;
import org.opencypher.gremlin.traversal.ReturnNormalizer;
import org.slf4j.Logger;
import scala.collection.Seq;

/**
* {@link OpProcessor} implementation for processing Cypher {@link RequestMessage}s:
Expand Down Expand Up @@ -94,15 +98,18 @@ private void evalCypher(Context context) throws OpProcessorException {
GraphTraversalSource gts = traversal(context);
DefaultGraphTraversal g = new DefaultGraphTraversal(gts.clone());
Map<String, Object> parameters = ParameterNormalizer.normalize(getParameters(args));
CypherAstWrapper ast = CypherAstWrapper.parse(cypher, parameters);
CypherAst ast = CypherAst.parse(cypher, parameters);

ProcedureContext procedureContext = ProcedureContext.global();
TranslatorFlavor flavor = TranslatorFlavor.gremlinServer();
Seq<GremlinStep> ir = ast.translate(flavor, procedureContext);

Translator<String, GroovyPredicate> stringTranslator = Translator.builder()
.gremlinGroovy()
.inlineParameters()
.procedures(ProcedureContext.global().all())
.build();

String gremlin = ast.buildTranslation(stringTranslator);
String gremlin = TranslationWriter.write(ir, stringTranslator, parameters);
logger.info("Gremlin: {}", gremlin);

if (ast.getOptions().contains(EXPLAIN)) {
Expand All @@ -112,10 +119,9 @@ private void evalCypher(Context context) throws OpProcessorException {

Translator<GraphTraversal, P> traversalTranslator = Translator.builder()
.traversal(g)
.procedures(ProcedureContext.global().all())
.build();

GraphTraversal<?, ?> traversal = ast.buildTranslation(traversalTranslator);
GraphTraversal<?, ?> traversal = TranslationWriter.write(ir, traversalTranslator, parameters);
ReturnNormalizer returnNormalizer = ReturnNormalizer.create(ast.getReturnTypes());
Traversal<?, Map<String, Object>> normalizedTraversal = traversal.map(returnNormalizer::normalize);
inTransaction(gts, () -> handleIterator(context, normalizedTraversal));
Expand Down Expand Up @@ -192,7 +198,7 @@ private void handleIterator(Context context, Traversal traversal) {
}
}

private void explainQuery(Context context, CypherAstWrapper ast, String gremlin) {
private void explainQuery(Context context, CypherAst ast, String gremlin) {
Map<String, Object> explanation = new LinkedHashMap<>();
explanation.put("translation", gremlin);
explanation.put("options", ast.getOptions().toString());
Expand Down
Loading