cockroachdb / cockroach

CockroachDB — the cloud native, distributed SQL database designed for high availability, effortless scale, and control over data placement.
https://www.cockroachlabs.com
Other
29.9k stars 3.78k forks source link

plpgsql: type coercion truncates when value is too wide #115385

Open DrewKimball opened 9 months ago

DrewKimball commented 9 months ago

This issue tracks a difference between postgres and CRDB when coercing a PLpgSQL expression into a type that is too narrow. For context: Explicit casts succeed, and truncate the value:

postgres=# SELECT ('foo'::TEXT)::CHAR;
 bpchar
--------
 f
(1 row)

Assignment casts fail with an error:

postgres=# CREATE TABLE t (c CHAR);
CREATE TABLE
postgres=# INSERT INTO t VALUES ('foo'::TEXT);
ERROR:  value too long for type character(1)

Finally, PLpgSQL type coercion succeeds, but does not truncate:

postgres=# CREATE OR REPLACE FUNCTION f() RETURNS CHAR AS $$
  BEGIN
    RETURN 'abcd'::TEXT;
  END
$$ LANGUAGE PLpgSQL;
CREATE FUNCTION
postgres=# SELECT f();
  f
------
 abcd
(1 row)

CRDB matches behavior for the first two cases, but truncates the value for the last case:

CREATE OR REPLACE FUNCTION f() RETURNS CHAR AS $$
  BEGIN
    RETURN 'abcd'::TEXT;
  END
$$ LANGUAGE PLpgSQL;

query T
SELECT f();
----
a

Jira issue: CRDB-34004

DrewKimball commented 9 months ago

Snippet from postgres docs:

If the expression's result data type doesn't match the variable's data type, the value will be coerced as though by an assignment cast (see [Section 10.4](https://www.postgresql.org/docs/current/typeconv-query.html)). If no assignment cast is known for the pair of data types involved, the 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.

Relevant comment in postgres source: https://github.com/postgres/postgres/blob/e722846daf4a37797ee39bc8ca3e78a4ef437f51/src/pl/plpgsql/src/pl_exec.c#L7856-L7870