aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-10-14 22:14:35 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-10-14 22:14:35 +0000
commitd508b057ac0834eb6ea83b10ba9fd6c439b454a4 (patch)
treec100e9e56c25d3f6f57cd2be986b294258665a36 /src
parentea3728ee5b60ee479caa865590d14f71f612dcdb (diff)
downloadpostgresql-d508b057ac0834eb6ea83b10ba9fd6c439b454a4.tar.gz
postgresql-d508b057ac0834eb6ea83b10ba9fd6c439b454a4.zip
Adjust handling of command status strings in the presence of rules,
as per recent pghackers discussions. initdb forced due to change in fields of stored Query nodes.
Diffstat (limited to 'src')
-rw-r--r--src/backend/nodes/copyfuncs.c4
-rw-r--r--src/backend/nodes/equalfuncs.c5
-rw-r--r--src/backend/nodes/outfuncs.c7
-rw-r--r--src/backend/nodes/readfuncs.c11
-rw-r--r--src/backend/parser/analyze.c6
-rw-r--r--src/backend/rewrite/rewriteHandler.c22
-rw-r--r--src/backend/tcop/postgres.c71
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/nodes/parsenodes.h17
9 files changed, 113 insertions, 34 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index bce849e4ec5..5fff2f762ab 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.213 2002/09/22 19:42:51 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.214 2002/10/14 22:14:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1778,6 +1778,7 @@ _copyQuery(Query *from)
Query *newnode = makeNode(Query);
newnode->commandType = from->commandType;
+ newnode->querySource = from->querySource;
Node_Copy(from, newnode, utilityStmt);
newnode->resultRelation = from->resultRelation;
Node_Copy(from, newnode, into);
@@ -1785,7 +1786,6 @@ _copyQuery(Query *from)
newnode->isBinary = from->isBinary;
newnode->hasAggs = from->hasAggs;
newnode->hasSubLinks = from->hasSubLinks;
- newnode->originalQuery = from->originalQuery;
Node_Copy(from, newnode, rtable);
Node_Copy(from, newnode, jointree);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 82d4fc6ab63..551c32d5dba 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.160 2002/09/22 19:42:51 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.161 2002/10/14 22:14:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -573,6 +573,8 @@ _equalQuery(Query *a, Query *b)
{
if (a->commandType != b->commandType)
return false;
+ if (a->querySource != b->querySource)
+ return false;
if (!equal(a->utilityStmt, b->utilityStmt))
return false;
if (a->resultRelation != b->resultRelation)
@@ -587,7 +589,6 @@ _equalQuery(Query *a, Query *b)
return false;
if (a->hasSubLinks != b->hasSubLinks)
return false;
- /* we deliberately ignore originalQuery */
if (!equal(a->rtable, b->rtable))
return false;
if (!equal(a->jointree, b->jointree))
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 364aa774ada..e1a34118a62 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.175 2002/09/22 19:42:51 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.176 2002/10/14 22:14:34 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -229,7 +229,8 @@ _outIndexElem(StringInfo str, IndexElem *node)
static void
_outQuery(StringInfo str, Query *node)
{
- appendStringInfo(str, " QUERY :command %d :utility ", node->commandType);
+ appendStringInfo(str, " QUERY :command %d :source %d :utility ",
+ (int) node->commandType, (int) node->querySource);
/*
* Hack to work around missing outfuncs routines for a lot of the
@@ -299,6 +300,8 @@ _outQuery(StringInfo str, Query *node)
appendStringInfo(str, " :resultRelations ");
_outIntList(str, node->resultRelations);
+
+ /* planner-internal fields are not written out */
}
static void
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index fc4bb97e4a7..33e28413439 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.134 2002/09/22 19:42:51 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.135 2002/10/14 22:14:34 tgl Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -123,6 +123,10 @@ _readQuery(void)
token = pg_strtok(&length); /* get commandType */
local_node->commandType = atoi(token);
+ token = pg_strtok(&length); /* skip :source */
+ token = pg_strtok(&length); /* get querySource */
+ local_node->querySource = atoi(token);
+
token = pg_strtok(&length); /* skip :utility */
local_node->utilityStmt = nodeRead(true);
@@ -149,9 +153,6 @@ _readQuery(void)
token = pg_strtok(&length); /* get hasSubLinks */
local_node->hasSubLinks = strtobool(token);
- /* we always want originalQuery to be false in a read-in query */
- local_node->originalQuery = false;
-
token = pg_strtok(&length); /* skip :rtable */
local_node->rtable = nodeRead(true);
@@ -188,6 +189,8 @@ _readQuery(void)
token = pg_strtok(&length); /* skip :resultRelations */
local_node->resultRelations = toIntList(nodeRead(true));
+ /* planner-internal fields are left zero */
+
return local_node;
}
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index fe058125a04..2dcaadc177f 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.250 2002/09/22 00:37:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.251 2002/10/14 22:14:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -164,13 +164,13 @@ parse_analyze(Node *parseTree, ParseState *parentParseState)
/*
* Make sure that only the original query is marked original. We have
* to do this explicitly since recursive calls of parse_analyze will
- * have set originalQuery in some of the added-on queries.
+ * have marked some of the added-on queries as "original".
*/
foreach(listscan, result)
{
Query *q = lfirst(listscan);
- q->originalQuery = (q == query);
+ q->querySource = (q == query ? QSRC_ORIGINAL : QSRC_PARSER);
}
pfree(pstate);
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 0b2d839eb3f..180e56d9208 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.110 2002/09/18 21:35:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.111 2002/10/14 22:14:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -942,6 +942,7 @@ fireRules(Query *parsetree,
RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
Node *event_qual;
List *actions;
+ QuerySource qsrc;
List *r;
/* multiple rule action time */
@@ -949,7 +950,18 @@ fireRules(Query *parsetree,
event_qual = rule_lock->qual;
actions = rule_lock->actions;
- if (event_qual != NULL && *instead_flag)
+ /* Determine correct QuerySource value for actions */
+ if (rule_lock->isInstead)
+ {
+ if (event_qual != NULL)
+ qsrc = QSRC_QUAL_INSTEAD_RULE;
+ else
+ qsrc = QSRC_INSTEAD_RULE;
+ }
+ else
+ qsrc = QSRC_NON_INSTEAD_RULE;
+
+ if (qsrc == QSRC_QUAL_INSTEAD_RULE)
{
Query *qual_product;
@@ -976,6 +988,7 @@ fireRules(Query *parsetree,
*qual_products = makeList1(qual_product);
}
+ /* Now process the rule's actions and add them to the result list */
foreach(r, actions)
{
Query *rule_action = lfirst(r);
@@ -986,6 +999,8 @@ fireRules(Query *parsetree,
rule_action = rewriteRuleAction(parsetree, rule_action,
event_qual, rt_index, event);
+ rule_action->querySource = qsrc;
+
results = lappend(results, rule_action);
}
@@ -993,9 +1008,10 @@ fireRules(Query *parsetree,
* If this was an unqualified instead rule, throw away an
* eventually saved 'default' parsetree
*/
- if (event_qual == NULL && *instead_flag)
+ if (qsrc == QSRC_INSTEAD_RULE)
*qual_products = NIL;
}
+
return results;
}
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 1b636c18d73..9538b34a4e9 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.301 2002/10/13 16:55:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.302 2002/10/14 22:14:35 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -621,6 +621,8 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
Node *parsetree = (Node *) lfirst(parsetree_item);
const char *commandTag;
char completionTag[COMPLETION_TAG_BUFSIZE];
+ CmdType origCmdType;
+ bool foundOriginalQuery = false;
List *querytree_list,
*querytree_item;
@@ -632,6 +634,26 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
*/
commandTag = CreateCommandTag(parsetree);
+ switch (nodeTag(parsetree))
+ {
+ case T_InsertStmt:
+ origCmdType = CMD_INSERT;
+ break;
+ case T_DeleteStmt:
+ origCmdType = CMD_DELETE;
+ break;
+ case T_UpdateStmt:
+ origCmdType = CMD_UPDATE;
+ break;
+ case T_SelectStmt:
+ origCmdType = CMD_SELECT;
+ break;
+ default:
+ /* Otherwise, never match commandType */
+ origCmdType = CMD_UNKNOWN;
+ break;
+ }
+
set_ps_display(commandTag);
BeginCommand(commandTag, dest);
@@ -694,6 +716,7 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
{
Query *querytree = (Query *) lfirst(querytree_item);
bool endTransactionBlock = false;
+ bool canSetTag;
/* Make sure we are in a transaction command */
if (!xact_started)
@@ -708,6 +731,24 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
*/
CHECK_FOR_INTERRUPTS();
+ /*
+ * This query can set the completion tag if it is the original
+ * query, or if it is an INSTEAD query of the same kind as the
+ * original and we haven't yet seen the original query.
+ */
+ if (querytree->querySource == QSRC_ORIGINAL)
+ {
+ canSetTag = true;
+ foundOriginalQuery = true;
+ }
+ else if (!foundOriginalQuery &&
+ querytree->commandType == origCmdType &&
+ (querytree->querySource == QSRC_INSTEAD_RULE ||
+ querytree->querySource == QSRC_QUAL_INSTEAD_RULE))
+ canSetTag = true;
+ else
+ canSetTag = false;
+
if (querytree->commandType == CMD_UTILITY)
{
/*
@@ -736,7 +777,7 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
IsA(utilityStmt, VariableResetStmt))
endTransactionBlock = true;
- if (querytree->originalQuery)
+ if (canSetTag)
{
/* utility statement can override default tag string */
ProcessUtility(utilityStmt, dest, completionTag);
@@ -785,9 +826,9 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
{
elog(DEBUG2, "ProcessQuery");
- if (querytree->originalQuery || length(querytree_list) == 1)
+ if (canSetTag)
{
- /* original stmt can override default tag string */
+ /* statement can override default tag string */
ProcessQuery(querytree, plan, dest, completionTag);
commandTag = completionTag;
}
@@ -853,17 +894,21 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
/*
* It is possible that the original query was removed due to a DO
- * INSTEAD rewrite rule. In that case we will still have the
- * default completion tag, which is fine for most purposes, but it
+ * INSTEAD rewrite rule. If so, and if we found no INSTEAD query
+ * matching the command type, we will still have the default
+ * completion tag. This is fine for most purposes, but it
* may confuse clients if it's INSERT/UPDATE/DELETE. Clients
* expect those tags to have counts after them (cf. ProcessQuery).
*/
- if (strcmp(commandTag, "INSERT") == 0)
- commandTag = "INSERT 0 0";
- else if (strcmp(commandTag, "UPDATE") == 0)
- commandTag = "UPDATE 0";
- else if (strcmp(commandTag, "DELETE") == 0)
- commandTag = "DELETE 0";
+ if (!foundOriginalQuery)
+ {
+ if (strcmp(commandTag, "INSERT") == 0)
+ commandTag = "INSERT 0 0";
+ else if (strcmp(commandTag, "UPDATE") == 0)
+ commandTag = "UPDATE 0";
+ else if (strcmp(commandTag, "DELETE") == 0)
+ commandTag = "DELETE 0";
+ }
/*
* Tell client that we're done with this query. Note we emit
@@ -1724,7 +1769,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
- puts("$Revision: 1.301 $ $Date: 2002/10/13 16:55:05 $\n");
+ puts("$Revision: 1.302 $ $Date: 2002/10/14 22:14:35 $\n");
}
/*
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 431e317c89b..967cb794f7d 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: catversion.h,v 1.160 2002/09/22 19:42:51 tgl Exp $
+ * $Id: catversion.h,v 1.161 2002/10/14 22:14:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200209221
+#define CATALOG_VERSION_NO 200210141
#endif
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index cde4acebc21..ee0d2210134 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.208 2002/09/22 19:42:52 tgl Exp $
+ * $Id: parsenodes.h,v 1.209 2002/10/14 22:14:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,6 +17,17 @@
#include "nodes/primnodes.h"
+/* Possible sources of a Query */
+typedef enum QuerySource
+{
+ QSRC_ORIGINAL, /* original parsetree (explicit query) */
+ QSRC_PARSER, /* added by parse analysis */
+ QSRC_INSTEAD_RULE, /* added by unconditional INSTEAD rule */
+ QSRC_QUAL_INSTEAD_RULE, /* added by conditional INSTEAD rule */
+ QSRC_NON_INSTEAD_RULE /* added by non-INSTEAD rule */
+} QuerySource;
+
+
/*****************************************************************************
* Query Tree
*****************************************************************************/
@@ -37,6 +48,8 @@ typedef struct Query
CmdType commandType; /* select|insert|update|delete|utility */
+ QuerySource querySource; /* where did I come from? */
+
Node *utilityStmt; /* non-null if this is a non-optimizable
* statement */
@@ -49,8 +62,6 @@ typedef struct Query
bool hasAggs; /* has aggregates in tlist or havingQual */
bool hasSubLinks; /* has subquery SubLink */
- bool originalQuery; /* marks original query through rewriting */
-
List *rtable; /* list of range table entries */
FromExpr *jointree; /* table join tree (FROM and WHERE
* clauses) */