OSDN Git Service

Restructure command-completion-report code so that there is just one
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 26 Feb 2002 22:47:12 +0000 (22:47 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 26 Feb 2002 22:47:12 +0000 (22:47 +0000)
report for each received SQL command, regardless of rewriting activity.
Also ensure that this report comes from the 'original' command, not the
last command generated by rewrite; this fixes 7.2 breakage for INSERT
commands that have actions added by rules.  Fernando Nasser and Tom Lane.

17 files changed:
src/backend/commands/command.c
src/backend/commands/explain.c
src/backend/executor/functions.c
src/backend/executor/spi.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/readfuncs.c
src/backend/parser/analyze.c
src/backend/tcop/dest.c
src/backend/tcop/postgres.c
src/backend/tcop/pquery.c
src/backend/tcop/utility.c
src/include/commands/command.h
src/include/nodes/parsenodes.h
src/include/tcop/dest.h
src/include/tcop/pquery.h
src/include/tcop/utility.h

index f01cf44..676caba 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.154 2002/02/19 20:11:12 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.155 2002/02/26 22:47:04 tgl Exp $
  *
  * NOTES
  *       The PerformAddAttribute() code, like most of the relation
@@ -89,16 +89,25 @@ PortalCleanup(Portal portal)
        MemoryContextSwitchTo(oldcontext);
 }
 
-/* --------------------------------
- *             PerformPortalFetch
- * --------------------------------
+
+/*
+ * PerformPortalFetch
+ *
+ *     name: name of portal
+ *     forward: forward or backward fetch?
+ *     count: # of tuples to fetch (0 implies all)
+ *     dest: where to send results
+ *     completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
+ *             in which to store a command completion status string.
+ *
+ * completionTag may be NULL if caller doesn't want a status string.
  */
 void
 PerformPortalFetch(char *name,
                                   bool forward,
                                   int count,
-                                  char *tag,
-                                  CommandDest dest)
+                                  CommandDest dest,
+                                  char *completionTag)
 {
        Portal          portal;
        QueryDesc  *queryDesc;
@@ -107,6 +116,10 @@ PerformPortalFetch(char *name,
        CommandId       savedId;
        bool            temp_desc = false;
 
+       /* initialize completion status in case of early exit */
+       if (completionTag)
+               strcpy(completionTag, (dest == None) ? "MOVE 0" : "FETCH 0");
+
        /*
         * sanity checks
         */
@@ -167,7 +180,7 @@ PerformPortalFetch(char *name,
                                                                 * relations */
                                 false,                 /* this is a portal fetch, not a "retrieve
                                                                 * portal" */
-                                tag,
+                                NULL,                  /* not used */
                                 queryDesc->dest);
 
        /*
@@ -193,16 +206,15 @@ PerformPortalFetch(char *name,
                {
                        ExecutorRun(queryDesc, estate, EXEC_FOR, (long) count);
 
-                       /*
-                        * I use CMD_UPDATE, because no CMD_MOVE or the like exists,
-                        * and I would like to provide the same kind of info as
-                        * CMD_UPDATE
-                        */
-                       UpdateCommandInfo(CMD_UPDATE, 0, estate->es_processed);
                        if (estate->es_processed > 0)
                                portal->atStart = false;                /* OK to back up now */
                        if (count <= 0 || (int) estate->es_processed < count)
                                portal->atEnd = true;   /* we retrieved 'em all */
+
+                       if (completionTag)
+                               snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "%s %u",
+                                                (dest == None) ? "MOVE" : "FETCH",
+                                                estate->es_processed);
                }
        }
        else
@@ -211,16 +223,15 @@ PerformPortalFetch(char *name,
                {
                        ExecutorRun(queryDesc, estate, EXEC_BACK, (long) count);
 
-                       /*
-                        * I use CMD_UPDATE, because no CMD_MOVE or the like exists,
-                        * and I would like to provide the same kind of info as
-                        * CMD_UPDATE
-                        */
-                       UpdateCommandInfo(CMD_UPDATE, 0, estate->es_processed);
                        if (estate->es_processed > 0)
                                portal->atEnd = false;  /* OK to go forward now */
                        if (count <= 0 || (int) estate->es_processed < count)
                                portal->atStart = true; /* we retrieved 'em all */
+
+                       if (completionTag)
+                               snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "%s %u",
+                                                (dest == None) ? "MOVE" : "FETCH",
+                                                estate->es_processed);
                }
        }
 
@@ -236,11 +247,6 @@ PerformPortalFetch(char *name,
                pfree(queryDesc);
 
        MemoryContextSwitchTo(oldcontext);
-
-       /*
-        * Note: the "end-of-command" tag is returned by higher-level utility
-        * code
-        */
 }
 
 /* --------------------------------
index c14d4ce..9c96687 100644 (file)
@@ -5,7 +5,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.67 2001/10/25 05:49:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.68 2002/02/26 22:47:04 tgl Exp $
  *
  */
 
@@ -120,7 +120,7 @@ ExplainOneQuery(Query *query, bool verbose, bool analyze, CommandDest dest)
                plan->instrument = InstrAlloc();
 
                gettimeofday(&starttime, NULL);
-               ProcessQuery(query, plan, None);
+               ProcessQuery(query, plan, None, NULL);
                CommandCounterIncrement();
                gettimeofday(&endtime, NULL);
 
index 7f73cdd..c38b807 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.47 2001/10/28 06:25:43 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.48 2002/02/26 22:47:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -275,7 +275,7 @@ postquel_getnext(execution_state *es)
                /*
                 * Process a utility command. (create, destroy...)      DZ - 30-8-1996
                 */
-               ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest);
+               ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest, NULL);
                if (!LAST_POSTQUEL_COMMAND(es))
                        CommandCounterIncrement();
                return (TupleTableSlot *) NULL;
index b9ab642..05044d6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.65 2002/02/14 15:24:08 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.66 2002/02/26 22:47:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1011,7 +1011,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
                        res = SPI_OK_UTILITY;
                        if (plan == NULL)
                        {
-                               ProcessUtility(queryTree->utilityStmt, None);
+                               ProcessUtility(queryTree->utilityStmt, None, NULL);
                                if (!islastquery)
                                        CommandCounterIncrement();
                                else
@@ -1085,7 +1085,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
 
                if (queryTree->commandType == CMD_UTILITY)
                {
-                       ProcessUtility(queryTree->utilityStmt, None);
+                       ProcessUtility(queryTree->utilityStmt, None, NULL);
                        if (!islastquery)
                                CommandCounterIncrement();
                        else
index 03ceb08..9838d98 100644 (file)
@@ -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.162 2002/02/24 20:20:20 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.163 2002/02/26 22:47:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1755,6 +1755,7 @@ _copyQuery(Query *from)
        newnode->isTemp = from->isTemp;
        newnode->hasAggs = from->hasAggs;
        newnode->hasSubLinks = from->hasSubLinks;
+       newnode->originalQuery = from->originalQuery;
 
        Node_Copy(from, newnode, rtable);
        Node_Copy(from, newnode, jointree);
index 2ea41d6..408c14b 100644 (file)
@@ -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.110 2002/02/24 20:20:20 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.111 2002/02/26 22:47:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -593,6 +593,7 @@ _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))
index 26fbebe..4414c03 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.113 2001/10/25 05:49:31 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.114 2002/02/26 22:47:07 tgl Exp $
  *
  * NOTES
  *       Most of the read functions for plan nodes are tested. (In fact, they
@@ -168,6 +168,9 @@ _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);
 
index aed1cf2..35944ff 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.214 2002/02/25 04:21:55 momjian Exp $
+ *     $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.215 2002/02/26 22:47:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -122,10 +122,11 @@ parse_analyze(Node *parseTree, ParseState *parentParseState)
 {
        List       *result = NIL;
        ParseState *pstate = make_parsestate(parentParseState);
-       Query      *query;
        /* Lists to return extra commands from transformation */
-       List *extras_before = NIL;
-       List *extras_after = NIL;
+       List       *extras_before = NIL;
+       List       *extras_after = NIL;
+       Query      *query;
+       List       *listscan;
 
        query = transformStmt(pstate, parseTree, &extras_before, &extras_after);
        release_pstate_resources(pstate);
@@ -144,6 +145,18 @@ parse_analyze(Node *parseTree, ParseState *parentParseState)
                extras_after = lnext(extras_after);
        }
 
+       /*
+        * 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.
+        */
+       foreach(listscan, result)
+       {
+               Query  *q = lfirst(listscan);
+
+               q->originalQuery = (q == query);
+       }
+
        pfree(pstate);
 
        return result;
index 5ed8896..f055bc3 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.46 2001/10/28 06:25:51 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.47 2002/02/26 22:47:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -41,8 +41,6 @@
 #include "libpq/pqformat.h"
 
 
-static char CommandInfo[32] = {0};
-
 /* ----------------
  *             dummy DestReceiver functions
  * ----------------
@@ -102,7 +100,6 @@ BeginCommand(char *pname,
                         * if this is a "retrieve into portal" query, done because
                         * nothing needs to be sent to the fe.
                         */
-                       CommandInfo[0] = '\0';
                        if (isIntoPortal)
                                break;
 
@@ -198,30 +195,22 @@ DestToFunction(CommandDest dest)
 }
 
 /* ----------------
- *             EndCommand - tell destination that no more tuples will arrive
+ *             EndCommand - tell destination that query is complete
  * ----------------
  */
 void
-EndCommand(char *commandTag, CommandDest dest)
+EndCommand(const char *commandTag, CommandDest dest)
 {
-       char            buf[64];
-
        switch (dest)
        {
                case Remote:
                case RemoteInternal:
-
-                       /*
-                        * tell the fe that the query is over
-                        */
-                       sprintf(buf, "%s%s", commandTag, CommandInfo);
-                       pq_puttextmessage('C', buf);
-                       CommandInfo[0] = '\0';
+                       pq_puttextmessage('C', commandTag);
                        break;
 
-               case Debug:
                case None:
-               default:
+               case Debug:
+               case SPI:
                        break;
        }
 }
@@ -317,23 +306,3 @@ ReadyForQuery(CommandDest dest)
                        break;
        }
 }
-
-void
-UpdateCommandInfo(int operation, Oid lastoid, uint32 tuples)
-{
-       switch (operation)
-       {
-               case CMD_INSERT:
-                       if (tuples > 1)
-                               lastoid = InvalidOid;
-                       sprintf(CommandInfo, " %u %u", lastoid, tuples);
-                       break;
-               case CMD_DELETE:
-               case CMD_UPDATE:
-                       sprintf(CommandInfo, " %u", tuples);
-                       break;
-               default:
-                       CommandInfo[0] = '\0';
-                       break;
-       }
-}
index 976b434..61fdf9c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.247 2002/02/23 01:31:36 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.248 2002/02/26 22:47:08 tgl Exp $
  *
  * NOTES
  *       this is the "main" module of the postgres backend and
@@ -64,6 +64,7 @@
 
 #include "pgstat.h"
 
+
 /* ----------------
  *             global variables
  * ----------------
@@ -87,6 +88,13 @@ bool         InError = false;
 
 static bool EchoQuery = false; /* default don't echo */
 
+/*
+ * Flag to mark SIGHUP. Whenever the main loop comes around it
+ * will reread the configuration file. (Better than doing the
+ * reading in the signal handler, ey?)
+ */
+static volatile bool got_SIGHUP = false;
+
 /* ----------------
  *             people who want to use EOF should #define DONTUSENEWLINE in
  *             tcop/tcopdebug.h
@@ -118,13 +126,7 @@ static void start_xact_command(void);
 static void finish_xact_command(void);
 static void SigHupHandler(SIGNAL_ARGS);
 static void FloatExceptionHandler(SIGNAL_ARGS);
-
-/*
- * Flag to mark SIGHUP. Whenever the main loop comes around it
- * will reread the configuration file. (Better than doing the
- * reading in the signal handler, ey?)
- */
-static volatile bool got_SIGHUP = false;
+static const char *CreateCommandTag(Node *parsetree);
 
 
 /* ----------------------------------------------------------------
@@ -635,6 +637,8 @@ pg_exec_query_string(char *query_string,            /* string to execute */
        {
                Node       *parsetree = (Node *) lfirst(parsetree_item);
                bool            isTransactionStmt;
+               const char *commandTag;
+               char            completionTag[COMPLETION_TAG_BUFSIZE];
                List       *querytree_list,
                                   *querytree_item;
 
@@ -670,16 +674,17 @@ pg_exec_query_string(char *query_string,          /* string to execute */
 
                        if (!allowit)
                        {
-                               /*
-                                * the EndCommand() stuff is to tell the frontend that the
-                                * command ended. -cim 6/1/90
-                                */
-                               char       *tag = "*ABORT STATE*";
-
                                elog(NOTICE, "current transaction is aborted, "
                                         "queries ignored until end of transaction block");
 
-                               EndCommand(tag, dest);
+                               /*
+                                * We need to emit a command-complete report to the client,
+                                * even though we didn't process the query.
+                                * - cim 6/1/90
+                                */
+                               commandTag = "*ABORT STATE*";
+
+                               EndCommand(commandTag, dest);
 
                                /*
                                 * We continue in the loop, on the off chance that there
@@ -702,7 +707,18 @@ pg_exec_query_string(char *query_string,           /* string to execute */
 
                /*
                 * OK to analyze and rewrite this query.
-                *
+                */
+                
+               /*
+                * First we set the command-completion tag to the main query
+                * (as opposed to each of the others that may be generated by
+                * analyze and rewrite).  Also set ps_status to the main query tag.
+                */
+               commandTag = CreateCommandTag(parsetree);
+
+               set_ps_display(commandTag);
+
+               /*
                 * Switch to appropriate context for constructing querytrees (again,
                 * these must outlive the execution context).
                 */
@@ -746,7 +762,19 @@ pg_exec_query_string(char *query_string,           /* string to execute */
                                else if (DebugLvl > 1)
                                        elog(DEBUG, "ProcessUtility");
 
-                               ProcessUtility(querytree->utilityStmt, dest);
+                               if (querytree->originalQuery)
+                               {
+                                       /* utility statement can override default tag string */
+                                       ProcessUtility(querytree->utilityStmt, dest,
+                                                                  completionTag);
+                                       if (completionTag[0])
+                                               commandTag = completionTag;
+                               }
+                               else
+                               {
+                                       /* utility added by rewrite cannot override tag */
+                                       ProcessUtility(querytree->utilityStmt, dest, NULL);
+                               }
                        }
                        else
                        {
@@ -778,7 +806,18 @@ pg_exec_query_string(char *query_string,           /* string to execute */
                                {
                                        if (DebugLvl > 1)
                                                elog(DEBUG, "ProcessQuery");
-                                       ProcessQuery(querytree, plan, dest);
+
+                                       if (querytree->originalQuery)
+                                       {
+                                               /* original stmt can override default tag string */
+                                               ProcessQuery(querytree, plan, dest, completionTag);
+                                               commandTag = completionTag;
+                                       }
+                                       else
+                                       {
+                                               /* stmt added by rewrite cannot override tag */
+                                               ProcessQuery(querytree, plan, dest, NULL);
+                                       }
                                }
 
                                if (Show_executor_stats)
@@ -818,6 +857,29 @@ pg_exec_query_string(char *query_string,           /* string to execute */
 
                }                                               /* end loop over queries generated from a
                                                                 * parsetree */
+
+               /*
+                * 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 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";
+
+               /*
+                * Tell client that we're done with this query.  Note we emit
+                * exactly one EndCommand report for each raw parsetree, thus
+                * one for each SQL command the client sent, regardless of
+                * rewriting.
+                */
+               EndCommand(commandTag, dest);
        }                                                       /* end loop over parsetrees */
 
        /*
@@ -1626,7 +1688,7 @@ PostgresMain(int argc, char *argv[], const char *username)
        if (!IsUnderPostmaster)
        {
                puts("\nPOSTGRES backend interactive interface ");
-               puts("$Revision: 1.247 $ $Date: 2002/02/23 01:31:36 $\n");
+               puts("$Revision: 1.248 $ $Date: 2002/02/26 22:47:08 $\n");
        }
 
        /*
@@ -2037,3 +2099,268 @@ assertTest(int val)
 #endif
 
 #endif
+
+
+/* ----------------------------------------------------------------
+ *             CreateCommandTag
+ *
+ *             utility to get a string representation of the
+ *             command operation.
+ * ----------------------------------------------------------------
+ */
+static const char *
+CreateCommandTag(Node *parsetree)
+{
+       const char   *tag;
+
+       switch (nodeTag(parsetree))
+       {
+               case T_InsertStmt:
+                       tag = "INSERT";
+                       break;
+
+               case T_DeleteStmt:
+                       tag = "DELETE";
+                       break;
+
+               case T_UpdateStmt:
+                       tag = "UPDATE";
+                       break;
+
+               case T_SelectStmt:
+                       tag = "SELECT";
+                       break;
+
+               case T_TransactionStmt:
+                       {
+                               TransactionStmt *stmt = (TransactionStmt *) parsetree;
+
+                               switch (stmt->command)
+                               {
+                                       case BEGIN_TRANS:
+                                               tag = "BEGIN";
+                                               break;
+
+                                       case COMMIT:
+                                               tag = "COMMIT";
+                                               break;
+
+                                       case ROLLBACK:
+                                               tag = "ROLLBACK";
+                                               break;
+
+                                       default:
+                                               tag = "???";
+                                               break;
+                               }
+                       }
+                       break;
+
+               case T_ClosePortalStmt:
+                       tag = "CLOSE";
+                       break;
+
+               case T_FetchStmt:
+                       {
+                               FetchStmt  *stmt = (FetchStmt *) parsetree;
+                               tag = (stmt->ismove) ? "MOVE" : "FETCH";
+                       }
+                       break;
+
+               case T_CreateStmt:
+                       tag = "CREATE";
+                       break;
+
+               case T_DropStmt:
+                       tag = "DROP";
+                       break;
+
+               case T_TruncateStmt:
+                       tag = "TRUNCATE";
+                       break;
+
+               case T_CommentStmt:
+                       tag = "COMMENT";
+                       break;
+
+               case T_CopyStmt:
+                       tag = "COPY";
+                       break;
+
+               case T_RenameStmt:
+                       tag = "ALTER";
+                       break;
+
+               case T_AlterTableStmt:
+                       tag = "ALTER";
+                       break;
+
+               case T_GrantStmt:
+                       {
+                               GrantStmt  *stmt = (GrantStmt *) parsetree;
+                               tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
+                       }
+                       break;
+
+               case T_DefineStmt:
+                       tag = "CREATE";
+                       break;
+
+               case T_ViewStmt:                /* CREATE VIEW */
+                       tag = "CREATE";
+                       break;
+
+               case T_ProcedureStmt:   /* CREATE FUNCTION */
+                       tag = "CREATE";
+                       break;
+
+               case T_IndexStmt:               /* CREATE INDEX */
+                       tag = "CREATE";
+                       break;
+
+               case T_RuleStmt:                /* CREATE RULE */
+                       tag = "CREATE";
+                       break;
+
+               case T_CreateSeqStmt:
+                       tag = "CREATE";
+                       break;
+
+               case T_RemoveAggrStmt:
+                       tag = "DROP";
+                       break;
+
+               case T_RemoveFuncStmt:
+                       tag = "DROP";
+                       break;
+
+               case T_RemoveOperStmt:
+                       tag = "DROP";
+                       break;
+
+               case T_VersionStmt:
+                       tag = "CREATE VERSION";
+                       break;
+
+               case T_CreatedbStmt:
+                       tag = "CREATE DATABASE";
+                       break;
+
+               case T_DropdbStmt:
+                       tag = "DROP DATABASE";
+                       break;
+
+               case T_NotifyStmt:
+                       tag = "NOTIFY";
+                       break;
+
+               case T_ListenStmt:
+                       tag = "LISTEN";
+                       break;
+
+               case T_UnlistenStmt:
+                       tag = "UNLISTEN";
+                       break;
+
+               case T_LoadStmt:
+                       tag = "LOAD";
+                       break;
+
+               case T_ClusterStmt:
+                       tag = "CLUSTER";
+                       break;
+
+               case T_VacuumStmt:
+                       if (((VacuumStmt *) parsetree)->vacuum)
+                               tag = "VACUUM";
+                       else
+                               tag = "ANALYZE";
+                       break;
+
+               case T_ExplainStmt:
+                       tag = "EXPLAIN";
+                       break;
+
+#ifdef NOT_USED
+               case T_RecipeStmt:
+                       tag = "EXECUTE RECIPE";
+                       break;
+#endif
+
+               case T_VariableSetStmt:
+                       tag = "SET VARIABLE";
+                       break;
+
+               case T_VariableShowStmt:
+                       tag = "SHOW VARIABLE";
+                       break;
+
+               case T_VariableResetStmt:
+                       tag = "RESET VARIABLE";
+                       break;
+
+               case T_CreateTrigStmt:
+                       tag = "CREATE";
+                       break;
+
+               case T_DropTrigStmt:
+                       tag = "DROP";
+                       break;
+
+               case T_CreatePLangStmt:
+                       tag = "CREATE";
+                       break;
+
+               case T_DropPLangStmt:
+                       tag = "DROP";
+                       break;
+
+               case T_CreateUserStmt:
+                       tag = "CREATE USER";
+                       break;
+
+               case T_AlterUserStmt:
+                       tag = "ALTER USER";
+                       break;
+
+               case T_DropUserStmt:
+                       tag = "DROP USER";
+                       break;
+
+               case T_LockStmt:
+                       tag = "LOCK TABLE";
+                       break;
+
+               case T_ConstraintsSetStmt:
+                       tag = "SET CONSTRAINTS";
+                       break;
+
+               case T_CreateGroupStmt:
+                       tag = "CREATE GROUP";
+                       break;
+
+               case T_AlterGroupStmt:
+                       tag = "ALTER GROUP";
+                       break;
+
+               case T_DropGroupStmt:
+                       tag = "DROP GROUP";
+                       break;
+
+               case T_CheckPointStmt:
+                       tag = "CHECKPOINT";
+                       break;
+
+               case T_ReindexStmt:
+                       tag = "REINDEX";
+                       break;
+
+               default:
+                       elog(DEBUG, "CreateCommandTag: unknown parse node type %d",
+                                nodeTag(parsetree));
+                       tag = "???";
+                       break;
+       }
+
+       return tag;
+}
index 91d98a2..75b99c2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.46 2001/10/25 05:49:43 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.47 2002/02/26 22:47:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -23,9 +23,6 @@
 #include "utils/ps_status.h"
 
 
-static char *CreateOperationTag(int operationType);
-
-
 /* ----------------------------------------------------------------
  *             CreateQueryDesc
  * ----------------------------------------------------------------
@@ -89,42 +86,6 @@ CreateExecutorState(void)
        return state;
 }
 
-/* ----------------------------------------------------------------
- *             CreateOperationTag
- *
- *             utility to get a string representation of the
- *             query operation.
- * ----------------------------------------------------------------
- */
-static char *
-CreateOperationTag(int operationType)
-{
-       char       *tag;
-
-       switch (operationType)
-       {
-               case CMD_SELECT:
-                       tag = "SELECT";
-                       break;
-               case CMD_INSERT:
-                       tag = "INSERT";
-                       break;
-               case CMD_DELETE:
-                       tag = "DELETE";
-                       break;
-               case CMD_UPDATE:
-                       tag = "UPDATE";
-                       break;
-               default:
-                       elog(DEBUG, "CreateOperationTag: unknown operation type %d",
-                                operationType);
-                       tag = "???";
-                       break;
-       }
-
-       return tag;
-}
-
 /* ----------------
  *             PreparePortal
  * ----------------
@@ -158,19 +119,25 @@ PreparePortal(char *portalName)
 }
 
 
-/* ----------------------------------------------------------------
- *             ProcessQuery
+/*
+ * ProcessQuery
+ *             Execute a query
  *
- *             Execute a plan, the non-parallel version
- * ----------------------------------------------------------------
+ *     parsetree: the query tree
+ *     plan: the plan tree for the query
+ *     dest: where to send results
+ *     completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
+ *             in which to store a command completion status string.
+ *
+ * completionTag may be NULL if caller doesn't want a status string.
  */
 void
 ProcessQuery(Query *parsetree,
                         Plan *plan,
-                        CommandDest dest)
+                        CommandDest dest,
+                        char *completionTag)
 {
        int                     operation = parsetree->commandType;
-       char       *tag;
        bool            isRetrieveIntoPortal;
        bool            isRetrieveIntoRelation;
        char       *intoName = NULL;
@@ -180,8 +147,6 @@ ProcessQuery(Query *parsetree,
        EState     *state;
        TupleDesc       attinfo;
 
-       set_ps_display(tag = CreateOperationTag(operation));
-
        /*
         * initialize portal/into relation status
         */
@@ -238,8 +203,7 @@ ProcessQuery(Query *parsetree,
         * When performing a retrieve into, we override the normal
         * communication destination during the processing of the the query.
         * This only affects the tuple-output function - the correct
-        * destination will still see BeginCommand() and EndCommand()
-        * messages.
+        * destination will still see the BeginCommand() call.
         */
        if (isRetrieveIntoRelation)
                queryDesc->dest = None;
@@ -263,7 +227,7 @@ ProcessQuery(Query *parsetree,
                                 attinfo,
                                 isRetrieveIntoRelation,
                                 isRetrieveIntoPortal,
-                                tag,
+                                NULL,                  /* not used */
                                 dest);
 
        /*
@@ -281,7 +245,9 @@ ProcessQuery(Query *parsetree,
                /* Now we can return to caller's memory context. */
                MemoryContextSwitchTo(oldContext);
 
-               EndCommand(tag, dest);
+               /* Set completion tag.  SQL calls this operation DECLARE CURSOR */
+               if (completionTag)
+                       strcpy(completionTag, "DECLARE");
 
                return;
        }
@@ -292,16 +258,42 @@ ProcessQuery(Query *parsetree,
         */
        ExecutorRun(queryDesc, state, EXEC_RUN, 0L);
 
-       /* save infos for EndCommand */
-       UpdateCommandInfo(operation, state->es_lastoid, state->es_processed);
-
        /*
-        * Now, we close down all the scans and free allocated resources.
+        * Build command completion status string, if caller wants one.
         */
-       ExecutorEnd(queryDesc, state);
+       if (completionTag)
+       {
+               Oid             lastOid;
+
+               switch (operation)
+               {
+                       case CMD_SELECT:
+                               strcpy(completionTag, "SELECT");
+                               break;
+                       case CMD_INSERT:
+                               if (state->es_processed == 1)
+                                       lastOid = state->es_lastoid;
+                               else
+                                       lastOid = InvalidOid;
+                               snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
+                                                "INSERT %u %u", lastOid, state->es_processed);
+                               break;
+                       case CMD_UPDATE:
+                               snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
+                                                "UPDATE %u", state->es_processed);
+                               break;
+                       case CMD_DELETE:
+                               snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
+                                                "DELETE %u", state->es_processed);
+                               break;
+                       default:
+                               strcpy(completionTag, "???");
+                               break;
+               }
+       }
 
        /*
-        * Notify the destination of end of processing.
+        * Now, we close down all the scans and free allocated resources.
         */
-       EndCommand(tag, dest);
+       ExecutorEnd(queryDesc, state);
 }
index f80a6bd..a6a8b56 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.126 2002/02/24 20:20:20 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.127 2002/02/26 22:47:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,7 +44,6 @@
 #include "rewrite/rewriteRemove.h"
 #include "tcop/utility.h"
 #include "utils/acl.h"
-#include "utils/ps_status.h"
 #include "utils/syscache.h"
 #include "utils/temprel.h"
 #include "access/xlog.h"
@@ -130,18 +129,31 @@ CheckDropPermissions(char *name, char rightkind)
 }
 
 
-/* ----------------
+/*
+ * ProcessUtility
  *             general utility function invoker
- * ----------------
+ *
+ *     parsetree: the parse tree for the utility statement
+ *     dest: where to send results
+ *     completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
+ *             in which to store a command completion status string.
+ *
+ * completionTag is only set nonempty if we want to return a nondefault
+ * status (currently, only used for MOVE/FETCH).
+ *
+ * completionTag may be NULL if caller doesn't want a status string.
  */
 void
 ProcessUtility(Node *parsetree,
-                          CommandDest dest)
+                          CommandDest dest,
+                          char *completionTag)
 {
-       char       *commandTag = NULL;
        char       *relname;
        char       *relationName;
 
+       if (completionTag)
+               completionTag[0] = '\0';
+
        switch (nodeTag(parsetree))
        {
                        /*
@@ -155,17 +167,14 @@ ProcessUtility(Node *parsetree,
                                switch (stmt->command)
                                {
                                        case BEGIN_TRANS:
-                                               set_ps_display(commandTag = "BEGIN");
                                                BeginTransactionBlock();
                                                break;
 
                                        case COMMIT:
-                                               set_ps_display(commandTag = "COMMIT");
                                                EndTransactionBlock();
                                                break;
 
                                        case ROLLBACK:
-                                               set_ps_display(commandTag = "ROLLBACK");
                                                UserAbortTransactionBlock();
                                                break;
                                }
@@ -180,8 +189,6 @@ ProcessUtility(Node *parsetree,
                        {
                                ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CLOSE");
-
                                PerformPortalClose(stmt->portalname, dest);
                        }
                        break;
@@ -193,8 +200,6 @@ ProcessUtility(Node *parsetree,
                                bool            forward;
                                int                     count;
 
-                               set_ps_display(commandTag = (stmt->ismove) ? "MOVE" : "FETCH");
-
                                SetQuerySnapshot();
 
                                forward = (bool) (stmt->direction == FORWARD);
@@ -204,8 +209,9 @@ ProcessUtility(Node *parsetree,
                                 */
 
                                count = stmt->howMany;
-                               PerformPortalFetch(portalName, forward, count, commandTag,
-                                                                  (stmt->ismove) ? None : dest);               /* /dev/null for MOVE */
+                               PerformPortalFetch(portalName, forward, count,
+                                                                  (stmt->ismove) ? None : dest,
+                                                                  completionTag);
                        }
                        break;
 
@@ -215,8 +221,6 @@ ProcessUtility(Node *parsetree,
                         *
                         */
                case T_CreateStmt:
-                       set_ps_display(commandTag = "CREATE");
-
                        DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
 
                        /*
@@ -234,8 +238,6 @@ ProcessUtility(Node *parsetree,
                                List       *args = stmt->names;
                                List       *arg;
 
-                               set_ps_display(commandTag = "DROP");
-
                                foreach(arg, args)
                                {
                                        relname = strVal(lfirst(arg));
@@ -296,8 +298,6 @@ ProcessUtility(Node *parsetree,
                        {
                                Relation        rel;
 
-                               set_ps_display(commandTag = "TRUNCATE");
-
                                relname = ((TruncateStmt *) parsetree)->relName;
                                if (!allowSystemTableMods && IsSystemRelationName(relname))
                                        elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
@@ -325,8 +325,6 @@ ProcessUtility(Node *parsetree,
 
                                statement = ((CommentStmt *) parsetree);
 
-                               set_ps_display(commandTag = "COMMENT");
-
                                CommentObject(statement->objtype, statement->objname,
                                                          statement->objproperty, statement->objlist,
                                                          statement->comment);
@@ -337,8 +335,6 @@ ProcessUtility(Node *parsetree,
                        {
                                CopyStmt   *stmt = (CopyStmt *) parsetree;
 
-                               set_ps_display(commandTag = "COPY");
-
                                if (stmt->direction != FROM)
                                        SetQuerySnapshot();
 
@@ -365,8 +361,6 @@ ProcessUtility(Node *parsetree,
                        {
                                RenameStmt *stmt = (RenameStmt *) parsetree;
 
-                               set_ps_display(commandTag = "ALTER");
-
                                relname = stmt->relname;
                                if (!allowSystemTableMods && IsSystemRelationName(relname))
                                        elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
@@ -413,8 +407,6 @@ ProcessUtility(Node *parsetree,
                        {
                                AlterTableStmt *stmt = (AlterTableStmt *) parsetree;
 
-                               set_ps_display(commandTag = "ALTER");
-
                                /*
                                 * Some or all of these functions are recursive to cover
                                 * inherited things, so permission checks are done there.
@@ -475,9 +467,6 @@ ProcessUtility(Node *parsetree,
                        {
                                GrantStmt  *stmt = (GrantStmt *) parsetree;
 
-                               commandTag = stmt->is_grant ? "GRANT" : "REVOKE";
-                               set_ps_display(commandTag);
-
                                ExecuteGrantStmt(stmt);
                        }
                        break;
@@ -491,8 +480,6 @@ ProcessUtility(Node *parsetree,
                        {
                                DefineStmt *stmt = (DefineStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE");
-
                                switch (stmt->defType)
                                {
                                        case OPERATOR:
@@ -514,15 +501,11 @@ ProcessUtility(Node *parsetree,
                        {
                                ViewStmt   *stmt = (ViewStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE");
-
                                DefineView(stmt->viewname, stmt->query);                /* retrieve parsetree */
                        }
                        break;
 
                case T_ProcedureStmt:   /* CREATE FUNCTION */
-                       set_ps_display(commandTag = "CREATE");
-
                        CreateFunction((ProcedureStmt *) parsetree);
                        break;
 
@@ -530,8 +513,6 @@ ProcessUtility(Node *parsetree,
                        {
                                IndexStmt  *stmt = (IndexStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE");
-
                                relname = stmt->relname;
                                if (!allowSystemTableMods && IsSystemRelationName(relname))
                                        elog(ERROR, "CREATE INDEX: relation \"%s\" is a system catalog",
@@ -559,15 +540,12 @@ ProcessUtility(Node *parsetree,
                                aclcheck_result = pg_aclcheck(relname, GetUserId(), ACL_RULE);
                                if (aclcheck_result != ACLCHECK_OK)
                                        elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
-                               set_ps_display(commandTag = "CREATE");
 
                                DefineQueryRewrite(stmt);
                        }
                        break;
 
                case T_CreateSeqStmt:
-                       set_ps_display(commandTag = "CREATE");
-
                        DefineSequence((CreateSeqStmt *) parsetree);
                        break;
 
@@ -576,8 +554,6 @@ ProcessUtility(Node *parsetree,
                                RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
                                char       *typename = (char *) NULL;
 
-                               set_ps_display(commandTag = "DROP");
-
                                if (stmt->aggtype != NULL)
                                        typename = TypeNameToInternalName((TypeName *) stmt->aggtype);
 
@@ -589,8 +565,6 @@ ProcessUtility(Node *parsetree,
                        {
                                RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
 
-                               set_ps_display(commandTag = "DROP");
-
                                RemoveFunction(stmt->funcname, stmt->args);
                        }
                        break;
@@ -603,8 +577,6 @@ ProcessUtility(Node *parsetree,
                                char       *typename1 = (char *) NULL;
                                char       *typename2 = (char *) NULL;
 
-                               set_ps_display(commandTag = "DROP");
-
                                if (typenode1 != NULL)
                                        typename1 = TypeNameToInternalName(typenode1);
                                if (typenode2 != NULL)
@@ -622,8 +594,6 @@ ProcessUtility(Node *parsetree,
                        {
                                CreatedbStmt *stmt = (CreatedbStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE DATABASE");
-
                                createdb(stmt->dbname, stmt->dbowner,
                                                 stmt->dbpath, stmt->dbtemplate,
                                                 stmt->encoding);
@@ -634,8 +604,6 @@ ProcessUtility(Node *parsetree,
                        {
                                DropdbStmt *stmt = (DropdbStmt *) parsetree;
 
-                               set_ps_display(commandTag = "DROP DATABASE");
-
                                dropdb(stmt->dbname);
                        }
                        break;
@@ -645,8 +613,6 @@ ProcessUtility(Node *parsetree,
                        {
                                NotifyStmt *stmt = (NotifyStmt *) parsetree;
 
-                               set_ps_display(commandTag = "NOTIFY");
-
                                Async_Notify(stmt->relname);
                        }
                        break;
@@ -655,8 +621,6 @@ ProcessUtility(Node *parsetree,
                        {
                                ListenStmt *stmt = (ListenStmt *) parsetree;
 
-                               set_ps_display(commandTag = "LISTEN");
-
                                Async_Listen(stmt->relname, MyProcPid);
                        }
                        break;
@@ -665,8 +629,6 @@ ProcessUtility(Node *parsetree,
                        {
                                UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
 
-                               set_ps_display(commandTag = "UNLISTEN");
-
                                Async_Unlisten(stmt->relname, MyProcPid);
                        }
                        break;
@@ -679,8 +641,6 @@ ProcessUtility(Node *parsetree,
                        {
                                LoadStmt   *stmt = (LoadStmt *) parsetree;
 
-                               set_ps_display(commandTag = "LOAD");
-
                                closeAllVfds(); /* probably not necessary... */
                                load_file(stmt->filename);
                        }
@@ -690,8 +650,6 @@ ProcessUtility(Node *parsetree,
                        {
                                ClusterStmt *stmt = (ClusterStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CLUSTER");
-
                                relname = stmt->relname;
                                if (IsSystemRelationName(relname))
                                        elog(ERROR, "CLUSTER: relation \"%s\" is a system catalog",
@@ -704,12 +662,6 @@ ProcessUtility(Node *parsetree,
                        break;
 
                case T_VacuumStmt:
-                       if (((VacuumStmt *) parsetree)->vacuum)
-                               commandTag = "VACUUM";
-                       else
-                               commandTag = "ANALYZE";
-                       set_ps_display(commandTag);
-
                        vacuum((VacuumStmt *) parsetree);
                        break;
 
@@ -717,8 +669,6 @@ ProcessUtility(Node *parsetree,
                        {
                                ExplainStmt *stmt = (ExplainStmt *) parsetree;
 
-                               set_ps_display(commandTag = "EXPLAIN");
-
                                ExplainQuery(stmt->query, stmt->verbose, stmt->analyze, dest);
                        }
                        break;
@@ -732,8 +682,6 @@ ProcessUtility(Node *parsetree,
                        {
                                RecipeStmt *stmt = (RecipeStmt *) parsetree;
 
-                               set_ps_display(commandTag = "EXECUTE RECIPE");
-
                                beginRecipe(stmt);
                        }
                        break;
@@ -747,7 +695,6 @@ ProcessUtility(Node *parsetree,
                                VariableSetStmt *n = (VariableSetStmt *) parsetree;
 
                                SetPGVariable(n->name, n->args);
-                               set_ps_display(commandTag = "SET VARIABLE");
                        }
                        break;
 
@@ -756,7 +703,6 @@ ProcessUtility(Node *parsetree,
                                VariableShowStmt *n = (VariableShowStmt *) parsetree;
 
                                GetPGVariable(n->name);
-                               set_ps_display(commandTag = "SHOW VARIABLE");
                        }
                        break;
 
@@ -765,7 +711,6 @@ ProcessUtility(Node *parsetree,
                                VariableResetStmt *n = (VariableResetStmt *) parsetree;
 
                                ResetPGVariable(n->name);
-                               set_ps_display(commandTag = "RESET VARIABLE");
                        }
                        break;
 
@@ -773,14 +718,10 @@ ProcessUtility(Node *parsetree,
                         * ******************************** TRIGGER statements *******************************
                         */
                case T_CreateTrigStmt:
-                       set_ps_display(commandTag = "CREATE");
-
                        CreateTrigger((CreateTrigStmt *) parsetree);
                        break;
 
                case T_DropTrigStmt:
-                       set_ps_display(commandTag = "DROP");
-
                        DropTrigger((DropTrigStmt *) parsetree);
                        break;
 
@@ -788,14 +729,10 @@ ProcessUtility(Node *parsetree,
                         * ************* PROCEDURAL LANGUAGE statements *****************
                         */
                case T_CreatePLangStmt:
-                       set_ps_display(commandTag = "CREATE");
-
                        CreateProceduralLanguage((CreatePLangStmt *) parsetree);
                        break;
 
                case T_DropPLangStmt:
-                       set_ps_display(commandTag = "DROP");
-
                        DropProceduralLanguage((DropPLangStmt *) parsetree);
                        break;
 
@@ -804,57 +741,39 @@ ProcessUtility(Node *parsetree,
                         *
                         */
                case T_CreateUserStmt:
-                       set_ps_display(commandTag = "CREATE USER");
-
                        CreateUser((CreateUserStmt *) parsetree);
                        break;
 
                case T_AlterUserStmt:
-                       set_ps_display(commandTag = "ALTER USER");
-
                        AlterUser((AlterUserStmt *) parsetree);
                        break;
 
                case T_DropUserStmt:
-                       set_ps_display(commandTag = "DROP USER");
-
                        DropUser((DropUserStmt *) parsetree);
                        break;
 
                case T_LockStmt:
-                       set_ps_display(commandTag = "LOCK TABLE");
-
                        LockTableCommand((LockStmt *) parsetree);
                        break;
 
                case T_ConstraintsSetStmt:
-                       set_ps_display(commandTag = "SET CONSTRAINTS");
-
                        DeferredTriggerSetState((ConstraintsSetStmt *) parsetree);
                        break;
 
                case T_CreateGroupStmt:
-                       set_ps_display(commandTag = "CREATE GROUP");
-
                        CreateGroup((CreateGroupStmt *) parsetree);
                        break;
 
                case T_AlterGroupStmt:
-                       set_ps_display(commandTag = "ALTER GROUP");
-
                        AlterGroup((AlterGroupStmt *) parsetree, "ALTER GROUP");
                        break;
 
                case T_DropGroupStmt:
-                       set_ps_display(commandTag = "DROP GROUP");
-
                        DropGroup((DropGroupStmt *) parsetree);
                        break;
 
                case T_CheckPointStmt:
                        {
-                               set_ps_display(commandTag = "CHECKPOINT");
-
                                if (!superuser())
                                        elog(ERROR, "permission denied");
                                CreateCheckPoint(false);
@@ -865,8 +784,6 @@ ProcessUtility(Node *parsetree,
                        {
                                ReindexStmt *stmt = (ReindexStmt *) parsetree;
 
-                               set_ps_display(commandTag = "REINDEX");
-
                                switch (stmt->reindexType)
                                {
                                        case INDEX:
@@ -912,9 +829,4 @@ ProcessUtility(Node *parsetree,
                                 nodeTag(parsetree));
                        break;
        }
-
-       /*
-        * tell fe/be or whatever that we're done.
-        */
-       EndCommand(commandTag, dest);
 }
index 4531b90..ee4e2c0 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: command.h,v 1.31 2001/11/05 17:46:33 momjian Exp $
+ * $Id: command.h,v 1.32 2002/02/26 22:47:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,7 +27,7 @@
  *             "ERROR" if portal not found.
  */
 extern void PerformPortalFetch(char *name, bool forward, int count,
-                                  char *tag, CommandDest dest);
+                                                          CommandDest dest, char *completionTag);
 
 /*
  * PerformPortalClose
index 0b40fe9..bfcbc91 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.153 2002/02/24 20:20:21 tgl Exp $
+ * $Id: parsenodes.h,v 1.154 2002/02/26 22:47:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -48,6 +48,8 @@ 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) */
index e23eb6b..d5ac420 100644 (file)
@@ -39,7 +39,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: dest.h,v 1.28 2001/11/05 17:46:36 momjian Exp $
+ * $Id: dest.h,v 1.29 2002/02/26 22:47:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "access/htup.h"
 
+
+/* buffer size to use for command completion tags */
+#define COMPLETION_TAG_BUFSIZE 64
+
+
 /* ----------------
  *             CommandDest is a simplistic means of identifying the desired
  *             destination.  Someday this will probably need to be improved.
@@ -88,7 +93,7 @@ extern void BeginCommand(char *pname, int operation, TupleDesc attinfo,
                         bool isIntoRel, bool isIntoPortal, char *tag,
                         CommandDest dest);
 extern DestReceiver *DestToFunction(CommandDest dest);
-extern void EndCommand(char *commandTag, CommandDest dest);
+extern void EndCommand(const char *commandTag, CommandDest dest);
 
 /* Additional functions that go with destination management, more or less. */
 
@@ -96,6 +101,5 @@ extern void SendCopyBegin(void);
 extern void ReceiveCopyBegin(void);
 extern void NullCommand(CommandDest dest);
 extern void ReadyForQuery(CommandDest dest);
-extern void UpdateCommandInfo(int operation, Oid lastoid, uint32 tuples);
 
 #endif   /* DEST_H */
index dbca9de..6333e01 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pquery.h,v 1.19 2001/11/05 17:46:36 momjian Exp $
+ * $Id: pquery.h,v 1.20 2002/02/26 22:47:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,7 +18,8 @@
 #include "utils/portal.h"
 
 
-extern void ProcessQuery(Query *parsetree, Plan *plan, CommandDest dest);
+extern void ProcessQuery(Query *parsetree, Plan *plan, CommandDest dest,
+                                                char *completionTag);
 
 extern EState *CreateExecutorState(void);
 
index 8e05c42..5b37eb0 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: utility.h,v 1.13 2001/11/05 17:46:36 momjian Exp $
+ * $Id: utility.h,v 1.14 2002/02/26 22:47:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,6 +16,7 @@
 
 #include "executor/execdesc.h"
 
-extern void ProcessUtility(Node *parsetree, CommandDest dest);
+extern void ProcessUtility(Node *parsetree, CommandDest dest,
+                                                  char *completionTag);
 
 #endif   /* UTILITY_H */