aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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) */