diff --git a/regress/expected/expr.out b/regress/expected/expr.out index 806a6f65c..5db1d1719 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -26,6 +26,11 @@ NOTICE: graph "expr" has been created (1 row) +-- Integer division must report bigint overflow instead of raising SIGFPE. +SELECT * FROM cypher('expr', $$ +RETURN (-9223372036854775807 - 1) / -1 +$$) AS (r agtype); +ERROR: bigint out of range -- -- map literal -- diff --git a/regress/sql/expr.sql b/regress/sql/expr.sql index d4d900a1c..34b80ae04 100644 --- a/regress/sql/expr.sql +++ b/regress/sql/expr.sql @@ -23,6 +23,11 @@ SET search_path TO ag_catalog; SELECT * FROM create_graph('expr'); +-- Integer division must report bigint overflow instead of raising SIGFPE. +SELECT * FROM cypher('expr', $$ +RETURN (-9223372036854775807 - 1) / -1 +$$) AS (r agtype); + -- -- map literal -- diff --git a/src/backend/utils/adt/agtype_ops.c b/src/backend/utils/adt/agtype_ops.c index 9a1c4033e..480ca3ea0 100644 --- a/src/backend/utils/adt/agtype_ops.c +++ b/src/backend/utils/adt/agtype_ops.c @@ -795,6 +795,14 @@ Datum agtype_div(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } + if (agtv_lhs->val.int_value == PG_INT64_MIN && + agtv_rhs->val.int_value == -1) + { + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("bigint out of range"))); + PG_RETURN_NULL(); + } + agtv_result.type = AGTV_INTEGER; agtv_result.val.int_value = agtv_lhs->val.int_value / agtv_rhs->val.int_value;