Re: BUG #18240: Undefined behaviour in cash_mul_flt8() and friends
От | Alexander Lakhin |
---|---|
Тема | Re: BUG #18240: Undefined behaviour in cash_mul_flt8() and friends |
Дата | |
Msg-id | ab338370-b941-9271-efbe-037d7f2218b7@gmail.com обсуждение исходный текст |
Ответ на | Re: BUG #18240: Undefined behaviour in cash_mul_flt8() and friends (Tom Lane <tgl@sss.pgh.pa.us>) |
Список | pgsql-bugs |
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
В списке pgsql-bugs по дате отправления: