summaryrefslogtreecommitdiff
path: root/src/backend/rewrite/rewriteHandler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite/rewriteHandler.c')
-rw-r--r--src/backend/rewrite/rewriteHandler.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 8ca7fb954f..5d481a3f0a 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.119 2003/04/29 22:13:10 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.120 2003/05/02 20:54:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1016,6 +1016,7 @@ fireRules(Query *parsetree,
event_qual, rt_index, event);
rule_action->querySource = qsrc;
+ rule_action->canSetTag = false; /* might change later */
results = lappend(results, rule_action);
}
@@ -1181,6 +1182,9 @@ QueryRewrite(Query *parsetree)
List *querylist;
List *results = NIL;
List *l;
+ CmdType origCmdType;
+ bool foundOriginalQuery;
+ Query *lastInstead;
/*
* Step 1
@@ -1235,5 +1239,51 @@ QueryRewrite(Query *parsetree)
results = lappend(results, query);
}
+ /*
+ * Step 3
+ *
+ * Determine which, if any, of the resulting queries is supposed to set
+ * the command-result tag; and update the canSetTag fields accordingly.
+ *
+ * If the original query is still in the list, it sets the command tag.
+ * Otherwise, the last INSTEAD query of the same kind as the original
+ * is allowed to set the tag. (Note these rules can leave us with no
+ * query setting the tag. The tcop code has to cope with this by
+ * setting up a default tag based on the original un-rewritten query.)
+ *
+ * The Asserts verify that at most one query in the result list is marked
+ * canSetTag. If we aren't checking asserts, we can fall out of the loop
+ * as soon as we find the original query.
+ */
+ origCmdType = parsetree->commandType;
+ foundOriginalQuery = false;
+ lastInstead = NULL;
+
+ foreach(l, results)
+ {
+ Query *query = (Query *) lfirst(l);
+
+ if (query->querySource == QSRC_ORIGINAL)
+ {
+ Assert(query->canSetTag);
+ Assert(!foundOriginalQuery);
+ foundOriginalQuery = true;
+#ifndef USE_ASSERT_CHECKING
+ break;
+#endif
+ }
+ else
+ {
+ Assert(!query->canSetTag);
+ if (query->commandType == origCmdType &&
+ (query->querySource == QSRC_INSTEAD_RULE ||
+ query->querySource == QSRC_QUAL_INSTEAD_RULE))
+ lastInstead = query;
+ }
+ }
+
+ if (!foundOriginalQuery && lastInstead != NULL)
+ lastInstead->canSetTag = true;
+
return results;
}