BUG #5987: Rows created by WITH (INSERT ... RETURNING) are not visible to the rest of the query

From: "Daniel Grace" <dgrace(at)wingsnw(dot)com>
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #5987: Rows created by WITH (INSERT ... RETURNING) are not visible to the rest of the query
Date: 2011-04-19 18:54:49
Message-ID: 201104191854.p3JIsn6a074429@wwwmaster.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs


The following bug has been logged online:

Bug reference: 5987
Logged by: Daniel Grace
Email address: dgrace(at)wingsnw(dot)com
PostgreSQL version: 9.1-alpha5
Operating system: Win7 x64
Description: Rows created by WITH (INSERT ... RETURNING) are not
visible to the rest of the query
Details:

This may not be a bug, but I'll describe it anyways. Apologies if this is a
duplicate -- "WITH" is apparently a stopword and searching the archives
using it produces zero results.

9.1 adds the ability to use WITH in INSERT/UPDATE/DELETE in both
directions.

However, the actual effects of the query in the WITH clause are not visible
to the outer query.

-----
DROP TABLE IF EXISTS a;
CREATE TABLE a ( t TEXT );

INSERT INTO a VALUES ('test1') RETURNING *; -- Works as expected

WITH b AS (INSERT INTO a VALUES ('test2') RETURNING *) SELECT * FROM b; --
Works as expected

WITH b AS (INSERT INTO a VALUES ('test3') RETURNING *) SELECT a.* FROM a
INNER JOIN b USING(t); -- Does not see the newly created row.

SELECT * FROM a WHERE t='test3'; -- But it was created.

WITH b AS (INSERT INTO a VALUES ('test4') RETURNING *) -- Does not see the
newly created row, thus the update does not happen.
UPDATE a SET t='test5'
FROM b
WHERE a.t=b.t;

SELECT * FROM a;
-----
This is also true if the WITH query is a stored procedure that modifies the
database and returns results, i.e. WITH b AS (SELECT * FROM
create_row('test6'))...

Presumably it affects UPDATE and DELETE as well, but I didn't test those
cases.

My actual use case is: I'm calling a function to duplicate+modify some rows.
(Essentially, it does INSERT ... SELECT from the same table, but forcing
the primary key to be reassigned via being a serial column and some other
changes). This function returns the new rows as results (doing RETURN QUERY
INSERT ... SELECT ... RETURNING *). In some situations, I want to further
update the freshly created rows, so the goal was to do this:

WITH newrows AS (SELECT * FROM function_that_creates_rows(...))
UPDATE basetable SET foo=overrides.bar
FROM newrows
LEFT JOIN (VALUES (...)) AS overrides(...)
WHERE ...

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Dewin 2011-04-19 19:03:15 Re: BUG #5985: CLUSTER ... USING can fail with ERROR: index xxx does not belong to table yyy
Previous Message Peter Eisentraut 2011-04-19 14:27:46 Re: BUG #5986: pg_dump output is not ordered