so we need to handle numeric source types with fractional points with
special care.
currently, this applies only to numeric, float4, and float8.
(hope this is all the corner case we need to catch...)
I'm fairly certain that the committers won't like us special-casing the internal cast functions, as we would have to maintain these special cases as new core types are added, and it still bypasses the defined cast function for user-defined types, which could have similar issues similar to the rounding issue.
I think the way forward here is either to:
1. add a second function definition to CAST. The potential syntax forr a second function gets clumsy, but might look something like this:
CREATE CAST (source_type AS target_type)
WITH FUNCTION function_name [ (argument_type [, ...]) ]
[ AS ASSIGNMENT | AS IMPLICIT ]
[
WITH SAFE FUNCTION function_name [ (argument_type [, ...]) ]
[ AS ASSIGNMENT | AS IMPLICIT ]
]
That doesn't seem right to me, it seems easier to:
2. Modify the CAST definition to indicate whether the existing cast function has the regular function signature or a -Safe one. In cases where a CAST has a defined function but the safe flag is turned off, we would have to fail the query with an error like "Defined CAST function from srctype to desttype is not error-safe".
This would involve changing the syntax of CREATE CAST by adding an option SAFE, or ERROR SAFE, or similar:
CREATE CAST (source_type AS target_type)
WITH [SAFE] FUNCTION function_name [ (argument_type [, ...]) ]
[ AS ASSIGNMENT | AS IMPLICIT ]
We would add a new value to pg_cast.castmethod, 's' for "safe".
We could refactor all the numeric types to use the modified functions, so no special-case code there anymore, and it gives extension writers an incentive to (eventually) make their own cast functions error-safe.
While method 2 seems a lot cleaner, there may be a performance regression in the now error-safe typecast functions. If so, that might tip the balance to having two functions defined.