Skip to content

Commit 7eaecf4

Browse files
committed
CTR deprecate has(key, traversal)
1 parent a795d38 commit 7eaecf4

File tree

7 files changed

+50
-9
lines changed

7 files changed

+50
-9
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
2727
* Added getter for `parameterItems` and `valueTraversal` on `DifferenceStep`.
2828
* Added properties to `Element` objects found in a `Path` for GraphSON v2 and v3 and GraphBinary.
2929
* Fixed edge properties for GraphBinary which were not deserializing properly.
30+
* Deprecated `has(key, traversal)` and `has(T, traversal)` options for `has()` step.
3031
* Improved GLV examples reliability and documentation with step-by-step instructions.
3132
* Added root-level GLV examples in `glv-examples/` directory that use published driver versions for easy out-of-the-box usage, separate from module-level examples that use local development code.
3233
* Bump netty to 4.1.125.Final

docs/src/reference/the-traversal.asciidoc

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,15 +1901,14 @@ the key,value pairs for those vertices.
19011901
<9> Property key is always stored as `String` and therefore an equality check with `null` will produce no result.
19021902
<10> An example of `has()` where the argument is a `Traversal` and does not quite behave the way most expect.
19031903
1904-
Item 10 in the above set of examples bears some discussion. The behavior is not such that the result of the `Traversal`
1905-
is used as the comparing value for `has()`, but the current `Traverser`, which in this case is the vertex `label`, is
1906-
given to the `Traversal` to behave as a filter itself. In other words, if the `Traversal` (i.e. `is('person')`) returns
1907-
a value then the `has()` is effectively `true`. A common mistake is to try to use `select()` in this context where one
1908-
would do `has('name', select('n'))` to try to inject the value of "n" into the step to get `has('name', <value-of-n>)`,
1909-
but this would instead simply produce an always `true` filter for `has()`.
1910-
1911-
TinkerPop does not support a regular expression predicate, although specific graph databases that leverage TinkerPop
1912-
may provide a partial match extension.
1904+
Item 10 in the above set of examples is deprecated as of 3.7.5, and bears some discussion. The behavior is not such that
1905+
the result of the `Traversal` is used as the comparing value for `has()`, but the current `Traverser`, which in this case
1906+
is the vertex `label`, is given to the `Traversal` to behave as a filter itself. In other words, if the `Traversal`
1907+
(i.e. `is('person')`) returns a value then the `has()` is effectively `true`. A common mistake is to try to use
1908+
`select()` in this context where one would do `has('name', select('n'))` to try to inject the value of "n" into the step
1909+
to get `has('name', <value-of-n>)`, but this would instead simply produce an always `true` filter for `has()`. Due to
1910+
this confusing expectation, this option is on the deprecation path for 3.7.5, and will be removed in next major version.
1911+
The recommendation is to consider using `where()` for complex filtering or `has(key, predicate)` for value comparisons.
19131912
19141913
*Additional References*
19151914

docs/src/upgrade/release-3.7.x.asciidoc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,35 @@ complete list of all the modifications that are part of this release.
3030
3131
=== Upgrading for Users
3232
33+
==== Deprecated has(key, traversal)
34+
35+
The `has(key, traversal)` API is deprecated as of 3.7.5, due to its confusing behavior that differed from other
36+
`has()` variants, and a common misunderstanding of the API. Unlike `has(key, value)`, which performs equality comparison,
37+
`has(key, traversal)` only checked if the traversal produced any result. This leads to inconsistency in the semantics,
38+
and this API be removed in the next major version. The recommendation is to consider using `where()` for complex
39+
filtering or `has(key, predicate)` for value comparisons.
40+
41+
[source,text]
42+
----
43+
// 3.7.4 - this condition is meaningless but yields result because count() is productive
44+
gremlin> g.V().has("age", __.count())
45+
==>v[1]
46+
==>v[2]
47+
==>v[3]
48+
==>v[4]
49+
==>v[5]
50+
==>v[6]
51+
// 3.7.4 - simple example
52+
gremlin> g.V().has("age", __.is(P.gt(30)))
53+
==>v[4]
54+
==>v[6]
55+
// 3.7.5+ - for proper use cases consider using predicate or where() for filtering
56+
gremlin> g.V().has("age", P.gt(30))
57+
==>v[4]
58+
==>v[6]
59+
----
60+
61+
See: link:https://issues.apache.org/jira/browse/TINKERPOP-1463[TINKERPOP-1463]
3362
3463
=== Upgrading for Providers
3564

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,6 +2254,8 @@ public default GraphTraversal<S, E> has(final String label, final String propert
22542254
* @return the traversal with an appended {@link HasStep}
22552255
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#has-step" target="_blank">Reference Documentation - Has Step</a>
22562256
* @since 3.1.0-incubating
2257+
* @deprecated As of release 3.7.5, not replaced. Consider {@code where()} for complex filtering or
2258+
* {@code has(T, predicate)} for value comparisons.
22572259
*/
22582260
public default GraphTraversal<S, E> has(final T accessor, final Traversal<?, ?> propertyTraversal) {
22592261
if (null == accessor)
@@ -2288,6 +2290,8 @@ public default GraphTraversal<S, E> has(final T accessor, final Traversal<?, ?>
22882290
* @return the traversal with an appended {@link HasStep}
22892291
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#has-step" target="_blank">Reference Documentation - Has Step</a>
22902292
* @since 3.0.0-incubating
2293+
* @deprecated As of release 3.7.5, not replaced. Consider {@code where()} for complex filtering or
2294+
* {@code has(key, predicate)} for value comparisons.
22912295
*/
22922296
public default GraphTraversal<S, E> has(final String propertyKey, final Traversal<?, ?> propertyTraversal) {
22932297
// the translation here of null to has(String, Object) is likely what was intended. a null Traversal doesn't

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,13 +943,17 @@ public static <A> GraphTraversal<A, A> has(final String label, final String prop
943943

944944
/**
945945
* @see GraphTraversal#has(T, Traversal)
946+
* @deprecated As of release 3.7.5, not replaced. Consider {@code where()} for complex filtering or
947+
* {@code has(T, predicate)} for value comparisons.
946948
*/
947949
public static <A> GraphTraversal<A, A> has(final T accessor, final Traversal<?, ?> propertyTraversal) {
948950
return __.<A>start().has(accessor, propertyTraversal);
949951
}
950952

951953
/**
952954
* @see GraphTraversal#has(String, Traversal)
955+
* @deprecated As of release 3.7.5, not replaced. Consider {@code where()} for complex filtering or
956+
* {@code has(key, predicate)} for value comparisons.
953957
*/
954958
public static <A> GraphTraversal<A, A> has(final String propertyKey, final Traversal<?, ?> propertyTraversal) {
955959
return __.<A>start().has(propertyKey, propertyTraversal);

gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,7 @@ public GraphTraversal<TStart, TEnd> Has (string? label, string? propertyKey, P?
973973
/// <summary>
974974
/// Adds the has step to this <see cref="GraphTraversal{SType, EType}" />.
975975
/// </summary>
976+
[Obsolete("Deprecated as of 3.7.5. Not replaced. Consider Where() for complex filtering or Has(key, predicate) for value comparisons", false)]
976977
public GraphTraversal<TStart, TEnd> Has (string? propertyKey, ITraversal propertyTraversal)
977978
{
978979
Bytecode.AddStep("has", propertyKey, propertyTraversal);
@@ -1000,6 +1001,7 @@ public GraphTraversal<TStart, TEnd> Has (T accessor, P? predicate)
10001001
/// <summary>
10011002
/// Adds the has step to this <see cref="GraphTraversal{SType, EType}" />.
10021003
/// </summary>
1004+
[Obsolete("Deprecated as of 3.7.5. Not replaced. Consider Where() for complex filtering or Has(T, predicate) for value comparisons", false)]
10031005
public GraphTraversal<TStart, TEnd> Has (T accessor, ITraversal propertyTraversal)
10041006
{
10051007
Bytecode.AddStep("has", accessor, propertyTraversal);

gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ public static GraphTraversal<object, object> Has(string? label, string? property
675675
/// <summary>
676676
/// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
677677
/// </summary>
678+
[Obsolete("Deprecated as of 3.7.5. Not replaced. Consider Where() for complex filtering or Has(key, predicate) for value comparisons", false)]
678679
public static GraphTraversal<object, object> Has(string? propertyKey, ITraversal propertyTraversal)
679680
{
680681
return new GraphTraversal<object, object>().Has(propertyKey, propertyTraversal);
@@ -699,6 +700,7 @@ public static GraphTraversal<object, object> Has(T accessor, P? predicate)
699700
/// <summary>
700701
/// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the has step to that traversal.
701702
/// </summary>
703+
[Obsolete("Deprecated as of 3.7.5. Not replaced. Consider Where() for complex filtering or Has(key, predicate) for value comparisons", false)]
702704
public static GraphTraversal<object, object> Has(T accessor, ITraversal propertyTraversal)
703705
{
704706
return new GraphTraversal<object, object>().Has(accessor, propertyTraversal);

0 commit comments

Comments
 (0)