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 по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Re: daterange constructor vs cast
Следующее
От: Kyotaro Horiguchi
Дата:
Сообщение: Re: BUG #18241: PushTransaction may cause Standby to execute ItemIdMarkDead