Skip to content

Commit 274c0bd

Browse files
committed
Merge branch '3.8-dev'
2 parents 3a6e5c4 + 0b2e77e commit 274c0bd

File tree

19 files changed

+106
-185
lines changed

19 files changed

+106
-185
lines changed

docs/src/dev/provider/gremlin-semantics.asciidoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,12 @@ The `addE()` step can be used as both a start step and a mid-traversal step. Whe
535535
and `to()` must be specified. When used as a mid-traversal step, the current traverser becomes the source vertex and
536536
only `to()` needs to be specified.
537537
538+
The gremlin-lang grammar only permits `Traversal` and `String` (alias for `__.select(String)`) arguments in `from()` and
539+
`to()`. The `Traversal` must either produce a `Vertex` which is attachable to the graph, or it must produce the id of an
540+
existing `Vertex` in the graph. `GraphTraversal` implementations in GLVs may optionally support `from(Vertex)` and
541+
`to(Vertex)` as syntactic sugar. If translating to gremlin-lang scripts, these sugared modulators must be converted to
542+
`from(__.V(vertex.id()))` or `from(__.constant(vertex.id()))` (and equivalents for `to()`).
543+
538544
*Exceptions*
539545
540546
* If the edge label is null, an `IllegalArgumentException` will be thrown.

docs/src/reference/the-traversal.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ vMarko = g.V().has('name','marko').next()
557557
vPeter = g.V().has('name','peter').next()
558558
g.V(vMarko).addE('knows').to(vPeter) <6>
559559
g.addE('knows').from(vMarko).to(vPeter) <7>
560+
g.addE('knows').from(__.V(1)).to(__.constant(6)) <8>
560561
----
561562
562563
<1> Add a co-developer edge with a year-property between marko and his collaborators.
@@ -567,6 +568,7 @@ g.addE('knows').from(vMarko).to(vPeter) <7>
567568
supports user provided ids.
568569
<6> Add an edge between marko and peter given the directed (detached) vertex references.
569570
<7> Add an edge between marko and peter given the directed (detached) vertex references.
571+
<8> Use child traversals producing either a vertex, or vertex id to add an edge between marko and peter.
570572
571573
*Additional References*
572574

docs/src/upgrade/release-3.8.x.asciidoc

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -737,41 +737,44 @@ after construction. All usages of `P.getOriginalValue()` should be replaced with
737737
738738
A number of changes have been introduced to the Gremlin grammar to help make it be more consistent and easier to use.
739739
740-
*Removed Vertex References for Grammar*
740+
*Removed StructureVertex from Grammar*
741741
742742
The grammar allowed the construction of a `Vertex` by way of syntax like `new Vertex(1,'person')` (or with similar
743743
arguments to `ReferenceVertex`). This syntax has been removed as it served little purpose within the grammar as it
744744
merely adds more characters to wrap around the identifier, which could simply be used by itself.
745745
746746
The `V()` step, as well as the `from()` and `to()` modulators used with `addE()`, previously accepted `Vertex` as
747-
arguments in the grammar. In its place, the `from()` and `to()` modulators can now directly accept a vertex id in place
748-
of a `Vertex` when used with `addE()` (`V()` has always accepted ids in addition to vertices). When using these steps in
749-
`gremlin-lang` scripts, the vertex id must be used directly.
747+
arguments in the grammar. The `V()` step has always accepted vertex ids as arguments, and continues to do so. The
748+
`from()` and `to()` modulators for `addE()` continue to accept `String` arguments (which are a shorthand for
749+
`__.select(String)`), as well as `Traversal` arguments. As always, these `Traversal` arguments may produce `Vertex`
750+
objects (such as `__.V(1)`) to directly bind to from/to. Newly added in 3.8.0, the `Traversal` may also produce the id
751+
of a vertex present in the graph (such as `__.constant(1)`), which will then bind to from/to.
750752
751-
This change has no effect on the `GraphTraversal` API, nor on `gremlin-groovy` scripts. Vertices can continue to be used
752-
directly in those contexts.
753+
When using these steps in `gremlin-lang` scripts, a `Traversal` or `String` argument must be used directly. This change
754+
has no effect on the `GraphTraversal` API, nor on `gremlin-groovy` scripts. Vertices can continue to be used directly in
755+
those contexts.
753756
754757
[source,text]
755758
----
756-
// 3.7.3
759+
// 3.7.4
757760
gremlin> v1 = g.V(1).next()
758761
==>v[1]
759-
gremlin> v2 = g.V(2).next()
760-
==>v[2]
761-
gremlin> script = String.format("g.V(new Vertex(%s)).outE().where(inV().is(new Vertex(%s)))", v1.id(), v2.id())
762-
==>g.V(new Vertex(1)).outE().where(inV().is(new Vertex(2)))
762+
gremlin> v6 = g.V(6).next()
763+
==>v[6]
764+
gremlin> script = String.format("g.addE('knows').from(new Vertex(%s)).to(new ReferenceVertex(%s))", v1.id(), v6.id())
765+
==>g.addE('knows').from(new Vertex(1)).to(new ReferenceVertex(6))
763766
gremlin> client.submit(script).all().get().get(0).getEdge()
764-
==>e[7][1-knows->2]
767+
==>e[0][1-knows->6]
765768
766769
// 3.8.0
767770
gremlin> v1 = g.V(1).next()
768771
==>v[1]
769-
gremlin> v2 = g.V(2).next()
770-
==>v[2]
771-
gremlin> script = String.format("g.V(%s).outE().where(inV().id().is(%s))", v1.id(), v2.id())
772-
==>g.V(1).outE().where(inV().id().is(2))
772+
gremlin> v6 = g.V(6).next()
773+
==>v[6]
774+
gremlin> script = String.format("g.addE('knows').from(__.V(%s)).to(__.constant(%s))", v1.id(), v6.id())
775+
==>g.addE('knows').from(__.V(1)).to(__.constant(6))
773776
gremlin> client.submit(script).all().get().get(0).getEdge()
774-
==>e[7][1-knows->2]
777+
==>e[0][1-knows->6]
775778
----
776779
777780
*`new` keyword is now optional*

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,10 +407,6 @@ protected void notImplemented(final ParseTree ctx) {
407407
* {@inheritDoc}
408408
*/
409409
@Override public T visitTraversalMethod_from_String(final GremlinParser.TraversalMethod_from_StringContext ctx) { notImplemented(ctx); return null; }
410-
/**
411-
* {@inheritDoc}
412-
*/
413-
@Override public T visitTraversalMethod_from_GenricArgument(final GremlinParser.TraversalMethod_from_GenricArgumentContext ctx) { return null; }
414410
/**
415411
* {@inheritDoc}
416412
*/
@@ -839,10 +835,6 @@ protected void notImplemented(final ParseTree ctx) {
839835
* {@inheritDoc}
840836
*/
841837
@Override public T visitTraversalMethod_to_String(final GremlinParser.TraversalMethod_to_StringContext ctx) { notImplemented(ctx); return null; }
842-
/**
843-
* {@inheritDoc}
844-
*/
845-
@Override public T visitTraversalMethod_to_GenricArgument(final GremlinParser.TraversalMethod_to_GenricArgumentContext ctx) { notImplemented(ctx); return null; }
846838
/**
847839
* {@inheritDoc}
848840
*/

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,22 +1864,6 @@ public Traversal visitTraversalMethod_option_Predicate_Traversal(final GremlinPa
18641864
antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal()));
18651865
}
18661866

1867-
/**
1868-
* {@inheritDoc}
1869-
*/
1870-
@Override
1871-
public GraphTraversal visitTraversalMethod_from_GenricArgument(final GremlinParser.TraversalMethod_from_GenricArgumentContext ctx) {
1872-
return graphTraversal.from(antlr.argumentVisitor.visitGenericArgument(ctx.genericArgument()));
1873-
}
1874-
1875-
/**
1876-
* {@inheritDoc}
1877-
*/
1878-
@Override
1879-
public Traversal visitTraversalMethod_to_GenricArgument(final GremlinParser.TraversalMethod_to_GenricArgumentContext ctx) {
1880-
return graphTraversal.to(antlr.argumentVisitor.visitGenericArgument(ctx.genericArgument()));
1881-
}
1882-
18831867
/**
18841868
* {@inheritDoc}
18851869
*/

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java

Lines changed: 32 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,14 +1615,14 @@ public default GraphTraversal<S, E> from(final String fromStepLabel) {
16151615
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
16161616
* @since 3.8.0
16171617
*/
1618-
public default GraphTraversal<S, E> from(final GValue<Vertex> fromVertex) {
1618+
public default GraphTraversal<S, E> from(final GValue<?> fromVertex) {
16191619
final Step<?,?> prev = this.asAdmin().getEndStep();
16201620
if (!(prev instanceof FromToModulating))
16211621
throw new IllegalArgumentException(String.format(
16221622
"The from() step cannot follow %s", prev.getClass().getSimpleName()));
16231623

16241624
this.asAdmin().getGremlinLang().addStep(Symbols.from, fromVertex);
1625-
((FromToModulating) prev).addFrom(new GValueConstantTraversal<S, Vertex>(fromVertex));
1625+
((FromToModulating) prev).addFrom(new GValueConstantTraversal<>(fromVertex));
16261626
return this;
16271627
}
16281628

@@ -1636,150 +1636,98 @@ public default GraphTraversal<S, E> from(final GValue<Vertex> fromVertex) {
16361636
* @since 3.3.0
16371637
*/
16381638
public default GraphTraversal<S, E> from(final Vertex fromVertex) {
1639-
final Step<?,?> prev = this.asAdmin().getEndStep();
1640-
if (!(prev instanceof FromToModulating))
1641-
throw new IllegalArgumentException(String.format(
1642-
"The from() step cannot follow %s", prev.getClass().getSimpleName()));
1643-
1644-
this.asAdmin().getGremlinLang().addStep(Symbols.from, fromVertex);
1645-
((FromToModulating) prev).addFrom(__.constant(fromVertex).asAdmin());
1646-
return this;
1639+
return this.from(__.V(fromVertex.id()));
16471640
}
16481641

16491642
/**
16501643
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
1651-
* outgoing vertex of the newly added {@link Edge}.
1644+
* incoming vertex of the newly added {@link Edge}.
16521645
*
1653-
* @param fromVertex the traversal for selecting the outgoing vertex
1646+
* @param toVertex the vertex for selecting the incoming vertex
16541647
* @return the traversal with the modified {@link AddEdgeStepContract}
16551648
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
1656-
* @since 3.1.0-incubating
1649+
* @since 3.8.0
16571650
*/
1658-
public default GraphTraversal<S, E> from(final Traversal<?, Object> fromVertex) {
1651+
public default GraphTraversal<S, E> to(final GValue<?> toVertex) {
16591652
final Step<?,?> prev = this.asAdmin().getEndStep();
16601653
if (!(prev instanceof FromToModulating))
16611654
throw new IllegalArgumentException(String.format(
1662-
"The from() step cannot follow %s", prev.getClass().getSimpleName()));
1655+
"The to() step cannot follow %s", prev.getClass().getSimpleName()));
16631656

1664-
this.asAdmin().getGremlinLang().addStep(Symbols.from, fromVertex);
1665-
((FromToModulating) prev).addFrom(fromVertex.asAdmin());
1657+
this.asAdmin().getGremlinLang().addStep(Symbols.to, toVertex);
1658+
((FromToModulating) prev).addTo(new GValueConstantTraversal<>(toVertex));
16661659
return this;
16671660
}
16681661

16691662
/**
16701663
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
16711664
* incoming vertex of the newly added {@link Edge}.
16721665
*
1673-
* @param toVertex the vertex for selecting the incoming vertex
1666+
* @param toVertex the traversal for selecting the incoming vertex
16741667
* @return the traversal with the modified {@link AddEdgeStepContract}
16751668
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
1676-
* @since 3.8.0
1669+
* @since 3.1.0-incubating
16771670
*/
1678-
public default GraphTraversal<S, E> to(final GValue<Vertex> toVertex) {
1671+
public default GraphTraversal<S, E> to(final Traversal<?, ?> toVertex) {
16791672
final Step<?,?> prev = this.asAdmin().getEndStep();
16801673
if (!(prev instanceof FromToModulating))
16811674
throw new IllegalArgumentException(String.format(
16821675
"The to() step cannot follow %s", prev.getClass().getSimpleName()));
16831676

16841677
this.asAdmin().getGremlinLang().addStep(Symbols.to, toVertex);
1685-
((FromToModulating) prev).addTo(new GValueConstantTraversal<S, Vertex>(toVertex));
1678+
((FromToModulating) prev).addTo(toVertex.asAdmin());
16861679
return this;
16871680
}
16881681

16891682
/**
16901683
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
16911684
* outgoing vertex of the newly added {@link Edge}.
16921685
*
1693-
* @param fromVertexOrId the vertex for selecting the outgoing vertex
1686+
* @param fromVertex the traversal for selecting the outgoing vertex
16941687
* @return the traversal with the modified {@link AddEdgeStepContract}
16951688
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
1696-
* @since 3.3.0
1697-
*/
1698-
public default GraphTraversal<S, E> from(final Object fromVertexOrId) {
1699-
if (fromVertexOrId instanceof String) {
1700-
return this.from((String) fromVertexOrId);
1701-
} else if (fromVertexOrId instanceof Traversal) {
1702-
this.from((Traversal<?, Object>)fromVertexOrId);
1703-
return this;
1704-
}
1705-
final Step<?,?> prev = this.asAdmin().getEndStep();
1706-
if (!(prev instanceof FromToModulating))
1707-
throw new IllegalArgumentException(String.format(
1708-
"The from() step cannot follow %s", prev.getClass().getSimpleName()));
1709-
1710-
// Convert vertex to id for the purposes of GremlinLang
1711-
Object fromId = fromVertexOrId instanceof Vertex ? ((Vertex) fromVertexOrId).id() : fromVertexOrId;
1712-
this.asAdmin().getGremlinLang().addStep(Symbols.from, fromId);
1713-
((FromToModulating) prev).addFrom(fromVertexOrId instanceof GValue ?
1714-
new GValueConstantTraversal<>((GValue<Object>) fromVertexOrId) :
1715-
__.constant(fromVertexOrId).asAdmin());
1716-
return this;
1717-
}
1718-
1719-
/**
1720-
* Provide {@code to()}-modulation to respective steps.
1721-
*
1722-
* @param toStepLabel the step label to modulate to.
1723-
* @return the traversal with the modified {@link FromToModulating} step.
1724-
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#to-step" target="_blank">Reference Documentation - To Step</a>
17251689
* @since 3.1.0-incubating
17261690
*/
1727-
public default GraphTraversal<S, E> to(final String toStepLabel) {
1691+
public default GraphTraversal<S, E> from(final Traversal<?, ?> fromVertex) {
17281692
final Step<?,?> prev = this.asAdmin().getEndStep();
17291693
if (!(prev instanceof FromToModulating))
17301694
throw new IllegalArgumentException(String.format(
1731-
"The to() step cannot follow %s", prev.getClass().getSimpleName()));
1695+
"The from() step cannot follow %s", prev.getClass().getSimpleName()));
17321696

1733-
this.asAdmin().getGremlinLang().addStep(Symbols.to, toStepLabel);
1734-
((FromToModulating) prev).addTo(toStepLabel);
1697+
this.asAdmin().getGremlinLang().addStep(Symbols.from, fromVertex);
1698+
((FromToModulating) prev).addFrom(fromVertex.asAdmin());
17351699
return this;
17361700
}
17371701

17381702
/**
17391703
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
17401704
* incoming vertex of the newly added {@link Edge}.
17411705
*
1742-
* @param toVertex the traversal for selecting the incoming vertex
1743-
* @return the traversal with the modified {@link AddEdgeStep}
1706+
* @param toVertex the vertex for selecting the incoming vertex
1707+
* @return the traversal with the modified {@link AddEdgeStepContract}
17441708
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
1745-
* @since 3.1.0-incubating
1709+
* @since 3.8.0
17461710
*/
1747-
public default GraphTraversal<S, E> to(final Traversal<?, Object> toVertex) {
1748-
final Step<?,?> prev = this.asAdmin().getEndStep();
1749-
if (!(prev instanceof FromToModulating))
1750-
throw new IllegalArgumentException(String.format(
1751-
"The to() step cannot follow %s", prev.getClass().getSimpleName()));
1752-
1753-
this.asAdmin().getGremlinLang().addStep(Symbols.to, toVertex);
1754-
((FromToModulating) prev).addTo(toVertex.asAdmin());
1755-
return this;
1711+
public default GraphTraversal<S, E> to(final Vertex toVertex) {
1712+
return this.to(__.V(toVertex.id()));
17561713
}
17571714

17581715
/**
1759-
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
1760-
* incoming vertex of the newly added {@link Edge}.
1716+
* Provide {@code to()}-modulation to respective steps.
17611717
*
1762-
* @param toVertexOrId the vertex for selecting the incoming vertex
1763-
* @return the traversal with the modified {@link AddEdgeStep}
1764-
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
1765-
* @since 3.3.0
1718+
* @param toStepLabel the step label to modulate to.
1719+
* @return the traversal with the modified {@link FromToModulating} step.
1720+
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#to-step" target="_blank">Reference Documentation - To Step</a>
1721+
* @since 3.1.0-incubating
17661722
*/
1767-
public default GraphTraversal<S, E> to(final Object toVertexOrId) {
1768-
if (toVertexOrId instanceof String) {
1769-
return this.to((String) toVertexOrId);
1770-
} else if (toVertexOrId instanceof Traversal) {
1771-
this.to((Traversal<?, Object>)toVertexOrId);
1772-
return this;
1773-
}
1723+
public default GraphTraversal<S, E> to(final String toStepLabel) {
17741724
final Step<?,?> prev = this.asAdmin().getEndStep();
17751725
if (!(prev instanceof FromToModulating))
17761726
throw new IllegalArgumentException(String.format(
17771727
"The to() step cannot follow %s", prev.getClass().getSimpleName()));
17781728

1779-
this.asAdmin().getGremlinLang().addStep(Symbols.to, toVertexOrId);
1780-
((FromToModulating) prev).addTo(toVertexOrId instanceof GValue ?
1781-
new GValueConstantTraversal<>((GValue<Object>) toVertexOrId) :
1782-
__.constant(toVertexOrId).asAdmin());
1729+
this.asAdmin().getGremlinLang().addStep(Symbols.to, toStepLabel);
1730+
((FromToModulating) prev).addTo(toStepLabel);
17831731
return this;
17841732
}
17851733

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddElementStepPlaceholder.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
2222
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
23-
import org.apache.tinkerpop.gremlin.process.traversal.lambda.ConstantTraversal;
2423
import org.apache.tinkerpop.gremlin.process.traversal.lambda.GValueConstantTraversal;
2524
import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
2625
import org.apache.tinkerpop.gremlin.process.traversal.step.GValueHolder;

gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public static Iterable<Object[]> generateTestParameters() {
9393
{g.V(1).out("knows").values("name"), "g.V(1).out(\"knows\").values(\"name\")"},
9494
{g.V().has(T.label, "person"), "g.V().has(T.label,\"person\")"},
9595
{g.addE("knows").from(new DetachedVertex(1, "test1", Collections.emptyList())).to(new DetachedVertex(6, "test2", Collections.emptyList())),
96-
"g.addE(\"knows\").from(1).to(6)"},
96+
"g.addE(\"knows\").from(__.V(1)).to(__.V(6))"},
9797
{newG().E(new ReferenceEdge(1, "test label", new ReferenceVertex(1, "v1"), new ReferenceVertex(1, "v1"))),
9898
"g.E(_0)"},
9999
{g.V().hasId(P.within(Collections.emptyList())).count(), "g.V().hasId(P.within([])).count()"},

gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public void shouldExtractIdFromVertex() {
165165
assertEquals("g.inject(\"foo\").V(1,2)", VMid.asAdmin().getGremlinLang().getGremlin());
166166

167167
GraphTraversal fromTo = g.addE("Edge").from(new ReferenceVertex(1)).to(new ReferenceVertex(2));
168-
assertEquals("g.addE(\"Edge\").from(1).to(2)", fromTo.asAdmin().getGremlinLang().getGremlin());
168+
assertEquals("g.addE(\"Edge\").from(__.V(1)).to(__.V(2))", fromTo.asAdmin().getGremlinLang().getGremlin());
169169

170170
Map mergeMap = new LinkedHashMap();
171171
mergeMap.put(T.label, "knows");

0 commit comments

Comments
 (0)