diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2015-03-04 11:04:30 -0500 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2015-03-04 11:04:30 -0500 |
| commit | 1345cc67bbb014209714af32b5681b1e11eaf964 (patch) | |
| tree | 5ded223b7f2a5d1e9a7ea408d8b904a341edc328 /doc/src | |
| parent | b9896198cfbc1b0cd0c631d2af72ffe34bd4c7e5 (diff) | |
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.
Diffstat (limited to 'doc/src')
| -rw-r--r-- | doc/src/sgml/plpgsql.sgml | 15 | ||||
| -rw-r--r-- | doc/src/sgml/typeconv.sgml | 7 |
2 files changed, 12 insertions, 10 deletions
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 69a0885f2aa..158d9d2f223 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -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> diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml index ed377722884..c031c01ed35 100644 --- a/doc/src/sgml/typeconv.sgml +++ b/doc/src/sgml/typeconv.sgml @@ -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> |
