apache / apache/age

List slicing may return a concrete sublist on Apache AGE when either the slice start bound or end bound is `null`.

Open
#2,392 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C
Stars
4.8k
Forks
523
Avg merge
1d 2h
Merged PRs (30d)
9

Description

**Describe the bug**
List slicing may return a concrete sublist on Apache AGE when either the slice start bound or end bound is `null`.

For example, in the minimized repro below, `[1,2,3][1..null]` should evaluate to `null` under Cypher null-propagation semantics. Instead, AGE treats the `null` bound like an omitted bound and returns `[2, 3]`.

The same issue appears symmetrically for a `null` start bound.

**How are you accessing AGE (Command line, driver, etc.)?**
- PostgreSQL `cypher(...)` wrapper through the local Python differential-testing harness
- Reproducible directly in `psql` inside the Docker container

**What data setup do we need to do?**
```pgsql
SELECT create_graph('expr_slice_bug');
```

No graph data is required beyond creating an empty graph.

**What is the necessary configuration info needed?**
- Plain Apache AGE Docker image was enough
- Docker image in local repro: `apache/age`
- AGE extension version: `1.7.0`
- PostgreSQL version: `18.1`
- Graph name used in repro: `expr_slice_bug`
- No extra extensions or special configuration were required

**What is the command that caused the error?**
```pgsql
SELECT * FROM cypher('expr_slice_bug', $$
RETURN [1, 2, 3][1..null] AS v
$$) AS (v agtype);
```

Returned result on AGE:
```text
[2, 3]
```

**Expected behavior**
The query should return:

```text
null
```

Both Neo4j and Memgraph return `null` for the equivalent Cypher query.

**Environment (please complete the following information):**
- Version: Apache AGE `1.7.0`
- PostgreSQL: `18.1`
- Host OS: Windows
- Architecture: x86_64
- Deployment: Docker

**Additional context**
The symmetric variant with a `null` start bound shows the same issue:

```pgsql
SELECT * FROM cypher('expr_slice_bug', $$
RETURN [1, 2, 3][null..2] AS v
$$) AS (v agtype);
```

Expected result on Neo4j and Memgraph:
```text
null
```

Observed result on AGE:
```text
[1, 2]
```

A normal non-null slice behaves as expected on the same AGE instance:

```pgsql
SELECT * FROM cypher('expr_slice_bug', $$
RETURN [1, 2, 3][1..2] AS v
$$) AS (v agtype);
```

Observed result on AGE:
```text
[2]
```

There is also an internal inconsistency when both bounds are `null`:

```pgsql
SELECT * FROM cypher('expr_slice_bug', $$
RETURN [1, 2, 3][null..null] AS v
$$) AS (v agtype);
```

Neo4j and Memgraph both return:
```text
null
```

But AGE reports:
```text
ERROR: slice start and/or end is required
```

So AGE appears to treat `null` slice bounds inconsistently:
- one `null` bound is interpreted like an omitted boundary
- two `null` bounds trigger an error

Neither behavior matches the `null` result returned by Neo4j and Memgraph.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.