mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Use standard casting mechanism to convert types in plpgsql, when possible.
plpgsql's historical method for converting datatypes during assignments was to apply the source type's output function and then the destination type's input function. Aside from being miserably inefficient in most cases, this method failed outright in many cases where a user might expect it to work; an example is that "declare x int; ... x := 3.9;" would fail, not round the value to 4. Instead, let's convert by applying the appropriate assignment cast whenever there is one. To avoid breaking compatibility unnecessarily, fall back to the I/O conversion method if there is no assignment cast. So far as I can tell, there is just one case where this method produces a different result than the old code in a case where the old code would not have thrown an error. That is assignment of a boolean value to a string variable (type text, varchar, or bpchar); the old way gave boolean's output representation, ie 't'/'f', while the new way follows the behavior of the bool-to-text cast and so gives 'true' or 'false'. This will need to be called out as an incompatibility in the 9.5 release notes. Aside from handling many conversion cases more sanely, this method is often significantly faster than the old way. In part that's because of more effective caching of the conversion info.
This commit is contained in:
@ -881,13 +881,14 @@ PREPARE <replaceable>statement_name</>(integer, integer) AS SELECT $1 < $2;
|
||||
|
||||
<para>
|
||||
If the expression's result data type doesn't match the variable's
|
||||
data type, or the variable has a specific size/precision
|
||||
(like <type>char(20)</type>), the result value will be implicitly
|
||||
converted by the <application>PL/pgSQL</application> interpreter using
|
||||
the result type's output-function and
|
||||
the variable type's input-function. Note that this could potentially
|
||||
result in run-time errors generated by the input function, if the
|
||||
string form of the result value is not acceptable to the input function.
|
||||
data type, the value will be coerced as though by an assignment cast
|
||||
(see <xref linkend="typeconv-query">). If no assignment cast is known
|
||||
for the pair of data types involved, the <application>PL/pgSQL</>
|
||||
interpreter will attempt to convert the result value textually, that is
|
||||
by applying the result type's output function followed by the variable
|
||||
type's input function. Note that this could result in run-time errors
|
||||
generated by the input function, if the string form of the result value
|
||||
is not acceptable to the input function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -844,9 +844,10 @@ Check for an exact match with the target.
|
||||
|
||||
<step performance="required">
|
||||
<para>
|
||||
Otherwise, try to convert the expression to the target type. This will succeed
|
||||
if there is a registered cast between the two types.
|
||||
If the expression is an unknown-type literal, the contents of
|
||||
Otherwise, try to convert the expression to the target type. This is possible
|
||||
if an <firstterm>assignment cast</> between the two types is registered in the
|
||||
<structname>pg_cast</> catalog (see <xref linkend="sql-createcast">).
|
||||
Alternatively, if the expression is an unknown-type literal, the contents of
|
||||
the literal string will be fed to the input conversion routine for the target
|
||||
type.
|
||||
</para>
|
||||
|
Reference in New Issue
Block a user