summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/rewrite/rewriteHandler.c52
-rw-r--r--src/test/regress/expected/rules.out4
-rw-r--r--src/test/regress/sql/rules.sql2
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;