1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Add casts from int4 and int8 to numeric.

Joey Adams, per gripe from Ramanujam.  Review by myself and Tom Lane.
This commit is contained in:
Robert Haas
2011-04-05 09:35:43 -04:00
parent 88f32b7ca2
commit f5e524d92b
8 changed files with 161 additions and 7 deletions

View File

@ -26,6 +26,7 @@
#include "libpq/pqformat.h"
#include "utils/builtins.h"
#include "utils/cash.h"
#include "utils/int8.h"
#include "utils/numeric.h"
#include "utils/pg_locale.h"
@ -92,7 +93,6 @@ num_word(Cash value)
return buf;
} /* num_word() */
/* cash_in()
* Convert a string to a cash data type.
* Format is [$]###[,]###[.##]
@ -938,3 +938,63 @@ numeric_cash(PG_FUNCTION_ARGS)
PG_RETURN_CASH(result);
}
/* int4_cash()
* Convert int4 (int) to cash
*/
Datum
int4_cash(PG_FUNCTION_ARGS)
{
int32 amount = PG_GETARG_INT32(0);
Cash result;
int fpoint;
int64 scale;
int i;
struct lconv *lconvert = PGLC_localeconv();
/* see comments about frac_digits in cash_in() */
fpoint = lconvert->frac_digits;
if (fpoint < 0 || fpoint > 10)
fpoint = 2;
/* compute required scale factor */
scale = 1;
for (i = 0; i < fpoint; i++)
scale *= 10;
/* compute amount * scale, checking for overflow */
result = DatumGetInt64(DirectFunctionCall2(int8mul, Int64GetDatum(amount),
Int64GetDatum(scale)));
PG_RETURN_CASH(result);
}
/* int8_cash()
* Convert int8 (bigint) to cash
*/
Datum
int8_cash(PG_FUNCTION_ARGS)
{
int64 amount = PG_GETARG_INT64(0);
Cash result;
int fpoint;
int64 scale;
int i;
struct lconv *lconvert = PGLC_localeconv();
/* see comments about frac_digits in cash_in() */
fpoint = lconvert->frac_digits;
if (fpoint < 0 || fpoint > 10)
fpoint = 2;
/* compute required scale factor */
scale = 1;
for (i = 0; i < fpoint; i++)
scale *= 10;
/* compute amount * scale, checking for overflow */
result = DatumGetInt64(DirectFunctionCall2(int8mul, Int64GetDatum(amount),
Int64GetDatum(scale)));
PG_RETURN_CASH(result);
}

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201103201
#define CATALOG_VERSION_NO 201104051
#endif

View File

@ -126,6 +126,8 @@ DATA(insert ( 1700 700 1745 i f ));
DATA(insert ( 1700 701 1746 i f ));
DATA(insert ( 790 1700 3823 a f ));
DATA(insert ( 1700 790 3824 a f ));
DATA(insert ( 23 790 3811 a f ));
DATA(insert ( 20 790 3812 a f ));
/* Allow explicit coercions between int4 and bool */
DATA(insert ( 23 16 2557 e f ));

View File

@ -971,6 +971,10 @@ DATA(insert OID = 3823 ( numeric PGNSP PGUID 12 1 0 0 f f f t f s 1 0 1700
DESCR("convert money to numeric");
DATA(insert OID = 3824 ( money PGNSP PGUID 12 1 0 0 f f f t f s 1 0 790 "1700" _null_ _null_ _null_ _null_ numeric_cash _null_ _null_ _null_ ));
DESCR("convert numeric to money");
DATA(insert OID = 3811 ( money PGNSP PGUID 12 1 0 0 f f f t f s 1 0 790 "23" _null_ _null_ _null_ _null_ int4_cash _null_ _null_ _null_ ));
DESCR("convert int4 to money");
DATA(insert OID = 3812 ( money PGNSP PGUID 12 1 0 0 f f f t f s 1 0 790 "20" _null_ _null_ _null_ _null_ int8_cash _null_ _null_ _null_ ));
DESCR("convert int8 to money");
/* OIDS 900 - 999 */

View File

@ -67,4 +67,7 @@ extern Datum cash_words(PG_FUNCTION_ARGS);
extern Datum cash_numeric(PG_FUNCTION_ARGS);
extern Datum numeric_cash(PG_FUNCTION_ARGS);
extern Datum int4_cash(PG_FUNCTION_ARGS);
extern Datum int8_cash(PG_FUNCTION_ARGS);
#endif /* CASH_H */

View File

@ -185,3 +185,66 @@ SELECT * FROM money_data;
$123.46
(1 row)
-- Cast int4/int8 to money
SELECT 1234567890::money;
money
-------------------
$1,234,567,890.00
(1 row)
SELECT 12345678901234567::money;
money
----------------------------
$12,345,678,901,234,567.00
(1 row)
SELECT 123456789012345678::money;
ERROR: bigint out of range
SELECT 9223372036854775807::money;
ERROR: bigint out of range
SELECT (-12345)::money;
money
-------------
-$12,345.00
(1 row)
SELECT (-1234567890)::money;
money
--------------------
-$1,234,567,890.00
(1 row)
SELECT (-12345678901234567)::money;
money
-----------------------------
-$12,345,678,901,234,567.00
(1 row)
SELECT (-123456789012345678)::money;
ERROR: bigint out of range
SELECT (-9223372036854775808)::money;
ERROR: bigint out of range
SELECT 1234567890::int4::money;
money
-------------------
$1,234,567,890.00
(1 row)
SELECT 12345678901234567::int8::money;
money
----------------------------
$12,345,678,901,234,567.00
(1 row)
SELECT (-1234567890)::int4::money;
money
--------------------
-$1,234,567,890.00
(1 row)
SELECT (-12345678901234567)::int8::money;
money
-----------------------------
-$12,345,678,901,234,567.00
(1 row)

View File

@ -56,3 +56,18 @@ SELECT * FROM money_data;
DELETE FROM money_data;
INSERT INTO money_data VALUES ('$123.459');
SELECT * FROM money_data;
-- Cast int4/int8 to money
SELECT 1234567890::money;
SELECT 12345678901234567::money;
SELECT 123456789012345678::money;
SELECT 9223372036854775807::money;
SELECT (-12345)::money;
SELECT (-1234567890)::money;
SELECT (-12345678901234567)::money;
SELECT (-123456789012345678)::money;
SELECT (-9223372036854775808)::money;
SELECT 1234567890::int4::money;
SELECT 12345678901234567::int8::money;
SELECT (-1234567890)::int4::money;
SELECT (-12345678901234567)::int8::money;