From: | Jeremy Finzel <finzelj(at)gmail(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | PostgreSQL mailing lists <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: UPSERT on view does not find constraint by name |
Date: | 2019-10-18 12:59:04 |
Message-ID: | CAMa1XUgY6-Xzv5B-eJQhUtdt1wbtNNaPch8EU8dHw_7Z4+cJBg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Fri, Oct 18, 2019 at 3:42 AM Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Jeremy Finzel <finzelj(at)gmail(dot)com> writes:
> > I'm not sure if this can be considered a bug or not, but it is perhaps
> > unexpected. I found that when using a view that is simply select * from
> > table, then doing INSERT ... ON CONFLICT ON CONSTRAINT constraint_name on
> > that view, it does not find the constraint and errors out. But it does
> > find the constraint if one lists the columns instead.
>
> I'm confused by this report. The view wouldn't have any constraints,
> and experimenting shows that the parser won't let you name a
> constraint of the underlying table here. So would you provide a
> concrete example of what you're talking about?
>
> regards, tom lane
>
Apologies for the lack of clarity. Here is a simple example of what I mean:
test=# CREATE TEMP TABLE foo (id int primary key);
CREATE TABLE
test=# \d foo
Table "pg_temp_4.foo"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | not null |
Indexes:
"foo_pkey" PRIMARY KEY, btree (id)
test=# CREATE VIEW bar AS SELECT * FROM foo;
NOTICE: view "bar" will be a temporary view
CREATE VIEW
test=# INSERT INTO foo (id)
test-# VALUES (1)
test-# ON CONFLICT ON CONSTRAINT foo_pkey
test-# DO NOTHING;
INSERT 0 1
test=# INSERT INTO foo (id)
VALUES (1)
ON CONFLICT ON CONSTRAINT foo_pkey
DO NOTHING;
INSERT 0 0
test=# INSERT INTO foo (id)
VALUES (1)
ON CONFLICT ON CONSTRAINT foo_pkey
DO NOTHING;
INSERT 0 0
test=# INSERT INTO bar (id)
VALUES (1)
ON CONFLICT ON CONSTRAINT foo_pkey
DO NOTHING;
ERROR: constraint "foo_pkey" for table "bar" does not exist
test=# INSERT INTO bar (id)
VALUES (1)
ON CONFLICT (id)
DO NOTHING;
INSERT 0 0
Of interest are the last 2 statements above. ON CONFLICT on the constraint
name does not work, but it does work by field name. I'm not saying it
*should* work both ways, but I'm more wondering if this is
known/expected/desired behavior.
The point of interest for us is that we frequently preserve a table's
"public API" by instead swapping out a table for a view as above, in order
for instance to rebuild a table behind the scenes without breaking table
usage. Above case is a rare example where that doesn't work, and which in
any case I advise (as does the docs) that they do not use on conflict on
constraint, but rather to list the field names instead.
Thanks,
Jeremy
From | Date | Subject | |
---|---|---|---|
Next Message | Chapman Flack | 2019-10-18 12:59:52 | Re: Proposal: Make use of C99 designated initialisers for nulls/values arrays |
Previous Message | ideriha.takeshi@fujitsu.com | 2019-10-18 12:53:16 | RE: Copy data to DSA area |