This is an automated email from the ASF dual-hosted git repository.
xiazcy pushed a commit to branch 3.7-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/3.7-dev by this push:
new 7eaecf4264 CTR deprecate has(key, traversal)
7eaecf4264 is described below
commit 7eaecf42640629934c20f68eebcbe5c2c3e23ad4
Author: xiazcy <[email protected]>
AuthorDate: Tue Oct 28 16:09:17 2025 -0700
CTR deprecate has(key, traversal)
---
CHANGELOG.asciidoc | 1 +
docs/src/reference/the-traversal.asciidoc | 17 ++++++-------
docs/src/upgrade/release-3.7.x.asciidoc | 29 ++++++++++++++++++++++
.../traversal/dsl/graph/GraphTraversal.java | 4 +++
.../gremlin/process/traversal/dsl/graph/__.java | 4 +++
.../Process/Traversal/GraphTraversal.cs | 2 ++
.../src/Gremlin.Net/Process/Traversal/__.cs | 2 ++
7 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 0e50ed6929..af6ba38b9b 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -27,6 +27,7 @@
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
* Added getter for `parameterItems` and `valueTraversal` on `DifferenceStep`.
* Added properties to `Element` objects found in a `Path` for GraphSON v2 and
v3 and GraphBinary.
* Fixed edge properties for GraphBinary which were not deserializing properly.
+* Deprecated `has(key, traversal)` and `has(T, traversal)` options for `has()`
step.
* Improved GLV examples reliability and documentation with step-by-step
instructions.
* 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.
* Bump netty to 4.1.125.Final
diff --git a/docs/src/reference/the-traversal.asciidoc
b/docs/src/reference/the-traversal.asciidoc
index 5be99761e8..f8c7a47930 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -1901,15 +1901,14 @@ the key,value pairs for those vertices.
<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.
+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
+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()`. Due to
+this confusing expectation, this option is on the deprecation path for 3.7.5,
and will be removed in next major version.
+The recommendation is to consider using `where()` for complex filtering or
`has(key, predicate)` for value comparisons.
*Additional References*
diff --git a/docs/src/upgrade/release-3.7.x.asciidoc
b/docs/src/upgrade/release-3.7.x.asciidoc
index 09d40562ac..3423b21837 100644
--- a/docs/src/upgrade/release-3.7.x.asciidoc
+++ b/docs/src/upgrade/release-3.7.x.asciidoc
@@ -30,6 +30,35 @@ complete list of all the modifications that are part of this
release.
=== Upgrading for Users
+==== Deprecated has(key, traversal)
+
+The `has(key, traversal)` API is deprecated as of 3.7.5, due to its confusing
behavior that differed from other
+`has()` variants, and a common misunderstanding of the API. Unlike `has(key,
value)`, which performs equality comparison,
+`has(key, traversal)` only checked if the traversal produced any result. This
leads to inconsistency in the semantics,
+and this API be removed in the next major version. The recommendation is to
consider using `where()` for complex
+filtering or `has(key, predicate)` for value comparisons.
+
+[source,text]
+----
+// 3.7.4 - this condition is meaningless but yields result because count() is
productive
+gremlin> g.V().has("age", __.count())
+==>v[1]
+==>v[2]
+==>v[3]
+==>v[4]
+==>v[5]
+==>v[6]
+// 3.7.4 - simple example
+gremlin> g.V().has("age", __.is(P.gt(30)))
+==>v[4]
+==>v[6]
+// 3.7.5+ - for proper use cases consider using predicate or where() for
filtering
+gremlin> g.V().has("age", P.gt(30))
+==>v[4]
+==>v[6]
+----
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1463[TINKERPOP-1463]
=== Upgrading for Providers
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 c97a172b6d..d7163ecfa0 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
@@ -2254,6 +2254,8 @@ public interface GraphTraversal<S, E> extends
Traversal<S, E> {
* @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
+ * @deprecated As of release 3.7.5, not replaced. Consider {@code where()}
for complex filtering or
+ * {@code has(T, predicate)} for value comparisons.
*/
public default GraphTraversal<S, E> has(final T accessor, final
Traversal<?, ?> propertyTraversal) {
if (null == accessor)
@@ -2288,6 +2290,8 @@ public interface GraphTraversal<S, E> extends
Traversal<S, E> {
* @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
+ * @deprecated As of release 3.7.5, not replaced. Consider {@code where()}
for complex filtering or
+ * {@code has(key, predicate)} for value comparisons.
*/
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
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 270317772c..cb9a9bf251 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
@@ -943,6 +943,8 @@ public class __ {
/**
* @see GraphTraversal#has(T, Traversal)
+ * @deprecated As of release 3.7.5, not replaced. Consider {@code where()}
for complex filtering or
+ * {@code has(T, predicate)} for value comparisons.
*/
public static <A> GraphTraversal<A, A> has(final T accessor, final
Traversal<?, ?> propertyTraversal) {
return __.<A>start().has(accessor, propertyTraversal);
@@ -950,6 +952,8 @@ public class __ {
/**
* @see GraphTraversal#has(String, Traversal)
+ * @deprecated As of release 3.7.5, not replaced. Consider {@code where()}
for complex filtering or
+ * {@code has(key, predicate)} for value comparisons.
*/
public static <A> GraphTraversal<A, A> has(final String propertyKey, final
Traversal<?, ?> propertyTraversal) {
return __.<A>start().has(propertyKey, propertyTraversal);
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index 8050f0ad56..9dbda4d2be 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -973,6 +973,7 @@ namespace Gremlin.Net.Process.Traversal
/// <summary>
/// Adds the has step to this <see cref="GraphTraversal{SType,
EType}" />.
/// </summary>
+ [Obsolete("Deprecated as of 3.7.5. Not replaced. Consider Where() for
complex filtering or Has(key, predicate) for value comparisons", false)]
public GraphTraversal<TStart, TEnd> Has (string? propertyKey,
ITraversal propertyTraversal)
{
Bytecode.AddStep("has", propertyKey, propertyTraversal);
@@ -1000,6 +1001,7 @@ namespace Gremlin.Net.Process.Traversal
/// <summary>
/// Adds the has step to this <see cref="GraphTraversal{SType,
EType}" />.
/// </summary>
+ [Obsolete("Deprecated as of 3.7.5. Not replaced. Consider Where() for
complex filtering or Has(T, predicate) for value comparisons", false)]
public GraphTraversal<TStart, TEnd> Has (T accessor, ITraversal
propertyTraversal)
{
Bytecode.AddStep("has", accessor, propertyTraversal);
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
index 2ae4603cd1..4c81c5bd38 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
@@ -675,6 +675,7 @@ namespace Gremlin.Net.Process.Traversal
/// <summary>
/// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds
the has step to that traversal.
/// </summary>
+ [Obsolete("Deprecated as of 3.7.5. Not replaced. Consider Where() for
complex filtering or Has(key, predicate) for value comparisons", false)]
public static GraphTraversal<object, object> Has(string? propertyKey,
ITraversal propertyTraversal)
{
return new GraphTraversal<object, object>().Has(propertyKey,
propertyTraversal);
@@ -699,6 +700,7 @@ namespace Gremlin.Net.Process.Traversal
/// <summary>
/// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds
the has step to that traversal.
/// </summary>
+ [Obsolete("Deprecated as of 3.7.5. Not replaced. Consider Where() for
complex filtering or Has(key, predicate) for value comparisons", false)]
public static GraphTraversal<object, object> Has(T accessor,
ITraversal propertyTraversal)
{
return new GraphTraversal<object, object>().Has(accessor,
propertyTraversal);