Skip to content

Commit 0e3e8fb

Browse files
committed
Fix corner-case 64-bit integer subtraction bug on some platforms.
When computing "0 - INT64_MIN", most platforms would report an overflow error, which is correct. However, platforms without integer overflow builtins or 128-bit integers would fail to spot the overflow, and incorrectly return INT64_MIN. Back-patch to all supported branches. Patch be me. Thanks to Jian He for initial investigation, and Laurenz Albe and Tom Lane for review. Discussion: https://postgr.es/m/CAEZATCUNK-AZSD0jVdgkk0N%3DNcAXBWeAEX-QU9AnJPensikmdQ%40mail.gmail.com
1 parent a7db71e commit 0e3e8fb

File tree

3 files changed

+8
-1
lines changed

3 files changed

+8
-1
lines changed

src/include/common/int.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,12 @@ pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
200200
*result = (int64) res;
201201
return false;
202202
#else
203+
/*
204+
* Note: overflow is also possible when a == 0 and b < 0 (specifically,
205+
* when b == PG_INT64_MIN).
206+
*/
203207
if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) ||
204-
(a > 0 && b < 0 && a > PG_INT64_MAX + b))
208+
(a >= 0 && b < 0 && a > PG_INT64_MAX + b))
205209
{
206210
*result = 0x5EED; /* to avoid spurious warnings */
207211
return true;

src/test/regress/expected/int8.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,8 @@ select -('-9223372036854775807'::int8);
679679

680680
select -('-9223372036854775808'::int8);
681681
ERROR: bigint out of range
682+
select 0::int8 - '-9223372036854775808'::int8;
683+
ERROR: bigint out of range
682684
select '9223372036854775800'::int8 + '9223372036854775800'::int8;
683685
ERROR: bigint out of range
684686
select '-9223372036854775800'::int8 + '-9223372036854775800'::int8;

src/test/regress/sql/int8.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ select '9223372036854775808'::int8;
132132

133133
select -('-9223372036854775807'::int8);
134134
select -('-9223372036854775808'::int8);
135+
select 0::int8 - '-9223372036854775808'::int8;
135136

136137
select '9223372036854775800'::int8 + '9223372036854775800'::int8;
137138
select '-9223372036854775800'::int8 + '-9223372036854775800'::int8;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy