Is there any way to do wrapping operations (addition, multiplication, SUM) on bigint columns?
By this I mean the standard method of wrapping addition in other programming languages on integer types of a fixed bit-length, e.g. in C++
#include <cstdint>
#include <iostream>
int main() {
int64_t t = 9223372036854775807;
t += 1;
std::cout << t << '\n'; // prints -9223372036854775808
}
In PostgreSQL, I get an overflow:
SELECT 9223372036854775807 + 1;
ERROR: bigint out of range
For aggregation functions in Postgres, it seems the standard behavior is to cast to variable-length numbers, and then calculate the sum, e.g.
SELECT pg_typeof(SUM(id)) FROM (VALUES(9223372036854775807), (9223372036854775807)) AS t(id);
pg_typeof
-----------
numeric
(1 row)
This also works for regular numbers:
SELECT 9223372036854775807::numeric + 1;
?column?
---------------------
9223372036854775808
(1 row)
I could of course do a modulo operation here and get the result I want, but going via variable-length numbers will be a lot slower than pure 64-bit operations.
Is there any way to force standard wrapping 64-bit integer operations?
BIGINTas an integral value within a range: operations that would result in values outside of that range cause an exception to be raised. When dealing with quantiities, raising an overflow exceptiion is preferable to returning erroneous results. There is no way to force PostgreSQL to wrap integer operations.BIGINTis more than just a collection of 64 bits: it is a signed integral quantity.BIGINTvalues don't have associated statuses so overflows are signaled by raising an exception. This is analogous to a CPU raising a segmentation fault when an address references a location outside of the permitted range.