diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/rewrite/rewriteHandler.c | 52 | ||||
-rw-r--r-- | src/test/regress/expected/rules.out | 4 | ||||
-rw-r--r-- | src/test/regress/sql/rules.sql | 2 |
3 files changed, 37 insertions, 21 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 3011e54fd71..3b3d209d468 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.96 2001/07/06 13:40:47 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.97 2001/07/09 23:50:32 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -831,7 +831,7 @@ deepRewriteQuery(Query *parsetree) numQueryRewriteInvoked - 1); } - instead = FALSE; + instead = false; result = RewriteQuery(parsetree, &instead, &qual_products); foreach(n, result) @@ -845,25 +845,41 @@ deepRewriteQuery(Query *parsetree) } /* - * qual_products are the original query with the negated rule - * qualification of an instead rule + * For INSERTs, the original query is done first; for UPDATE/DELETE, it is + * done last. This is needed because update and delete rule actions might + * not do anything if they are invoked after the update or delete is + * performed. The command counter increment between the query execution + * makes the deleted (and maybe the updated) tuples disappear so the scans + * for them in the rule actions cannot find them. */ - if (qual_products != NIL) - rewritten = nconc(rewritten, qual_products); - - /* - * The original query is appended last (if no "instead" rule) because - * update and delete rule actions might not do anything if they are - * invoked after the update or delete is performed. The command - * counter increment between the query execution makes the deleted - * (and maybe the updated) tuples disappear so the scans for them in - * the rule actions cannot find them. - */ - if (!instead) - if (parsetree->commandType == CMD_INSERT) + if (parsetree->commandType == CMD_INSERT) + { + /* + * qual_products are the original query with the negated rule + * qualification of an INSTEAD rule + */ + if (qual_products != NIL) + rewritten = nconc(qual_products, rewritten); + /* + * Add the unmodified original query, if no INSTEAD rule was seen. + */ + if (!instead) rewritten = lcons(parsetree, rewritten); - else + } + else + { + /* + * qual_products are the original query with the negated rule + * qualification of an INSTEAD rule + */ + if (qual_products != NIL) + rewritten = nconc(rewritten, qual_products); + /* + * Add the unmodified original query, if no INSTEAD rule was seen. + */ + if (!instead) rewritten = lappend(rewritten, parsetree); + } return rewritten; } diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 1c4fabd28bd..acf6aa47f06 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -107,7 +107,7 @@ create table rtest_nothn2 (a int4, b text); create table rtest_nothn3 (a int4, b text); create table rtest_nothn4 (a int4, b text); create rule rtest_nothn_r1 as on insert to rtest_nothn1 - where new.a >= 10 and new.a < 20 do instead (select 1); + where new.a >= 10 and new.a < 20 do instead nothing; create rule rtest_nothn_r2 as on insert to rtest_nothn1 where new.a >= 30 and new.a < 40 do instead nothing; create rule rtest_nothn_r3 as on insert to rtest_nothn2 @@ -1313,7 +1313,7 @@ SELECT tablename, rulename, definition FROM pg_rules rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired '::bpchar, '$0.00'::money, old.salary); rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired '::bpchar, new.salary, '$0.00'::money); rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored '::bpchar, new.salary, old.salary); - rtest_nothn1 | rtest_nothn_r1 | CREATE RULE rtest_nothn_r1 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 10) AND (new.a < 20)) DO INSTEAD SELECT 1; + rtest_nothn1 | rtest_nothn_r1 | CREATE RULE rtest_nothn_r1 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 10) AND (new.a < 20)) DO INSTEAD NOTHING; rtest_nothn1 | rtest_nothn_r2 | CREATE RULE rtest_nothn_r2 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 30) AND (new.a < 40)) DO INSTEAD NOTHING; rtest_nothn2 | rtest_nothn_r3 | CREATE RULE rtest_nothn_r3 AS ON INSERT TO rtest_nothn2 WHERE (new.a >= 100) DO INSTEAD INSERT INTO rtest_nothn3 (a, b) VALUES (new.a, new.b); rtest_nothn2 | rtest_nothn_r4 | CREATE RULE rtest_nothn_r4 AS ON INSERT TO rtest_nothn2 DO INSTEAD NOTHING; diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql index 9a04ed3a3dc..5068face885 100644 --- a/src/test/regress/sql/rules.sql +++ b/src/test/regress/sql/rules.sql @@ -131,7 +131,7 @@ create table rtest_nothn3 (a int4, b text); create table rtest_nothn4 (a int4, b text); create rule rtest_nothn_r1 as on insert to rtest_nothn1 - where new.a >= 10 and new.a < 20 do instead (select 1); + where new.a >= 10 and new.a < 20 do instead nothing; create rule rtest_nothn_r2 as on insert to rtest_nothn1 where new.a >= 30 and new.a < 40 do instead nothing; |