I am attempting to allow insert statements with a returning clause into a view in Postgres v9.4, but am struggling with the syntax. This is how I want to call the insert statement:
CREATE VIEW MyView AS SELECT a.*, b.someCol1
FROM tableA a JOIN tableB b USING(aPrimaryKey);
INSERT INTO MyView (time, someCol) VALUES (someTime, someValue) RETURNING *;
INSERT INTO MyView (someCol) VALUES (someValue) RETURNING *;
Note that the default for time is NOW(). This is what I have so far:
CREATE RULE MyRuleName AS ON INSERT TO MyView DO INSTEAD (
INSERT INTO tableA (time) VALUES COALESCE(NEW.time, NOW());
INSERT INTO tableB (aPrimaryKey, someCol)
VALUES (CURRVAL('tableA_aPrimaryKey_seq'), NEW.someValue);
);
The above works to insert the value, but I am struggling to try and figure out how to add the returning statement. I have tried the following without success:
CREATE RULE MyRuleName AS ON INSERT TO MyView DO INSTEAD (
INSERT INTO tableA (time) VALUES COALESCE(NEW.time, NOW())
RETURNING *, NEW.someValue;
INSERT INTO tableB (aPrimaryKey, someCol)
VALUES (CURRVAL('tableA_aPrimaryKey_seq'), NEW.someValue);
);
-- ERROR: invalid reference to FROM-clause entry for table "new"
CREATE RULE MyRuleName AS ON INSERT TO MyView DO INSTEAD (
WITH a AS (INSERT INTO tableA (time)
VALUES COALESCE(NEW.time, NOW()) RETURNING *)
INSERT INTO tableB (aPrimaryKey, someCol)
SELECT aPrimaryKey, NEW.someValue FROM a RETURNING *;
);
-- ERROR: cannot refer to NEW within WITH query
Argh! Does anyone know of a way to add a returning statement that gets the primary key (SERIAL) and time (TIMESTAMP WITH TIME ZONE) added to the database in the first insert, along with the value of someCol in the second insert? Thanks!
ON UPDATE DO INSTEAD
triggers for this, instead of rules. – Overcritical