diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index a339abf17b6..c33e3355826 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -1095,8 +1095,12 @@ int4mod(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } - /* SELECT ((-2147483648)::int4) % (-1); causes a floating point exception */ - if (arg1 == INT_MIN && arg2 == -1) + /* + * Some machines throw a floating-point exception for INT_MIN % -1, which + * is a bit silly since the correct answer is perfectly well-defined, + * namely zero. + */ + if (arg2 == -1) PG_RETURN_INT32(0); /* No overflow is possible */ @@ -1119,6 +1123,15 @@ int2mod(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } + /* + * Some machines throw a floating-point exception for INT_MIN % -1, which + * is a bit silly since the correct answer is perfectly well-defined, + * namely zero. (It's not clear this ever happens when dealing with + * int16, but we might as well have the test for safety.) + */ + if (arg2 == -1) + PG_RETURN_INT16(0); + /* No overflow is possible */ PG_RETURN_INT16(arg1 % arg2); diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index 0e599565726..59c110b0b30 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -649,6 +649,14 @@ int8mod(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } + /* + * Some machines throw a floating-point exception for INT64_MIN % -1, + * which is a bit silly since the correct answer is perfectly + * well-defined, namely zero. + */ + if (arg2 == -1) + PG_RETURN_INT64(0); + /* No overflow is possible */ PG_RETURN_INT64(arg1 % arg2);