Hello Michael and Tom,
11.12.2023 18:05, Tom Lane wrote:
> Michael Paquier <michael@paquier.xyz> writes:
>> On Mon, Dec 11, 2023 at 06:00:02AM +0000, PG Bug reporting form wrote:
>>> The following multiplication:
>>> SELECT 1_000_000_000::money * 1_000_000_000::float8;
>>> gives the incorrect result:
>>> -$92,233,720,368,547,758.08
>> Yep, good catch. Reproduced here.
> Yeah, approximately none of cash.c pays any attention to the risks
> of overflow/underflow. Improving that situation would be a good
> finger exercise for some aspiring hacker, perhaps. Although I bet
> somebody will ask again why it is that we continue to support the
> money type.
Thank you for looking at that!
I've tried a simple operator-testing query (with already known problematic
operators spelled out):
SELECT format('SELECT ''2000000000''::%s %s ''2000000000''::%s;',
tl.typname, oprname, tr.typname) FROM pg_operator
INNER JOIN pg_type tl ON tl.oid = oprleft
INNER JOIN pg_type tr ON tr.oid = oprright WHERE (
/* 2000000000 xxx 2000000000 */
NOT(tl.typname = 'money' AND oprname = '*' AND tr.typname = 'float4') AND
NOT(tl.typname = 'float4' AND oprname = '*' AND tr.typname = 'money') AND
NOT(tl.typname = 'money' AND oprname = '*' AND tr.typname = 'float8') AND
NOT(tl.typname = 'float8' AND oprname = '*' AND tr.typname = 'money') AND
NOT(tl.typname = 'int4' AND oprname = '<<' AND tr.typname = 'int4') AND
NOT(tl.typname = 'int4' AND oprname = '>>' AND tr.typname = 'int4') AND
NOT(tl.typname = 'int8' AND oprname = '<<' AND tr.typname = 'int4') AND
NOT(tl.typname = 'int8' AND oprname = '>>' AND tr.typname = 'int4') AND
/* 2000000000 xxx 0.0000000002 */
NOT(tl.typname = 'money' AND oprname = '/' AND tr.typname = 'float4') AND
NOT(tl.typname = 'money' AND oprname = '/' AND tr.typname = 'float8') AND
/* 32767 xxx 32767 */
NOT(tl.typname = 'int2' AND oprname = '<<' AND tr.typname = 'int4') AND
NOT(tl.typname = 'int2' AND oprname = '>>' AND tr.typname = 'int4')
)
\gexec
and found no new UBSan-detected anomalies with "extraordinary" numbers.
Best regards,
Alexander