You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2015/06/23 19:47:51 UTC
incubator-tinkerpop git commit: Split WhereStep into
WhereTraversalStep and WherePredicateStep to make the internals easier to
understand. Added a not(pattern) example to MatchStep documentation. Updated
the publish-docs.sh to build the docs first before
Repository: incubator-tinkerpop
Updated Branches:
refs/heads/master b410bf718 -> d299f9491
Split WhereStep into WhereTraversalStep and WherePredicateStep to make the internals easier to understand. Added a not(pattern) example to MatchStep documentation. Updated the publish-docs.sh to build the docs first before svn co and deleting the historic docs. Thus, any errors in doc building will be less of a stress.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/d299f949
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/d299f949
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/d299f949
Branch: refs/heads/master
Commit: d299f949109e9a97e41d8c8d10c1968216319e62
Parents: b410bf7
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 23 11:47:44 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 23 11:47:44 2015 -0600
----------------------------------------------------------------------
CHANGELOG.asciidoc | 3 +-
bin/publish-docs.sh | 7 +-
docs/src/the-traversal.asciidoc | 14 +-
.../traversal/dsl/graph/GraphTraversal.java | 9 +-
.../step/filter/WherePredicateStep.java | 147 +++++++++
.../traversal/step/filter/WhereStep.java | 318 -------------------
.../step/filter/WhereTraversalStep.java | 253 +++++++++++++++
.../process/traversal/step/map/MatchStep.java | 31 +-
.../strategy/finalization/ScopingStrategy.java | 1 -
.../AdjacentToIncidentStrategy.java | 4 +-
.../optimization/MatchPredicateStrategy.java | 12 +-
.../ComputerVerificationStrategy.java | 8 +-
.../process/traversal/util/TraversalHelper.java | 19 +-
.../traversal/step/filter/WhereStepTest.java | 23 +-
.../traversal/step/map/MatchStepTest.java | 153 ++++++---
.../SubgraphStrategyTraverseTest.java | 1 -
.../RangeByIsCountStrategyTest.java | 1 -
17 files changed, 577 insertions(+), 427 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index a20d8b1..307431f 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,9 +25,10 @@ image::http://www.tinkerpop.com/docs/current/images/gremlin-hindu.png[width=225]
TinkerPop 3.0.0.GA (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Split `WhereStep` into `WherePredicateStep` and `WhereTraversalStep` to simplify internals.
* Added `Traversal.toStream()` to turn the `Traversal<S,E>` into a `Stream<E>`.
* Added `Scoping.Variable` enum of `START` and `END` which allows the `Scoping` step to specify where its bindings are.
-* `ComputerVerificationStrategy` is smart about not allowing `WhereStep` with a start-variable to run in OLAP as it selects the value from the path.
+* `ComputerVerificationStrategy` is smart about not allowing `WhereXXXStep` with a start-variable to run in OLAP as it selects the value from the path.
* Rewrote `MatchStep` where it now works on `GraphComputer`, solves more patterns, provides plugable execution plans, supports nested AND/OR, `not()`-patterns, etc.
* Renamed `Graphs` in Gremlin Server to `GraphManager`.
* Fixed bug in Gremlin Driver where client-side serialization errors would not bubble up properly.
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/bin/publish-docs.sh
----------------------------------------------------------------------
diff --git a/bin/publish-docs.sh b/bin/publish-docs.sh
index 59960f0..7b42893 100755
--- a/bin/publish-docs.sh
+++ b/bin/publish-docs.sh
@@ -31,6 +31,10 @@ SVN_CMD="svn --no-auth-cache --username=${USERNAME}"
VERSION=$(cat pom.xml | grep -A1 '<artifactId>tinkerpop</artifactId>' | grep '<version>' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}')
rm -rf target
+
+bin/process-docs.sh
+mvn process-resources -Djavadoc
+
mkdir -p target/svn
${SVN_CMD} co --depth immediates https://svn.apache.org/repos/asf/incubator/tinkerpop/site/ target/svn
@@ -42,9 +46,6 @@ ${SVN_CMD} rm "javadocs/${VERSION}"
${SVN_CMD} commit . -m "Docs for TinkerPop ${VERSION} are being replaced."
popd
-bin/process-docs.sh
-mvn process-resources -Djavadoc
-
mkdir -p "target/svn/docs/${VERSION}"
mkdir -p "target/svn/javadocs/${VERSION}/core"
mkdir -p "target/svn/javadocs/${VERSION}/full"
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/docs/src/the-traversal.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/the-traversal.asciidoc b/docs/src/the-traversal.asciidoc
index 17c91b3..007e9bf 100644
--- a/docs/src/the-traversal.asciidoc
+++ b/docs/src/the-traversal.asciidoc
@@ -804,19 +804,21 @@ If a variable is at the start of a traversal pattern it *must* exist as a label
g.V().as('a').out().as('b'). <1>
match( <2>
__.as('a').out().count().as('c'), <3>
- or( <4>
+ __.not(__.as('a').in().as('b')), <4>
+ or( <5>
__.as('a').out('knows').as('b'),
- __.as('b').in().count().as('c').and().as('c').is(gt(2)) <5>
+ __.as('b').in().count().as('c').and().as('c').is(gt(2)) <6>
)
- ).select('a','b','c').by('name').by('name').by() <6>
+ ).select('a','b','c').by('name').by('name').by() <7>
----
<1> A standard, step-labeled traversal can come prior to `match()`.
<2> If the traverser's path prior to entering `match()` has the requisite variables, then no "start variable" is needed.
<3> It is possible to use <<a-note-on-barrier-steps,barrier steps>> though they are computed locally to the pattern (as one would expect).
-<4> It is possible to nest `and()`- and `or()`-steps for conjunction matching.
-<5> Both infix and prefix conjunction notation is supported.
-<6> The bound values are of different types -- vertex ("a"), vertex ("b"), long ("c").
+<4> It is possible to `not()` a pattern.
+<5> It is possible to nest `and()`- and `or()`-steps for conjunction matching.
+<6> Both infix and prefix conjunction notation is supported.
+<7> The bound values are of different types -- vertex ("a"), vertex ("b"), long ("c").
[[using-where-with-match]]
Using Where with Match
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/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 441884b..4e3416d 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
@@ -58,7 +58,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.filter.SimplePathStep
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TailGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TimeLimitStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.CoalesceStep;
@@ -660,7 +661,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default GraphTraversal<S, E> where(final Scope scope, final String startKey, final P<String> predicate) {
- return this.asAdmin().addStep(new WhereStep<>(this.asAdmin(), scope, Optional.ofNullable(startKey), predicate));
+ return this.asAdmin().addStep(new WherePredicateStep<>(this.asAdmin(), scope, Optional.ofNullable(startKey), predicate));
}
public default GraphTraversal<S, E> where(final Scope scope, final P<String> predicate) {
@@ -670,7 +671,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
public default GraphTraversal<S, E> where(final Scope scope, final Traversal<?, ?> whereTraversal) {
return TraversalHelper.getVariableLocations(whereTraversal.asAdmin()).isEmpty() ?
this.filter(whereTraversal) :
- this.asAdmin().addStep(new WhereStep(this.asAdmin(), scope, whereTraversal));
+ this.asAdmin().addStep(new WhereTraversalStep<>(this.asAdmin(), scope, whereTraversal));
}
public default GraphTraversal<S, E> where(final String startKey, final P<String> predicate) {
@@ -752,7 +753,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default GraphTraversal<S, E> not(final Traversal<?, ?> notTraversal) {
- return this.asAdmin().addStep(new NotStep<>(this.asAdmin(), (Traversal<E,?>)notTraversal));
+ return this.asAdmin().addStep(new NotStep<>(this.asAdmin(), (Traversal<E, ?>) notTraversal));
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
new file mode 100644
index 0000000..75d654e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
@@ -0,0 +1,147 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ConjunctionP;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class WherePredicateStep<S> extends FilterStep<S> implements Scoping {
+
+ private static final Set<TraverserRequirement> LOCAL_REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS);
+ private static final Set<TraverserRequirement> GLOBAL_REQUIREMENTS = EnumSet.of(TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS);
+
+ protected String startKey;
+ protected List<String> selectKeys;
+ protected P<Object> predicate;
+ protected Scope scope;
+ protected final Set<String> scopeKeys = new HashSet<>();
+
+ public WherePredicateStep(final Traversal.Admin traversal, final Scope scope, final Optional<String> startKey, final P<String> predicate) {
+ super(traversal);
+ this.scope = scope;
+ this.startKey = startKey.orElse(null);
+ if (null != this.startKey)
+ this.scopeKeys.add(this.startKey);
+ this.predicate = (P) predicate;
+ this.selectKeys = new ArrayList<>();
+ this.configurePredicates(this.predicate);
+ }
+
+ private void configurePredicates(final P<Object> predicate) {
+ if (predicate instanceof ConjunctionP)
+ ((ConjunctionP<Object>) predicate).getPredicates().forEach(this::configurePredicates);
+ else {
+ final String selectKey = (String) (predicate.getValue() instanceof Collection ? ((Collection) predicate.getValue()).iterator().next() : predicate.getValue()); // hack for within("x"))
+ this.selectKeys.add(selectKey);
+ this.scopeKeys.add(selectKey);
+ }
+ }
+
+ private void setPredicateValues(final P<Object> predicate, final Traverser.Admin<S> traverser, final Iterator<String> selectKeysIterator) {
+ if (predicate instanceof ConjunctionP)
+ ((ConjunctionP<Object>) predicate).getPredicates().forEach(p -> this.setPredicateValues(p, traverser, selectKeysIterator));
+ else
+ predicate.setValue(this.getScopeValueByKey(Pop.last, selectKeysIterator.next(), traverser));
+ }
+
+ public Optional<P<?>> getPredicate() {
+ return Optional.ofNullable(this.predicate);
+ }
+
+ public Optional<String> getStartKey() {
+ return Optional.ofNullable(this.startKey);
+ }
+
+ public void removeStartKey() {
+ this.selectKeys.remove(this.startKey);
+ this.startKey = null;
+ }
+
+ @Override
+ protected boolean filter(final Traverser.Admin<S> traverser) {
+ this.setPredicateValues(this.predicate, traverser, this.selectKeys.iterator());
+ return this.predicate.test(null == this.startKey ? traverser.get() : this.getScopeValueByKey(Pop.last, this.startKey, traverser));
+ }
+
+ @Override
+ public String toString() {
+ // TODO: revert the predicates to their string form?
+ return StringFactory.stepString(this, this.scope, this.startKey, this.predicate);
+ }
+
+ @Override
+ public Set<String> getScopeKeys() {
+ return Collections.unmodifiableSet(this.scopeKeys);
+ }
+
+ @Override
+ public WherePredicateStep<S> clone() {
+ final WherePredicateStep<S> clone = (WherePredicateStep<S>) super.clone();
+ clone.predicate = this.predicate.clone();
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() ^ this.scope.hashCode() ^ (null == this.startKey ? "null".hashCode() : this.startKey.hashCode()) ^ this.predicate.hashCode();
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return Scope.local == this.scope ? LOCAL_REQUIREMENTS : GLOBAL_REQUIREMENTS;
+ }
+
+ @Override
+ public void setScope(final Scope scope) {
+ this.scope = scope;
+ }
+
+ @Override
+ public Scope getScope() {
+ return this.scope;
+ }
+
+ @Override
+ public Scope recommendNextScope() {
+ return this.scope;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
deleted file mode 100644
index 659bc2c..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
-
-import org.apache.tinkerpop.gremlin.process.traversal.P;
-import org.apache.tinkerpop.gremlin.process.traversal.Pop;
-import org.apache.tinkerpop.gremlin.process.traversal.Scope;
-import org.apache.tinkerpop.gremlin.process.traversal.Step;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.map.MapStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StartStep;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConjunctionStrategy;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.util.ConjunctionP;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class WhereStep<S> extends FilterStep<S> implements TraversalParent, Scoping {
-
- protected String startKey;
- protected List<String> selectKeys;
- protected P<Object> predicate;
- protected Traversal.Admin<?, ?> whereTraversal;
- protected Scope scope;
- protected final Set<String> scopeKeys = new HashSet<>();
-
- public WhereStep(final Traversal.Admin traversal, final Scope scope, final Optional<String> startKey, final P<String> predicate) {
- super(traversal);
- this.scope = scope;
- this.startKey = startKey.orElse(null);
- if (null != this.startKey)
- this.scopeKeys.add(this.startKey);
- this.predicate = (P) predicate;
- this.selectKeys = new ArrayList<>();
- this.whereTraversal = null;
- this.configurePredicates(this.predicate);
- }
-
- public WhereStep(final Traversal.Admin traversal, final Scope scope, final Traversal<?, ?> whereTraversal) {
- super(traversal);
- this.scope = scope;
- this.startKey = null;
- this.predicate = null;
- this.selectKeys = null;
- this.whereTraversal = whereTraversal.asAdmin();
- this.configureStartAndEndSteps(this.whereTraversal);
- if (this.scopeKeys.isEmpty())
- throw new IllegalArgumentException("A where()-traversal must have at least a start or end label (i.e. variable): " + whereTraversal);
- this.whereTraversal = this.integrateChild(this.whereTraversal);
- }
-
- private void configureStartAndEndSteps(final Traversal.Admin<?, ?> whereTraversal) {
- ConjunctionStrategy.instance().apply(whereTraversal);
- //// START STEP to WhereStartStep
- final Step<?, ?> startStep = whereTraversal.getStartStep();
- if (startStep instanceof ConjunctionStep || startStep instanceof NotStep) { // for conjunction- and not-steps
- ((TraversalParent) startStep).getLocalChildren().forEach(this::configureStartAndEndSteps);
- } else if (startStep instanceof StartStep && ((StartStep) startStep).isVariableStartStep()) { // as("a").out()... traversals
- final String label = startStep.getLabels().iterator().next();
- this.scopeKeys.add(label);
- TraversalHelper.replaceStep(startStep, new WhereStartStep(whereTraversal, label), whereTraversal);
- } else if (!whereTraversal.getEndStep().getLabels().isEmpty()) { // ...out().as("a") traversals
- TraversalHelper.insertBeforeStep(new WhereStartStep(whereTraversal, null), (Step) startStep, whereTraversal);
- }
- //// END STEP to WhereEndStep
- final Step<?, ?> endStep = whereTraversal.getEndStep();
- if (!endStep.getLabels().isEmpty()) {
- if (endStep.getLabels().size() > 1)
- throw new IllegalArgumentException("The end step of a where()-traversal can only have one label: " + endStep);
- final String label = endStep.getLabels().iterator().next();
- this.scopeKeys.add(label);
- endStep.removeLabel(label);
- whereTraversal.addStep(new WhereEndStep(whereTraversal, label));
- }
- }
-
- private void configurePredicates(final P<Object> predicate) {
- if (predicate instanceof ConjunctionP)
- ((ConjunctionP<Object>) predicate).getPredicates().forEach(this::configurePredicates);
- else {
- final String selectKey = (String) (predicate.getValue() instanceof Collection ? ((Collection) predicate.getValue()).iterator().next() : predicate.getValue()); // hack for within("x"))
- this.selectKeys.add(selectKey);
- this.scopeKeys.add(selectKey);
- }
- }
-
- private void setPredicateValues(final P<Object> predicate, final Traverser.Admin<S> traverser, final Iterator<String> selectKeysIterator) {
- if (predicate instanceof ConjunctionP)
- ((ConjunctionP<Object>) predicate).getPredicates().forEach(p -> this.setPredicateValues(p, traverser, selectKeysIterator));
- else
- predicate.setValue(this.getScopeValueByKey(Pop.last, selectKeysIterator.next(), traverser));
- }
-
- public Optional<P<?>> getPredicate() {
- return Optional.ofNullable(this.predicate);
- }
-
- public Optional<String> getStartKey() {
- return Optional.ofNullable(this.startKey);
- }
-
- public boolean isPredicateBased() {
- return this.predicate != null;
- }
-
- public boolean isTraversalBased() {
- return this.whereTraversal != null;
- }
-
- public void removeStartKey() {
- this.selectKeys.remove(this.startKey);
- this.startKey = null;
- }
-
- @Override
- protected boolean filter(final Traverser.Admin<S> traverser) {
- if (null != this.whereTraversal)
- return TraversalUtil.test((Traverser.Admin) traverser, this.whereTraversal);
- else {
- this.setPredicateValues(this.predicate, traverser, this.selectKeys.iterator());
- return this.predicate.test(null == this.startKey ? traverser.get() : this.getScopeValueByKey(Pop.last, this.startKey, traverser));
- }
- }
-
- @Override
- public List<Traversal.Admin<?, ?>> getLocalChildren() {
- return null == this.whereTraversal ? Collections.emptyList() : Collections.singletonList(this.whereTraversal);
- }
-
- @Override
- public String toString() {
- // TODO: revert the predicates to their string form?
- return StringFactory.stepString(this, this.scope, this.startKey, this.predicate, this.whereTraversal);
- }
-
- @Override
- public Set<String> getScopeKeys() {
- return Collections.unmodifiableSet(this.scopeKeys);
- }
-
- @Override
- public WhereStep<S> clone() {
- final WhereStep<S> clone = (WhereStep<S>) super.clone();
- if (null != this.predicate)
- clone.predicate = this.predicate.clone();
- else
- clone.whereTraversal = clone.integrateChild(this.whereTraversal.clone());
- return clone;
- }
-
- @Override
- public int hashCode() {
- return super.hashCode() ^ this.scope.hashCode() ^ (null == this.startKey ? "null".hashCode() : this.startKey.hashCode()) ^ (null == this.predicate ? this.whereTraversal.hashCode() : this.predicate.hashCode());
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return this.getSelfAndChildRequirements(Scope.local == this.scope ?
- new TraverserRequirement[]{TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS} :
- new TraverserRequirement[]{TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS});
- }
-
- @Override
- public void setScope(final Scope scope) {
- this.scope = scope;
- }
-
- @Override
- public Scope getScope() {
- return this.scope;
- }
-
- @Override
- public Scope recommendNextScope() {
- return this.scope;
- }
-
- //////////////////////////////
-
- public static class WhereStartStep<S> extends MapStep<S, Object> implements Scoping {
-
- private String selectKey;
- private Scope scope = Scope.global;
-
- public WhereStartStep(final Traversal.Admin traversal, final String selectKey) {
- super(traversal);
- this.selectKey = selectKey;
- }
-
- @Override
- protected Object map(final Traverser.Admin<S> traverser) {
- if (this.getTraversal().getEndStep() instanceof WhereEndStep)
- ((WhereEndStep) this.getTraversal().getEndStep()).processStartTraverser(traverser);
- return null == this.selectKey ? traverser.get() : this.getScopeValueByKey(Pop.last, this.selectKey, traverser);
- }
-
- @Override
- public String toString() {
- return StringFactory.stepString(this, this.scope, this.selectKey);
- }
-
- @Override
- public int hashCode() {
- return super.hashCode() ^ this.scope.hashCode() ^ (null == this.selectKey ? "null".hashCode() : this.selectKey.hashCode());
- }
-
- @Override
- public Scope getScope() {
- return this.scope;
- }
-
- @Override
- public Scope recommendNextScope() {
- return this.scope;
- }
-
- @Override
- public void setScope(Scope scope) {
- this.scope = scope;
- }
-
- public void removeScopeKey() {
- this.selectKey = null;
- }
-
- @Override
- public Set<String> getScopeKeys() {
- return null == this.selectKey ? Collections.emptySet() : Collections.singleton(this.selectKey);
- }
- }
-
- public static class WhereEndStep extends FilterStep<Object> implements Scoping {
-
- private final String matchKey;
- private Object matchValue = null;
- private Scope scope = Scope.global;
-
- public WhereEndStep(final Traversal.Admin traversal, final String matchKey) {
- super(traversal);
- this.matchKey = matchKey;
- }
-
- public void processStartTraverser(final Traverser.Admin traverser) {
- if (null != this.matchKey)
- this.matchValue = this.getScopeValueByKey(Pop.last, this.matchKey, traverser);
- }
-
- @Override
- protected boolean filter(final Traverser.Admin<Object> traverser) {
- return null == this.matchKey || traverser.get().equals(this.matchValue);
- }
-
- @Override
- public String toString() {
- return StringFactory.stepString(this, this.scope, this.matchKey);
- }
-
- @Override
- public int hashCode() {
- return super.hashCode() ^ this.scope.hashCode() ^ (null == this.matchKey ? "null".hashCode() : this.matchKey.hashCode());
- }
-
- @Override
- public Scope getScope() {
- return this.scope;
- }
-
- @Override
- public Scope recommendNextScope() {
- return this.scope;
- }
-
- @Override
- public void setScope(Scope scope) {
- // this.scope = scope;
- }
-
- @Override
- public Set<String> getScopeKeys() {
- return null == this.matchKey ? Collections.emptySet() : Collections.singleton(this.matchKey);
- }
- }
-
-
- //////////////////////////////
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
new file mode 100644
index 0000000..d065610
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
@@ -0,0 +1,253 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.MapStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StartStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConjunctionStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class WhereTraversalStep<S> extends FilterStep<S> implements TraversalParent, Scoping {
+
+ private static final Set<TraverserRequirement> LOCAL_REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS);
+ private static final Set<TraverserRequirement> GLOBAL_REQUIREMENTS = EnumSet.of(TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS);
+
+ protected Traversal.Admin<?, ?> whereTraversal;
+ protected Scope scope;
+ protected final Set<String> scopeKeys = new HashSet<>();
+
+ public WhereTraversalStep(final Traversal.Admin traversal, final Scope scope, final Traversal<?, ?> whereTraversal) {
+ super(traversal);
+ this.scope = scope;
+ this.whereTraversal = whereTraversal.asAdmin();
+ this.configureStartAndEndSteps(this.whereTraversal);
+ if (this.scopeKeys.isEmpty())
+ throw new IllegalArgumentException("A where()-traversal must have at least a start or end label (i.e. variable): " + whereTraversal);
+ this.whereTraversal = this.integrateChild(this.whereTraversal);
+ }
+
+ private void configureStartAndEndSteps(final Traversal.Admin<?, ?> whereTraversal) {
+ ConjunctionStrategy.instance().apply(whereTraversal);
+ //// START STEP to WhereStartStep
+ final Step<?, ?> startStep = whereTraversal.getStartStep();
+ if (startStep instanceof ConjunctionStep || startStep instanceof NotStep) { // for conjunction- and not-steps
+ ((TraversalParent) startStep).getLocalChildren().forEach(this::configureStartAndEndSteps);
+ } else if (startStep instanceof StartStep && ((StartStep) startStep).isVariableStartStep()) { // as("a").out()... traversals
+ final String label = startStep.getLabels().iterator().next();
+ this.scopeKeys.add(label);
+ TraversalHelper.replaceStep(startStep, new WhereStartStep(whereTraversal, label), whereTraversal);
+ } else if (!whereTraversal.getEndStep().getLabels().isEmpty()) { // ...out().as("a") traversals
+ TraversalHelper.insertBeforeStep(new WhereStartStep(whereTraversal, null), (Step) startStep, whereTraversal);
+ }
+ //// END STEP to WhereEndStep
+ final Step<?, ?> endStep = whereTraversal.getEndStep();
+ if (!endStep.getLabels().isEmpty()) {
+ if (endStep.getLabels().size() > 1)
+ throw new IllegalArgumentException("The end step of a where()-traversal can only have one label: " + endStep);
+ final String label = endStep.getLabels().iterator().next();
+ this.scopeKeys.add(label);
+ endStep.removeLabel(label);
+ whereTraversal.addStep(new WhereEndStep(whereTraversal, label));
+ }
+ }
+
+
+ @Override
+ protected boolean filter(final Traverser.Admin<S> traverser) {
+ return TraversalUtil.test((Traverser.Admin) traverser, this.whereTraversal);
+ }
+
+ @Override
+ public List<Traversal.Admin<?, ?>> getLocalChildren() {
+ return null == this.whereTraversal ? Collections.emptyList() : Collections.singletonList(this.whereTraversal);
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.scope, this.whereTraversal);
+ }
+
+ @Override
+ public Set<String> getScopeKeys() {
+ return Collections.unmodifiableSet(this.scopeKeys);
+ }
+
+ @Override
+ public WhereTraversalStep<S> clone() {
+ final WhereTraversalStep<S> clone = (WhereTraversalStep<S>) super.clone();
+ clone.whereTraversal = clone.integrateChild(this.whereTraversal.clone());
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() ^ this.scope.hashCode() ^ this.whereTraversal.hashCode();
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return Scope.local == this.scope ? LOCAL_REQUIREMENTS : GLOBAL_REQUIREMENTS;
+ }
+
+ @Override
+ public void setScope(final Scope scope) {
+ this.scope = scope;
+ }
+
+ @Override
+ public Scope getScope() {
+ return this.scope;
+ }
+
+ @Override
+ public Scope recommendNextScope() {
+ return this.scope;
+ }
+
+ //////////////////////////////
+
+ public static class WhereStartStep<S> extends MapStep<S, Object> implements Scoping {
+
+ private String selectKey;
+ private Scope scope = Scope.global;
+
+ public WhereStartStep(final Traversal.Admin traversal, final String selectKey) {
+ super(traversal);
+ this.selectKey = selectKey;
+ }
+
+ @Override
+ protected Object map(final Traverser.Admin<S> traverser) {
+ if (this.getTraversal().getEndStep() instanceof WhereEndStep)
+ ((WhereEndStep) this.getTraversal().getEndStep()).processStartTraverser(traverser);
+ return null == this.selectKey ? traverser.get() : this.getScopeValueByKey(Pop.last, this.selectKey, traverser);
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.scope, this.selectKey);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() ^ this.scope.hashCode() ^ (null == this.selectKey ? "null".hashCode() : this.selectKey.hashCode());
+ }
+
+ @Override
+ public Scope getScope() {
+ return this.scope;
+ }
+
+ @Override
+ public Scope recommendNextScope() {
+ return this.scope;
+ }
+
+ @Override
+ public void setScope(Scope scope) {
+ this.scope = scope;
+ }
+
+ public void removeScopeKey() {
+ this.selectKey = null;
+ }
+
+ @Override
+ public Set<String> getScopeKeys() {
+ return null == this.selectKey ? Collections.emptySet() : Collections.singleton(this.selectKey);
+ }
+ }
+
+ public static class WhereEndStep extends FilterStep<Object> implements Scoping {
+
+ private final String matchKey;
+ private Object matchValue = null;
+ private Scope scope = Scope.global;
+
+ public WhereEndStep(final Traversal.Admin traversal, final String matchKey) {
+ super(traversal);
+ this.matchKey = matchKey;
+ }
+
+ public void processStartTraverser(final Traverser.Admin traverser) {
+ if (null != this.matchKey)
+ this.matchValue = this.getScopeValueByKey(Pop.last, this.matchKey, traverser);
+ }
+
+ @Override
+ protected boolean filter(final Traverser.Admin<Object> traverser) {
+ return null == this.matchKey || traverser.get().equals(this.matchValue);
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.scope, this.matchKey);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() ^ this.scope.hashCode() ^ (null == this.matchKey ? "null".hashCode() : this.matchKey.hashCode());
+ }
+
+ @Override
+ public Scope getScope() {
+ return this.scope;
+ }
+
+ @Override
+ public Scope recommendNextScope() {
+ return this.scope;
+ }
+
+ @Override
+ public void setScope(Scope scope) {
+ // this.scope = scope;
+ }
+
+ @Override
+ public Set<String> getScopeKeys() {
+ return null == this.matchKey ? Collections.emptySet() : Collections.singleton(this.matchKey);
+ }
+ }
+
+
+ //////////////////////////////
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
----------------------------------------------------------------------
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 2993040..f5b8216 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
@@ -32,7 +32,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AndStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConjunctionStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.NotStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StartStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep;
@@ -91,15 +92,15 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
}
//////////////////
- private String pullOutVariableStartStepToParent(final WhereStep<?> whereStep) {
+ private String pullOutVariableStartStepToParent(final WhereTraversalStep<?> whereStep) {
return this.pullOutVariableStartStepToParent(new HashSet<>(), whereStep.getLocalChildren().get(0), true).size() != 1 ? null : pullOutVariableStartStepToParent(new HashSet<>(), whereStep.getLocalChildren().get(0), false).iterator().next();
}
private Set<String> pullOutVariableStartStepToParent(final Set<String> selectKeys, final Traversal.Admin<?, ?> traversal, boolean testRun) {
final Step<?, ?> startStep = traversal.getStartStep();
- if (startStep instanceof WhereStep.WhereStartStep && !((WhereStep.WhereStartStep) startStep).getScopeKeys().isEmpty()) {
- selectKeys.addAll(((WhereStep.WhereStartStep<?>) startStep).getScopeKeys());
- if (!testRun) ((WhereStep.WhereStartStep) startStep).removeScopeKey();
+ if (startStep instanceof WhereTraversalStep.WhereStartStep && !((WhereTraversalStep.WhereStartStep) startStep).getScopeKeys().isEmpty()) {
+ selectKeys.addAll(((WhereTraversalStep.WhereStartStep<?>) startStep).getScopeKeys());
+ if (!testRun) ((WhereTraversalStep.WhereStartStep) startStep).removeScopeKey();
} else if (startStep instanceof ConjunctionStep || startStep instanceof NotStep) {
((TraversalParent) startStep).getLocalChildren().forEach(child -> this.pullOutVariableStartStepToParent(selectKeys, child, testRun));
}
@@ -121,19 +122,19 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
} else if (startStep instanceof NotStep) {
final DefaultTraversal notTraversal = new DefaultTraversal<>();
TraversalHelper.removeToTraversal(startStep, startStep.getNextStep(), notTraversal);
- matchTraversal.addStep(0, new WhereStep<>(matchTraversal, Scope.global, notTraversal));
+ matchTraversal.addStep(0, new WhereTraversalStep<>(matchTraversal, Scope.global, notTraversal));
this.configureStartAndEndSteps(matchTraversal);
} else if (startStep instanceof StartStep && ((StartStep) startStep).isVariableStartStep()) {
final String label = startStep.getLabels().iterator().next();
this.matchStartLabels.add(label);
TraversalHelper.replaceStep((Step) matchTraversal.getStartStep(), new MatchStartStep(matchTraversal, label), matchTraversal);
- } else if (startStep instanceof WhereStep) { // necessary for GraphComputer so the projection is not select'd from a path
- final WhereStep<?> whereStep = (WhereStep<?>) startStep;
- if (whereStep.isPredicateBased()) { // where('a',eq('b')) --> as('a').where(eq('b'))
- TraversalHelper.insertBeforeStep(new MatchStartStep(matchTraversal, whereStep.getStartKey().orElse(null)), (Step) whereStep, matchTraversal);
- whereStep.removeStartKey();
- } else // where(as('a').out()) -> as('a').where(out())
- TraversalHelper.insertBeforeStep(new MatchStartStep(matchTraversal, this.pullOutVariableStartStepToParent(whereStep)), (Step) whereStep, matchTraversal);
+ } else if (startStep instanceof WhereTraversalStep) { // necessary for GraphComputer so the projection is not select'd from a path
+ final WhereTraversalStep<?> whereStep = (WhereTraversalStep<?>) startStep;
+ TraversalHelper.insertBeforeStep(new MatchStartStep(matchTraversal, this.pullOutVariableStartStepToParent(whereStep)), (Step) whereStep, matchTraversal); // where(as('a').out()) -> as('a').where(out())
+ } else if (startStep instanceof WherePredicateStep) { // necessary for GraphComputer so the projection is not select'd from a path
+ final WherePredicateStep<?> whereStep = (WherePredicateStep<?>) startStep;
+ TraversalHelper.insertBeforeStep(new MatchStartStep(matchTraversal, whereStep.getStartKey().orElse(null)), (Step) whereStep, matchTraversal); // where('a',eq('b')) --> as('a').where(eq('b'))
+ whereStep.removeStartKey();
} else {
throw new IllegalArgumentException("All match()-traversals must have a single start label (i.e. variable): " + matchTraversal);
}
@@ -393,7 +394,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
if (null != this.selectKey)
this.scopeKeys.add(this.selectKey);
this.getTraversal().getSteps().forEach(step -> {
- if (step instanceof MatchStep || step instanceof WhereStep)
+ if (step instanceof MatchStep || step instanceof WhereTraversalStep || step instanceof WherePredicateStep)
this.scopeKeys.addAll(((Scoping) step).getScopeKeys());
});
}
@@ -525,7 +526,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
this.traversalLabels.add(traversal.getStartStep().getId());
this.requiredLabels.add(MatchAlgorithm.getRequiredLabels(traversal));
this.counts.add(new Integer[]{i, 0});
- this.whereTraversals.put(traversal, traversal.getStartStep().getNextStep() instanceof WhereStep);
+ this.whereTraversals.put(traversal, traversal.getStartStep().getNextStep() instanceof WhereTraversalStep || traversal.getStartStep().getNextStep() instanceof WherePredicateStep);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
index efce9b8..e613058 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
@@ -25,7 +25,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Scope;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java
index 109f30c..a8b11c9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java
@@ -26,7 +26,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConjunctionSte
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.NotStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep;
@@ -74,7 +74,7 @@ public final class AdjacentToIncidentStrategy extends AbstractTraversalStrategy<
final Step curr = steps.get(i);
if (i == size && isOptimizable(curr)) {
final TraversalParent parent = curr.getTraversal().getParent();
- if (parent instanceof NotStep || parent instanceof TraversalFilterStep || parent instanceof WhereStep || parent instanceof ConjunctionStep) {
+ if (parent instanceof NotStep || parent instanceof TraversalFilterStep || parent instanceof WhereTraversalStep || parent instanceof ConjunctionStep) {
optimizeStep(traversal, curr);
}
} else if (isOptimizable(prev)) {
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
index 3cc9b64..e9beec4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
@@ -22,7 +22,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectOneStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectStep;
@@ -37,7 +38,7 @@ import java.util.stream.Collectors;
/**
* MatchWhereStrategy will fold any post-<code>where()</code> step that maintains a traversal constraint into <code>match()</code>.
- * {@link MatchStep} is intelligent with traversal constraint applications and thus, can more efficiently use the constraint of {@link WhereStep}.
+ * {@link MatchStep} is intelligent with traversal constraint applications and thus, can more efficiently use the constraint of {@link WhereTraversalStep} or {@link WherePredicateStep}.
* <p/>
* <p/>
*
@@ -66,10 +67,11 @@ public final class MatchPredicateStrategy extends AbstractTraversalStrategy<Trav
TraversalHelper.getStepsOfClass(MatchStep.class, traversal).forEach(matchStep -> {
Step<?, ?> nextStep = matchStep.getNextStep();
- while (nextStep instanceof WhereStep ||
+ while (nextStep instanceof WherePredicateStep ||
+ nextStep instanceof WhereTraversalStep ||
(nextStep instanceof SelectStep && ((SelectStep) nextStep).getLocalChildren().isEmpty()) ||
- nextStep instanceof SelectOneStep && ((SelectOneStep) nextStep).getLocalChildren().isEmpty()) { // match().select().where() --> match(where()).select()
- if (nextStep instanceof WhereStep) {
+ (nextStep instanceof SelectOneStep && ((SelectOneStep) nextStep).getLocalChildren().isEmpty())) { // match().select().where() --> match(where()).select()
+ if (nextStep instanceof WherePredicateStep || nextStep instanceof WhereTraversalStep) {
traversal.removeStep(nextStep);
matchStep.addGlobalChild(new DefaultTraversal<>().addStep(nextStep));
nextStep = matchStep.getNextStep();
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
index 7885ab3..0fd0e82 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
@@ -33,7 +33,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.DedupGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TailGlobalStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GraphStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep;
@@ -106,9 +107,8 @@ public final class ComputerVerificationStrategy extends AbstractTraversalStrateg
throw new ComputerVerificationException("Local traversals on GraphComputer may not traverse past the local star-graph: " + traversalOptional.get(), traversal);
}
- if (step instanceof WhereStep &&
- ((((WhereStep) step).isPredicateBased() && ((WhereStep) step).getStartKey().isPresent()) ||
- (((WhereStep) step).isTraversalBased() && TraversalHelper.getVariableLocations(((WhereStep<?>) step).getLocalChildren().get(0)).contains(Scoping.Variable.START))))
+ if ((step instanceof WherePredicateStep && ((WherePredicateStep) step).getStartKey().isPresent()) ||
+ (step instanceof WhereTraversalStep && TraversalHelper.getVariableLocations(((WhereTraversalStep<?>) step).getLocalChildren().get(0)).contains(Scoping.Variable.START)))
throw new ComputerVerificationException("A where()-step that has a start variable is not allowed because the variable value is retrieved from the path: " + step, traversal);
if (UNSUPPORTED_STEPS.stream().filter(c -> c.isAssignableFrom(step.getClass())).findFirst().isPresent())
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
index 7a1b5f0..7325b91 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
@@ -26,7 +26,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConjunctionStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.NotStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
@@ -341,8 +342,11 @@ public final class TraversalHelper {
final Step<?, ?> startStep = traversal.getStartStep();
if (startStep instanceof StartStep && ((StartStep) startStep).isVariableStartStep())
variables.add(Scoping.Variable.START);
- else if (startStep instanceof WhereStep.WhereStartStep) {
- if (!((WhereStep.WhereStartStep) startStep).getScopeKeys().isEmpty())
+ else if (startStep instanceof WherePredicateStep) {
+ if (((WherePredicateStep) startStep).getStartKey().isPresent())
+ variables.add(Scoping.Variable.START);
+ } else if (startStep instanceof WhereTraversalStep.WhereStartStep) {
+ if (!((WhereTraversalStep.WhereStartStep) startStep).getScopeKeys().isEmpty())
variables.add(Scoping.Variable.START);
} else if (startStep instanceof MatchStep.MatchStartStep) {
if (((MatchStep.MatchStartStep) startStep).getSelectKey().isPresent())
@@ -352,12 +356,15 @@ public final class TraversalHelper {
variables.add(Scoping.Variable.START);
else
((MatchStep<?, ?>) startStep).getGlobalChildren().forEach(child -> TraversalHelper.getVariableLocations(variables, child));
- } else if (startStep instanceof ConjunctionStep || startStep instanceof NotStep || startStep instanceof WhereStep)
+ } else if (startStep instanceof ConjunctionStep || startStep instanceof NotStep || startStep instanceof WhereTraversalStep)
((TraversalParent) startStep).getLocalChildren().forEach(child -> TraversalHelper.getVariableLocations(variables, child));
///
final Step<?, ?> endStep = traversal.getEndStep();
- if (endStep instanceof WhereStep.WhereEndStep) {
- if (!((WhereStep.WhereEndStep) endStep).getScopeKeys().isEmpty())
+ if (endStep instanceof WherePredicateStep) {
+ if (((WherePredicateStep) endStep).getStartKey().isPresent())
+ variables.add(Scoping.Variable.END);
+ } else if (endStep instanceof WhereTraversalStep.WhereEndStep) {
+ if (!((WhereTraversalStep.WhereEndStep) endStep).getScopeKeys().isEmpty())
variables.add(Scoping.Variable.END);
} else if (endStep instanceof MatchStep.MatchEndStep) {
if (((MatchStep.MatchEndStep) endStep).getMatchKey().isPresent())
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
index 8c34250..b044631 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
@@ -21,11 +21,9 @@
package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.junit.Test;
import java.util.Arrays;
import java.util.List;
@@ -38,26 +36,13 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
*/
public class WhereStepTest extends StepTest {
- @Test
- public void shouldHaveProperPredicate() {
- Traversal<?, ?> traversal = as("a").out().as("b").where(as("a").out());
- WhereStep<?> whereStep = (WhereStep) traversal.asAdmin().getEndStep();
- //assertEquals(TraversalP.class, whereStep.predicate.getClass());
-
- traversal = as("a", "b").out().as("b", "c").where(as("a").out().as("b").and().as("c").out().as("d"));
- traversal.asAdmin().setStrategies(TraversalStrategies.GlobalCache.getStrategies(Graph.class));
- traversal.iterate();
- whereStep = (WhereStep) traversal.asAdmin().getEndStep();
- //System.out.println(traversal);
- //System.out.println(whereStep.predicate);
- // TODO: do something here
- }
-
@Override
public List<Traversal> getTraversals() {
return Arrays.asList(
as("a").out().as("b").where(as("a").out()),
- as("a").out().as("b").where(as("a").out().as("b"))
+ as("a").out().as("b").where(as("a").out().as("b")),
+ as("a").out().as("b").where("a", P.neq("b")),
+ as("a").out().as("b").where("a", P.neq("c"))
);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
index 1e97462..fa06a74 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
@@ -27,11 +27,14 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConjunctionStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.NoOpBarrierStep;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.EmptyTraverser;
import org.junit.Test;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
@@ -57,9 +60,9 @@ public class MatchStepTest extends StepTest {
}
@Test
- public void shouldDoPreCompilationCorrectly() {
- Traversal.Admin<?, ?> traversal = __.match("a", as("a").out().as("b"), as("c").path().as("d")).asAdmin();
- MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+ public void testPreCompilationOfStartAndEnds() {
+ final Traversal.Admin<?, ?> traversal = __.match("a", as("a").out().as("b"), as("c").path().as("d")).asAdmin();
+ final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
assertEquals(MatchStep.class, traversal.getStartStep().getClass());
assertEquals("a", matchStep.getStartKey().get());
assertEquals(2, matchStep.getGlobalChildren().size());
@@ -72,48 +75,116 @@ public class MatchStepTest extends StepTest {
assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(PathStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals("d", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+ }
- ///////////////////
+ @Test
+ public void testPreCompilationOfOr() {
+ final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
+ __.match("a", as("a").out().as("b"), or(as("c").path().as("d"), as("e").coin(0.5).as("f"))).asAdmin(),
+ __.match("a", as("a").out().as("b"), as("c").path().as("d").or().as("e").coin(0.5).as("f")).asAdmin());
+ assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
+ traversals.forEach(traversal -> {
+ final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+ assertEquals("a", matchStep.getStartKey().get());
+ assertEquals(2, matchStep.getGlobalChildren().size());
+ Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
+ assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+ assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
+ assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+ //
+ pattern = matchStep.getGlobalChildren().get(1);
+ assertEquals(MatchStep.class, pattern.getStartStep().getClass());
+ assertEquals(ConjunctionStep.Conjunction.OR, ((MatchStep<?, ?>) pattern.getStartStep()).getConjunction());
+ assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
+ assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
+ assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
+ assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
+ assertEquals(CoinStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
+ assertEquals("f", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().get());
+ });
+ }
- traversal = __.match("a", as("a").out().as("b"), or(as("c").path().as("d"), as("e").coin(0.5).as("f"))).asAdmin();
- matchStep = (MatchStep<?, ?>) traversal.getStartStep();
- assertEquals("a", matchStep.getStartKey().get());
- assertEquals(2, matchStep.getGlobalChildren().size());
- pattern = matchStep.getGlobalChildren().get(0);
- assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
- assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
- assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
- //
- pattern = matchStep.getGlobalChildren().get(1);
- assertTrue(pattern.getStartStep() instanceof MatchStep);
- assertEquals(ConjunctionStep.Conjunction.OR, ((MatchStep<?, ?>) pattern.getStartStep()).getConjunction());
- assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
- assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
- assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
- assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
- assertEquals(CoinStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
- assertEquals("f", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().get());
+ @Test
+ public void testPreCompilationOfAnd() {
+ final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
+ __.match("a", as("a").out().as("b"), and(as("c").path().as("d"), as("e").barrier())).asAdmin(),
+ __.match("a", as("a").out().as("b"), as("c").path().as("d").and().as("e").barrier()).asAdmin());
+ assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
+ traversals.forEach(traversal -> {
+ MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+ assertEquals("a", matchStep.getStartKey().get());
+ assertEquals(2, matchStep.getGlobalChildren().size());
+ Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
+ assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+ assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
+ assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+ //
+ pattern = matchStep.getGlobalChildren().get(1);
+ assertEquals(MatchStep.class, pattern.getStartStep().getClass());
+ assertEquals(ConjunctionStep.Conjunction.AND, ((MatchStep<?, ?>) pattern.getStartStep()).getConjunction());
+ assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
+ assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
+ assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
+ assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
+ assertEquals(NoOpBarrierStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
+ assertFalse(((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().isPresent());
+ });
+ }
- ///////////////////
+ @Test
+ public void testPreCompilationOfWhereTraversal() {
+ final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
+ __.match(as("a").out().as("b"), as("c").where(in().as("d"))).asAdmin(),
+ __.match(as("a").out().as("b"), where(as("c").in().as("d"))).asAdmin());
+ assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
+ traversals.forEach(traversal -> {
+ MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+ assertFalse(matchStep.getStartKey().isPresent());
+ assertEquals(2, matchStep.getGlobalChildren().size());
+ Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
+ assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+ assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
+ assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+ //
+ pattern = matchStep.getGlobalChildren().get(1);
+ assertEquals(MatchStep.MatchStartStep.class, pattern.getStartStep().getClass());
+ assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+ assertEquals(WhereTraversalStep.class, pattern.getStartStep().getNextStep().getClass());
+ assertEquals(MatchStep.MatchEndStep.class, pattern.getStartStep().getNextStep().getNextStep().getClass());
+ assertEquals(1, ((WhereTraversalStep<?>) pattern.getStartStep().getNextStep()).getLocalChildren().size());
+ Traversal.Admin<?, ?> whereTraversal = ((WhereTraversalStep<?>) pattern.getStartStep().getNextStep()).getLocalChildren().get(0);
+ assertEquals(WhereTraversalStep.WhereStartStep.class, whereTraversal.getStartStep().getClass());
+ assertTrue(((WhereTraversalStep.WhereStartStep) whereTraversal.getStartStep()).getScopeKeys().isEmpty());
+ assertEquals(VertexStep.class, whereTraversal.getStartStep().getNextStep().getClass());
+ assertEquals(WhereTraversalStep.WhereEndStep.class, whereTraversal.getStartStep().getNextStep().getNextStep().getClass());
+ assertEquals(1, ((WhereTraversalStep.WhereEndStep) whereTraversal.getStartStep().getNextStep().getNextStep()).getScopeKeys().size());
+ assertEquals("d", ((WhereTraversalStep.WhereEndStep) whereTraversal.getStartStep().getNextStep().getNextStep()).getScopeKeys().iterator().next());
+ });
+ }
- traversal = __.match("a", as("a").out().as("b"), as("c").path().as("d").and().as("e").barrier()).asAdmin();
- matchStep = (MatchStep<?, ?>) traversal.getStartStep();
- assertEquals("a", matchStep.getStartKey().get());
- assertEquals(2, matchStep.getGlobalChildren().size());
- pattern = matchStep.getGlobalChildren().get(0);
- assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
- assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
- assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
- //
- pattern = matchStep.getGlobalChildren().get(1);
- assertTrue(pattern.getStartStep() instanceof MatchStep);
- assertEquals(ConjunctionStep.Conjunction.AND, ((MatchStep<?, ?>) pattern.getStartStep()).getConjunction());
- assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
- assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
- assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
- assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
- assertEquals(NoOpBarrierStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
- assertFalse(((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().isPresent());
+ @Test
+ public void testPreCompilationOfWherePredicate() {
+ final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
+ __.match(as("a").out().as("b"), as("c").where(P.neq("d"))).asAdmin(),
+ __.match(as("a").out().as("b"), where("c", P.neq("d"))).asAdmin());
+ assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
+ traversals.forEach(traversal -> {
+ MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+ assertFalse(matchStep.getStartKey().isPresent());
+ assertEquals(2, matchStep.getGlobalChildren().size());
+ Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
+ assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+ assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
+ assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+ //
+ pattern = matchStep.getGlobalChildren().get(1);
+ assertEquals(MatchStep.MatchStartStep.class, pattern.getStartStep().getClass());
+ assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+ assertEquals(WherePredicateStep.class, pattern.getStartStep().getNextStep().getClass());
+ assertEquals(MatchStep.MatchEndStep.class, pattern.getStartStep().getNextStep().getNextStep().getClass());
+ assertFalse(((WherePredicateStep<?>) pattern.getStartStep().getNextStep()).getStartKey().isPresent());
+ assertEquals("d", ((WherePredicateStep<?>) pattern.getStartStep().getNextStep()).getPredicate().get().getOriginalValue());
+ });
}
@Test
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java
index a64ad77..8c668c8 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java
@@ -22,7 +22,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GraphStep;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
import org.apache.tinkerpop.gremlin.structure.Direction;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java
index 4bc3866..1642b41 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java
@@ -24,7 +24,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
import org.junit.Before;