You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@age.apache.org by "hkjiang26 (via GitHub)" <gi...@apache.org> on 2026/09/04 07:45:45 UTC

[I] toInteger() silently clamps out-of-range values to INT64_MAX/MIN instead of raising an error [age]

hkjiang26 opened a new issue, #2564:
URL: https://github.com/apache/age/issues/2564

   **AGE Version:** apache/age master @ cfd3b634 (2026-08-14), extension 1.8.0, on PostgreSQL 18.6
   
   **Installation Method:** Docker
   
   **API:** Cypher
   
   ### Steps to reproduce
   
   1. On a fresh graph, run:
   
   ```sql
   LOAD 'age';
   SET search_path = ag_catalog, public;
   SELECT * FROM create_graph('test_overflow');
   SELECT * FROM cypher('test_overflow', $$ RETURN toInteger('9223372036854775808') $$) AS (r agtype);
   ```
   
   ```
             r
   ---------------------
    9223372036854775807   -- INT64_MAX, silently clamped
   ```
   
   `toInteger('-9223372036854775809')` returns `-9223372036854775808` (INT64_MIN), and arbitrarily large inputs (`'99999999999999999999999999'`) clamp the same way.
   
   Related form (also verified): a numeric **literal** that overflows int64 is silently converted to a float with loss of precision — `RETURN 9223372036854775808` yields `9.223372036854776e+18` (and `-9223372036854775809` yields the negative float) instead of erroring. No error or warning in either case.
   
   ### Expected behavior
   
   Out-of-range input should raise an error or return null. The host database's own integer cast rejects the same value:
   
   ```sql
   SELECT '9223372036854775808'::int8;
   -- ERROR:  value "9223372036854775808" is out of range for type bigint
   ```
   
   ### Actual behavior
   
   The value is silently clamped to the nearest 64-bit bound and returned as a normal result — silent data corruption (e.g. sums, comparisons and property writes then operate on the wrong number).
   
   Root cause: the string argument is re-parsed as an agtype scalar by `agtype_in_scalar` (`src/backend/utils/adt/agtype.c:1076`), which calls PostgreSQL's `pg_strtoint64()` **without checking `errno`**. `pg_strtoint64()` saturates out-of-range input to `INT64_MAX`/`INT64_MIN`; PostgreSQL's own `int8in()` makes the same call but checks `errno` and raises "out of range" (which is why `::int8` rejects the same string). `agtype_to_int8` then returns the already-clamped value unchanged.
   
   


-- 
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: dev-unsubscribe@age.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org