Fix yet another bug in ON CONFLICT rule deparsing.

Expand testing of rule deparsing a good bit, it's evidently needed.

Author: Peter Geoghegan, Andres Freund
Discussion: CAM3SWZQmXxZhQC32QVEOTYfNXJBJ_Q2SDENL7BV14Cq-zL0FLg@mail.gmail.com
This commit is contained in:
Andres Freund 2015-05-23 02:16:24 +02:00
parent 631d749007
commit 284bef2977
3 changed files with 75 additions and 5 deletions

View File

@ -5500,7 +5500,7 @@ get_insert_query_def(Query *query, deparse_context *context)
get_rule_expr(confl->arbiterWhere, context, false);
}
}
else
else if (confl->constraint != InvalidOid)
{
char *constraint = get_constraint_name(confl->constraint);

View File

@ -2811,14 +2811,26 @@ CREATE TABLE hat_data (
);
create unique index hat_data_unique_idx
on hat_data (hat_name COLLATE "C" bpchar_pattern_ops);
-- okay
-- DO NOTHING with ON CONFLICT
CREATE RULE hat_nosert AS ON INSERT TO hats
DO INSTEAD
INSERT INTO hat_data VALUES (
NEW.hat_name,
NEW.hat_color)
ON CONFLICT (hat_name COLLATE "C" bpchar_pattern_ops) WHERE hat_color = 'green'
DO NOTHING RETURNING *;
DO NOTHING
RETURNING *;
SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename;
definition
---------------------------------------------------------------------------------------------
CREATE RULE hat_nosert AS +
ON INSERT TO hats DO INSTEAD INSERT INTO hat_data (hat_name, hat_color) +
VALUES (new.hat_name, new.hat_color) ON CONFLICT(hat_name COLLATE "C" bpchar_pattern_ops)+
WHERE (hat_data.hat_color = 'green'::bpchar) DO NOTHING +
RETURNING hat_data.hat_name, +
hat_data.hat_color;
(1 row)
-- Works (projects row)
INSERT INTO hats VALUES ('h7', 'black') RETURNING *;
hat_name | hat_color
@ -2845,6 +2857,34 @@ SELECT tablename, rulename, definition FROM pg_rules
(1 row)
DROP RULE hat_nosert ON hats;
-- DO NOTHING without ON CONFLICT
CREATE RULE hat_nosert_all AS ON INSERT TO hats
DO INSTEAD
INSERT INTO hat_data VALUES (
NEW.hat_name,
NEW.hat_color)
ON CONFLICT
DO NOTHING
RETURNING *;
SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename;
definition
------------------------------------------------------------------------------
CREATE RULE hat_nosert_all AS +
ON INSERT TO hats DO INSTEAD INSERT INTO hat_data (hat_name, hat_color)+
VALUES (new.hat_name, new.hat_color) ON CONFLICT DO NOTHING +
RETURNING hat_data.hat_name, +
hat_data.hat_color;
(1 row)
DROP RULE hat_nosert_all ON hats;
-- Works (does nothing)
INSERT INTO hats VALUES ('h7', 'black') RETURNING *;
hat_name | hat_color
------------+------------
h7 | black
(1 row)
-- DO UPDATE with a WHERE clause
CREATE RULE hat_upsert AS ON INSERT TO hats
DO INSTEAD
INSERT INTO hat_data VALUES (
@ -2855,6 +2895,17 @@ CREATE RULE hat_upsert AS ON INSERT TO hats
SET hat_name = hat_data.hat_name, hat_color = excluded.hat_color
WHERE excluded.hat_color <> 'forbidden'
RETURNING *;
SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename;
definition
-----------------------------------------------------------------------------------------------------------------------------------------
CREATE RULE hat_upsert AS +
ON INSERT TO hats DO INSTEAD INSERT INTO hat_data (hat_name, hat_color) +
VALUES (new.hat_name, new.hat_color) ON CONFLICT(hat_name) DO UPDATE SET hat_name = hat_data.hat_name, hat_color = excluded.hat_color+
WHERE (excluded.hat_color <> 'forbidden'::bpchar) +
RETURNING hat_data.hat_name, +
hat_data.hat_color;
(1 row)
-- Works (does upsert)
INSERT INTO hats VALUES ('h8', 'black') RETURNING *;
hat_name | hat_color

View File

@ -1062,14 +1062,16 @@ CREATE TABLE hat_data (
create unique index hat_data_unique_idx
on hat_data (hat_name COLLATE "C" bpchar_pattern_ops);
-- okay
-- DO NOTHING with ON CONFLICT
CREATE RULE hat_nosert AS ON INSERT TO hats
DO INSTEAD
INSERT INTO hat_data VALUES (
NEW.hat_name,
NEW.hat_color)
ON CONFLICT (hat_name COLLATE "C" bpchar_pattern_ops) WHERE hat_color = 'green'
DO NOTHING RETURNING *;
DO NOTHING
RETURNING *;
SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename;
-- Works (projects row)
INSERT INTO hats VALUES ('h7', 'black') RETURNING *;
@ -1079,6 +1081,22 @@ SELECT tablename, rulename, definition FROM pg_rules
WHERE tablename = 'hats';
DROP RULE hat_nosert ON hats;
-- DO NOTHING without ON CONFLICT
CREATE RULE hat_nosert_all AS ON INSERT TO hats
DO INSTEAD
INSERT INTO hat_data VALUES (
NEW.hat_name,
NEW.hat_color)
ON CONFLICT
DO NOTHING
RETURNING *;
SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename;
DROP RULE hat_nosert_all ON hats;
-- Works (does nothing)
INSERT INTO hats VALUES ('h7', 'black') RETURNING *;
-- DO UPDATE with a WHERE clause
CREATE RULE hat_upsert AS ON INSERT TO hats
DO INSTEAD
INSERT INTO hat_data VALUES (
@ -1089,6 +1107,7 @@ CREATE RULE hat_upsert AS ON INSERT TO hats
SET hat_name = hat_data.hat_name, hat_color = excluded.hat_color
WHERE excluded.hat_color <> 'forbidden'
RETURNING *;
SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename;
-- Works (does upsert)
INSERT INTO hats VALUES ('h8', 'black') RETURNING *;