Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
f5e524d9
Commit
f5e524d9
authored
Apr 05, 2011
by
Robert Haas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add casts from int4 and int8 to numeric.
Joey Adams, per gripe from Ramanujam. Review by myself and Tom Lane.
parent
88f32b7c
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
161 additions
and
7 deletions
+161
-7
doc/src/sgml/datatype.sgml
doc/src/sgml/datatype.sgml
+12
-5
src/backend/utils/adt/cash.c
src/backend/utils/adt/cash.c
+61
-1
src/include/catalog/catversion.h
src/include/catalog/catversion.h
+1
-1
src/include/catalog/pg_cast.h
src/include/catalog/pg_cast.h
+2
-0
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+4
-0
src/include/utils/cash.h
src/include/utils/cash.h
+3
-0
src/test/regress/expected/money.out
src/test/regress/expected/money.out
+63
-0
src/test/regress/sql/money.sql
src/test/regress/sql/money.sql
+15
-0
No files found.
doc/src/sgml/datatype.sgml
View file @
f5e524d9
...
...
@@ -886,15 +886,22 @@ ALTER SEQUENCE <replaceable class="parameter">tablename</replaceable>_<replaceab
</para>
<para>
Values of the <type>numeric</type> data type can be cast to
<type>money</type>. Other numeric types can be converted to
<type>money</type> by casting to <type>numeric</type> first, for example:
Values of the <type>numeric</type>, <type>int</type>, and
<type>bigint</type> data types can be cast to <type>money</type>.
Conversion from the <type>real</type> and <type>double precision</type>
data types can be done by casting to <type>numeric</type> first, for
example:
<programlisting>
SELECT
1234
::numeric::money;
SELECT
'12.34'::float8
::numeric::money;
</programlisting>
However, this is not recommended. Floating point numbers should not be
used to handle money due to the potential for rounding errors.
</para>
<para>
A <type>money</type> value can be cast to <type>numeric</type> without
loss of precision. Conversion to other types could potentially lose
precision, and
it must be done in two stages, for example
:
precision, and
must also be done in two stages
:
<programlisting>
SELECT '52093.89'::money::numeric::float8;
</programlisting>
...
...
src/backend/utils/adt/cash.c
View file @
f5e524d9
...
...
@@ -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
);
}
src/include/catalog/catversion.h
View file @
f5e524d9
...
...
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 20110
320
1
#define CATALOG_VERSION_NO 20110
405
1
#endif
src/include/catalog/pg_cast.h
View file @
f5e524d9
...
...
@@ -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
));
...
...
src/include/catalog/pg_proc.h
View file @
f5e524d9
...
...
@@ -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 */
...
...
src/include/utils/cash.h
View file @
f5e524d9
...
...
@@ -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 */
src/test/regress/expected/money.out
View file @
f5e524d9
...
...
@@ -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)
src/test/regress/sql/money.sql
View file @
f5e524d9
...
...
@@ -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
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment