This is an automated email from the ASF dual-hosted git repository. xiazcy pushed a commit to branch remove-has-k-traversal in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 7cb5a98c4977d3899a3d1cbdf11bd88064a6ead6 Author: xiazcy <[email protected]> AuthorDate: Tue Oct 14 09:59:46 2025 -0700 remove has(key, traversal) --- CHANGELOG.asciidoc | 1 + docs/src/reference/the-traversal.asciidoc | 15 +----- docs/src/upgrade/release-3.8.x.asciidoc | 26 ++++++++++ .../grammar/DefaultGremlinBaseVisitor.java | 8 --- .../language/grammar/TraversalMethodVisitor.java | 18 ------- .../translator/DotNetTranslateVisitor.java | 25 ---------- .../translator/JavascriptTranslateVisitor.java | 5 -- .../traversal/dsl/graph/GraphTraversal.java | 58 ---------------------- .../gremlin/process/traversal/dsl/graph/__.java | 14 ------ .../grammar/TraversalMethodVisitorTest.java | 10 ---- .../language/grammar/TraversalRootVisitorTest.java | 10 ---- .../process/traversal/step/filter/HasStepTest.java | 4 +- .../Process/Traversal/GraphTraversal.cs | 18 ------- .../src/Gremlin.Net/Process/Traversal/__.cs | 16 ------ .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 8 +-- gremlin-go/driver/cucumber/gremlin.go | 8 +-- .../gremlin-javascript/test/cucumber/gremlin.js | 8 +-- gremlin-language/src/main/antlr4/Gremlin.g4 | 2 - gremlin-python/src/main/python/radish/gremlin.py | 8 +-- .../process/traversal/step/LambdaStepTest.java | 19 ------- .../process/traversal/step/filter/HasTest.java | 16 +++--- .../process/traversal/step/map/SelectTest.java | 15 ------ .../gremlin/test/features/filter/Has.feature | 28 +---------- .../gremlin/test/features/filter/Where.feature | 26 +++++++++- .../gremlin/test/features/map/Select.feature | 4 +- 25 files changed, 83 insertions(+), 287 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 04ae491b5c..73db90a7a6 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -29,6 +29,7 @@ This release also includes changes from <<release-3-7-XXX, 3.7.XXX>>. * Added a minimal distribution for `tinkergraph-gremlin` using the `min` classifier that doesn't include the sample datasets. * Removed Vertex/ReferenceVertex from grammar. Use vertex id in traversals now instead. * Renamed `none()` step to `discard()`. +* Removed `has(key, traversal)` option for `has()` step. * Fixed bug where `InlineFilterStrategy` could add an empty `has()`. * Repurposed `none()` step as a list filtering step with the signature `none(P)`. * Modified mathematical operators to prevent overflows in steps such as `sum()` and 'sack()' to prefer promotion to the next highest number type. diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc index dbcb9af468..a9385196fb 100644 --- a/docs/src/reference/the-traversal.asciidoc +++ b/docs/src/reference/the-traversal.asciidoc @@ -2053,7 +2053,6 @@ It is possible to filter vertices, edges, and vertex properties based on their p * `hasValue(values...)`: Remove the `Property` traverser if it does not match one of the provided values. * `has(key)`: Remove the traverser if its element does not have a value for the key. * `hasNot(key)`: Remove the traverser if its element has a value for the key. - * `has(key, traversal)`: Remove the traverser if its object does not yield a result through the traversal off the property value. [gremlin-groovy,modern] ---- @@ -2071,7 +2070,7 @@ g.V().properties().hasKey('age').value() <6> g.V().hasNot('age').values('name') <7> g.V().has('person','name', startingWith('m')) <8> g.V().has(null, 'vadas') <9> -g.V().has(label, __.is('person')) <10> +g.V().has('person', 'name', regex('r')).values('name') <10> ---- <1> Find all vertices whose ages are between 20 (exclusive) and 30 (exclusive). In other words, the age must be greater than 20 and less than 30. @@ -2084,17 +2083,7 @@ the key,value pairs for those vertices. <7> Find all vertices that do not have an age-property and emit their name. <8> Find all "person" vertices that have a name property that starts with the letter "m". <9> Property key is always stored as `String` and therefore an equality check with `null` will produce no result. -<10> An example of `has()` where the argument is a `Traversal` and does not quite behave the way most expect. - -Item 10 in the above set of examples bears some discussion. The behavior is not such that the result of the `Traversal` -is used as the comparing value for `has()`, but the current `Traverser`, which in this case is the vertex `label`, is -given to the `Traversal` to behave as a filter itself. In other words, if the `Traversal` (i.e. `is('person')`) returns -a value then the `has()` is effectively `true`. A common mistake is to try to use `select()` in this context where one -would do `has('name', select('n'))` to try to inject the value of "n" into the step to get `has('name', <value-of-n>)`, -but this would instead simply produce an always `true` filter for `has()`. - -TinkerPop does not support a regular expression predicate, although specific graph databases that leverage TinkerPop -may provide a partial match extension. +<10> An example of using `has()` with regular expression predicate. *Additional References* diff --git a/docs/src/upgrade/release-3.8.x.asciidoc b/docs/src/upgrade/release-3.8.x.asciidoc index d404c2b915..72253e721c 100644 --- a/docs/src/upgrade/release-3.8.x.asciidoc +++ b/docs/src/upgrade/release-3.8.x.asciidoc @@ -305,6 +305,32 @@ The `asString()` step will no longer allow `null` input. An `IllegalArgumentExce See: link:https://lists.apache.org/thread/q76pgrvhprosb4lty63bnsnbw2ljyl7m[DISCUSS] thread +==== Removal of has(key, traversal) + +The current `has(key, traversal)` implementation has long caused confusion, as it only checks if the traversal produces +any result, rather than performing equality comparison with the traversal's output value. While fixing this behavior is +desirable, it would require extensive changes. Therefore, we are removing the current `has(key, traversal)` API as a +breaking change in version 3.8.0, with plans to reintroduce a properly implemented version in the next major release. + +Users needing to filter with traversals should use the `where()` step instead, which provides the expected traversal-based +filtering behavior. Existing `has(key, traversal)` traversals should also be easily translated to use the `where()` step. + +[source,text] +---- +// 3.7.x +g.V().has("age", __.is(P.gt(30))) +==>v[4] +==>v[6] + +// 3.8.0 - use where() instead +g.V().where(values("age").is(P.gt(30))) +==>v[4] +==>v[6] +---- + +See: link:https://lists.apache.org/thread/mtfy1jshb8rwqglp7ooxswwwwj70qy33[DISCUSS] thread +See: link:https://issues.apache.org/jira/browse/TINKERPOP-1463[TINKERPOP-1463] + ==== Javascript Set Deserialization Starting from this version, `gremlin-javascript` will deserialize `Set` data into a ECMAScript 2015 Set. Previously, 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 1b0e1f38bf..58a9652a33 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 @@ -451,10 +451,6 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im * {@inheritDoc} */ @Override public T visitTraversalMethod_has_String_String_P(final GremlinParser.TraversalMethod_has_String_String_PContext ctx) { notImplemented(ctx); return null; } - /** - * {@inheritDoc} - */ - @Override public T visitTraversalMethod_has_String_Traversal(final GremlinParser.TraversalMethod_has_String_TraversalContext ctx) { notImplemented(ctx); return null; } /** * {@inheritDoc} */ @@ -463,10 +459,6 @@ public class DefaultGremlinBaseVisitor<T> extends AbstractParseTreeVisitor<T> im * {@inheritDoc} */ @Override public T visitTraversalMethod_has_T_P(final GremlinParser.TraversalMethod_has_T_PContext ctx) { notImplemented(ctx); return null; } - /** - * {@inheritDoc} - */ - @Override public T visitTraversalMethod_has_T_Traversal(final GremlinParser.TraversalMethod_has_T_TraversalContext 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 32462d5b2a..42a7cd42c5 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 @@ -871,15 +871,6 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal> } } - /** - * {@inheritDoc} - */ - @Override - public GraphTraversal visitTraversalMethod_has_String_Traversal(final GremlinParser.TraversalMethod_has_String_TraversalContext ctx) { - return graphTraversal.has(antlr.genericVisitor.parseString(ctx.stringNullableLiteral()), - antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal())); - } - /** * {@inheritDoc} */ @@ -898,15 +889,6 @@ public class TraversalMethodVisitor extends TraversalRootVisitor<GraphTraversal> antlr.traversalPredicateVisitor.visitTraversalPredicate(ctx.traversalPredicate())); } - /** - * {@inheritDoc} - */ - @Override - public GraphTraversal visitTraversalMethod_has_T_Traversal(final GremlinParser.TraversalMethod_has_T_TraversalContext ctx) { - return graphTraversal.has(TraversalEnumParser.parseTraversalEnumFromContext(T.class, ctx.traversalT()), - antlr.tvisitor.visitNestedTraversal(ctx.nestedTraversal())); - } - /** * {@inheritDoc} */ diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java index 638fb450e4..bcd38a6dcb 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/DotNetTranslateVisitor.java @@ -654,19 +654,6 @@ public class DotNetTranslateVisitor extends AbstractTranslateVisitor { return null; } - @Override - public Void visitTraversalMethod_has_String_Traversal(final GremlinParser.TraversalMethod_has_String_TraversalContext ctx) { - final String step = ctx.getChild(0).getText(); - sb.append(convertToPascalCase(step)); - sb.append("("); - tryAppendCastToString(ctx.stringNullableLiteral()); - visit(ctx.stringNullableLiteral()); - sb.append(", "); - visit(ctx.nestedTraversal()); - sb.append(")"); - return null; - } - @Override public Void visitTraversalMethod_has_T_Object(final GremlinParser.TraversalMethod_has_T_ObjectContext ctx) { final String step = ctx.getChild(0).getText(); @@ -692,18 +679,6 @@ public class DotNetTranslateVisitor extends AbstractTranslateVisitor { return null; } - @Override - public Void visitTraversalMethod_has_T_Traversal(final GremlinParser.TraversalMethod_has_T_TraversalContext ctx) { - final String step = ctx.getChild(0).getText(); - sb.append(convertToPascalCase(step)); - sb.append("("); - visit(ctx.traversalT()); - sb.append(", "); - visit(ctx.nestedTraversal()); - sb.append(")"); - return null; - } - @Override public Void visitTraversalMethod_hasKey_P(final GremlinParser.TraversalMethod_hasKey_PContext ctx) { final String step = ctx.getChild(0).getText(); diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavascriptTranslateVisitor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavascriptTranslateVisitor.java index bd86a8ca43..a6ceb9ff83 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavascriptTranslateVisitor.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/translator/JavascriptTranslateVisitor.java @@ -20,18 +20,13 @@ package org.apache.tinkerpop.gremlin.language.translator; import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.TerminalNode; import org.apache.tinkerpop.gremlin.language.grammar.GremlinParser; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.apache.tinkerpop.gremlin.util.DatetimeHelper; import java.time.OffsetDateTime; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.stream.Collectors; /** 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 482d4d9e49..b4d86ac79d 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 @@ -2745,64 +2745,6 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> { return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(propertyKey, value instanceof P ? (P) value : P.eq(value))); } - /** - * Filters vertices, edges and vertex properties based on their value of {@link T} where only {@link T#id} and - * {@link T#label} are supported. - * - * @param accessor the {@link T} accessor of the property to filter on - * @param propertyTraversal the traversal to filter the accessor value by - * @return the traversal with an appended {@link HasStep} - * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#has-step" target="_blank">Reference Documentation - Has Step</a> - * @since 3.1.0-incubating - */ - public default GraphTraversal<S, E> has(final T accessor, final Traversal<?, ?> propertyTraversal) { - if (null == accessor) - throw new IllegalArgumentException("The T accessor value of has(T,Object) cannot be null"); - - // Groovy can get the overload wrong for has(T, null) which should probably go at has(T,Object). users could - // explicit cast but a redirect here makes this a bit more seamless - if (null == propertyTraversal) - return has(accessor, (Object) null); - - this.asAdmin().getBytecode().addStep(Symbols.has, accessor, propertyTraversal); - switch (accessor) { - case id: - return this.asAdmin().addStep( - new TraversalFilterStep<>(this.asAdmin(), propertyTraversal.asAdmin().addStep(0, - new IdStep<>(propertyTraversal.asAdmin())))); - case label: - return this.asAdmin().addStep( - new TraversalFilterStep<>(this.asAdmin(), propertyTraversal.asAdmin().addStep(0, - new LabelStep<>(propertyTraversal.asAdmin())))); - default: - throw new IllegalArgumentException("has(T,Traversal) can only take id or label as its argument"); - } - - } - - /** - * Filters vertices, edges and vertex properties based on the value of the specified property key. - * - * @param propertyKey the key of the property to filter on - * @param propertyTraversal the traversal to filter the property value by - * @return the traversal with an appended {@link HasStep} - * @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#has-step" target="_blank">Reference Documentation - Has Step</a> - * @since 3.0.0-incubating - */ - public default GraphTraversal<S, E> has(final String propertyKey, final Traversal<?, ?> propertyTraversal) { - // the translation here of null to has(String, Object) is likely what was intended. a null Traversal doesn't - // really make much sense. this should resolve issues with JavaTranslator grabbing this method when bytecode - // uses null as the second argument. we've taken this tactic for other overloads of has() as well, so just - // continuing with that pattern. - if (null == propertyTraversal) - return has(propertyKey, (Object) null); - - this.asAdmin().getBytecode().addStep(Symbols.has, propertyKey, propertyTraversal); - return this.asAdmin().addStep( - new TraversalFilterStep<>(this.asAdmin(), propertyTraversal.asAdmin().addStep(0, - new PropertiesStep(propertyTraversal.asAdmin(), PropertyType.VALUE, propertyKey)))); - } - /** * Filters vertices, edges and vertex properties based on the existence of properties. * 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 5f64bcfc31..00d609665f 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 @@ -1127,20 +1127,6 @@ public class __ { return __.<A>start().has(label, propertyKey, predicate); } - /** - * @see GraphTraversal#has(T, Traversal) - */ - public static <A> GraphTraversal<A, A> has(final T accessor, final Traversal<?, ?> propertyTraversal) { - return __.<A>start().has(accessor, propertyTraversal); - } - - /** - * @see GraphTraversal#has(String, Traversal) - */ - public static <A> GraphTraversal<A, A> has(final String propertyKey, final Traversal<?, ?> propertyTraversal) { - return __.<A>start().has(propertyKey, propertyTraversal); - } - /** * @see GraphTraversal#has(String) */ 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 6660eaa9b1..b66b83734d 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 @@ -446,11 +446,6 @@ public class TraversalMethodVisitorTest { compare(g.V().has("a", "b", eq("c")), eval("g.V().has(\"a\", \"b\", eq(\"c\"))")); } - @Test - public void shouldParseTraversalMethod_has_String_Traversal() throws Exception { - compare(g.V().has("age", bothE()), eval("g.V().has('age', bothE())")); - } - @Test public void shouldParseTraversalMethod_has_T_Object() throws Exception { compare(g.V().has(T.id, 6), eval("g.V().has(id, 6)")); @@ -461,11 +456,6 @@ public class TraversalMethodVisitorTest { compare(g.V().has(T.id, eq("asd")), eval("g.V().has(id, eq('asd'))")); } - @Test - public void shouldParseTraversalMethod_has_T_Traversal() throws Exception { - compare(g.V().has(T.id, bothE()), eval("g.V().has(id, bothE())")); - } - @Test public void shouldParseTraversalMethod_hasId_Object_Object() throws Exception { compare(g.V().hasId(3, 4), eval("g.V().hasId(3, 4)")); diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalRootVisitorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalRootVisitorTest.java index 56b050e8cb..1b54e15e8c 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalRootVisitorTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalRootVisitorTest.java @@ -524,11 +524,6 @@ public class TraversalRootVisitorTest { compare(g.V().map(__.has("a", "b", eq("c"))), eval("g.V().map(__.has(\"a\", \"b\", eq(\"c\")))")); } - @Test - public void shouldParseTraversalMethod_has_String_Traversal() { - compare(g.V().map(__.has("age", bothE())), eval("g.V().map(__.has('age', bothE()))")); - } - @Test public void shouldParseTraversalMethod_has_T_Object() { compare(g.V().map(__.has(T.id, 6)), eval("g.V().map(__.has(id, 6))")); @@ -539,11 +534,6 @@ public class TraversalRootVisitorTest { compare(g.V().map(__.has(T.id, eq("asd"))), eval("g.V().map(__.has(id, eq('asd')))")); } - @Test - public void shouldParseTraversalMethod_has_T_Traversal() { - compare(g.V().map(__.has(T.id, bothE())), eval("g.V().map(__.has(id, bothE()))")); - } - @Test public void shouldParseTraversalMethod_has_GValue() { compare(g.V().map(__.has(GValue.of("foo", "bar"), "b", eq("c"))), eval("g.V().map(__.has(foo, \"b\", eq(\"c\")))")); diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasStepTest.java index c4f43c126f..ca390ccfac 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasStepTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasStepTest.java @@ -40,6 +40,7 @@ import static org.apache.tinkerpop.gremlin.process.traversal.P.eq; import static org.apache.tinkerpop.gremlin.process.traversal.P.within; import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; /** @@ -52,7 +53,6 @@ public class HasStepTest extends GValueStepTest { return Arrays.asList( __.has("name"), __.has("name", "marko"), - __.has("name", out("knows").values("name")), __.hasId(1), __.hasId(1.0), __.hasKey("name"), @@ -64,7 +64,6 @@ public class HasStepTest extends GValueStepTest { __.hasValue("marko"), __.hasValue("josh"), __.has("name", GValue.of("name", "marko")), - __.has("name", out(GValue.of("label", "knows")).values("name")), __.hasId(GValue.of("idInt", 1)), __.hasId(GValue.of("idDouble", 1.0)), __.hasLabel(GValue.of("label", "person")), @@ -78,7 +77,6 @@ public class HasStepTest extends GValueStepTest { protected List<Pair<Traversal, Set<String>>> getGValueTraversals() { return List.of( Pair.of(__.has("name", GValue.of("name", "marko")), Set.of("name")), - Pair.of(__.has("name", out(GValue.of("label", "knows")).values("name")), Set.of("label")), Pair.of(__.hasId(GValue.of("id", 1)), Set.of("id")), Pair.of(__.hasId(GValue.of("id", 1.0)), Set.of("id")), Pair.of(__.hasLabel(GValue.of("label", "person")), Set.of("label")), diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs index eb3f60e0c5..29ca466609 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs @@ -1015,15 +1015,6 @@ namespace Gremlin.Net.Process.Traversal return Wrap<TStart, TEnd>(this); } - /// <summary> - /// Adds the has step to this <see cref="GraphTraversal{SType, EType}" />. - /// </summary> - public GraphTraversal<TStart, TEnd> Has (string? propertyKey, ITraversal propertyTraversal) - { - Bytecode.AddStep("has", propertyKey, propertyTraversal); - return Wrap<TStart, TEnd>(this); - } - /// <summary> /// Adds the has step to this <see cref="GraphTraversal{SType, EType}" />. /// </summary> @@ -1042,15 +1033,6 @@ namespace Gremlin.Net.Process.Traversal return Wrap<TStart, TEnd>(this); } - /// <summary> - /// Adds the has step to this <see cref="GraphTraversal{SType, EType}" />. - /// </summary> - public GraphTraversal<TStart, TEnd> Has (T accessor, ITraversal propertyTraversal) - { - Bytecode.AddStep("has", accessor, propertyTraversal); - return Wrap<TStart, TEnd>(this); - } - /// <summary> /// Adds the hasId 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 edf0d76b7b..910ef8365e 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs @@ -712,14 +712,6 @@ namespace Gremlin.Net.Process.Traversal return new GraphTraversal<object, object>().Has(label, propertyKey, predicate); } - /// <summary> - /// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal. - /// </summary> - public static GraphTraversal<object, object> Has(string? propertyKey, ITraversal propertyTraversal) - { - return new GraphTraversal<object, object>().Has(propertyKey, propertyTraversal); - } - /// <summary> /// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal. /// </summary> @@ -736,14 +728,6 @@ namespace Gremlin.Net.Process.Traversal return new GraphTraversal<object, object>().Has(accessor, predicate); } - /// <summary> - /// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal. - /// </summary> - public static GraphTraversal<object, object> Has(T accessor, ITraversal propertyTraversal) - { - return new GraphTraversal<object, object>().Has(accessor, propertyTraversal); - } - /// <summary> /// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the hasId 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 9ab8812476..eedc2d855a 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs @@ -267,8 +267,6 @@ namespace Gremlin.Net.IntegrationTest.Gherkin {"g_V_hasXname_markoX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name", "marko")}}, {"g_V_hasXname_blahX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name", "blah")}}, {"g_V_hasXage_gt_30X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("age", P.Gt(30))}}, - {"g_V_hasXage_isXgt_30XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("age", __.Is(P.Gt(30)))}}, - {"g_V_hasXlabel_isXsoftwareXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has(T.Label, __.Is("software"))}}, {"g_VX1X_hasXage_gt_30X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid1"]).Has("age", P.Gt(30))}}, {"g_V_hasXpersonvar_age_gt_30X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has((string) p["xx1"], "age", P.Gt(30))}}, {"g_VX4X_hasXage_gt_30X", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V(p["vid4"]).Has("age", P.Gt(30))}}, @@ -311,7 +309,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin {"g_E_hasXnullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Has(null)}}, {"g_V_hasXlabel_personX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has(T.Label, "person")}}, {"g_V_hasXlabel_eqXpersonXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has(T.Label, P.Eq("person"))}}, - {"g_V_hasXlabel_isXpersonXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has(T.Label, __.Is("person"))}}, + {"g_V_whereXlabel_isXpersonXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Where(__.Label().Is("person"))}}, {"g_V_hasXname_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name", (object) null)}}, {"g_V_hasIdXemptyX_count", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasId(p["xx1"]).Count()}}, {"g_V_hasIdXwithinXemptyXX_count", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasId(P.Within(new List<object> { })).Count()}}, @@ -483,6 +481,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin {"g_V_asXnX_whereXorXhasLabelXsoftwareX_hasLabelXpersonXXX_selectXnX_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().As("n").Where(__.Or(__.HasLabel("software"), __.HasLabel("person"))).Select<object>("n").By("name")}}, {"g_V_asXnX_whereXorXselectXnX_hasLabelXsoftwareX_selectXnX_hasLabelXpersonXXX_selectXnX_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().As("n").Where(__.Or(__.Select<object>("n").HasLabel("software"), __.Select<object>("n").HasLabel("person"))).Select<object>("n").By("name")}}, {"g_V_hasLabelXpersonX_asXxX_whereXinEXknowsX_count_isXgteX1XXX_selectXxX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("person").As("x").Where(__.InE("knows").Count().Is(P.Gte(1))).Select<object>("x")}}, + {"get_g_V_whereXage_isXgt_30XX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Where(__.Values<object>("age").Is(P.Gt(30)))}}, + {"g_V_whereXlabel_isXsoftwareXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Where(__.Label().Is("software"))}}, {"g_withStrategiesXAdjacentToIncidentStrategyX_V", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.WithStrategies(new AdjacentToIncidentStrategy()).V()}}, {"g_withoutStrategiesXAdjacentToIncidentStrategyX_V", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.WithoutStrategies(typeof(AdjacentToIncidentStrategy)).V()}}, {"g_withStrategiesXAdjacentToIncidentStrategyX_V_out_count", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.WithStrategies(new AdjacentToIncidentStrategy()).V().Out().Count()}}, @@ -1362,7 +1362,7 @@ namespace Gremlin.Net.IntegrationTest.Gherkin {"g_V_asXaX_out_aggregateXxX_asXbX_selectXa_bX_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().As("a").Out().Aggregate("x").As("b").Select<object>("a", "b").By("name")}}, {"g_V_asXaX_name_order_asXbX_selectXa_bX_byXnameX_by_XitX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().As("a").Values<object>("name").Order().As("b").Select<object>("a", "b").By("name").By()}}, {"g_V_hasXname_gremlinX_inEXusesX_order_byXskill_ascX_asXaX_outV_asXbX_selectXa_bX_byXskillX_byXnameX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name", "gremlin").InE("uses").Order().By("skill", Order.Asc).As("a").OutV().As("b").Select<object>("a", "b").By("skill").By("name")}}, - {"g_V_hasXname_isXmarkoXX_asXaX_selectXaX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Has("name", __.Is("marko")).As("a").Select<object>("a")}}, + {"g_V_whereX_valueXnameX_isXmarkoXX_asXaX_selectXaX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Where(__.Values<object>("name").Is("marko")).As("a").Select<object>("a")}}, {"g_V_label_groupCount_asXxX_selectXxX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Label().GroupCount<object>().As("x").Select<object>("x")}}, {"g_V_hasLabelXpersonX_asXpX_mapXbothE_label_groupCountX_asXrX_selectXp_rX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().HasLabel("person").As("p").Map<object>(__.BothE().Label().GroupCount<object>()).As("r").Select<object>("p", "r")}}, {"g_V_chooseXoutE_count_isX0X__asXaX__asXbXX_chooseXselectXaX__selectXaX__selectXbXX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Choose<object>(__.OutE().Count().Is(p["xx1"]), __.As("a"), __.As("b")).Choose<object>(__.Select<object>("a"), __.Select<object>("a"), __.Select<object>("b"))}}, diff --git a/gremlin-go/driver/cucumber/gremlin.go b/gremlin-go/driver/cucumber/gremlin.go index 3c3d92fc6b..0dff80d443 100644 --- a/gremlin-go/driver/cucumber/gremlin.go +++ b/gremlin-go/driver/cucumber/gremlin.go @@ -237,8 +237,6 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[ "g_V_hasXname_markoX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", "marko")}}, "g_V_hasXname_blahX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", "blah")}}, "g_V_hasXage_gt_30X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("age", gremlingo.P.Gt(30))}}, - "g_V_hasXage_isXgt_30XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("age", gremlingo.T__.Is(gremlingo.P.Gt(30)))}}, - "g_V_hasXlabel_isXsoftwareXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has(gremlingo.T.Label, gremlingo.T__.Is("software"))}}, "g_VX1X_hasXage_gt_30X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid1"]).Has("age", gremlingo.P.Gt(30))}}, "g_V_hasXpersonvar_age_gt_30X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has(p["xx1"], "age", gremlingo.P.Gt(30))}}, "g_VX4X_hasXage_gt_30X": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V(p["vid4"]).Has("age", gremlingo.P.Gt(30))}}, @@ -281,7 +279,7 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[ "g_E_hasXnullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.E().Has(nil)}}, "g_V_hasXlabel_personX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has(gremlingo.T.Label, "person")}}, "g_V_hasXlabel_eqXpersonXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has(gremlingo.T.Label, gremlingo.P.Eq("person"))}}, - "g_V_hasXlabel_isXpersonXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has(gremlingo.T.Label, gremlingo.T__.Is("person"))}}, + "g_V_whereXlabel_isXpersonXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Where(gremlingo.T__.Label().Is("person"))}}, "g_V_hasXname_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", nil)}}, "g_V_hasIdXemptyX_count": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasId(p["xx1"]).Count()}}, "g_V_hasIdXwithinXemptyXX_count": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasId(gremlingo.P.Within([]interface{}{})).Count()}}, @@ -453,6 +451,8 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[ "g_V_asXnX_whereXorXhasLabelXsoftwareX_hasLabelXpersonXXX_selectXnX_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("n").Where(gremlingo.T__.Or(gremlingo.T__.HasLabel("software"), gremlingo.T__.HasLabel("person"))).Select("n").By("name")}}, "g_V_asXnX_whereXorXselectXnX_hasLabelXsoftwareX_selectXnX_hasLabelXpersonXXX_selectXnX_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("n").Where(gremlingo.T__.Or(gremlingo.T__.Select("n").HasLabel("software"), gremlingo.T__.Select("n").HasLabel("person"))).Select("n").By("name")}}, "g_V_hasLabelXpersonX_asXxX_whereXinEXknowsX_count_isXgteX1XXX_selectXxX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("person").As("x").Where(gremlingo.T__.InE("knows").Count().Is(gremlingo.P.Gte(1))).Select("x")}}, + "get_g_V_whereXage_isXgt_30XX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Where(gremlingo.T__.Values("age").Is(gremlingo.P.Gt(30)))}}, + "g_V_whereXlabel_isXsoftwareXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Where(gremlingo.T__.Label().Is("software"))}}, "g_withStrategiesXAdjacentToIncidentStrategyX_V": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.WithStrategies(gremlingo.AdjacentToIncidentStrategy()).V()}}, "g_withoutStrategiesXAdjacentToIncidentStrategyX_V": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.WithoutStrategies(gremlingo.AdjacentToIncidentStrategy()).V()}}, "g_withStrategiesXAdjacentToIncidentStrategyX_V_out_count": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.WithStrategies(gremlingo.AdjacentToIncidentStrategy()).V().Out().Count()}}, @@ -1332,7 +1332,7 @@ var translationMap = map[string][]func(g *gremlingo.GraphTraversalSource, p map[ "g_V_asXaX_out_aggregateXxX_asXbX_selectXa_bX_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("a").Out().Aggregate("x").As("b").Select("a", "b").By("name")}}, "g_V_asXaX_name_order_asXbX_selectXa_bX_byXnameX_by_XitX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().As("a").Values("name").Order().As("b").Select("a", "b").By("name").By()}}, "g_V_hasXname_gremlinX_inEXusesX_order_byXskill_ascX_asXaX_outV_asXbX_selectXa_bX_byXskillX_byXnameX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", "gremlin").InE("uses").Order().By("skill", gremlingo.Order.Asc).As("a").OutV().As("b").Select("a", "b").By("skill").By("name")}}, - "g_V_hasXname_isXmarkoXX_asXaX_selectXaX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("name", gremlingo.T__.Is("marko")).As("a").Select("a")}}, + "g_V_whereX_valueXnameX_isXmarkoXX_asXaX_selectXaX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Where(gremlingo.T__.Values("name").Is("marko")).As("a").Select("a")}}, "g_V_label_groupCount_asXxX_selectXxX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Label().GroupCount().As("x").Select("x")}}, "g_V_hasLabelXpersonX_asXpX_mapXbothE_label_groupCountX_asXrX_selectXp_rX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("person").As("p").Map(gremlingo.T__.BothE().Label().GroupCount()).As("r").Select("p", "r")}}, "g_V_chooseXoutE_count_isX0X__asXaX__asXbXX_chooseXselectXaX__selectXaX__selectXbXX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Choose(gremlingo.T__.OutE().Count().Is(p["xx1"]), gremlingo.T__.As("a"), gremlingo.T__.As("b")).Choose(gremlingo.T__.Select("a"), gremlingo.T__.Select("a"), gremlingo.T__.Select("b"))}}, 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 e01d05fbc1..11bf419f3d 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 @@ -268,8 +268,6 @@ const gremlins = { g_V_hasXname_markoX: [function({g}) { return g.V().has("name", "marko") }], g_V_hasXname_blahX: [function({g}) { return g.V().has("name", "blah") }], g_V_hasXage_gt_30X: [function({g}) { return g.V().has("age", P.gt(30)) }], - g_V_hasXage_isXgt_30XX: [function({g}) { return g.V().has("age", __.is(P.gt(30))) }], - g_V_hasXlabel_isXsoftwareXX: [function({g}) { return g.V().has(T.label, __.is("software")) }], g_VX1X_hasXage_gt_30X: [function({g, vid1}) { return g.V(vid1).has("age", P.gt(30)) }], g_V_hasXpersonvar_age_gt_30X: [function({g, xx1}) { return g.V().has(xx1, "age", P.gt(30)) }], g_VX4X_hasXage_gt_30X: [function({g, vid4}) { return g.V(vid4).has("age", P.gt(30)) }], @@ -312,7 +310,7 @@ const gremlins = { g_E_hasXnullX: [function({g}) { return g.E().has(null) }], g_V_hasXlabel_personX: [function({g}) { return g.V().has(T.label, "person") }], g_V_hasXlabel_eqXpersonXX: [function({g}) { return g.V().has(T.label, P.eq("person")) }], - g_V_hasXlabel_isXpersonXX: [function({g}) { return g.V().has(T.label, __.is("person")) }], + g_V_whereXlabel_isXpersonXX: [function({g}) { return g.V().where(__.label().is("person")) }], g_V_hasXname_nullX: [function({g}) { return g.V().has("name", null) }], g_V_hasIdXemptyX_count: [function({g, xx1}) { return g.V().hasId(xx1).count() }], g_V_hasIdXwithinXemptyXX_count: [function({g}) { return g.V().hasId(P.within([])).count() }], @@ -484,6 +482,8 @@ const gremlins = { g_V_asXnX_whereXorXhasLabelXsoftwareX_hasLabelXpersonXXX_selectXnX_byXnameX: [function({g}) { return g.V().as("n").where(__.or(__.hasLabel("software"), __.hasLabel("person"))).select("n").by("name") }], g_V_asXnX_whereXorXselectXnX_hasLabelXsoftwareX_selectXnX_hasLabelXpersonXXX_selectXnX_byXnameX: [function({g}) { return g.V().as("n").where(__.or(__.select("n").hasLabel("software"), __.select("n").hasLabel("person"))).select("n").by("name") }], g_V_hasLabelXpersonX_asXxX_whereXinEXknowsX_count_isXgteX1XXX_selectXxX: [function({g}) { return g.V().hasLabel("person").as("x").where(__.inE("knows").count().is(P.gte(1))).select("x") }], + get_g_V_whereXage_isXgt_30XX: [function({g}) { return g.V().where(__.values("age").is(P.gt(30))) }], + g_V_whereXlabel_isXsoftwareXX: [function({g}) { return g.V().where(__.label().is("software")) }], g_withStrategiesXAdjacentToIncidentStrategyX_V: [function({g}) { return g.withStrategies(new AdjacentToIncidentStrategy()).V() }], g_withoutStrategiesXAdjacentToIncidentStrategyX_V: [function({g}) { return g.withoutStrategies(AdjacentToIncidentStrategy).V() }], g_withStrategiesXAdjacentToIncidentStrategyX_V_out_count: [function({g}) { return g.withStrategies(new AdjacentToIncidentStrategy()).V().out().count() }], @@ -1363,7 +1363,7 @@ const gremlins = { g_V_asXaX_out_aggregateXxX_asXbX_selectXa_bX_byXnameX: [function({g}) { return g.V().as("a").out().aggregate("x").as("b").select("a", "b").by("name") }], g_V_asXaX_name_order_asXbX_selectXa_bX_byXnameX_by_XitX: [function({g}) { return g.V().as("a").values("name").order().as("b").select("a", "b").by("name").by() }], g_V_hasXname_gremlinX_inEXusesX_order_byXskill_ascX_asXaX_outV_asXbX_selectXa_bX_byXskillX_byXnameX: [function({g}) { return g.V().has("name", "gremlin").inE("uses").order().by("skill", Order.asc).as("a").outV().as("b").select("a", "b").by("skill").by("name") }], - g_V_hasXname_isXmarkoXX_asXaX_selectXaX: [function({g}) { return g.V().has("name", __.is("marko")).as("a").select("a") }], + g_V_whereX_valueXnameX_isXmarkoXX_asXaX_selectXaX: [function({g}) { return g.V().where(__.values("name").is("marko")).as("a").select("a") }], g_V_label_groupCount_asXxX_selectXxX: [function({g}) { return g.V().label().groupCount().as("x").select("x") }], g_V_hasLabelXpersonX_asXpX_mapXbothE_label_groupCountX_asXrX_selectXp_rX: [function({g}) { return g.V().hasLabel("person").as("p").map(__.bothE().label().groupCount()).as("r").select("p", "r") }], g_V_chooseXoutE_count_isX0X__asXaX__asXbXX_chooseXselectXaX__selectXaX__selectXbXX: [function({g, xx1}) { return g.V().choose(__.outE().count().is(xx1), __.as("a"), __.as("b")).choose(__.select("a"), __.select("a"), __.select("b")) }], diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 b/gremlin-language/src/main/antlr4/Gremlin.g4 index fbe2f373e3..8b17b61d36 100644 --- a/gremlin-language/src/main/antlr4/Gremlin.g4 +++ b/gremlin-language/src/main/antlr4/Gremlin.g4 @@ -552,10 +552,8 @@ traversalMethod_has | K_HAS LPAREN stringNullableLiteral COMMA traversalPredicate RPAREN #traversalMethod_has_String_P | K_HAS LPAREN stringNullableArgument COMMA stringNullableLiteral COMMA genericArgument RPAREN #traversalMethod_has_String_String_Object | K_HAS LPAREN stringNullableArgument COMMA stringNullableLiteral COMMA traversalPredicate RPAREN #traversalMethod_has_String_String_P - | K_HAS LPAREN stringNullableLiteral COMMA nestedTraversal RPAREN #traversalMethod_has_String_Traversal | K_HAS LPAREN traversalT COMMA genericArgument RPAREN #traversalMethod_has_T_Object | K_HAS LPAREN traversalT COMMA traversalPredicate RPAREN #traversalMethod_has_T_P - | K_HAS LPAREN traversalT COMMA nestedTraversal RPAREN #traversalMethod_has_T_Traversal ; traversalMethod_hasId diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py index 3fd2da2666..4daef760e6 100644 --- a/gremlin-python/src/main/python/radish/gremlin.py +++ b/gremlin-python/src/main/python/radish/gremlin.py @@ -240,8 +240,6 @@ world.gremlins = { 'g_V_hasXname_markoX': [(lambda g:g.V().has('name', 'marko'))], 'g_V_hasXname_blahX': [(lambda g:g.V().has('name', 'blah'))], 'g_V_hasXage_gt_30X': [(lambda g:g.V().has('age', P.gt(30)))], - 'g_V_hasXage_isXgt_30XX': [(lambda g:g.V().has('age', __.is_(P.gt(30))))], - 'g_V_hasXlabel_isXsoftwareXX': [(lambda g:g.V().has(T.label, __.is_('software')))], 'g_VX1X_hasXage_gt_30X': [(lambda g, vid1=None:g.V(vid1).has('age', P.gt(30)))], 'g_V_hasXpersonvar_age_gt_30X': [(lambda g, xx1=None:g.V().has(xx1, 'age', P.gt(30)))], 'g_VX4X_hasXage_gt_30X': [(lambda g, vid4=None:g.V(vid4).has('age', P.gt(30)))], @@ -284,7 +282,7 @@ world.gremlins = { 'g_E_hasXnullX': [(lambda g:g.E().has(None))], 'g_V_hasXlabel_personX': [(lambda g:g.V().has(T.label, 'person'))], 'g_V_hasXlabel_eqXpersonXX': [(lambda g:g.V().has(T.label, P.eq('person')))], - 'g_V_hasXlabel_isXpersonXX': [(lambda g:g.V().has(T.label, __.is_('person')))], + 'g_V_whereXlabel_isXpersonXX': [(lambda g:g.V().where(__.label().is_('person')))], 'g_V_hasXname_nullX': [(lambda g:g.V().has('name', None))], 'g_V_hasIdXemptyX_count': [(lambda g, xx1=None:g.V().has_id(xx1).count())], 'g_V_hasIdXwithinXemptyXX_count': [(lambda g:g.V().has_id(P.within([])).count())], @@ -456,6 +454,8 @@ world.gremlins = { 'g_V_asXnX_whereXorXhasLabelXsoftwareX_hasLabelXpersonXXX_selectXnX_byXnameX': [(lambda g:g.V().as_('n').where(__.or_(__.has_label('software'), __.has_label('person'))).select('n').by('name'))], 'g_V_asXnX_whereXorXselectXnX_hasLabelXsoftwareX_selectXnX_hasLabelXpersonXXX_selectXnX_byXnameX': [(lambda g:g.V().as_('n').where(__.or_(__.select('n').has_label('software'), __.select('n').has_label('person'))).select('n').by('name'))], 'g_V_hasLabelXpersonX_asXxX_whereXinEXknowsX_count_isXgteX1XXX_selectXxX': [(lambda g:g.V().has_label('person').as_('x').where(__.in_e('knows').count().is_(P.gte(1))).select('x'))], + 'get_g_V_whereXage_isXgt_30XX': [(lambda g:g.V().where(__.values('age').is_(P.gt(30))))], + 'g_V_whereXlabel_isXsoftwareXX': [(lambda g:g.V().where(__.label().is_('software')))], 'g_withStrategiesXAdjacentToIncidentStrategyX_V': [(lambda g:g.with_strategies(AdjacentToIncidentStrategy()).V())], 'g_withoutStrategiesXAdjacentToIncidentStrategyX_V': [(lambda g:g.without_strategies(*[GremlinType('org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.AdjacentToIncidentStrategy')]).V())], 'g_withStrategiesXAdjacentToIncidentStrategyX_V_out_count': [(lambda g:g.with_strategies(AdjacentToIncidentStrategy()).V().out().count())], @@ -1335,7 +1335,7 @@ world.gremlins = { 'g_V_asXaX_out_aggregateXxX_asXbX_selectXa_bX_byXnameX': [(lambda g:g.V().as_('a').out().aggregate('x').as_('b').select('a', 'b').by('name'))], 'g_V_asXaX_name_order_asXbX_selectXa_bX_byXnameX_by_XitX': [(lambda g:g.V().as_('a').values('name').order().as_('b').select('a', 'b').by('name').by())], 'g_V_hasXname_gremlinX_inEXusesX_order_byXskill_ascX_asXaX_outV_asXbX_selectXa_bX_byXskillX_byXnameX': [(lambda g:g.V().has('name', 'gremlin').in_e('uses').order().by('skill', Order.asc).as_('a').out_v().as_('b').select('a', 'b').by('skill').by('name'))], - 'g_V_hasXname_isXmarkoXX_asXaX_selectXaX': [(lambda g:g.V().has('name', __.is_('marko')).as_('a').select('a'))], + 'g_V_whereX_valueXnameX_isXmarkoXX_asXaX_selectXaX': [(lambda g:g.V().where(__.values('name').is_('marko')).as_('a').select('a'))], 'g_V_label_groupCount_asXxX_selectXxX': [(lambda g:g.V().label().group_count().as_('x').select('x'))], 'g_V_hasLabelXpersonX_asXpX_mapXbothE_label_groupCountX_asXrX_selectXp_rX': [(lambda g:g.V().has_label('person').as_('p').map(__.both_e().label().group_count()).as_('r').select('p', 'r'))], 'g_V_chooseXoutE_count_isX0X__asXaX__asXbXX_chooseXselectXaX__selectXaX__selectXbXX': [(lambda g, xx1=None:g.V().choose(__.out_e().count().is_(xx1), __.as_('a'), __.as_('b')).choose(__.select('a'), __.select('a'), __.select('b')))], diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/LambdaStepTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/LambdaStepTest.java index 0bd0bd9687..ab24c813a8 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/LambdaStepTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/LambdaStepTest.java @@ -24,7 +24,6 @@ import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner; import org.apache.tinkerpop.gremlin.process.IgnoreEngine; import org.apache.tinkerpop.gremlin.process.traversal.Operator; import org.apache.tinkerpop.gremlin.process.traversal.Order; -import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.Path; import org.apache.tinkerpop.gremlin.process.traversal.Scope; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; @@ -109,10 +108,6 @@ public abstract class LambdaStepTest extends AbstractGremlinProcessTest { public abstract Traversal<Vertex, Map<String, Long>> get_g_V_groupXaX_byXname_substring_1X_byXconstantX1XX_capXaX(); - /// has - - public abstract Traversal<Vertex, String> get_g_V_outXcreatedX_hasXname__mapXlengthX_isXgtX3XXX_name(); - /// inject public abstract Traversal<Vertex, Path> get_g_VX1X_out_name_injectXdanielX_asXaX_mapXlengthX_path(final Object v1Id); @@ -305,15 +300,6 @@ public abstract class LambdaStepTest extends AbstractGremlinProcessTest { assertFalse(traversal.hasNext()); } - @Test - @LoadGraphWith(MODERN) - public void g_V_outXcreatedX_hasXname__mapXlengthX_isXgtX3XXX_name() { - final Traversal<Vertex, String> traversal = get_g_V_outXcreatedX_hasXname__mapXlengthX_isXgtX3XXX_name(); - printTraversalForm(traversal); - checkResults(Arrays.asList("ripple"), traversal); - } - - @Test @LoadGraphWith(MODERN) public void g_VX1X_mapXnameX() { @@ -704,11 +690,6 @@ public abstract class LambdaStepTest extends AbstractGremlinProcessTest { return g.E().filter(e -> true); } - @Override - public Traversal<Vertex, String> get_g_V_outXcreatedX_hasXname__mapXlengthX_isXgtX3XXX_name() { - return g.V().out("created").has("name", __.<String, Integer>map(s -> s.get().length()).is(P.gt(3))).values("name"); - } - @Override public Traversal<Vertex, String> get_g_VX1X_mapXnameX(final Object v1Id) { return g.V(v1Id).<String>map(v -> v.get().value("name")); diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasTest.java index 0c516d19d3..9d9165e565 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasTest.java @@ -94,9 +94,9 @@ public abstract class HasTest extends AbstractGremlinProcessTest { public abstract Traversal<Vertex, Vertex> get_g_V_hasXage_gt_30X(); - public abstract Traversal<Vertex, Vertex> get_g_V_hasXage_isXgt_30XX(); + public abstract Traversal<Vertex, Vertex> get_g_V_whereXage_isXgt_30XX(); - public abstract Traversal<Vertex, Vertex> get_g_V_hasXlabel_isXsoftwareXX(); + public abstract Traversal<Vertex, Vertex> get_g_V_whereXlabel_isXsoftwareXX(); public abstract Traversal<Edge, Edge> get_g_EX7X_hasLabelXknowsX(final Object e7Id); @@ -264,7 +264,7 @@ public abstract class HasTest extends AbstractGremlinProcessTest { @Test @LoadGraphWith(MODERN) public void g_V_hasXage_isXgt_30XX() { - final Traversal<Vertex, Vertex> traversal = get_g_V_hasXage_isXgt_30XX(); + final Traversal<Vertex, Vertex> traversal = get_g_V_whereXage_isXgt_30XX(); printTraversalForm(traversal); final List<Vertex> list = traversal.toList(); assertEquals(2, list.size()); @@ -276,7 +276,7 @@ public abstract class HasTest extends AbstractGremlinProcessTest { @Test @LoadGraphWith(MODERN) public void g_V_hasXlabel_isXsoftwareXX() { - final Traversal<Vertex, Vertex> traversal = get_g_V_hasXlabel_isXsoftwareXX(); + final Traversal<Vertex, Vertex> traversal = get_g_V_whereXlabel_isXsoftwareXX(); printTraversalForm(traversal); final List<Vertex> list = traversal.toList(); assertEquals(2, list.size()); @@ -1076,13 +1076,13 @@ public abstract class HasTest extends AbstractGremlinProcessTest { } @Override - public Traversal<Vertex, Vertex> get_g_V_hasXage_isXgt_30XX() { - return g.V().has("age", __.is(P.gt(30))); + public Traversal<Vertex, Vertex> get_g_V_whereXage_isXgt_30XX() { + return g.V().where(__.values("age").is(P.gt(30))); } @Override - public Traversal<Vertex, Vertex> get_g_V_hasXlabel_isXsoftwareXX() { - return g.V().has(T.label, __.is("software")); + public Traversal<Vertex, Vertex> get_g_V_whereXlabel_isXsoftwareXX() { + return g.V().where(__.label().is("software")); } @Override diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectTest.java index dd8b7cab34..e30ef2f1b0 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectTest.java @@ -79,8 +79,6 @@ public abstract class SelectTest extends AbstractGremlinProcessTest { public abstract Traversal<Vertex, Map<String, Object>> get_g_V_hasXname_gremlinX_inEXusesX_order_byXskill_ascX_asXaX_outV_asXbX_selectXa_bX_byXskillX_byXnameX(); - public abstract Traversal<Vertex, Vertex> get_g_V_hasXname_isXmarkoXX_asXaX_selectXaX(); - public abstract Traversal<Vertex, Map<String, Long>> get_g_V_label_groupCount_asXxX_selectXxX(); public abstract Traversal<Vertex, Map<String, Object>> get_g_V_hasLabelXpersonX_asXpX_mapXbothE_label_groupCountX_asXrX_selectXp_rX(); @@ -315,14 +313,6 @@ public abstract class SelectTest extends AbstractGremlinProcessTest { checkResults(expected, traversal); } - @Test - @LoadGraphWith(MODERN) - public void g_V_hasXname_isXmarkoXX_asXaX_selectXaX() { - final Traversal<Vertex, Vertex> traversal = get_g_V_hasXname_isXmarkoXX_asXaX_selectXaX(); - printTraversalForm(traversal); - checkResults(Arrays.asList(convertToVertex(graph, "marko")), traversal); - } - @Test @LoadGraphWith(MODERN) public void g_V_label_groupCount_asXxX_selectXxX() { @@ -950,11 +940,6 @@ public abstract class SelectTest extends AbstractGremlinProcessTest { return g.V().has("name", "gremlin").inE("uses").order().by("skill", Order.asc).as("a").outV().as("b").select("a", "b").by("skill").by("name"); } - @Override - public Traversal<Vertex, Vertex> get_g_V_hasXname_isXmarkoXX_asXaX_selectXaX() { - return g.V().has("name", __.is("marko")).as("a").select("a"); - } - @Override public Traversal<Vertex, Map<String, Long>> get_g_V_label_groupCount_asXxX_selectXxX() { return g.V().label().groupCount().as("x").select("x"); diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Has.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Has.feature index ced031ef92..38713781b9 100644 --- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Has.feature +++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Has.feature @@ -107,30 +107,6 @@ Feature: Step - has() | v[josh] | | v[peter] | - Scenario: g_V_hasXage_isXgt_30XX - Given the modern graph - And the traversal of - """ - g.V().has("age", __.is(P.gt(30))) - """ - When iterated to list - Then the result should be unordered - | result | - | v[josh] | - | v[peter] | - - Scenario: g_V_hasXlabel_isXsoftwareXX - Given the modern graph - And the traversal of - """ - g.V().has(T.label, __.is('software')) - """ - When iterated to list - Then the result should be unordered - | result | - | v[lop] | - | v[ripple] | - Scenario: g_VX1X_hasXage_gt_30X Given the modern graph And using the parameter vid1 defined as "v[marko].id" @@ -637,11 +613,11 @@ Feature: Step - has() | v[josh] | | v[peter] | - Scenario: g_V_hasXlabel_isXpersonXX + Scenario: g_V_whereXlabel_isXpersonXX Given the modern graph And the traversal of """ - g.V().has(T.label, __.is("person")) + g.V().where(label().is("person")) """ When iterated to list Then the result should be unordered diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Where.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Where.feature index c448d96994..44ff093629 100644 --- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Where.feature +++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Where.feature @@ -407,4 +407,28 @@ Feature: Step - where() Then the result should be unordered | result | | v[vadas] | - | v[josh] | \ No newline at end of file + | v[josh] | + + Scenario: get_g_V_whereXage_isXgt_30XX + Given the modern graph + And the traversal of + """ + g.V().where(values("age").is(P.gt(30))) + """ + When iterated to list + Then the result should be unordered + | result | + | v[josh] | + | v[peter] | + + Scenario: g_V_whereXlabel_isXsoftwareXX + Given the modern graph + And the traversal of + """ + g.V().where(label().is('software')) + """ + When iterated to list + Then the result should be unordered + | result | + | v[lop] | + | v[ripple] | diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Select.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Select.feature index 3109a9f289..948f6070e9 100644 --- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Select.feature +++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/Select.feature @@ -149,11 +149,11 @@ Feature: Step - select() | m[{"a":"d[5].i", "b": "stephen"}] | | m[{"a":"d[5].i", "b": "daniel"}] | - Scenario: g_V_hasXname_isXmarkoXX_asXaX_selectXaX + Scenario: g_V_whereX_valueXnameX_isXmarkoXX_asXaX_selectXaX Given the modern graph And the traversal of """ - g.V().has("name", __.is("marko")).as("a").select("a") + g.V().where(values("name").is("marko")).as("a").select("a") """ When iterated to list Then the result should be unordered
