Hi hackers,

I'd like to propose a patch to identify the target column when an
assignment fails because a value exceeds a varchar(n) length limit.

For example:
```
CREATE TABLE t (
    a varchar(4),
    b varchar(2)
);

INSERT INTO t VALUES ('abcd', 'xyz');
```

Currently, this reports:
```
ERROR:  value too long for type character varying(2)
```

With the patch, it reports:
```
ERROR:  value too long for type character varying(2)
CONTEXT:  column "b" of relation "t"
```

This has been discussed previously, including:

   - "Mention column name in error messages" (2015)
   
<https://www.postgresql.org/message-id/CANfkH5k-6nNt-4cSv1vPB80nq2BZCzhFVR5O4VznYbsX0wZmow%40mail.gmail.com>
   - "Add column-name hint to log messages generated by inserts when
   varchars don't fit" (2015)
   
<https://www.postgresql.org/message-id/trinity-53b335a3-11e3-43df-b820-e28935108e6b-1438771166514%403capp-gmx-bs49>
   - BUG #19642 (2026)
   
<https://www.postgresql.org/message-id/19642-5e93d3e409f1387c%40postgresql.org>

One difficulty discussed in those threads is that the error can occur well
below the point where the target column is known, including during constant
folding. My patch attempts to address that difficulty in three parts:

   - Preserve destination identity: The patch records the destination
   relation OID and attribute number on the FuncExpr nodes representing
   assignment length coercions. The executor installs an
   ErrorContextCallback around a labeled coercion call and resolves the
   current relation and column names only when producing error context. The
   datatype functions retain their existing messages, SQLSTATEs, and
   diagnostic fields.
   - Scope error context to the coercion: The callback is installed only
   after evaluating the coercion's arguments, so failures in the source
   expression do not acquire misleading destination-column context. A
   dedicated expression opcode uses a shared C helper for both interpreted and
   LLVM execution. Constant folding reaches the same helper through
   evaluate_expr().
   - Preserve metadata across transformations: Using relation OID and
   attribute number allows the context to reflect renames and preserves the
   destination association in stored expressions. The patch preserves this
   metadata during expression simplification, retargets copied or inherited
   defaults, and prevents SQL-function inlining from discarding an annotated
   coercion's context.

Although varchar(n) motivated the change, the callback applies to labeled
assignment length coercions generally, so errors from types such as char(n)
and numeric also gain context.

Coverage is deliberately limited: domain constraint errors, failures during
input conversion before annotation, and some composite and domain-default
cases retain their existing behavior.

The patch is against master and includes regression coverage for
planning-time and runtime errors, prepared statements and renames, defaults
and generated columns, source-error attribution, and callback cleanup. All
239 core regression tests pass locally. The LLVM dispatch is implemented
and tested as well.

I'd particularly appreciate feedback on whether FuncExpr is the appropriate
place to preserve the destination identity, whether the scoped callback is
a suitable approach, and whether there are expression transformations or
stored-expression cases that need additional handling.

Patch attached.

Best,
Midhush

Attachment: v1-0001-Add-target-column-context-to-errors.patch
Description: Binary data

Reply via email to