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);            

Reply via email to