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]

Reply via email to