[ 
https://issues.apache.org/jira/browse/TINKERPOP-3271?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18098570#comment-18098570
 ] 

ASF GitHub Bot commented on TINKERPOP-3271:
-------------------------------------------

GumpacG opened a new pull request, #3556:
URL: https://github.com/apache/tinkerpop/pull/3556

   ## Summary
   
   `subgraph()` produces an edge-induced subgraph and must be called at an edge 
step.
   When the traversal instead feeds it a non-Edge value, `SubgraphStep` passed 
that
   value straight into an `Edge`-typed method, producing a raw 
`ClassCastException`
   with no indication of what went wrong.
   
   This change validates the traverser value at runtime and throws a descriptive
   `IllegalStateException` naming the required `Edge` input, consistent with the
   existing pattern in `AddPropertyStep` and `AddEdgeStep`. Valid queries are
   unaffected; only the failure message for already-invalid queries changes.
   
   This is a backward-compatible diagnostics fix (runtime validation only, no 
API or
   generics change).
   
   ## Before vs After
   
   ### Non-edge (primitive) input
   ```groovy
   g.inject(1).subgraph('sg').cap('sg').iterate()
   ```
   - Before: `ClassCastException: class java.lang.Integer cannot be cast to 
class ...Edge`
   - After: `IllegalStateException: subgraph() requires Edge input but 
encountered Integer; use an edge step such as outE(), inE(), or bothE()`
   
   ### Vertex input
   ```groovy
   g.addV().subgraph('sg').cap('sg').iterate()
   ```
   - Before: `ClassCastException: class ...TinkerVertex cannot be cast to class 
...Edge`
   - After: `IllegalStateException: subgraph() requires Edge input but 
encountered TinkerVertex; use an edge step such as outE(), inE(), or bothE()`
   
   ### Correct usage (unchanged)
   ```groovy
   g.V().has('v',1).outE('X').subgraph('sg').cap('sg')  // edges in -> builds 
subgraph
   ```
   - Before and after: works identically
   
   ## Changes
   - `gremlin-core`: runtime `Edge` validation in `SubgraphStep.sideEffect(...)`
   - `gremlin-test`: two negative tests added to the `SubgraphTest` suite
   - `CHANGELOG.asciidoc`: entry under 3.7.7
   
   
   Assisted-by: Kiro: Claude Opus 4.8




> subgraph() throws ClassCastException instead of a descriptive error for 
> non-Edge input
> --------------------------------------------------------------------------------------
>
>                 Key: TINKERPOP-3271
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-3271
>             Project: TinkerPop
>          Issue Type: Bug
>          Components: process
>    Affects Versions: 3.7.6
>            Reporter: Lei Shu
>            Priority: Minor
>
> ### Environment
> Runtime reproduction on:
>  
> - TinkerPop 3.7.0 — Docker `tinkerpop/gremlin-server:3.7.0`
> - TinkerPop 3.8.1 — Docker `tinkerpop/gremlin-server:latest`
>  
> ### Description
> `subgraph()` is documented as producing an edge-induced subgraph and must be 
> called at edge steps. The fluent `GraphTraversal.subgraph(String)` method 
> returns the existing `GraphTraversal<S,E>` without constraining `E` to 
> `Edge`, so traversals producing non-Edge values can be constructed without a 
> compile-time error and fail only at runtime. Regardless of whether 
> compile-time enforcement is practical within the current DSL design, the 
> runtime failure could identify the violated `subgraph()` input contract 
> instead of exposing an internal `ClassCastException`.
>  
> ### To Reproduce
> Minimal (Integer input):
> ```groovy
> g.inject(1).subgraph('sg').cap('sg').iterate()
> ```
>  
> Vertex input:
> ```groovy
> g.addV().subgraph('sg').cap('sg').iterate()
> ```
>  
> Realistic (out() emits vertices into subgraph()):
> ```groovy
> g.V().drop().iterate()
> g.addV('N').property('v',1).as('a').addV('N').property('v',2).as('b').addE('X').from('a').to('b').iterate()
>  
> g.V().has('v',1).out('X').subgraph('sg').cap('sg')
> ```
>  
> ### Expected
> The step should reject a traverser value that is not an `Edge` with a 
> descriptive argument or traversal-validation error identifying that 
> `subgraph()` requires edge input, rather than exposing an internal 
> `ClassCastException`.
>  
> ### Actual
> ```
> ClassCastException: class java.lang.Integer cannot be cast to class Edge
> ClassCastException: class TinkerVertex cannot be cast to class Edge
> at SubgraphStep.sideEffect(SubgraphStep.java:81)
> ```
>  
> ### Root cause
> `SubgraphStep` is typed for `Edge` traversers, but the traversal can be 
> constructed with a non-Edge end type. During execution, `sideEffect()` 
> retrieves the traverser value and passes it to `addEdgeToSubgraph(Edge)`. 
> When that value is not an `Edge`, the runtime cast fails before a 
> domain-specific validation error can be produced.
>  
> 3.7.0 uses `SideEffectStep<Edge>`; 3.8.1 uses `SideEffectBarrierStep<Edge>`. 
> Both pass `traverser.get()` directly to edge-accepting methods without 
> runtime type checking.
>  
> ### Workaround
> Use `outE()` to ensure edge-only input:
> ```groovy
> g.V().has('v',1).outE('X').subgraph('sg').cap('sg')
> ```
>  
> ### Notes
> - This is a `gremlin-core` issue, not TinkerGraph-specific
> - No server crash, data corruption, or wrong results — error diagnosis 
> improvement
> - The input itself violates the documented constraint (subgraph requires edge 
> input)
>  
> ### Suggested JIRA fields
> | Field | Value |
> |-------|-------|
> | Type | Improvement |
> | Component | process |
> | Priority | Minor |
> | Affects Version/s | 3.7.0, 3.8.1 |
>  



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

Reply via email to