money type's overflow handling is woefully incomplete - Mailing list pgsql-hackers

From Andres Freund
Subject money type's overflow handling is woefully incomplete
Date
Msg-id 20171211225032.2phzzekso4337xmy@alap3.anarazel.de
Whole thread Raw
Responses Re: money type's overflow handling is woefully incomplete
List pgsql-hackers
Hi,

The money type has overflow handling in its input function:
Datum
cash_in(PG_FUNCTION_ARGS)
...
            Cash        newvalue = (value * 10) - (*s - '0');

            if (newvalue / 10 != value)
                ereport(ERROR,
                        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                         errmsg("value \"%s\" is out of range for type %s",
                                str, "money")));

but not in a lot of other relevant places:

Datum
cash_pl(PG_FUNCTION_ARGS)
{
    Cash        c1 = PG_GETARG_CASH(0);
    Cash        c2 = PG_GETARG_CASH(1);
    Cash        result;

    result = c1 + c2;

    PG_RETURN_CASH(result);
}

Same with cash_mi, int8_mul_cash, cash_div_int8, etc.

cash_out doesn't have a plain overflow, but:
    if (value < 0)
    {
        /* make the amount positive for digit-reconstruction loop */
        value = -value;

doesn't reliably work if value is PG_INT64_MIN.


This leads to fun like:

postgres[2002][1]=# SELECT '92233720368547758.07'::money+'0.1';
┌─────────────────────────────┐
│          ?column?           │
├─────────────────────────────┤
│ -$92,233,720,368,547,757.99 │
└─────────────────────────────┘



Greetings,

Andres Freund


pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: [HACKERS] static assertions in C++
Next
From: Michael Paquier
Date:
Subject: Re: Testing Extension Upgrade Paths