Skip to content

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

@Silence6666668

Description

@Silence6666668

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?

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?

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

Returned result on AGE:

[2, 3]

Expected behavior
The query should return:

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:

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

Expected result on Neo4j and Memgraph:

null

Observed result on AGE:

[1, 2]

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

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

Observed result on AGE:

[2]

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

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

Neo4j and Memgraph both return:

null

But AGE reports:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions