You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by dk...@apache.org on 2019/06/04 14:47:29 UTC

[tinkerpop] 01/01: TINKERPOP-2230 Fixed bug in match() step

This is an automated email from the ASF dual-hosted git repository.

dkuppitz pushed a commit to branch TINKERPOP-2230
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 75233d96b711ac1f5ad750dde50f84cfecab31ad
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Tue May 28 12:25:15 2019 -0700

    TINKERPOP-2230 Fixed bug in match() step
---
 CHANGELOG.asciidoc                                   |  1 +
 .../process/traversal/step/map/MatchStep.java        | 12 ++++++++++++
 gremlin-test/features/map/Match.feature              | 13 +++++++++++++
 .../process/traversal/step/map/MatchTest.java        | 19 +++++++++++++++++++
 .../tinkergraph/structure/TinkerGraphPlayTest.java   | 20 ++++++--------------
 5 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 232312d..d5d740e 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 
 * Bump to Groovy 2.4.17.
 * Improved error messaging when an attempt is made to serialize multi-properties to GraphML.
+* Fixed bug in `MatchStep` where the correct was not properly determined.
 
 [[release-3-3-7]]
 === TinkerPop 3.3.7 (Release Date: May 28, 2019)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
index 8e2207a..900d356 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
@@ -658,6 +658,18 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
         }
 
         public static String computeStartLabel(final List<Traversal.Admin<Object, Object>> traversals) {
+            {
+                // a traversal start label, that's not used as an end label, must be the step's start label
+                final Set<String> startLabels = new HashSet<>();
+                final Set<String> endLabels = new HashSet<>();
+                for (final Traversal.Admin<Object, Object> traversal : traversals) {
+                    Helper.getEndLabel(traversal).ifPresent(endLabels::add);
+                    startLabels.addAll(Helper.getStartLabels(traversal));
+                }
+                startLabels.removeAll(endLabels);
+                if (!startLabels.isEmpty())
+                    return startLabels.iterator().next();
+            }
             final List<String> sort = new ArrayList<>();
             for (final Traversal.Admin<Object, Object> traversal : traversals) {
                 Helper.getStartLabels(traversal).stream().filter(startLabel -> !sort.contains(startLabel)).forEach(sort::add);
diff --git a/gremlin-test/features/map/Match.feature b/gremlin-test/features/map/Match.feature
index 0c78e76..d0dee12 100644
--- a/gremlin-test/features/map/Match.feature
+++ b/gremlin-test/features/map/Match.feature
@@ -78,6 +78,19 @@ Feature: Step - match()
       | m[{"a":"v[marko]","b":"v[josh]", "c":"v[ripple]"}] |
       | m[{"a":"v[marko]","b":"v[josh]", "c":"v[lop]"}] |
 
+  Scenario: g_V_matchXb_created_c__a_knows_bX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().match(__.as("b").out("created").as("c"),
+                  __.as("a").out("knows").as("b"))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | m[{"a":"v[marko]","b":"v[josh]", "c":"v[ripple]"}] |
+      | m[{"a":"v[marko]","b":"v[josh]", "c":"v[lop]"}] |
+
   Scenario: g_V_matchXa_created_b__b_0created_cX_whereXa_neq_cX_selectXa_cX
     Given the modern graph
     And the traversal of
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
index ec59d33..965def1 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
@@ -78,6 +78,8 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
     // linked traversals
     public abstract Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa_knows_b__b_created_cX();
 
+    public abstract Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXb_created_c__a_knows_bX();
+
     // a basic tree with two leaves
     public abstract Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa_knows_b__a_created_cX();
 
@@ -235,6 +237,16 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
 
     @Test
     @LoadGraphWith(MODERN)
+    public void g_V_matchXb_created_c__a_knows_bX() throws Exception {
+        final Traversal<Vertex, Map<String, Vertex>> traversal = get_g_V_matchXb_created_c__a_knows_bX();
+        printTraversalForm(traversal);
+        checkResults(makeMapList(3,
+                "a", convertToVertex(graph, "marko"), "b", convertToVertex(graph, "josh"), "c", convertToVertex(graph, "lop"),
+                "a", convertToVertex(graph, "marko"), "b", convertToVertex(graph, "josh"), "c", convertToVertex(graph, "ripple")), traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
     public void g_V_matchXa_knows_b__a_created_cX() throws Exception {
         final Traversal<Vertex, Map<String, Vertex>> traversal = get_g_V_matchXa_knows_b__a_created_cX();
         printTraversalForm(traversal);
@@ -632,6 +644,13 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
         }
 
         @Override
+        public Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXb_created_c__a_knows_bX() {
+            return g.V().match(
+                    as("b").out("created").as("c"),
+                    as("a").out("knows").as("b"));
+        }
+
+        @Override
         public Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa_knows_b__a_created_cX() {
             return g.V().match(
                     as("a").out("knows").as("b"),
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index c278e89..d4f7d5d 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -124,20 +124,12 @@ public class TinkerGraphPlayTest {
     @Ignore
     public void testPlayDK() throws Exception {
 
-        Graph graph = TinkerGraph.open();
-        graph.io(GraphMLIo.build()).readGraph("../data/grateful-dead.xml");
-
-        GraphTraversalSource g = graph.traversal();//.withoutStrategies(EarlyLimitStrategy.class);
-        g.V().has("name", "Bob_Dylan").in("sungBy").as("a").
-                repeat(out().order().by(Order.shuffle).simplePath().from("a")).
-                until(out("writtenBy").has("name", "Johnny_Cash")).limit(1).as("b").
-                repeat(out().order().by(Order.shuffle).as("c").simplePath().from("b").to("c")).
-                until(out("sungBy").has("name", "Grateful_Dead")).limit(1).
-                path().from("a").unfold().
-                <List<String>>project("song", "artists").
-                by("name").
-                by(__.coalesce(out("sungBy", "writtenBy").dedup().values("name"), constant("Unknown")).fold()).
-                forEachRemaining(System.out::println);
+        final GraphTraversalSource g = TinkerFactory.createModern().traversal();
+        g.V().match(
+                __.as("b").out("created").as("c"),
+                __.as("a").hasLabel("person"),
+                __.as("b").hasLabel("person"),
+                __.as("a").out("knows").as("b")).forEachRemaining(System.out::println);
     }
 
     @Test