You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ke...@apache.org on 2023/09/25 22:58:30 UTC
[tinkerpop] branch TINKERPOP-2978 updated (bbf9ca7530 -> af47e8d6e6)
This is an automated email from the ASF dual-hosted git repository.
kenhuuu pushed a change to branch TINKERPOP-2978
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
omit bbf9ca7530 add tests for non-primitive array type
omit a7bf93420b TINKERPOP-2978 Implement all() and any() steps.
add 8da7169ebf [TINKERPOP-2978] Date functions (#2223)
add 45c8d78a98 Fix JS Direction import (#2259)
add 5933fbd53e Merge branch '3.5-dev' into 3.6-dev
add d32ed8512a Merge branch '3.6-dev'
new af47e8d6e6 TINKERPOP-2978 Implement all() and any() steps.
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (bbf9ca7530)
\
N -- N -- N refs/heads/TINKERPOP-2978 (af47e8d6e6)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
CHANGELOG.asciidoc | 3 +
docs/src/dev/developer/for-committers.asciidoc | 1 +
docs/src/dev/io/graphbinary.asciidoc | 5 +
docs/src/dev/io/graphson.asciidoc | 20 ++++
docs/src/dev/provider/gremlin-semantics.asciidoc | 100 +++++++++++++++++++-
docs/src/reference/gremlin-variants.asciidoc | 13 +--
docs/src/reference/the-traversal.asciidoc | 63 +++++++++++++
docs/src/upgrade/release-3.7.x.asciidoc | 19 ++++
.../tinkerpop/gremlin/jsr223/CoreImports.java | 5 +-
.../gremlin/language/grammar/ArgumentVisitor.java | 35 ++++++-
.../grammar/DefaultGremlinBaseVisitor.java | 37 ++++++++
.../language/grammar/GenericLiteralVisitor.java | 8 ++
.../language/grammar/TraversalMethodVisitor.java | 34 +++++++
.../process/traversal/{Pick.java => DT.java} | 12 ++-
.../traversal/dsl/graph/GraphTraversal.java | 56 +++++++++++
.../gremlin/process/traversal/dsl/graph/__.java | 32 ++++++-
.../{TraversalFlatMapStep.java => AsDateStep.java} | 59 ++++++------
.../process/traversal/step/map/DateAddStep.java | 102 +++++++++++++++++++++
.../{TraversalMapStep.java => DateDiffStep.java} | 68 ++++++++------
.../traversal/translator/GolangTranslator.java | 7 +-
.../traversal/translator/JavascriptTranslator.java | 1 -
.../traversal/translator/PythonTranslator.java | 9 +-
.../process/traversal/util/BytecodeHelper.java | 6 ++
.../gremlin/structure/io/binary/DataType.java | 1 +
.../io/binary/TypeSerializerRegistry.java | 53 ++++++++++-
.../structure/io/binary/types/EnumSerializer.java | 10 +-
.../structure/io/graphson/GraphSONModule.java | 7 ++
.../gremlin/structure/io/gryo/GryoVersion.java | 5 +-
.../tinkerpop/gremlin/util/DatetimeHelper.java | 1 -
.../language/grammar/ArgumentVisitorTest.java | 10 ++
.../process/traversal/step/map/AsDateStepTest.java | 79 ++++++++++++++++
.../traversal/step/map/DateAddStepTest.java | 100 ++++++++++++++++++++
.../traversal/step/map/DateDiffStepTest.java | 94 +++++++++++++++++++
.../Process/Traversal/{GryoVersion.cs => DT.cs} | 26 +++---
.../Process/Traversal/GraphTraversal.cs | 37 ++++++++
.../src/Gremlin.Net/Process/Traversal/__.cs | 33 +++++++
.../Structure/IO/GraphBinary/DataType.cs | 1 +
.../IO/GraphBinary/TypeSerializerRegistry.cs | 2 +
.../IO/GraphBinary/Types/EnumSerializer.cs | 6 ++
.../{TDeserializer.cs => DTDeserializer.cs} | 6 +-
.../Structure/IO/GraphSON/GraphSONReader.cs | 1 +
.../Gherkin/CommonSteps.cs | 6 ++
.../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 31 +++++--
.../Structure/IO/GraphBinary/GraphBinaryTests.cs | 15 +++
.../Structure/IO/GraphSON/GraphSONReaderTests.cs | 14 ++-
.../Structure/IO/GraphSON/GraphSONWriterTests.cs | 11 +++
gremlin-go/build/generate.groovy | 1 +
gremlin-go/driver/anonymousTraversal.go | 15 +++
gremlin-go/driver/cucumber/cucumberSteps_test.go | 12 ++-
gremlin-go/driver/cucumber/gremlin.go | 32 +++++--
gremlin-go/driver/graphBinary.go | 6 +-
gremlin-go/driver/graphTraversal.go | 18 ++++
gremlin-go/driver/serializer.go | 2 +
gremlin-go/driver/traversal.go | 21 +++++
gremlin-javascript/build/generate.groovy | 1 +
.../main/javascript/gremlin-javascript/index.js | 1 +
.../lib/process/graph-traversal.js | 33 +++++++
.../gremlin-javascript/lib/process/traversal.js | 1 +
.../lib/structure/io/binary/internals/DataType.js | 1 +
.../io/binary/internals/EnumSerializer.js | 1 +
.../test/cucumber/feature-steps.js | 5 +
.../gremlin-javascript/test/cucumber/gremlin.js | 32 +++++--
.../test/unit/graphbinary/AnySerializer-test.js | 7 ++
gremlin-language/src/main/antlr4/Gremlin.g4 | 34 +++++++
gremlin-python/build/generate.groovy | 4 +-
.../gremlin_python/process/graph_traversal.py | 42 +++++++++
.../python/gremlin_python/process/traversal.py | 7 ++
.../gremlin_python/structure/io/graphbinaryV1.py | 8 +-
.../gremlin_python/structure/io/graphsonV3d0.py | 1 +
.../src/main/python/radish/feature_steps.py | 4 +
gremlin-python/src/main/python/radish/gremlin.py | 35 +++++--
.../tinkerpop/gremlin/features/StepDefinition.java | 5 +
.../features/map/{Split.feature => AsDate.feature} | 77 +++++++++-------
.../map/{Substring.feature => DateAdd.feature} | 63 ++++++-------
.../map/{Length.feature => DateDiff.feature} | 33 ++-----
.../GraphBinaryReaderWriterRoundTripTest.java | 5 +-
76 files changed, 1518 insertions(+), 233 deletions(-)
copy gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/{Pick.java => DT.java} (78%)
copy gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/{TraversalFlatMapStep.java => AsDateStep.java} (55%)
create mode 100644 gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStep.java
copy gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/{TraversalMapStep.java => DateDiffStep.java} (50%)
create mode 100644 gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStepTest.java
create mode 100644 gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStepTest.java
create mode 100644 gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStepTest.java
copy gremlin-dotnet/src/Gremlin.Net/Process/Traversal/{GryoVersion.cs => DT.cs} (63%)
copy gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/{TDeserializer.cs => DTDeserializer.cs} (81%)
copy gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/{Split.feature => AsDate.feature} (51%)
copy gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/{Substring.feature => DateAdd.feature} (55%)
copy gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/{Length.feature => DateDiff.feature} (62%)
[tinkerpop] 01/01: TINKERPOP-2978 Implement all() and any() steps.
Posted by ke...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kenhuuu pushed a commit to branch TINKERPOP-2978
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit af47e8d6e6e51a91911ec3ba3d250ead84efe8a9
Author: Ken Hu <10...@users.noreply.github.com>
AuthorDate: Sun Aug 27 14:36:38 2023 -0700
TINKERPOP-2978 Implement all() and any() steps.
---
CHANGELOG.asciidoc | 1 +
.../dev/future/proposal-3-remove-closures.asciidoc | 42 +++---
docs/src/dev/provider/gremlin-semantics.asciidoc | 66 +++++++++
docs/src/reference/gremlin-variants.asciidoc | 2 +-
docs/src/reference/the-traversal.asciidoc | 48 +++++++
docs/src/upgrade/release-3.7.x.asciidoc | 17 +++
.../grammar/DefaultGremlinBaseVisitor.java | 8 ++
.../language/grammar/TraversalMethodVisitor.java | 16 +++
.../traversal/dsl/graph/GraphTraversal.java | 30 ++++
.../gremlin/process/traversal/dsl/graph/__.java | 10 ++
.../process/traversal/step/filter/AllStep.java | 87 ++++++++++++
.../process/traversal/step/filter/AnyStep.java | 87 ++++++++++++
.../traversal/translator/PythonTranslator.java | 6 +
.../process/traversal/util/BytecodeHelper.java | 4 +
.../grammar/TraversalMethodVisitorTest.java | 9 ++
.../process/traversal/step/filter/AllStepTest.java | 89 ++++++++++++
.../process/traversal/step/filter/AnyStepTest.java | 93 +++++++++++++
.../Process/Traversal/GraphTraversal.cs | 18 +++
.../src/Gremlin.Net/Process/Traversal/__.cs | 16 +++
.../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 24 ++++
gremlin-go/driver/anonymousTraversal.go | 14 ++
gremlin-go/driver/cucumber/gremlin.go | 24 ++++
gremlin-go/driver/graphTraversal.go | 12 ++
.../lib/process/graph-traversal.js | 22 +++
.../gremlin-javascript/test/cucumber/gremlin.js | 24 ++++
gremlin-language/src/main/antlr4/Gremlin.g4 | 10 ++
.../gremlin_python/process/graph_traversal.py | 16 +++
gremlin-python/src/main/python/radish/gremlin.py | 24 ++++
.../gremlin/test/features/filter/All.feature | 151 ++++++++++++++++++++
.../gremlin/test/features/filter/Any.feature | 155 +++++++++++++++++++++
30 files changed, 1098 insertions(+), 27 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index e5da7a64dc..f924127e27 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -33,6 +33,7 @@ This release also includes changes from <<release-3-6-5, 3.6.6>> and <<release-3
* Added date manipulation steps `asDate`, `dateAdd` and `dateDiff`.
* Added new data type `DT` to represent periods of time.
* Added Gherkin support for Date.
+* Added list filtering functions `all` and `any`.
[[release-3-7.0]]
=== TinkerPop 3.7.0 (Release Date: July 31, 2023)
diff --git a/docs/src/dev/future/proposal-3-remove-closures.asciidoc b/docs/src/dev/future/proposal-3-remove-closures.asciidoc
index 12806a258b..90d1ed60c8 100644
--- a/docs/src/dev/future/proposal-3-remove-closures.asciidoc
+++ b/docs/src/dev/future/proposal-3-remove-closures.asciidoc
@@ -1087,64 +1087,54 @@ g.inject([1,2]).product([3,4])
=== `any()` [[any_list]]
-Returns true if any items in the array `value` exist in the input
+Allows the traverser to continue if any items in the array pass the
+supplied predicate.
==== Signature(s)
-`any(value)`
-
-`any(Traversal)`
+`any(Predicate)`
==== Parameters
-* value - An array of the items to check in the incoming list
+* Predicate - The predicate to use to test the values in the array
==== Allowed incoming traverser types
-Array data types. If non-array data types are passed in then an
-`IllegalArgumentException` will be thrown
+Array data types. All other types will be filtered out.
==== Expected Output
-True if any values from one list are in the other, False otherwise
+The arrays which have any item pass the predicate.
....
-g.inject([1,2]).any([1])
-==>true
-g.inject([1,2]).any([3])
-==>false
+g.inject([1,2]).any(P.eq(1))
+==>[1,2]
....
=== `all()` [[all_list]]
-Returns true if all items in the array `value` exist in the input
+Allows the traverser to continue if all items in the array pass the
+supplied predicate.
==== Signature(s)
-`all(value)`
-
-`all(Traversal)`
+`all(Predicate)`
==== Parameters
-* value - An array of the items to check in the incoming list
+* Predicate - The predicate to use to test the values in the array
==== Allowed incoming traverser types
-Array data types. If non-array data types are passed in then an
-`IllegalArgumentException` will be thrown
+Array data types. All other types will be filtered out.
==== Expected Output
-True if all values from one list are in the other, False otherwise
+The arrays which have all items pass the predicate.
....
-g.inject([1,2]).all([1])
-==>true
-g.inject([1,2]).all([1, 3])
-==>false
-g.inject([1,2]).all([3])
-==>false
+g.inject([1,2]).all(P.gt(0))
+==>[1,2]
....
=== `none()` [[none_list]]
diff --git a/docs/src/dev/provider/gremlin-semantics.asciidoc b/docs/src/dev/provider/gremlin-semantics.asciidoc
index 409d718745..74b69e5329 100644
--- a/docs/src/dev/provider/gremlin-semantics.asciidoc
+++ b/docs/src/dev/provider/gremlin-semantics.asciidoc
@@ -524,6 +524,72 @@ fully demonstrative of Gremlin step semantics. It is also hard to simply read th
step is meant to behave. This section discusses the semantics for individual steps to help users and providers
understand implementation expectations.
+[[all-step]]
+=== all()
+
+*Description:* Filters array data from the Traversal Stream if all of the array's items match the supplied predicate.
+
+*Syntax:* `all(Predicate)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`List`/`array`/`Iterable`/`Iterator` |`List`/`array`/`Iterable`/`Iterator`
+|=========================================================
+
+*Arguments:*
+
+* `Predicate` - The predicate to use to test each value in the array data.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+Each value will be tested using the supplied predicate. Empty lists always pass through and null/non-list traversers
+will be filtered out of the Traversal Stream.
+
+*Exceptions*
+
+* A GremlinTypeErrorException will be thrown if one occurs and no other value evaluates to false.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AllStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#all-step[reference]
+
+[[any-step]]
+=== any()
+
+*Description:* Filters array data from the Traversal Stream if any of the array's items match the supplied predicate.
+
+*Syntax:* `any(Predicate)`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`List`/`array`/`Iterable`/`Iterator` |`List`/`array`/`Iterable`/`Iterator`
+|=========================================================
+
+*Arguments:*
+
+* `Predicate` - The predicate to use to test each value in the array data.
+
+*Modulation:*
+
+None
+
+*Considerations:*
+
+Each value will be tested using the supplied predicate. Empty lists, null traversers, and non-list traversers will be
+filtered out of the Traversal Stream.
+
+*Exceptions*
+
+* A GremlinTypeErrorException will be thrown if one occurs and no other value evaluates to true.
+
+See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AnyStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#any-step[reference]
+
[[asDate-step]]
=== asDate()
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index 5b9f237666..0917fa1fbd 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -2469,7 +2469,7 @@ that makes traversals a bit more concise.
In situations where Python reserved words and global functions overlap with standard Gremlin steps and tokens, those
bits of conflicting Gremlin get an underscore appended as a suffix:
-*Steps* - <<and-step,and_()>>, <<as-step,as_()>>, <<filter-step,filter_()>>, <<from-step,from_()>>,
+*Steps* - <<all-step,all_()>>, <<and-step,and_()>>, <<any-step,any_()>>, <<as-step,as_()>>, <<filter-step,filter_()>>, <<from-step,from_()>>,
<<has-step,has_key_>>, <<id-step,id_()>>, <<is-step,is_()>>, <<in-step,in_()>>, <<max-step,max_()>>,
<<min-step,min_()>>, <<not-step,not_()>>, <<or-step,or_()>>, <<range-step,range_()>>, <<sum-step,sum_()>>,
<<with-step,with_()>>
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index a1bd940968..76eb708543 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -657,6 +657,30 @@ g.E().aggregate(local,'x').by('weight').cap('x')
link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#aggregate-java.lang.String-++[`aggregate(String)`],
link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#aggregate-org.apache.tinkerpop.gremlin.process.traversal.Scope,java.lang.String-++[`aggregate(Scope,String)`]
+[[all-step]]
+=== All Step
+
+It is possible to filter list traversers using `all()`-step (*filter*). Every item in the list will be tested against
+the supplied predicate and if all of the items pass then the traverser is passed along the stream, otherwise it is
+filtered. Empty lists are passed along but null or non-iterable traversers are filtered out.
+
+[NOTE, caption=Python]
+====
+The term `all` is a reserved word in Python, and therefore must be referred to in Gremlin with `all_()`.
+====
+
+[gremlin-groovy,modern]
+----
+g.V().values('age').fold().all(gt(25)) <1>
+----
+
+<1> Return the list of ages only if everyone's age is greater than 25.
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#all-org.apache.tinkerpop.gremlin.process.traversal.P-++[`all(P)`],
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`]
+
[[and-step]]
=== And Step
@@ -689,6 +713,30 @@ g.V().where(outE('created').and().outE('knows')).values('name')
link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#and-org.apache.tinkerpop.gremlin.process.traversal.Traversal...-++[`and(Traversal...)`]
+[[any-step]]
+=== Any Step
+
+It is possible to filter list traversers using `any()`-step (*filter*). All items in the list will be tested against
+the supplied predicate and if any of the items pass then the traverser is passed along the stream, otherwise it is
+filtered. Empty lists, null traversers, and non-iterable traversers are filtered out as well.
+
+[NOTE, caption=Python]
+====
+The term `any` is a reserved word in Python, and therefore must be referred to in Gremlin with `any_()`.
+====
+
+[gremlin-groovy,modern]
+----
+g.V().values('age').fold().any(gt(25)) <1>
+----
+
+<1> Return the list of ages if anyone's age is greater than 25.
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#any-org.apache.tinkerpop.gremlin.process.traversal.P-++[`any(P)`],
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/P.html++[`P`]
+
[[as-step]]
=== As Step
diff --git a/docs/src/upgrade/release-3.7.x.asciidoc b/docs/src/upgrade/release-3.7.x.asciidoc
index 77e491c5da..75206c7076 100644
--- a/docs/src/upgrade/release-3.7.x.asciidoc
+++ b/docs/src/upgrade/release-3.7.x.asciidoc
@@ -232,6 +232,23 @@ See: link:https://tinkerpop.apache.org/docs/x.y.z/reference/#split-step[split()-
See: link:https://tinkerpop.apache.org/docs/x.y.z/reference/#substring-step[substring()-step]
See: link:https://issues.apache.org/jira/browse/TINKERPOP-2672[TINKERPOP-2672]
+==== List Traverser based Steps
+Additional List manipulation/filter steps have been added to replace the use of closures: `any()` and `all()`.
+
+The following example demonstrates usage of the newly introduced steps:
+
+[source,text]
+----
+gremlin> g.V().values("age").fold().all(P.gt(10))
+==>[29,27,32,35]
+gremlin> g.V().values("age").fold().any(P.eq(32))
+==>[29,27,32,35]
+----
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-2978[TINKERPOP-2978],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#all-step[all()-step],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#any-step[any()-step]
+
=== Upgrading for Providers
==== Graph System Providers
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
index d51dc618b9..eca310f6aa 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
@@ -195,10 +195,18 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im
* {@inheritDoc}
*/
@Override public T visitTraversalMethod_aggregate_Scope_String(final GremlinParser.TraversalMethod_aggregate_Scope_StringContext ctx) { notImplemented(ctx); return null; }
+ /**
+ * {@inheritDoc}
+ */
+ @Override public T visitTraversalMethod_all_P(final GremlinParser.TraversalMethod_all_PContext ctx) { notImplemented(ctx); return null; }
/**
* {@inheritDoc}
*/
@Override public T visitTraversalMethod_and(final GremlinParser.TraversalMethod_andContext ctx) { notImplemented(ctx); return null; }
+ /**
+ * {@inheritDoc}
+ */
+ @Override public T visitTraversalMethod_any_P(final GremlinParser.TraversalMethod_any_PContext ctx) { notImplemented(ctx); return null; }
/**
* {@inheritDoc}
*/
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
index 6e5ab38706..dc42e84598 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
@@ -177,6 +177,14 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
antlr.argumentVisitor.parseString(ctx.stringArgument()));
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GraphTraversal visitTraversalMethod_all_P(final GremlinParser.TraversalMethod_all_PContext ctx) {
+ return graphTraversal.all(antlr.traversalPredicateVisitor.visitTraversalPredicate(ctx.traversalPredicate()));
+ }
+
/**
* {@inheritDoc}
*/
@@ -186,6 +194,14 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal>
antlr.tListVisitor.visitNestedTraversalList(ctx.nestedTraversalList()));
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GraphTraversal visitTraversalMethod_any_P(final GremlinParser.TraversalMethod_any_PContext ctx) {
+ return graphTraversal.any(antlr.traversalPredicateVisitor.visitTraversalPredicate(ctx.traversalPredicate()));
+ }
+
/**
* {@inheritDoc}
*/
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 cebc035045..be9674e507 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
@@ -57,7 +57,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.branch.LocalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.OptionalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.UnionStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AllStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AndStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AnyStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConnectiveStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.DedupGlobalStep;
@@ -2502,6 +2504,32 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this.asAdmin().addStep(new DropStep<>(this.asAdmin()));
}
+ /**
+ * Filters <code>E</code> lists given the provided {@code predicate}.
+ *
+ * @param predicate the filter to apply
+ * @return the traversal with an appended {@link AllStep}
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#all-step" target="_blank">Reference Documentation - All Step</a>
+ * @since 3.7.1
+ */
+ public default <S2> GraphTraversal<S, E> all(final P<S2> predicate) {
+ this.asAdmin().getBytecode().addStep(Symbols.all, predicate);
+ return this.asAdmin().addStep(new AllStep<>(this.asAdmin(), predicate));
+ }
+
+ /**
+ * Filters <code>E</code> lists given the provided {@code predicate}.
+ *
+ * @param predicate the filter to apply
+ * @return the traversal with an appended {@link AnyStep}
+ * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#any-step" target="_blank">Reference Documentation - Any Step</a>
+ * @since 3.7.1
+ */
+ public default <S2> GraphTraversal<S, E> any(final P<S2> predicate) {
+ this.asAdmin().getBytecode().addStep(Symbols.any, predicate);
+ return this.asAdmin().addStep(new AnyStep<>(this.asAdmin(), predicate));
+ }
+
///////////////////// SIDE-EFFECT STEPS /////////////////////
/**
@@ -3747,6 +3775,8 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
public static final String asDate = "asDate";
public static final String dateAdd = "dateAdd";
public static final String dateDiff = "dateDiff";
+ public static final String all = "all";
+ public static final String any = "any";
public static final String timeLimit = "timeLimit";
public static final String simplePath = "simplePath";
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
index 715f9711e6..f41f3506a6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
@@ -1047,6 +1047,16 @@ public class __ {
return __.<A>start().drop();
}
+ /**
+ * @see GraphTraversal#all(P)
+ */
+ public static <A> GraphTraversal<A, A> all(final P<A> predicate) { return __.<A>start().all(predicate); }
+
+ /**
+ * @see GraphTraversal#any(P)
+ */
+ public static <A> GraphTraversal<A, A> any(final P<A> predicate) { return __.<A>start().any(predicate); }
+
///////////////////// SIDE-EFFECT STEPS /////////////////////
/**
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AllStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AllStep.java
new file mode 100644
index 0000000000..6f002bbea6
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AllStep.java
@@ -0,0 +1,87 @@
+/*
+ * 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.GremlinTypeErrorException;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public final class AllStep<S, S2> extends FilterStep<S> {
+
+ private P<S2> predicate;
+
+ public AllStep(final Traversal.Admin traversal, final P<S2> predicate) {
+ super(traversal);
+
+ if (null == predicate) {
+ throw new IllegalArgumentException("Input predicate to all step can't be null.");
+ }
+
+ this.predicate = predicate;
+ }
+
+ @Override
+ protected boolean filter(final Traverser.Admin<S> traverser) {
+ final S item = traverser.get();
+
+ if (item instanceof Iterable || item instanceof Iterator || ((item != null) && item.getClass().isArray())) {
+ GremlinTypeErrorException typeError = null;
+ final Iterator<S2> iterator = IteratorUtils.asIterator(item);
+ while (iterator.hasNext()) {
+ try {
+ if (!this.predicate.test(iterator.next())) {
+ return false;
+ }
+ } catch (GremlinTypeErrorException gtee) {
+ // hold onto it until the end in case any other element evaluates to FALSE
+ typeError = gtee;
+ }
+ }
+ if (typeError != null) throw typeError;
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.predicate);
+ }
+
+ @Override
+ public AllStep<S, S2> clone() {
+ final AllStep<S, S2> clone = (AllStep<S, S2>) super.clone();
+ clone.predicate = this.predicate.clone();
+ return clone;
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return EnumSet.of(TraverserRequirement.OBJECT);
+ }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AnyStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AnyStep.java
new file mode 100644
index 0000000000..4144dd5d66
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AnyStep.java
@@ -0,0 +1,87 @@
+/*
+ * 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.GremlinTypeErrorException;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public final class AnyStep<S, S2> extends FilterStep<S> {
+
+ private P<S2> predicate;
+
+ public AnyStep(final Traversal.Admin traversal, final P<S2> predicate) {
+ super(traversal);
+
+ if (null == predicate) {
+ throw new IllegalArgumentException("Input predicate to any step can't be null.");
+ }
+
+ this.predicate = predicate;
+ }
+
+ @Override
+ protected boolean filter(final Traverser.Admin<S> traverser) {
+ final S item = traverser.get();
+
+ if (item instanceof Iterable || item instanceof Iterator || ((item != null) && item.getClass().isArray())) {
+ GremlinTypeErrorException typeError = null;
+ final Iterator<S2> iterator = IteratorUtils.asIterator(item);
+ while (iterator.hasNext()) {
+ try {
+ if (this.predicate.test(iterator.next())) {
+ return true;
+ }
+ } catch (GremlinTypeErrorException gtee) {
+ // hold onto it until the end in case any other element evaluates to TRUE
+ typeError = gtee;
+ }
+ }
+
+ if (typeError != null) throw typeError;
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.predicate);
+ }
+
+ @Override
+ public AnyStep<S, S2> clone() {
+ final AnyStep<S, S2> clone = (AnyStep<S, S2>) super.clone();
+ clone.predicate = this.predicate.clone();
+ return clone;
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return EnumSet.of(TraverserRequirement.OBJECT);
+ }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
index 0cc96ebf81..cbab751d56 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
@@ -203,6 +203,11 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
@Override
protected String getSyntax(final Pick o) {
+ if (o.equals(Pick.any)) {
+ // We don't want this getting resolved to Pick.any_ due to any() being a built-in function in Python.
+ return "Pick.any";
+ }
+
return "Pick." + resolveSymbol(o.toString());
}
@@ -433,6 +438,7 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
TO_PYTHON_MAP.put("global", "global_");
TO_PYTHON_MAP.put("all", "all_");
TO_PYTHON_MAP.put("and", "and_");
+ TO_PYTHON_MAP.put("any", "any_");
TO_PYTHON_MAP.put("as", "as_");
TO_PYTHON_MAP.put("asString", "as_string");
TO_PYTHON_MAP.put("asDate", "as_date");
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
index c335e9f334..e1b7c436af 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
@@ -42,7 +42,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.branch.LocalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.OptionalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.UnionStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AllStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AndStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AnyStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.DedupGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.DropStep;
@@ -226,6 +228,8 @@ public final class BytecodeHelper {
put(GraphTraversal.Symbols.asDate, Collections.singletonList(AsDateStep.class));
put(GraphTraversal.Symbols.dateAdd, Collections.singletonList(DateAddStep.class));
put(GraphTraversal.Symbols.dateDiff, Collections.singletonList(DateDiffStep.class));
+ put(GraphTraversal.Symbols.all, Collections.singletonList(AllStep.class));
+ put(GraphTraversal.Symbols.any, Collections.singletonList(AnyStep.class));
put(GraphTraversal.Symbols.group, Arrays.asList(GroupStep.class, GroupSideEffectStep.class));
put(GraphTraversal.Symbols.groupCount, Arrays.asList(GroupCountStep.class, GroupCountSideEffectStep.class));
put(GraphTraversal.Symbols.tree, Arrays.asList(TreeStep.class, TreeSideEffectStep.class));
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitorTest.java
index f89d047c3b..a4c4ddd33f 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitorTest.java
@@ -116,11 +116,20 @@ public class TraversalMethodVisitorTest {
compare(g.V().aggregate(Scope.local, "test"), eval("g.V().aggregate(Scope.local, 'test')"));
}
+ @Test
+ public void shouldParseTraversalMethod_all_P() throws Exception {
+ compare(g.V().id().fold().all(gt(1)), eval("g.V().id().fold().all(gt(1))"));
+ }
+
@Test
public void shouldParseTraversalMethod_and() throws Exception {
compare(g.V().and(outE("knows")), eval("g.V().and(outE('knows'))"));
}
+ @Test
+ public void shouldParseTraversalMethod_any_P() throws Exception {
+ compare(g.V().id().fold().any(gt(1)), eval("g.V().id().fold().any(gt(1))"));
+ }
@Test
public void shouldParseTraversalMethod_as() throws Exception {
compare(g.V().as("test"), eval("g.V().as('test')"));
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AllStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AllStepTest.java
new file mode 100644
index 0000000000..1bd979fd3a
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AllStepTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+public class AllStepTest extends StepTest {
+
+ @Override
+ protected List<Traversal> getTraversals() { return Collections.singletonList(__.all(P.gt(0))); }
+
+ @Test
+ public void testReturnTypes() {
+ assertTrue(__.__(new int[]{}).all(P.gt(7)).hasNext());
+ assertArrayEquals(new int[] {7, 10}, __.__(new int[] {5, 8, 10}, new int[] {7, 10}).all(P.gte(7)).next());
+ assertArrayEquals(new long[] {7L, 10L}, __.__(new long[] {5L, 8L, 10L}, new long[] {7L, 10L}).all(P.gte(7)).next());
+ assertArrayEquals(new Long[] {7L, 10L}, __.__(1).constant(new Long[] {7L, 10L}).all(P.gte(7)).next());
+ assertArrayEquals(new double[] {7.1, 10.5}, __.__(new double[] {5.5, 8.0, 10.1}, new double[] {7.1, 10.5}).all(P.gte(7.0)).next(), 0.01);
+ }
+
+ @Test
+ public void testNullParameter() {
+ final Throwable thrown = assertThrows(IllegalArgumentException.class, () -> __.__(new int[]{1}).all(null).hasNext());
+ assertEquals("Input predicate to all step can't be null.", thrown.getMessage());
+ }
+
+ @Test
+ public void testSetTraverser() {
+ final Set<Integer> numbers = new HashSet<>();
+ numbers.add(10);
+ numbers.add(11);
+
+ assertTrue(__.__(numbers).all(P.gt(7)).hasNext());
+ }
+
+ @Test
+ public void testListIteratorTraverser() {
+ final List<Integer> numbers = new ArrayList<>();
+ numbers.add(10);
+ numbers.add(11);
+
+ assertTrue(__.__(numbers.iterator()).all(P.gte(10)).hasNext());
+ }
+
+ @Test
+ public void testCornerCases() {
+ final List validOne = new ArrayList() {{ add(20); }};
+ final List validTwo = new ArrayList() {{ add(21); add(25);}};
+ final List validThree = new ArrayList() {{ add(51); add(57); add(71); }};
+ final List containsNull = new ArrayList() {{ add(50); add(null); add(60); }};
+ final List empty = new ArrayList();
+ final List incorrectType = new ArrayList() {{ add(100); add("25"); }};
+ final List valueTooSmall = new ArrayList() {{ add(101); add(1); add(10);}};
+
+ assertEquals(4L, __.__(validOne, null, containsNull, empty, incorrectType, valueTooSmall, validTwo, validThree)
+ .all(P.gt(3)).count().next().longValue());
+ }
+}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AnyStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AnyStepTest.java
new file mode 100644
index 0000000000..58f7b0e0e7
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AnyStepTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+public class AnyStepTest extends StepTest {
+
+ @Override
+ protected List<Traversal> getTraversals() { return Collections.singletonList(__.any(P.gt(0))); }
+
+ @Test
+ public void testReturnTypes() {
+ assertFalse(__.__(new int[] {}).any(P.gt(7)).hasNext());
+ assertArrayEquals(new int[] {7, 10}, __.__(new int[] {3, 5, 6}, new int[] {7, 10}).any(P.gte(7)).next());
+ assertArrayEquals(new long[] {7L, 10L}, __.__(new long[] {3L, 5L, 6L}, new long[] {7L, 10L}).any(P.gte(7)).next());
+ assertArrayEquals(new Long[] {7L, 10L}, __.__(1).constant(new Long[] {7L, 10L}).any(P.gte(7)).next());
+ assertArrayEquals(new double[] {7.7, 10.1}, __.__(new double[] {3.3, 5.791739562, 6.1082}, new double[] {7.7, 10.1}).any(P.gte(7)).next(), 0.01);
+ assertArrayEquals(new Object[] {2, "hello", 10L}, __.__(new Object[] {3.6, "other"}, new Object[] {2, "hello", 10L}).any(P.gte(7)).next());
+ }
+
+ @Test
+ public void testNullParameter() {
+ final Throwable thrown = assertThrows(IllegalArgumentException.class, () -> __.__(new int[]{1}).any(null).hasNext());
+ assertEquals("Input predicate to any step can't be null.", thrown.getMessage());
+ }
+
+ @Test
+ public void testSetTraverser() {
+ final Set<Integer> numbers = new HashSet<>();
+ numbers.add(10);
+ numbers.add(11);
+
+ assertTrue(__.__(numbers).any(P.eq(10)).hasNext());
+ }
+
+ @Test
+ public void testListIteratorTraverser() {
+ final List<Integer> numbers = new ArrayList<>();
+ numbers.add(10);
+ numbers.add(11);
+
+ assertTrue(__.__(numbers.iterator()).any(P.eq(11)).hasNext());
+ }
+
+ @Test
+ public void testCornerCases() {
+ final List validOne = new ArrayList() {{ add(20); }};
+ final List validTwo = new ArrayList() {{ add(21); add(25);}};
+ final List validThree = new ArrayList() {{ add(51); add(57); add(71); }};
+ final List validFour = new ArrayList() {{ add(1); add(2); add(10); }};
+ final List invalidOne = new ArrayList() {{ add(0); add(1); }};
+ final List containsNull = new ArrayList() {{ add(50); add(null); add(60); }};
+ final List empty = new ArrayList();
+ final List incorrectType = new ArrayList() {{ add(100); add("25"); }};
+ final List valueTooSmall = new ArrayList() {{ add(101); add(1); add(10);}};
+
+ assertEquals(7L, __.__(validOne, null, containsNull, empty, incorrectType, validFour, invalidOne, valueTooSmall, validTwo, validThree)
+ .any(P.gt(3)).count().next().longValue());
+ }
+}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index 253fc2935b..91df6644f7 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -178,6 +178,15 @@ namespace Gremlin.Net.Process.Traversal
return Wrap<TStart, TEnd>(this);
}
+ /// <summary>
+ /// Adds the all step to this <see cref="GraphTraversal{SType, EType}" />.
+ /// </summary>
+ public GraphTraversal<TStart, TEnd> All (P? predicate)
+ {
+ Bytecode.AddStep("all", predicate);
+ return Wrap<TStart, TEnd>(this);
+ }
+
/// <summary>
/// Adds the and step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
@@ -191,6 +200,15 @@ namespace Gremlin.Net.Process.Traversal
return Wrap<TStart, TEnd>(this);
}
+ /// <summary>
+ /// Adds the any step to this <see cref="GraphTraversal{SType, EType}" />.
+ /// </summary>
+ public GraphTraversal<TStart, TEnd> Any (P? predicate)
+ {
+ Bytecode.AddStep("any", predicate);
+ return Wrap<TStart, TEnd>(this);
+ }
+
/// <summary>
/// Adds the as step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
index 6715d8bee8..a0fdae1632 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
@@ -116,6 +116,14 @@ namespace Gremlin.Net.Process.Traversal
return new GraphTraversal<object, object>().Aggregate(sideEffectKey);
}
+ /// <summary>
+ /// Spawns a <see cref="GraphTraversal{SType, EType}" /> all adds the all step to that traversal.
+ /// </summary>
+ public static GraphTraversal<object, object> All(P? predicate)
+ {
+ return new GraphTraversal<object, object>().All(predicate);
+ }
+
/// <summary>
/// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the and step to that traversal.
/// </summary>
@@ -126,6 +134,14 @@ namespace Gremlin.Net.Process.Traversal
: new GraphTraversal<object, object>().And(andTraversals);
}
+ /// <summary>
+ /// Spawns a <see cref="GraphTraversal{SType, EType}" /> any adds the any step to that traversal.
+ /// </summary>
+ public static GraphTraversal<object, object> Any(P? predicate)
+ {
+ return new GraphTraversal<object, object>().Any(predicate);
+ }
+
/// <summary>
/// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the as step to that traversal.
/// </summary>
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 2f4148a479..799fe2ed21 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -130,11 +130,35 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
{"g_VX1_2X_unionXoutE_count__inE_count__outE_weight_sumX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"],p["vid2"]).Union<object>(__.OutE().Count(),__.InE().Count(),__.OutE().Values<object>("weight").Sum<object>())}},
{"g_VX1_2X_localXunionXoutE_count__inE_count__outE_weight_sumXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"],p["vid2"]).Local<object>(__.Union<object>(__.OutE().Count(),__.InE().Count(),__.OutE().Values<object>("weight").Sum<object>()))}},
{"g_VX1_2X_localXunionXcountXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"],p["vid2"]).Local<object>(__.Union<object>(__.Count()))}},
+ {"g_V_valuesXageX_allXgtX32XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").All(P.Gt(32))}},
+ {"g_V_valuesXageX_whereXisXP_gtX33XXX_fold_allXgtX33XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Where(__.Is(P.Gt(33))).Fold().All(P.Gt(33))}},
+ {"g_V_valuesXageX_order_byXdescX_fold_allXgtX10XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().By(Order.Desc).Fold().All(P.Gt(10))}},
+ {"g_V_valuesXageX_order_byXdescX_fold_allXgtX30XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().By(Order.Desc).Fold().All(P.Gt(30))}},
+ {"g_injectXabc_bcdX_allXeqXbcdXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).All(P.Eq("bcd"))}},
+ {"g_injectXbcd_bcdX_allXeqXbcdXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).All(P.Eq("bcd"))}},
+ {"g_injectXnull_abcX_allXTextP_startingWithXaXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).All(TextP.StartingWith("a"))}},
+ {"g_injectX5_8_10_10_7X_allXgteX7XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"],p["xx2"]).All(P.Gte(7))}},
+ {"g_injectXnullX_allXeqXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).All(P.Eq(null))}},
+ {"g_injectX7X_allXeqX7XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(7).All(P.Eq(7))}},
+ {"g_injectXnull_nullX_allXeqXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).All(P.Eq(null))}},
+ {"g_injectX3_threeX_allXeqX3XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).All(P.Eq(3))}},
{"g_V_andXhasXage_gt_27X__outE_count_gte_2X_name", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().And(__.Has("age",P.Gt(27)),__.OutE().Count().Is(P.Gte(2))).Values<object>("name")}},
{"g_V_andXoutE__hasXlabel_personX_and_hasXage_gte_32XX_name", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().And(__.OutE(),__.Has(T.Label,"person").And().Has("age",P.Gte(32))).Values<object>("name")}},
{"g_V_asXaX_outXknowsX_and_outXcreatedX_inXcreatedX_asXaX_name", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().As("a").Out("knows").And().Out("created").In("created").As("a").Values<object>("name")}},
{"g_V_asXaX_andXselectXaX_selectXaXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().As("a").And(__.Select<object>("a"),__.Select<object>("a"))}},
{"g_V_hasXname_markoX_and_hasXname_markoX_and_hasXname_markoX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name","marko").And().Has("name","marko").And().Has("name","marko")}},
+ {"g_V_valuesXageX_anyXgtX32XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Any(P.Gt(32))}},
+ {"g_V_valuesXageX_order_byXdescX_fold_anyXeqX29XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().By(Order.Desc).Fold().Any(P.Eq(29))}},
+ {"g_V_valuesXageX_order_byXdescX_fold_anyXgtX10XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().By(Order.Desc).Fold().Any(P.Gt(10))}},
+ {"g_V_valuesXageX_order_byXdescX_fold_anyXgtX42XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("age").Order().By(Order.Desc).Fold().Any(P.Gt(42))}},
+ {"g_injectXabc_cdeX_anyXeqXbcdXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Any(P.Eq("bcd"))}},
+ {"g_injectXabc_bcdX_anyXeqXbcdXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Any(P.Eq("bcd"))}},
+ {"g_injectXnull_abcX_anyXTextP_startingWithXaXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Any(TextP.StartingWith("a"))}},
+ {"g_injectX5_8_10_10_7X_anyXeqX7XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"],p["xx2"]).Any(P.Eq(7))}},
+ {"g_injectXnullX_anyXeqXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(null).Any(P.Eq(null))}},
+ {"g_injectX7X_anyXeqX7XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(7).Any(P.Eq(7))}},
+ {"g_injectXnull_nullX_anyXeqXnullXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Any(P.Eq(null))}},
+ {"g_injectX3_threeX_anyXeqX3XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Any(P.Eq(3))}},
{"g_V_coinX1X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Coin(1.0)}},
{"g_V_coinX0X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Coin(0.0)}},
{"g_withStrategiesXSeedStrategyX_V_order_byXnameX_coinX50X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.WithStrategies(new SeedStrategy(seed: 999999)).V().Order().By("name").Coin(0.5)}},
diff --git a/gremlin-go/driver/anonymousTraversal.go b/gremlin-go/driver/anonymousTraversal.go
index 306f03992f..009f25dd25 100644
--- a/gremlin-go/driver/anonymousTraversal.go
+++ b/gremlin-go/driver/anonymousTraversal.go
@@ -55,8 +55,12 @@ type AnonymousTraversal interface {
AddV(args ...interface{}) *GraphTraversal
// Aggregate adds the aggregate step to the GraphTraversal.
Aggregate(args ...interface{}) *GraphTraversal
+ // All adds the all step to the GraphTraversal.
+ All(args ...interface{}) *GraphTraversal
// And adds the and step to the GraphTraversal.
And(args ...interface{}) *GraphTraversal
+ // Any adds the any step to the GraphTraversal.
+ Any(args ...interface{}) *GraphTraversal
// As adds the as step to the GraphTraversal.
As(args ...interface{}) *GraphTraversal
// AsString adds the asString step to the GraphTraversal.
@@ -329,11 +333,21 @@ func (anonymousTraversal *anonymousTraversal) Aggregate(args ...interface{}) *Gr
return anonymousTraversal.graphTraversal().Aggregate(args...)
}
+// All adds the all step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) All(args ...interface{}) *GraphTraversal {
+ return anonymousTraversal.graphTraversal().All(args...)
+}
+
// And adds the and step to the GraphTraversal.
func (anonymousTraversal *anonymousTraversal) And(args ...interface{}) *GraphTraversal {
return anonymousTraversal.graphTraversal().And(args...)
}
+// Any adds the any step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) Any(args ...interface{}) *GraphTraversal {
+ return anonymousTraversal.graphTraversal().Any(args...)
+}
+
// As adds the as step to the GraphTraversal.
func (anonymousTraversal *anonymousTraversal) As(args ...interface{}) *GraphTraversal {
return anonymousTraversal.graphTraversal().As(args...)
diff --git a/gremlin-go/driver/cucumber/gremlin.go b/gremlin-go/driver/cucumber/gremlin.go
index 4374d10527..d06719597d 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -101,11 +101,35 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[
"g_VX1_2X_unionXoutE_count__inE_count__outE_weight_sumX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"], p["vid2"]).Union(gremlingo.T__.OutE().Count(), gremlingo.T__.InE().Count(), gremlingo.T__.OutE().Values("weight").Sum())}},
"g_VX1_2X_localXunionXoutE_count__inE_count__outE_weight_sumXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"], p["vid2"]).Local(gremlingo.T__.Union(gremlingo.T__.OutE().Count(), gremlingo.T__.InE().Count(), gremlingo.T__.OutE().Values("weight").Sum()))}},
"g_VX1_2X_localXunionXcountXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"], p["vid2"]).Local(gremlingo.T__.Union(gremlingo.T__.Count()))}},
+ "g_V_valuesXageX_allXgtX32XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").All(gremlingo.P.Gt(32))}},
+ "g_V_valuesXageX_whereXisXP_gtX33XXX_fold_allXgtX33XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Where(gremlingo.T__.Is(gremlingo.P.Gt(33))).Fold().All(gremlingo.P.Gt(33))}},
+ "g_V_valuesXageX_order_byXdescX_fold_allXgtX10XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().By(gremlingo.Order.Desc).Fold().All(gremlingo.P.Gt(10))}},
+ "g_V_valuesXageX_order_byXdescX_fold_allXgtX30XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().By(gremlingo.Order.Desc).Fold().All(gremlingo.P.Gt(30))}},
+ "g_injectXabc_bcdX_allXeqXbcdXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).All(gremlingo.P.Eq("bcd"))}},
+ "g_injectXbcd_bcdX_allXeqXbcdXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).All(gremlingo.P.Eq("bcd"))}},
+ "g_injectXnull_abcX_allXTextP_startingWithXaXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).All(gremlingo.TextP.StartingWith("a"))}},
+ "g_injectX5_8_10_10_7X_allXgteX7XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"], p["xx2"]).All(gremlingo.P.Gte(7))}},
+ "g_injectXnullX_allXeqXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).All(gremlingo.P.Eq(nil))}},
+ "g_injectX7X_allXeqX7XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(7).All(gremlingo.P.Eq(7))}},
+ "g_injectXnull_nullX_allXeqXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).All(gremlingo.P.Eq(nil))}},
+ "g_injectX3_threeX_allXeqX3XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).All(gremlingo.P.Eq(3))}},
"g_V_andXhasXage_gt_27X__outE_count_gte_2X_name": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().And(gremlingo.T__.Has("age", gremlingo.P.Gt(27)), gremlingo.T__.OutE().Count().Is(gremlingo.P.Gte(2))).Values("name")}},
"g_V_andXoutE__hasXlabel_personX_and_hasXage_gte_32XX_name": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().And(gremlingo.T__.OutE(), gremlingo.T__.Has(gremlingo.T.Label, "person").And().Has("age", gremlingo.P.Gte(32))).Values("name")}},
"g_V_asXaX_outXknowsX_and_outXcreatedX_inXcreatedX_asXaX_name": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("a").Out("knows").And().Out("created").In("created").As("a").Values("name")}},
"g_V_asXaX_andXselectXaX_selectXaXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("a").And(gremlingo.T__.Select("a"), gremlingo.T__.Select("a"))}},
"g_V_hasXname_markoX_and_hasXname_markoX_and_hasXname_markoX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", "marko").And().Has("name", "marko").And().Has("name", "marko")}},
+ "g_V_valuesXageX_anyXgtX32XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Any(gremlingo.P.Gt(32))}},
+ "g_V_valuesXageX_order_byXdescX_fold_anyXeqX29XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().By(gremlingo.Order.Desc).Fold().Any(gremlingo.P.Eq(29))}},
+ "g_V_valuesXageX_order_byXdescX_fold_anyXgtX10XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().By(gremlingo.Order.Desc).Fold().Any(gremlingo.P.Gt(10))}},
+ "g_V_valuesXageX_order_byXdescX_fold_anyXgtX42XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Values("age").Order().By(gremlingo.Order.Desc).Fold().Any(gremlingo.P.Gt(42))}},
+ "g_injectXabc_cdeX_anyXeqXbcdXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Any(gremlingo.P.Eq("bcd"))}},
+ "g_injectXabc_bcdX_anyXeqXbcdXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Any(gremlingo.P.Eq("bcd"))}},
+ "g_injectXnull_abcX_anyXTextP_startingWithXaXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Any(gremlingo.TextP.StartingWith("a"))}},
+ "g_injectX5_8_10_10_7X_anyXeqX7XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"], p["xx2"]).Any(gremlingo.P.Eq(7))}},
+ "g_injectXnullX_anyXeqXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil).Any(gremlingo.P.Eq(nil))}},
+ "g_injectX7X_anyXeqX7XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(7).Any(gremlingo.P.Eq(7))}},
+ "g_injectXnull_nullX_anyXeqXnullXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Any(gremlingo.P.Eq(nil))}},
+ "g_injectX3_threeX_anyXeqX3XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"]).Any(gremlingo.P.Eq(3))}},
"g_V_coinX1X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Coin(1.0)}},
"g_V_coinX0X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Coin(0.0)}},
"g_withStrategiesXSeedStrategyX_V_order_byXnameX_coinX50X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.WithStrategies(gremlingo.SeedStrategy(gremlingo.SeedStrategyConfig{Seed: 999999})).V().Order().By("name").Coin(0.5)}},
diff --git a/gremlin-go/driver/graphTraversal.go b/gremlin-go/driver/graphTraversal.go
index a7a960f500..ec85578b0a 100644
--- a/gremlin-go/driver/graphTraversal.go
+++ b/gremlin-go/driver/graphTraversal.go
@@ -82,12 +82,24 @@ func (g *GraphTraversal) Aggregate(args ...interface{}) *GraphTraversal {
return g
}
+// All adds the all step to the GraphTraversal.
+func (g *GraphTraversal) All(args ...interface{}) *GraphTraversal {
+ g.Bytecode.AddStep("all", args...)
+ return g
+}
+
// And adds the and step to the GraphTraversal.
func (g *GraphTraversal) And(args ...interface{}) *GraphTraversal {
g.Bytecode.AddStep("and", args...)
return g
}
+// Any adds the any step to the GraphTraversal.
+func (g *GraphTraversal) Any(args ...interface{}) *GraphTraversal {
+ g.Bytecode.AddStep("any", args...)
+ return g
+}
+
// As adds the as step to the GraphTraversal.
func (g *GraphTraversal) As(args ...interface{}) *GraphTraversal {
g.Bytecode.AddStep("as", args...)
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
index 09e5db1814..d6ebf0f273 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
@@ -414,6 +414,16 @@ class GraphTraversal extends Traversal {
return this;
}
+ /**
+ * Graph traversal all method.
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+ all(...args) {
+ this.bytecode.addStep('all', args);
+ return this;
+ }
+
/**
* Graph traversal and method.
* @param {...Object} args
@@ -424,6 +434,16 @@ class GraphTraversal extends Traversal {
return this;
}
+ /**
+ * Graph traversal any method.
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+ any(...args) {
+ this.bytecode.addStep('any', args);
+ return this;
+ }
+
/**
* Graph traversal as method.
* @param {...Object} args
@@ -1657,7 +1677,9 @@ const statics = {
addE: (...args) => callOnEmptyTraversal('addE', args),
addV: (...args) => callOnEmptyTraversal('addV', args),
aggregate: (...args) => callOnEmptyTraversal('aggregate', args),
+ all: (...args) => callOnEmptyTraversal('all', args),
and: (...args) => callOnEmptyTraversal('and', args),
+ any: (...args) => callOnEmptyTraversal('any', args),
as: (...args) => callOnEmptyTraversal('as', args),
asDate: (...args) => callOnEmptyTraversal('asDate', args),
asString: (...args) => callOnEmptyTraversal('asString', args),
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index d393fd05d5..70561e6463 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -121,11 +121,35 @@ const gremlins = {
g_VX1_2X_unionXoutE_count__inE_count__outE_weight_sumX: [function({g, vid2, vid1}) { return g.V(vid1,vid2).union(__.outE().count(),__.inE().count(),__.outE().values("weight").sum()) }],
g_VX1_2X_localXunionXoutE_count__inE_count__outE_weight_sumXX: [function({g, vid2, vid1}) { return g.V(vid1,vid2).local(__.union(__.outE().count(),__.inE().count(),__.outE().values("weight").sum())) }],
g_VX1_2X_localXunionXcountXX: [function({g, vid2, vid1}) { return g.V(vid1,vid2).local(__.union(__.count())) }],
+ g_V_valuesXageX_allXgtX32XX: [function({g}) { return g.V().values("age").all(P.gt(32)) }],
+ g_V_valuesXageX_whereXisXP_gtX33XXX_fold_allXgtX33XX: [function({g}) { return g.V().values("age").where(__.is(P.gt(33))).fold().all(P.gt(33)) }],
+ g_V_valuesXageX_order_byXdescX_fold_allXgtX10XX: [function({g}) { return g.V().values("age").order().by(Order.desc).fold().all(P.gt(10)) }],
+ g_V_valuesXageX_order_byXdescX_fold_allXgtX30XX: [function({g}) { return g.V().values("age").order().by(Order.desc).fold().all(P.gt(30)) }],
+ g_injectXabc_bcdX_allXeqXbcdXX: [function({g, xx1}) { return g.inject(xx1).all(P.eq("bcd")) }],
+ g_injectXbcd_bcdX_allXeqXbcdXX: [function({g, xx1}) { return g.inject(xx1).all(P.eq("bcd")) }],
+ g_injectXnull_abcX_allXTextP_startingWithXaXX: [function({g, xx1}) { return g.inject(xx1).all(TextP.startingWith("a")) }],
+ g_injectX5_8_10_10_7X_allXgteX7XX: [function({g, xx1, xx2}) { return g.inject(xx1,xx2).all(P.gte(7)) }],
+ g_injectXnullX_allXeqXnullXX: [function({g}) { return g.inject(null).all(P.eq(null)) }],
+ g_injectX7X_allXeqX7XX: [function({g}) { return g.inject(7).all(P.eq(7)) }],
+ g_injectXnull_nullX_allXeqXnullXX: [function({g, xx1}) { return g.inject(xx1).all(P.eq(null)) }],
+ g_injectX3_threeX_allXeqX3XX: [function({g, xx1}) { return g.inject(xx1).all(P.eq(3)) }],
g_V_andXhasXage_gt_27X__outE_count_gte_2X_name: [function({g}) { return g.V().and(__.has("age",P.gt(27)),__.outE().count().is(P.gte(2))).values("name") }],
g_V_andXoutE__hasXlabel_personX_and_hasXage_gte_32XX_name: [function({g}) { return g.V().and(__.outE(),__.has(T.label,"person").and().has("age",P.gte(32))).values("name") }],
g_V_asXaX_outXknowsX_and_outXcreatedX_inXcreatedX_asXaX_name: [function({g}) { return g.V().as("a").out("knows").and().out("created").in_("created").as("a").values("name") }],
g_V_asXaX_andXselectXaX_selectXaXX: [function({g}) { return g.V().as("a").and(__.select("a"),__.select("a")) }],
g_V_hasXname_markoX_and_hasXname_markoX_and_hasXname_markoX: [function({g}) { return g.V().has("name","marko").and().has("name","marko").and().has("name","marko") }],
+ g_V_valuesXageX_anyXgtX32XX: [function({g}) { return g.V().values("age").any(P.gt(32)) }],
+ g_V_valuesXageX_order_byXdescX_fold_anyXeqX29XX: [function({g}) { return g.V().values("age").order().by(Order.desc).fold().any(P.eq(29)) }],
+ g_V_valuesXageX_order_byXdescX_fold_anyXgtX10XX: [function({g}) { return g.V().values("age").order().by(Order.desc).fold().any(P.gt(10)) }],
+ g_V_valuesXageX_order_byXdescX_fold_anyXgtX42XX: [function({g}) { return g.V().values("age").order().by(Order.desc).fold().any(P.gt(42)) }],
+ g_injectXabc_cdeX_anyXeqXbcdXX: [function({g, xx1}) { return g.inject(xx1).any(P.eq("bcd")) }],
+ g_injectXabc_bcdX_anyXeqXbcdXX: [function({g, xx1}) { return g.inject(xx1).any(P.eq("bcd")) }],
+ g_injectXnull_abcX_anyXTextP_startingWithXaXX: [function({g, xx1}) { return g.inject(xx1).any(TextP.startingWith("a")) }],
+ g_injectX5_8_10_10_7X_anyXeqX7XX: [function({g, xx1, xx2}) { return g.inject(xx1,xx2).any(P.eq(7)) }],
+ g_injectXnullX_anyXeqXnullXX: [function({g}) { return g.inject(null).any(P.eq(null)) }],
+ g_injectX7X_anyXeqX7XX: [function({g}) { return g.inject(7).any(P.eq(7)) }],
+ g_injectXnull_nullX_anyXeqXnullXX: [function({g, xx1}) { return g.inject(xx1).any(P.eq(null)) }],
+ g_injectX3_threeX_anyXeqX3XX: [function({g, xx1}) { return g.inject(xx1).any(P.eq(3)) }],
g_V_coinX1X: [function({g}) { return g.V().coin(1.0) }],
g_V_coinX0X: [function({g}) { return g.V().coin(0.0) }],
g_withStrategiesXSeedStrategyX_V_order_byXnameX_coinX50X: [function({g}) { return g.withStrategies(new SeedStrategy({seed:999999})).V().order().by("name").coin(0.5) }],
diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 b/gremlin-language/src/main/antlr4/Gremlin.g4
index 6fee352017..8d08eb1676 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -183,7 +183,9 @@ traversalMethod
| traversalMethod_mergeE
| traversalMethod_mergeV
| traversalMethod_aggregate
+ | traversalMethod_all
| traversalMethod_and
+ | traversalMethod_any
| traversalMethod_as
| traversalMethod_barrier
| traversalMethod_both
@@ -336,10 +338,18 @@ traversalMethod_aggregate
| 'aggregate' LPAREN stringArgument RPAREN #traversalMethod_aggregate_String
;
+traversalMethod_all
+ : 'all' LPAREN traversalPredicate RPAREN #traversalMethod_all_P
+ ;
+
traversalMethod_and
: 'and' LPAREN nestedTraversalList RPAREN
;
+traversalMethod_any
+ : 'any' LPAREN traversalPredicate RPAREN #traversalMethod_any_P
+ ;
+
traversalMethod_as
: 'as' LPAREN stringArgument (COMMA stringLiteralVarargs)? RPAREN
;
diff --git a/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py b/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
index 24958b5d21..db12758288 100644
--- a/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
@@ -309,10 +309,18 @@ class GraphTraversal(Traversal):
self.bytecode.add_step("aggregate", *args)
return self
+ def all_(self, *args):
+ self.bytecode.add_step("all", *args)
+ return self
+
def and_(self, *args):
self.bytecode.add_step("and", *args)
return self
+ def any_(self, *args):
+ self.bytecode.add_step("any", *args)
+ return self
+
def as_(self, *args):
self.bytecode.add_step("as", *args)
return self
@@ -1031,10 +1039,18 @@ class __(object, metaclass=MagicType):
def aggregate(cls, *args):
return cls.graph_traversal(None, None, Bytecode()).aggregate(*args)
+ @classmethod
+ def all_(cls, *args):
+ return cls.graph_traversal(None, None, Bytecode()).all_(*args)
+
@classmethod
def and_(cls, *args):
return cls.graph_traversal(None, None, Bytecode()).and_(*args)
+ @classmethod
+ def any_(cls, *args):
+ return cls.graph_traversal(None, None, Bytecode()).any_(*args)
+
@classmethod
def as_(cls, *args):
return cls.graph_traversal(None, None, Bytecode()).as_(*args)
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index deee5cfcc8..f02b8d186e 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -103,11 +103,35 @@ world.gremlins = {
'g_VX1_2X_unionXoutE_count__inE_count__outE_weight_sumX': [(lambda g, vid2=None,vid1=None:g.V(vid1,vid2).union(__.outE().count(),__.inE().count(),__.outE().weight.sum_()))],
'g_VX1_2X_localXunionXoutE_count__inE_count__outE_weight_sumXX': [(lambda g, vid2=None,vid1=None:g.V(vid1,vid2).local(__.union(__.outE().count(),__.inE().count(),__.outE().weight.sum_())))],
'g_VX1_2X_localXunionXcountXX': [(lambda g, vid2=None,vid1=None:g.V(vid1,vid2).local(__.union(__.count())))],
+ 'g_V_valuesXageX_allXgtX32XX': [(lambda g:g.V().age.all_(P.gt(32)))],
+ 'g_V_valuesXageX_whereXisXP_gtX33XXX_fold_allXgtX33XX': [(lambda g:g.V().age.where(__.is_(P.gt(33))).fold().all_(P.gt(33)))],
+ 'g_V_valuesXageX_order_byXdescX_fold_allXgtX10XX': [(lambda g:g.V().age.order().by(Order.desc).fold().all_(P.gt(10)))],
+ 'g_V_valuesXageX_order_byXdescX_fold_allXgtX30XX': [(lambda g:g.V().age.order().by(Order.desc).fold().all_(P.gt(30)))],
+ 'g_injectXabc_bcdX_allXeqXbcdXX': [(lambda g, xx1=None:g.inject(xx1).all_(P.eq('bcd')))],
+ 'g_injectXbcd_bcdX_allXeqXbcdXX': [(lambda g, xx1=None:g.inject(xx1).all_(P.eq('bcd')))],
+ 'g_injectXnull_abcX_allXTextP_startingWithXaXX': [(lambda g, xx1=None:g.inject(xx1).all_(TextP.startingWith('a')))],
+ 'g_injectX5_8_10_10_7X_allXgteX7XX': [(lambda g, xx1=None,xx2=None:g.inject(xx1,xx2).all_(P.gte(7)))],
+ 'g_injectXnullX_allXeqXnullXX': [(lambda g:g.inject(None).all_(P.eq(None)))],
+ 'g_injectX7X_allXeqX7XX': [(lambda g:g.inject(7).all_(P.eq(7)))],
+ 'g_injectXnull_nullX_allXeqXnullXX': [(lambda g, xx1=None:g.inject(xx1).all_(P.eq(None)))],
+ 'g_injectX3_threeX_allXeqX3XX': [(lambda g, xx1=None:g.inject(xx1).all_(P.eq(3)))],
'g_V_andXhasXage_gt_27X__outE_count_gte_2X_name': [(lambda g:g.V().and_(__.has('age',P.gt(27)),__.outE().count().is_(P.gte(2))).name)],
'g_V_andXoutE__hasXlabel_personX_and_hasXage_gte_32XX_name': [(lambda g:g.V().and_(__.outE(),__.has(T.label,'person').and_().has('age',P.gte(32))).name)],
'g_V_asXaX_outXknowsX_and_outXcreatedX_inXcreatedX_asXaX_name': [(lambda g:g.V().as_('a').out('knows').and_().out('created').in_('created').as_('a').name)],
'g_V_asXaX_andXselectXaX_selectXaXX': [(lambda g:g.V().as_('a').and_(__.select('a'),__.select('a')))],
'g_V_hasXname_markoX_and_hasXname_markoX_and_hasXname_markoX': [(lambda g:g.V().has('name','marko').and_().has('name','marko').and_().has('name','marko'))],
+ 'g_V_valuesXageX_anyXgtX32XX': [(lambda g:g.V().age.any_(P.gt(32)))],
+ 'g_V_valuesXageX_order_byXdescX_fold_anyXeqX29XX': [(lambda g:g.V().age.order().by(Order.desc).fold().any_(P.eq(29)))],
+ 'g_V_valuesXageX_order_byXdescX_fold_anyXgtX10XX': [(lambda g:g.V().age.order().by(Order.desc).fold().any_(P.gt(10)))],
+ 'g_V_valuesXageX_order_byXdescX_fold_anyXgtX42XX': [(lambda g:g.V().age.order().by(Order.desc).fold().any_(P.gt(42)))],
+ 'g_injectXabc_cdeX_anyXeqXbcdXX': [(lambda g, xx1=None:g.inject(xx1).any_(P.eq('bcd')))],
+ 'g_injectXabc_bcdX_anyXeqXbcdXX': [(lambda g, xx1=None:g.inject(xx1).any_(P.eq('bcd')))],
+ 'g_injectXnull_abcX_anyXTextP_startingWithXaXX': [(lambda g, xx1=None:g.inject(xx1).any_(TextP.startingWith('a')))],
+ 'g_injectX5_8_10_10_7X_anyXeqX7XX': [(lambda g, xx1=None,xx2=None:g.inject(xx1,xx2).any_(P.eq(7)))],
+ 'g_injectXnullX_anyXeqXnullXX': [(lambda g:g.inject(None).any_(P.eq(None)))],
+ 'g_injectX7X_anyXeqX7XX': [(lambda g:g.inject(7).any_(P.eq(7)))],
+ 'g_injectXnull_nullX_anyXeqXnullXX': [(lambda g, xx1=None:g.inject(xx1).any_(P.eq(None)))],
+ 'g_injectX3_threeX_anyXeqX3XX': [(lambda g, xx1=None:g.inject(xx1).any_(P.eq(3)))],
'g_V_coinX1X': [(lambda g:g.V().coin(float(1.0)))],
'g_V_coinX0X': [(lambda g:g.V().coin(float(0.0)))],
'g_withStrategiesXSeedStrategyX_V_order_byXnameX_coinX50X': [(lambda g:g.withStrategies(*[TraversalStrategy('SeedStrategy',{'seed':999999,'strategy':'org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SeedStrategy'}, 'org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SeedStrategy')]).V().order().by('name').coin(float(0.5)))],
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/All.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/All.feature
new file mode 100644
index 0000000000..0e9689d010
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/All.feature
@@ -0,0 +1,151 @@
+# 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.
+
+@StepClassFilter @StepAll
+Feature: Step - all()
+
+ Scenario: g_V_valuesXageX_allXgtX32XX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().values("age").all(P.gt(32))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ Scenario: g_V_valuesXageX_whereXisXP_gtX33XXX_fold_allXgtX33XX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().values("age").where(__.is(P.gt(33))).fold().all(P.gt(33))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[d[35].i] |
+
+ Scenario: g_V_valuesXageX_order_byXdescX_fold_allXgtX10XX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().values("age").order().by(desc).fold().all(P.gt(10))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[d[35].i,d[32].i,d[29].i,d[27].i] |
+
+ Scenario: g_V_valuesXageX_order_byXdescX_fold_allXgtX30XX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().values("age").order().by(desc).fold().all(P.gt(30))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXabc_bcdX_allXeqXbcdXX
+ Given the empty graph
+ And the traversal of
+ """
+ g.inject(["abc","bcd"]).all(P.eq("bcd"))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXbcd_bcdX_allXeqXbcdXX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[bcd,bcd]"
+ And the traversal of
+ """
+ g.inject(xx1).all(P.eq("bcd"))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[bcd,bcd] |
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXnull_abcX_allXTextP_startingWithXaXX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[null,abc]"
+ And the traversal of
+ """
+ g.inject(xx1).all(TextP.startingWith("a"))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectX5_8_10_10_7X_allXgteX7XX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[d[5].i,d[8].i,d[10].i]"
+ And using the parameter xx2 defined as "l[d[10].i,d[7].i]"
+ And the traversal of
+ """
+ g.inject(xx1,xx2).all(P.gte(7))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[d[10].i,d[7].i] |
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXnullX_allXeqXnullXX
+ Given the empty graph
+ And the traversal of
+ """
+ g.inject(null).all(P.eq(null))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectX7X_allXeqX7XX
+ Given the empty graph
+ And the traversal of
+ """
+ g.inject(7).all(P.eq(7))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXnull_nullX_allXeqXnullXX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[null,null]"
+ And the traversal of
+ """
+ g.inject(xx1).all(P.eq(null))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[null,null] |
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectX3_threeX_allXeqX3XX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[d[3].i,three]"
+ And the traversal of
+ """
+ g.inject(xx1).all(P.eq(3))
+ """
+ When iterated to list
+ Then the result should be empty
\ No newline at end of file
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Any.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Any.feature
new file mode 100644
index 0000000000..633c253291
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Any.feature
@@ -0,0 +1,155 @@
+# 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.
+
+@StepClassFilter @StepAny
+Feature: Step - any()
+
+ Scenario: g_V_valuesXageX_anyXgtX32XX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().values("age").any(P.gt(32))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ Scenario: g_V_valuesXageX_order_byXdescX_fold_anyXeqX29XX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().values("age").order().by(desc).fold().any(P.eq(29))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[d[35].i,d[32].i,d[29].i,d[27].i] |
+
+ Scenario: g_V_valuesXageX_order_byXdescX_fold_anyXgtX10XX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().values("age").order().by(desc).fold().any(P.gt(10))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[d[35].i,d[32].i,d[29].i,d[27].i] |
+
+ Scenario: g_V_valuesXageX_order_byXdescX_fold_anyXgtX42XX
+ Given the modern graph
+ And the traversal of
+ """
+ g.V().values("age").order().by(desc).fold().any(P.gt(42))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXabc_cdeX_anyXeqXbcdXX
+ Given the empty graph
+ And the traversal of
+ """
+ g.inject(["abc","cde"]).any(P.eq("bcd"))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXabc_bcdX_anyXeqXbcdXX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[abc,bcd]"
+ And the traversal of
+ """
+ g.inject(xx1).any(P.eq("bcd"))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[abc,bcd] |
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXnull_abcX_anyXTextP_startingWithXaXX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[null,abc]"
+ And the traversal of
+ """
+ g.inject(xx1).any(TextP.startingWith("a"))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[null,abc] |
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectX5_8_10_10_7X_anyXeqX7XX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[d[5].i,d[8].i,d[10].i]"
+ And using the parameter xx2 defined as "l[d[10].i,d[7].i]"
+ And the traversal of
+ """
+ g.inject(xx1,xx2).any(P.eq(7))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[d[10].i,d[7].i] |
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXnullX_anyXeqXnullXX
+ Given the empty graph
+ And the traversal of
+ """
+ g.inject(null).any(P.eq(null))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectX7X_anyXeqX7XX
+ Given the empty graph
+ And the traversal of
+ """
+ g.inject(7).any(P.eq(7))
+ """
+ When iterated to list
+ Then the result should be empty
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectXnull_nullX_anyXeqXnullXX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[null,null]"
+ And the traversal of
+ """
+ g.inject(xx1).any(P.eq(null))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[null,null] |
+
+ @GraphComputerVerificationInjectionNotSupported
+ Scenario: g_injectX3_threeX_anyXeqX3XX
+ Given the empty graph
+ And using the parameter xx1 defined as "l[d[3].i,three]"
+ And the traversal of
+ """
+ g.inject(xx1).any(P.eq(3))
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | l[d[3].i,three] |
\ No newline at end of file