Thread: [GENERAL] upsert: is there a shortcut?

[GENERAL] upsert: is there a shortcut?

From
Daniele Varrazzo
Date:
Hello,

it seems not, but I feel like asking.

Is there a way to express a statement like "if you have a conflict on
insert replace all the values in the conflicting record" without
specifying all the fields explicitly? I.e. in a replication system
(where occasional accidents mean replication may restart slightly
before what's already on the target) I generate statements like:

insert into "order_log" ("id","cr_date","order_id","message")
    values (%s, %s, %s, %s)
    on conflict ("id") do update
    set ("cr_date","order_id","message") =
        (excluded."cr_date",excluded."order_id",excluded."message")

Is there a way to avoid replicating the list of fields and use instead
something like (new.*) = (excluded.*) as one could do in a trigger?
(that would also imply an (id = excluded.id but it seems harmless).

It seems to me an use case common enough that some syntactic help...
would help. "do update *"? "do update (target.*) = (excluded.*)"?


-- Daniele


Re: [GENERAL] upsert: is there a shortcut?

From
Peter Geoghegan
Date:
Daniele Varrazzo <daniele.varrazzo@gmail.com> wrote:
>Is there a way to avoid replicating the list of fields and use instead
>something like (new.*) = (excluded.*) as one could do in a trigger?
>(that would also imply an (id = excluded.id but it seems harmless).

This is certainly something that I've seen requests for before. I tend
to think that using such a feature would be a bit like using "SELECT *"
in production: something that provides an immediate convenience, but
creates unforeseen problems.

As an example, imagine if someone adds an "inserted_at" column, which
has "now()" as its default value. Today, a user can be pretty confident
that no existing or future query is going to change that itself, because
in order for that to happen the query would have to be written with the
explicit intention of updating "inserted_at". That property would go
away with the feature you describe. Subtleties like this could easily be
missed.

--
Peter Geoghegan