On Mon, 2026-09-21 at 23:48 +0200, Alberto Piai wrote:
> in an attempt to avoid wasting committer time, I decided to use an
> LLM-based tool to analyze this patch and try to come up with
> counterexamples to break my usage of IS NOT DISTINCT FROM.
> 
> It produced an example showing how IS NOT DISTINCT FROM isn't good
> enough either for my purpose.
> 
> The problem is types where some values are evaluated as equal (according
> to =), but don't have the same representation. In conjuction with a
> unique index, they could be used to put a database in an invalid state
> where rewriting operations (update ... set a = a or pg_dump/pg_restore)
> fail.
> 
> Repro:
> 
>   create table tgen.t_repro_1 (a numeric, b numeric);
>   insert into tgen.t_repro_1 values ('1.0', '1.00'), ('1.0', '1.0');
>   create unique index on tgen.t_repro_1 ((b::text));
>   alter table tgen.t_repro_1
>     add constraint chk_gen check (b is not distinct from a);
> 
>   alter table tgen.t_repro_1
>     alter b add generated using constraint chk_gen stored;
> 
>   update tgen.t_repro_1 set a = a;
>   ERROR:  duplicate key value violates unique constraint "t_repro_1_b_idx"
>   DETAIL:  Key ((b::text))=(1.0) already exists.
> 
> 
> I will have to re-think this quite a bit.

Ho, hum.  Case insensitive collations would be another example.

There is no way to write "is binary identical to" in SQL, as far as
I can tell.

Perhaps a solution would be to force the use of the data type's send
function in the check constraint:

  ALTER TABLE t_repro_1 ADD CHECK
     (numeric_send(b) IS NOT DISTINCT FROM numeric_send(a));

That would exclude data types that don't have a send function
(which is probably no big loss), and I am not certain if the send
function is required to represent the binary data exactly (it does
for the system data types, as far as I know).

Yours,
Laurenz Albe


Reply via email to