shulei5831sl opened a new issue, #2471:
URL: https://github.com/apache/age/issues/2471
### Apache AGE version
Observed on Docker image:
```text
docker pull apache/age:latest
Pulled: 2026-07-09
Apache AGE: PG18
Endpoint:
postgres://127.0.0.1:5432
```
### How are you accessing AGE
psql and Python `psycopg2` driver
### Environment
* Host OS: Linux `5.4.0-216-generic`
* Deployment: Docker `apache/age:latest`
* Query interface: psql and psycopg2
* Query language: Cypher via `ag_catalog.cypher`
* Configuration: default AGE on PostgreSQL 18, no extensions beyond AGE
* Differential comparison targets:
* Neo4j `2026.05.0`
* PostgreSQL native arithmetic
### Description
AGE Cypher integer arithmetic silently wraps around on 64-bit overflow
instead of failing the query.
For example:
```pgsql
SELECT * FROM cypher('test_graph', $$
RETURN 9223372036854775807 + 1 AS r
$$) AS (r agtype);
```
AGE returns:
```text
r
---------------------
-9223372036854775808
```
This is a two's-complement wraparound from `INT64_MAX` to `INT64_MIN`.
The mathematical result is outside the signed 64-bit integer range, so the
query should fail instead of returning another valid-looking integer value.
PostgreSQL native arithmetic rejects the same operation with `bigint out of
range`, and Neo4j also rejects the equivalent Cypher expression with an
arithmetic overflow error.
### Setup
```pgsql
LOAD 'age';
SET search_path = ag_catalog, '$user', public;
SELECT * FROM ag_catalog.create_graph('test_graph');
```
### Minimal reproduction
```pgsql
SELECT * FROM cypher('test_graph', $$
RETURN 9223372036854775807 + 1 AS r
$$) AS (r agtype);
```
### Expected behavior
The query should fail with an integer overflow error.
PostgreSQL native arithmetic:
```pgsql
SELECT 9223372036854775807::bigint + 1::bigint;
```
returns:
```text
ERROR: bigint out of range
```
Neo4j `2026.05.0` also rejects:
```cypher
RETURN 9223372036854775807 + 1 AS r;
```
with an arithmetic overflow/client error.
### Actual behavior
AGE returns a wrapped value:
```text
r
---------------------
-9223372036854775808
```
No error or warning is reported.
### Additional affected expressions
```pgsql
SELECT * FROM cypher('test_graph', $$
RETURN 9223372036854775807 * 2 AS r
$$) AS (r agtype);
```
AGE returns:
```text
r = -2
```
Expected: overflow error.
```pgsql
SELECT * FROM cypher('test_graph', $$
RETURN -9223372036854775808 - 1 AS r
$$) AS (r agtype);
```
AGE returns:
```text
r = 9223372036854775807
```
Expected: overflow error.
### Control query
Arithmetic within range works correctly:
```pgsql
SELECT * FROM cypher('test_graph', $$
RETURN 1 + 1 AS r
$$) AS (r agtype);
```
AGE returns:
```text
r = 2
```
### Impact: silent wrong results
The overflowed value participates in further query evaluation.
```pgsql
SELECT * FROM cypher('test_graph', $$
RETURN 9223372036854775807 + 1 > 0 AS r
$$) AS (r agtype);
```
AGE returns:
```text
r = false
```
This result is derived from the wrapped negative value, not from the
mathematical result of the expression.
A write context can also persist the wrapped value:
```pgsql
SELECT * FROM cypher('test_graph', $$
CREATE (:Overflow {v: 9223372036854775807 + 1})
RETURN 1 AS ok
$$) AS (ok agtype);
SELECT * FROM cypher('test_graph', $$
MATCH (n:Overflow)
RETURN n.v AS v
$$) AS (v agtype);
```
AGE returns:
```text
v = -9223372036854775808
```
Expected: the write query should fail before persisting an overflowed value.
### Cross-engine comparison
| Engine | `MAX_INT + 1` |
`MAX_INT * 2` | `MIN_INT - 1` |
| -------------------------- | ---------------------------: |
---------------------------: | ---------------------------: |
| Neo4j `2026.05.0` | ArithmeticError |
ArithmeticError | ArithmeticError |
| PostgreSQL native `bigint` | `ERROR: bigint out of range` | `ERROR: bigint
out of range` | `ERROR: bigint out of range` |
| Apache AGE Cypher | `-9223372036854775808` |
`-2` | `9223372036854775807` |
### Why this looks like a bug
AGE documents `agtype` integer as a 64-bit field with the signed 64-bit
range:
```text
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
```
and states that attempts to store values outside this range result in an
error.
The tested Cypher expressions produce mathematical results outside that
range. Instead of rejecting them, AGE returns wrapped in-range values. This
behavior is consistent with unchecked `int64` arithmetic.
### Summary
64-bit integer arithmetic overflow should fail the query. Silently wrapping
the result changes arithmetic semantics, can produce wrong predicates, and can
persist incorrect property values.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]