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

From Daniel Grace
Subject BUG #5987: Rows created by WITH (INSERT ... RETURNING) are not visible to the rest of the query
Date
Msg-id 201104191854.p3JIsn6a074429@wwwmaster.postgresql.org
Whole thread Raw
Responses Re: BUG #5987: Rows created by WITH (INSERT ... RETURNING) are not visible to the rest of the query  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
The following bug has been logged online:

Bug reference:      5987
Logged by:          Daniel Grace
Email address:      dgrace@wingsnw.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 ...

pgsql-bugs by date:

Previous
From: anij ninan
Date:
Subject: help
Next
From: Tom Lane
Date:
Subject: Re: BUG #5987: Rows created by WITH (INSERT ... RETURNING) are not visible to the rest of the query