Lei Shu created TINKERPOP-3269:
----------------------------------

             Summary: Invalid non-string predicate in where(P) throws an 
internal ClassCastException instead of a validation error
                 Key: TINKERPOP-3269
                 URL: https://issues.apache.org/jira/browse/TINKERPOP-3269
             Project: TinkerPop
          Issue Type: New Feature
            Reporter: Lei Shu


h3. TinkerPop version

Originally observed on:

 

{{Apache TinkerPop 3.7.0
Gremlin Server with TinkerGraph
Interface: WebSocket}}

Please note that the issue should also be retested on a currently maintained 
release before triage.
h3. Environment
 * Deployment: Docker

 * Image: {{tinkerpop/gremlin-server}}

 * Graph implementation: TinkerGraph

 * Query language: Gremlin-Groovy

 * Interface: Gremlin Server over WebSocket

h3. Description

Passing a predicate with a non-string value to {{where(P)}} causes an internal 
{{ClassCastException}} in {{{}WherePredicateStep.getSelectKey(){}}}.

For example:

 

{{g.inject(10).where(gt(5)).fold()}}

fails with:

 

{{java.lang.ClassCastException:
class java.lang.Integer cannot be cast to class java.lang.String

at WherePredicateStep.getSelectKey(...)}}

{{where(P)}} uses the predicate value as the name of a path label, map key, or 
side-effect binding. Therefore, {{where(gt(5))}} is not the correct way to test 
whether the current scalar value is greater than {{{}5{}}}.

The correct scalar-filtering form is:

 

{{g.inject(10).is(gt(5)).fold()}}

which returns:

 

{{[10]}}

The invalid traversal may reasonably be rejected, but it should produce a 
descriptive validation or argument error rather than exposing an internal Java 
type cast.
h3. Minimal reproduction

 

{{g.inject(10).where(gt(5)).fold()}}
h3. Expected behavior

The traversal should be rejected with a descriptive error explaining that the 
predicate value supplied to {{where(P)}} must identify a string scope key or 
variable binding.

For example:

 

{{where(P) requires the predicate value to be a String scope key;
use is(P) to filter the current scalar value}}

The exact wording is not important, but the engine should not expose an 
internal {{{}ClassCastException{}}}.
h3. Actual behavior

The traversal fails with an internal exception:

 

{{ClassCastException: Integer cannot be cast to String
at WherePredicateStep.getSelectKey(...)}}
h3. Additional reproduction through {{values()}}

 

{{g.V().drop().iterate()
g.addV('X').property('v', 10).iterate()
g.addV('X').property('v', 20).iterate()

g.V().
  hasLabel('X').
  where(__.values('v').where(gt(5))).
  values('v').
  fold()}}

Actual result:

 

{{ClassCastException: Integer cannot be cast to String}}

The equivalent valid traversal works:

 

{{g.V().
  hasLabel('X').
  where(__.values('v').is(gt(5))).
  values('v').
  fold()}}

Result:

 

{{[10, 20]}}
h3. Additional reproduction after {{select()}}

 

{{g.V().
  hasLabel('X').
  as('x').
  where(
    __.select('x').
      values('v').
      where(gt(5))
  ).
  values('v').
  fold()}}

Actual result:

 

{{ClassCastException: Integer cannot be cast to String}}

Valid form:

 

{{g.V().
  hasLabel('X').
  as('x').
  where(
    __.select('x').
      values('v').
      is(gt(5))
  ).
  values('v').
  fold()}}

Result:

 

{{[10, 20]}}
h3. Why this appears to be a bug

The traversal itself uses the wrong step for scalar filtering:

 

{{where(gt(5))}}

instead of:

 

{{is(gt(5))}}

However, the invalid predicate reaches 
{{{}WherePredicateStep.getSelectKey(){}}}, where its integer value is cast 
directly to {{{}String{}}}.

This exposes an internal implementation exception rather than reporting an 
invalid {{where(P)}} argument.

The issue is therefore error validation and diagnostics, not incorrect 
filtering semantics. {{where(P)}} does not need to support numeric literal 
predicates, but it should reject them cleanly.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to