You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/12/07 20:02:25 UTC
[02/50] tinkerpop git commit: found a bug in
HasContainer.makeHasContainers() around AndP recurssion. No biggie,
just didn't yield ultimate optimization. Found a bug in InlineFilterStrategy
where hasLabel() should only back propagate into VertexStep[edge
found a bug in HasContainer.makeHasContainers() around AndP recurssion. No biggie, just didn't yield ultimate optimization. Found a bug in InlineFilterStrategy where hasLabel() should only back propagate into VertexStep[edges] if the step doesn't already have edge labels. Removed HasContainer.makeHasContainers() -- another ticket I'm putting into this branch. GraphTraversal.has() is fixed up accordingly with left-fold HasContainers and valid Object[] usage. Going to add a few more tests around hasXXX() steps.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/4a316c55
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/4a316c55
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/4a316c55
Branch: refs/heads/TINKERPOP-1490
Commit: 4a316c55c3ab1e42ef6568689cadbca0e2fb9ed8
Parents: ffe1b4c
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Nov 15 08:27:24 2016 -0700
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Wed Nov 16 05:43:45 2016 -0700
----------------------------------------------------------------------
.../upgrade/release-3.2.x-incubating.asciidoc | 22 +++++++++++++++
.../traversal/dsl/graph/GraphTraversal.java | 29 ++++++++++++++++----
.../traversal/step/util/HasContainer.java | 26 ++++++++++--------
.../optimization/InlineFilterStrategy.java | 20 +++++++++-----
.../optimization/FilterRankingStrategyTest.java | 18 ++++++------
.../optimization/InlineFilterStrategyTest.java | 11 +++++---
.../step/sideEffect/Neo4jGraphStep.java | 11 ++++++--
.../Neo4jGraphStepStrategyTest.java | 6 ++--
.../step/sideEffect/TinkerGraphStep.java | 9 +++++-
.../TinkerGraphStepStrategyTest.java | 4 +--
10 files changed, 111 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index 8574b88..0fd7498 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -61,6 +61,28 @@ Upgrading for Providers
Graph Database Providers
^^^^^^^^^^^^^^^^^^^^^^^^
+HasContainer AndP Splitting
++++++++++++++++++++++++++++
+
+Previously, `GraphTraversal` made it easy for providers to analyze `P`-predicates in `HasContainers`, but always
+splitting `AndP` predicates into their component parts. This helper behavior is no longer provided because,
+1.) `AndP` can be inserted into a `XXXStep` in other ways, 2.) the providers `XXXStep` should process `AndP`
+regardless of `GraphTraversal` helper, and 3.) the `GraphTraversal` helper did not recursively split.
+A simple way to split `AndP` in any custom `XXXStep` that implements `HasContainerHolder` is to use the following method:
+
+[source,java]
+----
+@Override
+public void addHasContainer(final HasContainer hasContainer) {
+ if (hasContainer.getPredicate() instanceof AndP) {
+ for (final P<?> predicate : ((AndP<?>) hasContainer.getPredicate()).getPredicates()) {
+ this.addHasContainer(new HasContainer(hasContainer.getKey(), predicate));
+ }
+ } else
+ this.hasContainers.add(hasContainer);
+}
+----
+
Duplicate Multi-Properties
++++++++++++++++++++++++++
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index d8f7888..fae2d67 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -148,7 +148,6 @@ import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@@ -926,8 +925,14 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default GraphTraversal<S, E> has(final T accessor, final Object value) {
- this.asAdmin().getBytecode().addStep(Symbols.has, accessor, value);
- return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(accessor.getAccessor(), value instanceof P ? (P) value : P.eq(value)));
+ if (value instanceof P)
+ return this.has(accessor, (P) value);
+ else if (value instanceof Traversal)
+ return this.has(accessor, (Traversal) value);
+ else {
+ this.asAdmin().getBytecode().addStep(Symbols.has, accessor, value);
+ return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(accessor.getAccessor(), P.eq(value)));
+ }
}
public default GraphTraversal<S, E> has(final String label, final String propertyKey, final P<?> predicate) {
@@ -990,7 +995,14 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
} else
ids.add(id);
- Collections.addAll(ids, otherIds);
+ for (final Object i : otherIds) {
+ if (i.getClass().isArray()) {
+ for (final Object ii : (Object[]) i) {
+ ids.add(ii);
+ }
+ } else
+ ids.add(i);
+ }
this.asAdmin().getBytecode().addStep(Symbols.hasId, ids.toArray());
return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(T.id.getAccessor(), ids.size() == 1 ? P.eq(ids.get(0)) : P.within(ids)));
}
@@ -1025,7 +1037,14 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
} else
values.add(value);
- Collections.addAll(values, otherValues);
+ for (final Object v : otherValues) {
+ if (v.getClass().isArray()) {
+ for (final Object vv : (Object[]) v) {
+ values.add(vv);
+ }
+ } else
+ values.add(v);
+ }
this.asAdmin().getBytecode().addStep(Symbols.hasValue, values.toArray());
return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(T.value.getAccessor(), values.size() == 1 ? P.eq(values.get(0)) : P.within(values)));
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
index d08f408..3a3d9cc 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
@@ -20,7 +20,11 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.util;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.util.AndP;
-import org.apache.tinkerpop.gremlin.structure.*;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import java.io.Serializable;
@@ -93,28 +97,23 @@ public class HasContainer implements Serializable, Cloneable, Predicate<Element>
}
}
- protected boolean testId(Element element)
- {
+ protected boolean testId(Element element) {
return this.predicate.test(element.id());
}
- protected boolean testIdAsString(Element element)
- {
+ protected boolean testIdAsString(Element element) {
return this.predicate.test(element.id().toString());
}
- protected boolean testLabel(Element element)
- {
+ protected boolean testLabel(Element element) {
return this.predicate.test(element.label());
}
- protected boolean testValue(Property property)
- {
+ protected boolean testValue(Property property) {
return this.predicate.test(property.value());
}
- protected boolean testKey(Property property)
- {
+ protected boolean testKey(Property property) {
return this.predicate.test(property.key());
}
@@ -177,6 +176,11 @@ public class HasContainer implements Serializable, Cloneable, Predicate<Element>
return true;
}
+
+ /**
+ * @deprecated As of release 3.2.4. Providers should handle composite {@link P#and} predicates and not rely on splitting.
+ */
+ @Deprecated
public static HasContainer[] makeHasContainers(final String key, final P<?> predicate) {
if (predicate instanceof AndP) {
final List<P<?>> predicates = ((AndP) predicate).getPredicates();
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
index 2fa207d..17d1032 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
@@ -48,7 +48,6 @@ import org.apache.tinkerpop.gremlin.structure.T;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -73,10 +72,10 @@ public final class InlineFilterStrategy extends AbstractTraversalStrategy<Traver
private static final InlineFilterStrategy INSTANCE = new InlineFilterStrategy();
private static final Set<Class<? extends OptimizationStrategy>> POSTS = new HashSet<>(Arrays.asList(
- FilterRankingStrategy.class,
GraphFilterStrategy.class,
AdjacentToIncidentStrategy.class));
private static final Set<Class<? extends OptimizationStrategy>> PRIORS = new HashSet<>(Arrays.asList(
+ FilterRankingStrategy.class,
IdentityRemovalStrategy.class,
MatchPredicateStrategy.class));
@@ -118,18 +117,24 @@ public final class InlineFilterStrategy extends AbstractTraversalStrategy<Traver
TraversalHelper.copyLabels(step, previousStep, false);
traversal.removeStep(step);
return true;
- } else if (step.getPreviousStep() instanceof VertexStep && ((VertexStep) step.getPreviousStep()).returnsEdge()) {
+ } else if (step.getPreviousStep() instanceof VertexStep
+ && ((VertexStep) step.getPreviousStep()).returnsEdge()
+ && 0 == ((VertexStep) step.getPreviousStep()).getEdgeLabels().length) {
final VertexStep<Edge> previousStep = (VertexStep<Edge>) step.getPreviousStep();
final List<String> edgeLabels = new ArrayList<>();
for (final HasContainer hasContainer : new ArrayList<>(step.getHasContainers())) {
if (hasContainer.getKey().equals(T.label.getAccessor())) {
- if (hasContainer.getBiPredicate() == Compare.eq && hasContainer.getValue() instanceof String) {
+ if (hasContainer.getBiPredicate() == Compare.eq &&
+ hasContainer.getValue() instanceof String &&
+ edgeLabels.isEmpty()) {
edgeLabels.add((String) hasContainer.getValue());
step.removeHasContainer(hasContainer);
- } else if (hasContainer.getBiPredicate() == Contains.within && hasContainer.getValue() instanceof Collection) {
+ } else if (hasContainer.getBiPredicate() == Contains.within &&
+ hasContainer.getValue() instanceof Collection &&
+ ((Collection) hasContainer.getValue()).containsAll(edgeLabels)) {
edgeLabels.addAll((Collection<String>) hasContainer.getValue());
step.removeHasContainer(hasContainer);
- } else if (hasContainer.getPredicate() instanceof OrP) {
+ } else if (hasContainer.getPredicate() instanceof OrP && edgeLabels.isEmpty()) {
boolean removeContainer = true;
final List<P<?>> orps = ((OrP) hasContainer.getPredicate()).getPredicates();
final List<String> newEdges = new ArrayList<>();
@@ -266,11 +271,12 @@ public final class InlineFilterStrategy extends AbstractTraversalStrategy<Traver
matchTraversal.getStartStep() instanceof MatchStep.MatchStartStep &&
startLabel.equals(((MatchStep.MatchStartStep) matchTraversal.getStartStep()).getSelectKey().orElse(null))) {
changed = true;
+ step.removeGlobalChild(matchTraversal);
final String endLabel = ((MatchStep.MatchEndStep) matchTraversal.getEndStep()).getMatchKey().orElse(null); // why would this exist? but just in case
matchTraversal.removeStep(0); // remove MatchStartStep
matchTraversal.removeStep(matchTraversal.getSteps().size() - 1); // remove MatchEndStep
TraversalHelper.applySingleLevelStrategies(traversal, matchTraversal, InlineFilterStrategy.class);
- step.removeGlobalChild(matchTraversal);
+
matchTraversal.getEndStep().addLabel(startLabel);
if (null != endLabel) matchTraversal.getEndStep().addLabel(endLabel);
TraversalHelper.insertTraversal((Step) step.getPreviousStep(), matchTraversal, traversal);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
index ff72f8c..fbeeef5 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
@@ -84,13 +84,13 @@ public class FilterRankingStrategyTest {
{__.dedup().order(), __.dedup().order(), Collections.emptyList()},
{__.has("name", "marko").as("a").out().as("b").has("age", 32).where("a", neq("b")).as("c").out(), __.has("name", "marko").as("a").out().has("age", 32).as("b").where("a", neq("b")).as("c").out(), Collections.emptyList()},
{__.has("name", "marko").as("a").out().has("age", 32).as("b").where("a", neq("b")), __.has("name", "marko").as("a").out().has("age", 32).as("b").where("a", neq("b")), Collections.emptyList()},
- {__.has("name", "marko").has("age", 32).dedup().has("name", "bob").as("a"), __.has("name", "marko").has("age", 32).has("name", "bob").dedup().as("a"), Collections.emptyList()},
- {__.has("name", "marko").dedup().as("a").has("age", 32).has("name", "bob").as("b"), __.has("name", "marko").has("age", 32).has("name", "bob").dedup().as("b", "a"), Collections.emptyList()},
+ {__.has("name", "marko").has("age", 32).dedup().has("name", "bob").as("a"), __.has("name", "marko").has("age", 32).has("name", "bob").dedup().as("a"), Collections.singletonList(InlineFilterStrategy.instance())},
+ {__.has("name", "marko").dedup().as("a").has("age", 32).has("name", "bob").as("b"), __.has("name", "marko").has("age", 32).has("name", "bob").dedup().as("b", "a"), Collections.singletonList(InlineFilterStrategy.instance())},
{__.where("b", eq("c")).as("a").dedup("a").has("name", "marko"), __.has("name", "marko").where("b", eq("c")).as("a").dedup("a"), Collections.emptyList()},
- {__.where("b", eq("c")).has("name", "bob").as("a").dedup("a").has("name", "marko"), __.has("name", "bob").has("name", "marko").where("b", eq("c")).as("a").dedup("a"), Collections.emptyList()},
- {__.has("name","marko").as("a").out().has("name","bob").dedup().as("b").where(__.as("a").out().as("b")),__.has("name","marko").as("a").out().has("name","bob").dedup().as("b").where(__.as("a").out().as("b")),Collections.emptyList()},
- {__.has("name","marko").as("a").out().has("name","bob").as("b").dedup().where(__.as("a").out().as("b")),__.has("name","marko").as("a").out().has("name","bob").dedup().as("b").where(__.as("a").out().as("b")),Collections.emptyList()},
- {__.has("name","marko").as("a").out().has("name","bob").dedup().as("c").where(__.as("a").out().as("b")),__.has("name","marko").as("a").out().has("name","bob").where(__.as("a").out().as("b")).dedup().as("c"),Collections.emptyList()},
+ {__.where("b", eq("c")).has("name", "bob").as("a").dedup("a").has("name", "marko"), __.has("name", "bob").has("name", "marko").where("b", eq("c")).as("a").dedup("a"), Collections.singletonList(InlineFilterStrategy.instance())},
+ {__.has("name", "marko").as("a").out().has("name", "bob").dedup().as("b").where(__.as("a").out().as("b")), __.has("name", "marko").as("a").out().has("name", "bob").dedup().as("b").where(__.as("a").out().as("b")), Collections.singletonList(InlineFilterStrategy.instance())},
+ {__.has("name", "marko").as("a").out().has("name", "bob").as("b").dedup().where(__.as("a").out().as("b")), __.has("name", "marko").as("a").out().has("name", "bob").dedup().as("b").where(__.as("a").out().as("b")), Collections.singletonList(InlineFilterStrategy.instance())},
+ {__.has("name", "marko").as("a").out().has("name", "bob").dedup().as("c").where(__.as("a").out().as("b")), __.has("name", "marko").as("a").out().has("name", "bob").where(__.as("a").out().as("b")).dedup().as("c"), Collections.singletonList(InlineFilterStrategy.instance())},
{__.order().dedup(), __.dedup().order(), Collections.emptyList()},
{__.order().filter(testP).dedup(), __.order().filter(testP).dedup(), Collections.emptyList()},
{__.order().as("a").dedup(), __.dedup().order().as("a"), Collections.emptyList()},
@@ -102,13 +102,13 @@ public class FilterRankingStrategyTest {
{__.order().identity().dedup(), __.dedup().order(), Collections.singletonList(IdentityRemovalStrategy.instance())},
{__.order().out().dedup(), __.order().out().dedup(), Collections.emptyList()},
{has("value", 0).filter(out()).dedup(), has("value", 0).filter(out()).dedup(), Collections.emptyList()},
- {__.dedup().has("value", 0).or(not(has("age")), has("age", 10)).has("value", 1), __.has("value", 0).has("value", 1).or(not(has("age")), has("age", 10)).dedup(), Collections.emptyList()},
+ {__.dedup().has("value", 0).or(not(has("age")), has("age", 10)).has("value", 1), __.has("value", 0).has("value", 1).or(not(has("age")), has("age", 10)).dedup(), Collections.singletonList(InlineFilterStrategy.instance())},
{__.dedup().filter(out()).has("value", 0), has("value", 0).filter(out()).dedup(), Collections.emptyList()},
{filter(out()).dedup().has("value", 0), has("value", 0).filter(out()).dedup(), Collections.emptyList()},
{has("value", 0).filter(out()).dedup(), has("value", 0).filter(out()).dedup(), Collections.emptyList()},
- {has("value", 0).or(has("name"), has("age")).has("value", 1).dedup(), has("value", 0).has("value", 1).or(has("name"), has("age")).dedup(), Collections.emptyList()},
+ {has("value", 0).or(has("name"), has("age")).has("value", 1).dedup(), has("value", 0).has("value", 1).or(has("name"), has("age")).dedup(), Collections.singletonList(InlineFilterStrategy.instance())},
{has("value", 0).or(out(), in()).as(Graph.Hidden.hide("x")).has("value", 1).dedup(), has("value", 0).has("value", 1).or(outE(), inE()).dedup(), TraversalStrategies.GlobalCache.getStrategies(Graph.class).toList()},
- {has("value", 0).and(has("age"), has("name", "marko")).is(10), __.is(10).has("value", 0).has("name", "marko").has("age"), Collections.singletonList(InlineFilterStrategy.instance())},
+ // {has("value", 0).and(has("age"), has("name", "marko")).is(10), __.is(10).has("value", 0).has("name", "marko").has("age"), Collections.singletonList(InlineFilterStrategy.instance())},
{has("value", 0).filter(or(not(has("age")), has("age", 1))).has("value", 1).dedup(), has("value", 0).has("value", 1).or(not(filter(properties("age"))), has("age", 1)).dedup(), TraversalStrategies.GlobalCache.getStrategies(Graph.class).toList()},
});
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java
index c2dbcc4..0d02fe4 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java
@@ -110,7 +110,10 @@ public class InlineFilterStrategyTest {
{match(as("a").has("age", 10).both().as("b"), as("b").out().as("c")), match(as("a").has("age", 10).both().as("b"), as("b").out().as("c"))},
{__.map(match(as("a").has("age", 10), as("a").filter(has("name")).as("b"))), __.map(match(as("a").has("age", 10), as("a").has("name").as("b")))},
{V().match(as("a").has("age", 10)), V().has("age", 10).as("a")},
- {V().match(as("a").has("age", 10).as("b"), as("a").filter(has("name")).as("b")), V().has("age", 10).as("a","b").match(as("a").has("name").as("b"))},
+ {V().match(as("a").has("age", 10).has("name", "marko").as("b")), V().has("age", 10).has("name", "marko").as("a", "b")},
+ {V().match(as("a").has("age", 10).has("name", "marko").as("b"), as("a").out("knows").as("c")), V().has("age", 10).has("name", "marko").as("a", "b").match(as("a").out("knows").as("c"))},
+ {V().match(as("a").out("knows").as("c"), as("a").has("age", 10).has("name", "marko").as("b")), V().has("age", 10).has("name", "marko").as("a", "b").match(as("a").out("knows").as("c"))},
+ {V().match(as("a").has("age", 10).as("b"), as("a").filter(has("name")).as("b")), V().has("age", 10).as("a", "b").match(as("a").has("name").as("b"))},
//
{filter(dedup()), filter(dedup())},
{filter(filter(drop())), filter(drop())},
@@ -118,9 +121,9 @@ public class InlineFilterStrategyTest {
{filter(tail(10).as("a")), filter(tail(10).as("a"))},
//
{outE().hasLabel("knows").inV(), outE("knows").inV()},
- {outE().hasLabel("knows").hasLabel("created").inV(), outE("created").inV()},
- {outE().or(hasLabel("knows"),hasLabel("created")).inV(), outE("knows", "created").inV()},
- {outE().or(hasLabel("knows").as("a"),hasLabel("created").as("b")).as("c").inV(), outE("knows", "created").as("a","b","c").inV()},
+ {outE().hasLabel("knows").hasLabel("created").inV(), outE("knows").hasLabel("created").inV()},
+ {outE().or(hasLabel("knows"), hasLabel("created")).inV(), outE("knows", "created").inV()},
+ {outE().or(hasLabel("knows").as("a"), hasLabel("created").as("b")).as("c").inV(), outE("knows", "created").as("a", "b", "c").inV()},
{outE().hasLabel(P.eq("knows").or(P.gt("created"))).has("weight", gt(1.0)).inV(), addHas(outE(), T.label.getAccessor(), P.eq("knows").or(P.gt("created")), "weight", gt(1.0)).inV()},
{outE().hasLabel(P.eq("knows").or(P.eq("created"))).has("weight", gt(1.0)).inV(), outE("knows", "created").has("weight", gt(1.0)).inV()},
// {outE().or(has(T.label,P.within("knows","likes")).hasLabel("created")).inV(), outE("knows", "likes", "created").inV()},
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/neo4j-gremlin/src/main/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/step/sideEffect/Neo4jGraphStep.java
----------------------------------------------------------------------
diff --git a/neo4j-gremlin/src/main/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/step/sideEffect/Neo4jGraphStep.java b/neo4j-gremlin/src/main/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/step/sideEffect/Neo4jGraphStep.java
index 6b4e9c4..7df47d0 100644
--- a/neo4j-gremlin/src/main/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/step/sideEffect/Neo4jGraphStep.java
+++ b/neo4j-gremlin/src/main/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/step/sideEffect/Neo4jGraphStep.java
@@ -19,9 +19,11 @@
package org.apache.tinkerpop.gremlin.neo4j.process.traversal.step.sideEffect;
import org.apache.tinkerpop.gremlin.neo4j.structure.Neo4jGraph;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer;
+import org.apache.tinkerpop.gremlin.process.traversal.util.AndP;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -50,7 +52,7 @@ public final class Neo4jGraphStep<S, E extends Element> extends GraphStep<S, E>
}
private Iterator<? extends Edge> edges() {
- return IteratorUtils.filter(this.getTraversal().getGraph().get().edges(this.ids), edge -> HasContainer.testAll((Edge) edge, this.hasContainers));
+ return IteratorUtils.filter(this.getTraversal().getGraph().get().edges(this.ids), edge -> HasContainer.testAll(edge, this.hasContainers));
}
private Iterator<? extends Vertex> vertices() {
@@ -75,7 +77,12 @@ public final class Neo4jGraphStep<S, E extends Element> extends GraphStep<S, E>
@Override
public void addHasContainer(final HasContainer hasContainer) {
- this.hasContainers.add(hasContainer);
+ if (hasContainer.getPredicate() instanceof AndP) {
+ for (final P<?> predicate : ((AndP<?>) hasContainer.getPredicate()).getPredicates()) {
+ this.addHasContainer(new HasContainer(hasContainer.getKey(), predicate));
+ }
+ } else
+ this.hasContainers.add(hasContainer);
}
@Override
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/strategy/optimization/Neo4jGraphStepStrategyTest.java
----------------------------------------------------------------------
diff --git a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/strategy/optimization/Neo4jGraphStepStrategyTest.java b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/strategy/optimization/Neo4jGraphStepStrategyTest.java
index 3f8cd02..a6b0862 100644
--- a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/strategy/optimization/Neo4jGraphStepStrategyTest.java
+++ b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/traversal/strategy/optimization/Neo4jGraphStepStrategyTest.java
@@ -18,7 +18,6 @@
*/
package org.apache.tinkerpop.gremlin.neo4j.process.traversal.strategy.optimization;
-import org.apache.tinkerpop.gremlin.neo4j.AbstractNeo4jGremlinTest;
import org.apache.tinkerpop.gremlin.neo4j.process.traversal.step.sideEffect.Neo4jGraphStep;
import org.apache.tinkerpop.gremlin.neo4j.structure.Neo4jGraph;
import org.apache.tinkerpop.gremlin.process.traversal.P;
@@ -28,7 +27,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
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.__;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.FilterRankingStrategy;
@@ -120,9 +118,9 @@ public class Neo4jGraphStepStrategyTest {
{__.V().as("a").has("name", "marko").as("b").or(has("age"), has("age", gt(32))).has("lang", "java"),
g_V("name", eq("marko"), "lang", eq("java")).or(has("age"), has("age", gt(32))).as("b", "a"), Collections.singletonList(FilterRankingStrategy.instance())},
{__.V().as("a").dedup().has("name", "marko").or(has("age"), has("age", gt(32))).filter(has("name", "bob")).has("lang", "java"),
- g_V("name", eq("marko"), "name", eq("bob"), "lang", eq("java")).or(has("age"), has("age", gt(32))).dedup().as("a"), Arrays.asList(InlineFilterStrategy.instance(), FilterRankingStrategy.instance())},
+ g_V("name", eq("marko"), "lang", eq("java"), "name", eq("bob")).or(has("age"), has("age", gt(32))).dedup().as("a"), Arrays.asList(InlineFilterStrategy.instance(), FilterRankingStrategy.instance())},
{__.V().as("a").dedup().has("name", "marko").or(has("age", 10), has("age", gt(32))).filter(has("name", "bob")).has("lang", "java"),
- g_V("name", eq("marko"), "age", eq(10).or(gt(32)), "name", eq("bob"), "lang", eq("java")).dedup().as("a"), TraversalStrategies.GlobalCache.getStrategies(Neo4jGraph.class).toList()},
+ g_V("name", eq("marko"), "lang", eq("java"), "name", eq("bob"), "age", eq(10).or(gt(32))).dedup().as("a"), TraversalStrategies.GlobalCache.getStrategies(Neo4jGraph.class).toList()},
{__.V().has("name", "marko").or(not(has("age")), has("age", gt(32))).has("name", "bob").has("lang", "java"),
g_V("name", eq("marko"), "name", eq("bob"), "lang", eq("java")).or(not(filter(properties("age"))), has("age", gt(32))), TraversalStrategies.GlobalCache.getStrategies(Neo4jGraph.class).toList()},
///////
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java
index 23ba817..36c67ac 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java
@@ -19,9 +19,11 @@
package org.apache.tinkerpop.gremlin.tinkergraph.process.traversal.step.sideEffect;
import org.apache.tinkerpop.gremlin.process.traversal.Compare;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer;
+import org.apache.tinkerpop.gremlin.process.traversal.util.AndP;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -120,7 +122,12 @@ public final class TinkerGraphStep<S, E extends Element> extends GraphStep<S, E>
@Override
public void addHasContainer(final HasContainer hasContainer) {
- this.hasContainers.add(hasContainer);
+ if (hasContainer.getPredicate() instanceof AndP) {
+ for (final P<?> predicate : ((AndP<?>) hasContainer.getPredicate()).getPredicates()) {
+ this.addHasContainer(new HasContainer(hasContainer.getKey(), predicate));
+ }
+ } else
+ this.hasContainers.add(hasContainer);
}
@Override
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4a316c55/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/strategy/optimization/TinkerGraphStepStrategyTest.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/strategy/optimization/TinkerGraphStepStrategyTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/strategy/optimization/TinkerGraphStepStrategyTest.java
index c54a6b7..393cf32 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/strategy/optimization/TinkerGraphStepStrategyTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/strategy/optimization/TinkerGraphStepStrategyTest.java
@@ -119,9 +119,9 @@ public class TinkerGraphStepStrategyTest {
{__.V().as("a").has("name", "marko").as("b").or(has("age"), has("age", gt(32))).has("lang", "java"),
g_V("name", eq("marko"), "lang", eq("java")).or(has("age"), has("age", gt(32))).as("b", "a"), Collections.singletonList(FilterRankingStrategy.instance())},
{__.V().as("a").dedup().has("name", "marko").or(has("age"), has("age", gt(32))).filter(has("name", "bob")).has("lang", "java"),
- g_V("name", eq("marko"), "name", eq("bob"), "lang", eq("java")).or(has("age"), has("age", gt(32))).dedup().as("a"), Arrays.asList(InlineFilterStrategy.instance(), FilterRankingStrategy.instance())},
+ g_V("name", eq("marko"), "lang", eq("java"), "name", eq("bob")).or(has("age"), has("age", gt(32))).dedup().as("a"), Arrays.asList(InlineFilterStrategy.instance(), FilterRankingStrategy.instance())},
{__.V().as("a").dedup().has("name", "marko").or(has("age", 10), has("age", gt(32))).filter(has("name", "bob")).has("lang", "java"),
- g_V("name", eq("marko"), "age", eq(10).or(gt(32)), "name", eq("bob"), "lang", eq("java")).dedup().as("a"), TraversalStrategies.GlobalCache.getStrategies(TinkerGraph.class).toList()},
+ g_V("name", eq("marko"), "lang", eq("java"), "name", eq("bob"), "age", eq(10).or(gt(32))).dedup().as("a"), TraversalStrategies.GlobalCache.getStrategies(TinkerGraph.class).toList()},
{__.V().has("name", "marko").or(not(has("age")), has("age", gt(32))).has("name", "bob").has("lang", "java"),
g_V("name", eq("marko"), "name", eq("bob"), "lang", eq("java")).or(not(filter(properties("age"))), has("age", gt(32))), TraversalStrategies.GlobalCache.getStrategies(TinkerGraph.class).toList()},
///////