Lei Shu created TINKERPOP-3272:
----------------------------------
Summary: Labeled `or()`/`and()` pattern inside `match()` causes
unhandled IndexOutOfBoundsException
Key: TINKERPOP-3272
URL: https://issues.apache.org/jira/browse/TINKERPOP-3272
Project: TinkerPop
Issue Type: Bug
Reporter: Lei Shu
### Environment
- TinkerPop 3.7.0 — Docker `tinkerpop/gremlin-server:3.7.0`
- TinkerPop 3.8.1 — Docker `tinkerpop/gremlin-server:latest`
- Query interface: WebSocket Gremlin protocol
Both versions reproduce.
### Description
Placing a labeled `or()` or `and()` connective step inside a `match()` pattern
triggers an unhandled `IndexOutOfBoundsException` in `InlineFilterStrategy`.
The `.as()` label on the outer connective causes
`MatchStep$Helper.computeStartLabel` to access an empty list during strategy
application.
### To Reproduce
```groovy
g.V().drop()
g.addV('A').property('id',1).as('a').addV('B').property('id',2).addE('R').from('a').iterate()
g.addV('A').property('id',3).as('a').addV('B').property('id',4).addE('R').from('a').iterate()
// Crash: or() inside match() with .as('b')
g.V().match(
__.as('a').hasLabel('A'),
__.or(
__.as('a').out('R').has('id',2),
__.as('a').out('R').has('id',4)
).as('b')
).select('a','b').by('id').fold()
// Also crashes: and() inside match() with .as()
g.V().match(
__.as('a').hasLabel('A'),
__.and(
__.as('a').out('R'),
__.as('a').out('R')
).as('b')
).select('a','b').by('id').fold()
```
### Expected
The optimizer should either handle the pattern correctly or produce a
descriptive traversal-validation error rather than an internal
`IndexOutOfBoundsException`.
### Actual behavior
```
java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at MatchStep$Helper.computeStartLabel(MatchStep.java:701)
at InlineFilterStrategy.processMatchStep(InlineFilterStrategy.java:294)
```
### Workaround
Place `.as('b')` inside each `or()` branch:
```groovy
g.V().match(
__.as('a').hasLabel('A'),
__.or(
__.as('a').out('R').has('id',2).as('b'),
__.as('a').out('R').has('id',4).as('b')
)
).select('a','b').by('id').fold()
```
Alternatively, move the connective into a `where()` after `match()`.
### Trigger matrix
| Pattern | Result |
|---------|--------|
| `match(__.as('a').hasLabel('A'), __.as('a').out('R').as('b'))` | OK |
| `match(..., __.or(...,...).as('b'))` | CRASH |
| `match(..., __.and(...,...).as('b'))` | CRASH |
| `or()` standalone (no match) | OK |
--
This message was sent by Atlassian Jira
(v8.20.10#820010)