Re: Fix issuing of multiple command completions per command - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: Fix issuing of multiple command completions per command
Date
Msg-id 200202251834.g1PIYN926066@candle.pha.pa.us
Whole thread Raw
In response to Fix issuing of multiple command completions per command  (Fernando Nasser <fnasser@redhat.com>)
List pgsql-patches
Your patch has been added to the PostgreSQL unapplied patches list at:

    http://candle.pha.pa.us/cgi-bin/pgpatches

I will try to apply it within the next 48 hours.

---------------------------------------------------------------------------


Fernando Nasser wrote:
> (Please note that "[PATCHES] Allow arbitrary levels of
> analyze/rewriting"
> must be applied before this patch)
>
> This patch prevents the issue of multiple command completions
> when queries are rewritten into a sequence queries by analyze/rewrite.
> Currently the front ends are receiving many;  libpq just uses the last
> one received so that is why we see only one response in psql, for
> instance.
>
> It fixes a bug where the user receives a bogus completion message
> for queries that have been turned into a sequence of queries where
> the last one has a different completion tag.
>
> It also prevents command-completions to be generated by utility commands
> that are inside SQL-functions.
>
> It also fixes some misplaced calls to set ps_status.
>
> Furthermore, these changes made possible to reduce the number of
> times ps_status is set (a request from Tom Lane). This is done by
> default but it is still possible to set a compiler flag and have
> it generate more calls as it does today (one for each query produced
> by the rewriting of the original query).
>
>
> Here is basically what is done:
>
> The completion is sent by EndCommand().  This call is used OK by
> plannable queries and is necessary there for telling that the data
> sent to a backend has come to an end.  Utilities, however, don't
> send any data (except FETCH) and may be rewritten into a series of
> other utility queries.  The changes consolidate the calls to
> EndCommand() for utility queries and let the plannable ones
> handle it pairwise with BeginCommand() (which is not used by
> utility queries).
>
>
> ChangeLog:
>
>         * src/backend/commands/command.c (PerformPortalFetch): Send
>         command completion so that fe knows we are done with sending
> data.
>         * src/backend/commands/explain.c (ExplainOneQuery): Set
> ps_status
>         to EXPLAIN or SELECT (for the EXPLAIN ANALYZE case).
>         * src/backend/executor/functions.c (postquel_getnext): Do not
> send
>         command completion messages for utilities inside SQL-functions
>         (one will be sent for the command that invoked the function).
>         * src/backend/executor/spi.c (_SPI_execute, _SPI_execute_plan):
> Add
>         comments.
>         * src/backend/tcop/postgres.c (pg_exec_query_string):
>         Do not send a command completion message or set the ps_status
> for
>         each utility query that results for the rewriting of a command;
>         just send one for the original command.  Let plannable queries
> take
>         care of their own completion.
>         (CreateCommandTag): New function.  Create a command completion
> tag
>         based on the parse tree node (rather than on an already/analyzed
>         query node).
>         * src/backend/tcop/utility.c (ProcessUtility): Do
>         not meddle with ps_status or command completion in this
> function.
>         * src/backend/tcop/pquery.c (ProcessQuery): Let the caller set
>         ps_status.
>
>
>
>
>
> --
> Fernando Nasser
> Red Hat Canada Ltd.                     E-Mail:  fnasser@redhat.com
> 2323 Yonge Street, Suite #300
> Toronto, Ontario   M4P 2C9

> Index: src/backend/commands/command.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/commands/command.c,v
> retrieving revision 1.152
> diff -c -p -r1.152 command.c
> *** src/backend/commands/command.c    2002/01/03 23:19:30    1.152
> --- src/backend/commands/command.c    2002/02/14 10:49:18
> *************** PerformPortalFetch(char *name,
> *** 215,231 ****
>       }
>
>       /*
>        * Clean up and switch back to old context.
>        */
>       if (temp_desc)
>           pfree(queryDesc);
>
>       MemoryContextSwitchTo(oldcontext);
> -
> -     /*
> -      * Note: the "end-of-command" tag is returned by higher-level utility
> -      * code
> -      */
>   }
>
>   /* --------------------------------
> --- 215,231 ----
>       }
>
>       /*
> +      * tell fe/be or whatever that we're done sending the data
> +      */
> +     EndCommand(tag, queryDesc->dest);
> +
> +     /*
>        * Clean up and switch back to old context.
>        */
>       if (temp_desc)
>           pfree(queryDesc);
>
>       MemoryContextSwitchTo(oldcontext);
>   }
>
>   /* --------------------------------
> Index: src/backend/commands/explain.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/commands/explain.c,v
> retrieving revision 1.67
> diff -c -p -r1.67 explain.c
> *** src/backend/commands/explain.c    2001/10/25 05:49:25    1.67
> --- src/backend/commands/explain.c    2002/02/14 10:49:18
> ***************
> *** 19,24 ****
> --- 19,25 ----
>   #include "parser/parsetree.h"
>   #include "rewrite/rewriteHandler.h"
>   #include "tcop/pquery.h"
> + #include "utils/ps_status.h"
>   #include "utils/relcache.h"
>
>   typedef struct ExplainState
> *************** ExplainOneQuery(Query *query, bool verbo
> *** 113,118 ****
> --- 114,121 ----
>           struct timeval starttime;
>           struct timeval endtime;
>
> +         set_ps_display("SELECT");
> +
>           /*
>            * Set up the instrumentation for the top node. This will cascade
>            * during plan initialisation
> *************** ExplainOneQuery(Query *query, bool verbo
> *** 133,138 ****
> --- 136,143 ----
>           }
>           totaltime = (double) endtime.tv_sec +
>               (double) endtime.tv_usec / 1000000.0;
> +
> +         set_ps_display("EXPLAIN");
>       }
>
>       es = (ExplainState *) palloc(sizeof(ExplainState));
> Index: src/backend/executor/functions.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/executor/functions.c,v
> retrieving revision 1.47
> diff -c -p -r1.47 functions.c
> *** src/backend/executor/functions.c    2001/10/28 06:25:43    1.47
> --- src/backend/executor/functions.c    2002/02/14 10:49:18
> *************** postquel_getnext(execution_state *es)
> *** 276,281 ****
> --- 276,283 ----
>            * Process a utility command. (create, destroy...)    DZ - 30-8-1996
>            */
>           ProcessUtility(es->qd->parsetree->utilityStmt, es->qd->dest);
> +         /* We should not call EndCommand() here as we are inside a function
> +          * call and command-complete reports should not be issued. */
>           if (!LAST_POSTQUEL_COMMAND(es))
>               CommandCounterIncrement();
>           return (TupleTableSlot *) NULL;
> Index: src/backend/executor/spi.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/executor/spi.c,v
> retrieving revision 1.64
> diff -c -p -r1.64 spi.c
> *** src/backend/executor/spi.c    2002/01/03 20:30:47    1.64
> --- src/backend/executor/spi.c    2002/02/14 10:49:18
> *************** _SPI_execute(char *src, int tcount, _SPI
> *** 1010,1015 ****
> --- 1010,1017 ----
>               if (plan == NULL)
>               {
>                   ProcessUtility(queryTree->utilityStmt, None);
> +                 /* We don't need to call EndCommand() as we don't want to
> +                  * send anything (dest = None) */
>                   if (!islastquery)
>                       CommandCounterIncrement();
>                   else
> *************** _SPI_execute_plan(_SPI_plan *plan, Datum
> *** 1084,1089 ****
> --- 1086,1093 ----
>           if (queryTree->commandType == CMD_UTILITY)
>           {
>               ProcessUtility(queryTree->utilityStmt, None);
> +             /* We don't need to call EndCommand() as we don't want to
> +              * send anything (dest = None) */
>               if (!islastquery)
>                   CommandCounterIncrement();
>               else
> Index: src/backend/parser/analyze.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/parser/analyze.c,v
> retrieving revision 1.213
> diff -c -p -r1.213 analyze.c
> *** src/backend/parser/analyze.c    2002/01/03 23:21:31    1.213
> --- src/backend/parser/analyze.c    2002/02/14 10:49:18
> *************** typedef struct
> *** 64,80 ****
>   } CreateStmtContext;
>
>
> ! static Query *transformStmt(ParseState *pstate, Node *stmt);
>   static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
> ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
>   static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
> ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
>   static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
>   static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
>   static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt);
>   static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
> ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
> ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt);
>   static void transformColumnDefinition(ParseState *pstate,
>                             CreateStmtContext *cxt,
>                             ColumnDef *column);
> --- 64,85 ----
>   } CreateStmtContext;
>
>
> ! static Query *transformStmt(ParseState *pstate, Node *stmt,
> !                         List **extras_before, List **extras_after);
>   static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
> ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
> !                         List **extras_before, List **extras_after);
>   static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
> ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt,
> !                         List **extras_before, List **extras_after);
>   static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
>   static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
>   static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt);
>   static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
> ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
> !                         List **extras_before, List **extras_after);
> ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
> !                         List **extras_before, List **extras_after);
>   static void transformColumnDefinition(ParseState *pstate,
>                             CreateStmtContext *cxt,
>                             ColumnDef *column);
> *************** static Oid    transformFkeyGetColType(Creat
> *** 101,109 ****
>   static void release_pstate_resources(ParseState *pstate);
>   static FromExpr *makeFromExpr(List *fromlist, Node *quals);
>
> - /* kluge to return extra info from transformCreateStmt() */
> - static List *extras_before;
> - static List *extras_after;
>
>
>   /*
> --- 106,111 ----
> *************** parse_analyze(Node *parseTree, ParseStat
> *** 121,137 ****
>       List       *result = NIL;
>       ParseState *pstate = make_parsestate(parentParseState);
>       Query       *query;
>
> !     extras_before = extras_after = NIL;
> !
> !     query = transformStmt(pstate, parseTree);
>       release_pstate_resources(pstate);
> !
>       while (extras_before != NIL)
>       {
> !         result = lappend(result,
> !                          transformStmt(pstate, lfirst(extras_before)));
> !         release_pstate_resources(pstate);
>           extras_before = lnext(extras_before);
>       }
>
> --- 123,138 ----
>       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;
>
> !     query = transformStmt(pstate, parseTree, &extras_before, &extras_after);
>       release_pstate_resources(pstate);
> !
>       while (extras_before != NIL)
>       {
> !         result = nconc(result, parse_analyze(lfirst(extras_before), pstate));
>           extras_before = lnext(extras_before);
>       }
>
> *************** parse_analyze(Node *parseTree, ParseStat
> *** 139,147 ****
>
>       while (extras_after != NIL)
>       {
> !         result = lappend(result,
> !                          transformStmt(pstate, lfirst(extras_after)));
> !         release_pstate_resources(pstate);
>           extras_after = lnext(extras_after);
>       }
>
> --- 140,146 ----
>
>       while (extras_after != NIL)
>       {
> !         result = nconc(result, parse_analyze(lfirst(extras_after), pstate));
>           extras_after = lnext(extras_after);
>       }
>
> *************** release_pstate_resources(ParseState *pst
> *** 164,170 ****
>    *      transform a Parse tree into a Query tree.
>    */
>   static Query *
> ! transformStmt(ParseState *pstate, Node *parseTree)
>   {
>       Query       *result = NULL;
>
> --- 163,170 ----
>    *      transform a Parse tree into a Query tree.
>    */
>   static Query *
> ! transformStmt(ParseState *pstate, Node *parseTree,
> !               List **extras_before,    List **extras_after)
>   {
>       Query       *result = NULL;
>
> *************** transformStmt(ParseState *pstate, Node *
> *** 174,180 ****
>                * Non-optimizable statements
>                */
>           case T_CreateStmt:
> !             result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
>               break;
>
>           case T_IndexStmt:
> --- 174,181 ----
>                * Non-optimizable statements
>                */
>           case T_CreateStmt:
> !             result = transformCreateStmt(pstate, (CreateStmt *) parseTree,
> !                                     extras_before, extras_after);
>               break;
>
>           case T_IndexStmt:
> *************** transformStmt(ParseState *pstate, Node *
> *** 182,195 ****
>               break;
>
>           case T_RuleStmt:
> !             result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
>               break;
>
>           case T_ViewStmt:
>               {
>                   ViewStmt   *n = (ViewStmt *) parseTree;
>
> !                 n->query = transformStmt(pstate, (Node *) n->query);
>
>                   /*
>                    * If a list of column names was given, run through and
> --- 183,198 ----
>               break;
>
>           case T_RuleStmt:
> !             result = transformRuleStmt(pstate, (RuleStmt *) parseTree,
> !                                     extras_before, extras_after);
>               break;
>
>           case T_ViewStmt:
>               {
>                   ViewStmt   *n = (ViewStmt *) parseTree;
>
> !                 n->query = transformStmt(pstate, (Node *) n->query,
> !                                     extras_before, extras_after);
>
>                   /*
>                    * If a list of column names was given, run through and
> *************** transformStmt(ParseState *pstate, Node *
> *** 239,258 ****
>
>                   result = makeNode(Query);
>                   result->commandType = CMD_UTILITY;
> !                 n->query = transformStmt(pstate, (Node *) n->query);
>                   result->utilityStmt = (Node *) parseTree;
>               }
>               break;
>
>           case T_AlterTableStmt:
> !             result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree);
>               break;
>
>               /*
>                * Optimizable statements
>                */
>           case T_InsertStmt:
> !             result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
>               break;
>
>           case T_DeleteStmt:
> --- 242,264 ----
>
>                   result = makeNode(Query);
>                   result->commandType = CMD_UTILITY;
> !                 n->query = transformStmt(pstate, (Node *) n->query,
> !                                 extras_before, extras_after);
>                   result->utilityStmt = (Node *) parseTree;
>               }
>               break;
>
>           case T_AlterTableStmt:
> !             result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree,
> !                                         extras_before, extras_after);
>               break;
>
>               /*
>                * Optimizable statements
>                */
>           case T_InsertStmt:
> !             result = transformInsertStmt(pstate, (InsertStmt *) parseTree,
> !                                         extras_before, extras_after);
>               break;
>
>           case T_DeleteStmt:
> *************** transformDeleteStmt(ParseState *pstate,
> *** 337,343 ****
>    *      transform an Insert Statement
>    */
>   static Query *
> ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
>   {
>       Query       *qry = makeNode(Query);
>       List       *sub_rtable;
> --- 343,350 ----
>    *      transform an Insert Statement
>    */
>   static Query *
> ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
> !                     List **extras_before, List **extras_after)
>   {
>       Query       *qry = makeNode(Query);
>       List       *sub_rtable;
> *************** transformInsertStmt(ParseState *pstate,
> *** 402,408 ****
>           sub_pstate->p_rtable = sub_rtable;
>           sub_pstate->p_namespace = sub_namespace;
>
> !         selectQuery = transformStmt(sub_pstate, stmt->selectStmt);
>
>           release_pstate_resources(sub_pstate);
>           pfree(sub_pstate);
> --- 409,420 ----
>           sub_pstate->p_rtable = sub_rtable;
>           sub_pstate->p_namespace = sub_namespace;
>
> !         /*
> !          * Note: we are not expecting that extras_before and extras_after
> !          * are going to be used by the transformation of the SELECT statement.
> !           */
> !         selectQuery = transformStmt(sub_pstate, stmt->selectStmt,
> !                                 extras_before, extras_after);
>
>           release_pstate_resources(sub_pstate);
>           pfree(sub_pstate);
> *************** CreateIndexName(char *table_name, char *
> *** 658,664 ****
>    *      - thomas 1997-12-02
>    */
>   static Query *
> ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
>   {
>       CreateStmtContext cxt;
>       Query       *q;
> --- 670,677 ----
>    *      - thomas 1997-12-02
>    */
>   static Query *
> ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
> !                     List **extras_before, List **extras_after)
>   {
>       CreateStmtContext cxt;
>       Query       *q;
> *************** transformCreateStmt(ParseState *pstate,
> *** 728,735 ****
>       q->utilityStmt = (Node *) stmt;
>       stmt->tableElts = cxt.columns;
>       stmt->constraints = cxt.ckconstraints;
> !     extras_before = cxt.blist;
> !     extras_after = cxt.alist;
>
>       return q;
>   }
> --- 741,748 ----
>       q->utilityStmt = (Node *) stmt;
>       stmt->tableElts = cxt.columns;
>       stmt->constraints = cxt.ckconstraints;
> !     *extras_before = nconc (*extras_before, cxt.blist);
> !     *extras_after = nconc (cxt.alist, *extras_after);
>
>       return q;
>   }
> *************** transformIndexStmt(ParseState *pstate, I
> *** 1668,1674 ****
>    *      trees which is transformed into a list of query trees.
>    */
>   static Query *
> ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
>   {
>       Query       *qry;
>       RangeTblEntry *oldrte;
> --- 1681,1688 ----
>    *      trees which is transformed into a list of query trees.
>    */
>   static Query *
> ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
> !                 List **extras_before, List **extras_after)
>   {
>       Query       *qry;
>       RangeTblEntry *oldrte;
> *************** transformRuleStmt(ParseState *pstate, Ru
> *** 1797,1803 ****
>               addRTEtoQuery(sub_pstate, newrte, false, true);
>
>               /* Transform the rule action statement */
> !             top_subqry = transformStmt(sub_pstate, action);
>
>               /*
>                * We cannot support utility-statement actions (eg NOTIFY)
> --- 1811,1818 ----
>               addRTEtoQuery(sub_pstate, newrte, false, true);
>
>               /* Transform the rule action statement */
> !             top_subqry = transformStmt(sub_pstate, action,
> !                                 extras_before, extras_after);
>
>               /*
>                * We cannot support utility-statement actions (eg NOTIFY)
> *************** transformUpdateStmt(ParseState *pstate,
> *** 2494,2500 ****
>    *    transform an Alter Table Statement
>    */
>   static Query *
> ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt)
>   {
>       CreateStmtContext cxt;
>       Query       *qry;
> --- 2509,2516 ----
>    *    transform an Alter Table Statement
>    */
>   static Query *
> ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
> !                         List **extras_before, List **extras_after)
>   {
>       CreateStmtContext cxt;
>       Query       *qry;
> *************** transformAlterTableStmt(ParseState *psta
> *** 2534,2541 ****
>               transformFKConstraints(pstate, &cxt);
>
>               ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints;
> !             extras_before = cxt.blist;
> !             extras_after = cxt.alist;
>               break;
>
>           case 'C':
> --- 2550,2557 ----
>               transformFKConstraints(pstate, &cxt);
>
>               ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints;
> !             *extras_before = nconc(*extras_before, cxt.blist);
> !             *extras_after = nconc(cxt.alist, *extras_after);
>               break;
>
>           case 'C':
> *************** transformAlterTableStmt(ParseState *psta
> *** 2571,2578 ****
>
>               Assert(cxt.columns == NIL);
>               stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints);
> !             extras_before = cxt.blist;
> !             extras_after = cxt.alist;
>               break;
>
>           default:
> --- 2587,2594 ----
>
>               Assert(cxt.columns == NIL);
>               stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints);
> !             *extras_before = nconc(*extras_before, cxt.blist);
> !             *extras_after = nconc(cxt.alist, *extras_after);
>               break;
>
>           default:
> Index: src/backend/tcop/postgres.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/tcop/postgres.c,v
> retrieving revision 1.245
> diff -c -p -r1.245 postgres.c
> *** src/backend/tcop/postgres.c    2002/01/10 01:11:45    1.245
> --- src/backend/tcop/postgres.c    2002/02/14 10:49:19
> ***************
> *** 64,69 ****
> --- 64,78 ----
>
>   #include "pgstat.h"
>
> + static char *CreateCommandTag(Node *parsetree);
> +
> + /* Uncomment the following line if you want ps_status
> +  * to be set for each individual query that may result from
> +  * a rewrite as oposed to just the main (original) one
> +  */
> + /* #define FINE_GRAIN_PROFILE 1 */
> +
> +
>   /* ----------------
>    *        global variables
>    * ----------------
> *************** pg_exec_query_string(char *query_string,
> *** 634,639 ****
> --- 643,650 ----
>       foreach(parsetree_item, parsetree_list)
>       {
>           Node       *parsetree = (Node *) lfirst(parsetree_item);
> +         char       *commandTag = NULL;
> +         bool        isQueryStmt = false;
>           bool        isTransactionStmt;
>           List       *querytree_list,
>                      *querytree_item;
> *************** pg_exec_query_string(char *query_string,
> *** 675,680 ****
> --- 686,693 ----
>                    * command ended. -cim 6/1/90
>                    */
>                   char       *tag = "*ABORT STATE*";
> +
> +                 set_ps_display(tag);
>
>                   elog(NOTICE, "current transaction is aborted, "
>                        "queries ignored until end of transaction block");
> *************** pg_exec_query_string(char *query_string,
> *** 702,708 ****
>
>           /*
>            * OK to analyze and rewrite this query.
> !          *
>            * Switch to appropriate context for constructing querytrees (again,
>            * these must outlive the execution context).
>            */
> --- 715,737 ----
>
>           /*
>            * 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 have
> !          * been generated by analyze and rewrite)
> !          */
> !         commandTag = CreateCommandTag(parsetree);
> !
> ! #ifndef FINE_GRAIN_PROFILE
> !         /*
> !          * Set ps_status to the main query tag
> !          */
> !         set_ps_display(commandTag);
> ! #endif
> !
> !         /*
>            * Switch to appropriate context for constructing querytrees (again,
>            * these must outlive the execution context).
>            */
> *************** pg_exec_query_string(char *query_string,
> *** 746,752 ****
> --- 775,796 ----
>                   else if (DebugLvl > 1)
>                       elog(DEBUG, "ProcessUtility");
>
> + #ifdef FINE_GRAIN_PROFILE
> +                 set_ps_display(CreateUtilityTag(querytree->utilityStmt));
> + #endif
>                   ProcessUtility(querytree->utilityStmt, dest);
> +
> +                 /*
> +                  * FETCHes, as plannable queries, take care of completion
> +                  * themselves but we still have to do it for MOVEs as they
> +                  * do not send data (and thus, do not send a completion).
> +                  */
> +                 if (nodeTag(parsetree) == T_FetchStmt)
> +                 {
> +                     FetchStmt  *stmt = (FetchStmt *) parsetree;
> +                     if (!(stmt->ismove))
> +                         isQueryStmt = true;  /* Don't do it twice */
> +                 }
>               }
>               else
>               {
> *************** pg_exec_query_string(char *query_string,
> *** 754,759 ****
> --- 798,805 ----
>                    * process a plannable query.
>                    */
>                   Plan       *plan;
> +
> +                 isQueryStmt = true;
>
>                   plan = pg_plan_query(querytree);
>
> *************** pg_exec_query_string(char *query_string,
> *** 818,823 ****
> --- 864,876 ----
>
>           }                        /* end loop over queries generated from a
>                                    * parsetree */
> +
> +         /*
> +          * tell fe/be or whatever that we're done if we only processed
> +          * utilities (plannable queries take care of completion themselves)
> +          */
> +         if (!isQueryStmt)
> +             EndCommand(commandTag, dest);
>       }                            /* end loop over parsetrees */
>
>       /*
> *************** assertTest(int val)
> *** 2037,2039 ****
> --- 2090,2354 ----
>   #endif
>
>   #endif
> +
> +
> + /* ----------------------------------------------------------------
> +  *        CreateCommandTag
> +  *
> +  *        utility to get a string representation of the
> +  *        command operation.
> +  * ----------------------------------------------------------------
> +  */
> + static char *
> + CreateCommandTag(Node *parsetree)
> + {
> +     char       *tag = NULL;
> +
> +     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;
> +                 }
> +             }
> +             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, "CreateUtilityTag: unknown utility operation type %d",
> +                  nodeTag(parsetree));
> +             tag = "???";
> +             break;
> +     }
> +
> +     return tag;
> + }
> +
> Index: src/backend/tcop/pquery.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/tcop/pquery.c,v
> retrieving revision 1.46
> diff -c -p -r1.46 pquery.c
> *** src/backend/tcop/pquery.c    2001/10/25 05:49:43    1.46
> --- src/backend/tcop/pquery.c    2002/02/14 10:49:19
> *************** ProcessQuery(Query *parsetree,
> *** 180,186 ****
>       EState       *state;
>       TupleDesc    attinfo;
>
> !     set_ps_display(tag = CreateOperationTag(operation));
>
>       /*
>        * initialize portal/into relation status
> --- 180,186 ----
>       EState       *state;
>       TupleDesc    attinfo;
>
> !     tag = CreateOperationTag(operation);
>
>       /*
>        * initialize portal/into relation status
> Index: src/backend/tcop/utility.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/tcop/utility.c,v
> retrieving revision 1.125
> diff -c -p -r1.125 utility.c
> *** src/backend/tcop/utility.c    2002/02/07 00:27:30    1.125
> --- src/backend/tcop/utility.c    2002/02/14 10:49:19
> ***************
> *** 44,54 ****
>   #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"
>
>   /*
>    * Error-checking support for DROP commands
>    */
> --- 44,54 ----
>   #include "rewrite/rewriteRemove.h"
>   #include "tcop/utility.h"
>   #include "utils/acl.h"
>   #include "utils/syscache.h"
>   #include "utils/temprel.h"
>   #include "access/xlog.h"
>
> +
>   /*
>    * Error-checking support for DROP commands
>    */
> *************** CheckDropPermissions(char *name, char ri
> *** 132,144 ****
>
>   /* ----------------
>    *        general utility function invoker
>    * ----------------
>    */
>   void
>   ProcessUtility(Node *parsetree,
>                  CommandDest dest)
>   {
> -     char       *commandTag = NULL;
>       char       *relname;
>       char       *relationName;
>
> --- 132,145 ----
>
>   /* ----------------
>    *        general utility function invoker
> +  *
> +  *    Returns the command-complete tag appropriate for the function
>    * ----------------
>    */
>   void
>   ProcessUtility(Node *parsetree,
>                  CommandDest dest)
>   {
>       char       *relname;
>       char       *relationName;
>
> *************** ProcessUtility(Node *parsetree,
> *** 155,171 ****
>                   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;
>                   }
> --- 156,169 ----
> *************** ProcessUtility(Node *parsetree,
> *** 180,187 ****
>               {
>                   ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "CLOSE");
> -
>                   PerformPortalClose(stmt->portalname, dest);
>               }
>               break;
> --- 178,183 ----
> *************** ProcessUtility(Node *parsetree,
> *** 193,200 ****
>                   bool        forward;
>                   int            count;
>
> -                 set_ps_display(commandTag = (stmt->ismove) ? "MOVE" : "FETCH");
> -
>                   SetQuerySnapshot();
>
>                   forward = (bool) (stmt->direction == FORWARD);
> --- 189,194 ----
> *************** ProcessUtility(Node *parsetree,
> *** 204,210 ****
>                    */
>
>                   count = stmt->howMany;
> !                 PerformPortalFetch(portalName, forward, count, commandTag,
>                                      (stmt->ismove) ? None : dest);        /* /dev/null for MOVE */
>               }
>               break;
> --- 198,204 ----
>                    */
>
>                   count = stmt->howMany;
> !                 PerformPortalFetch(portalName, forward, count,(stmt->ismove) ? "MOVE" : "FETCH",
>                                      (stmt->ismove) ? None : dest);        /* /dev/null for MOVE */
>               }
>               break;
> *************** ProcessUtility(Node *parsetree,
> *** 215,222 ****
>                *
>                */
>           case T_CreateStmt:
> -             set_ps_display(commandTag = "CREATE");
> -
>               DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
>
>               /*
> --- 209,214 ----
> *************** ProcessUtility(Node *parsetree,
> *** 234,241 ****
>                   List       *args = stmt->names;
>                   List       *arg;
>
> -                 set_ps_display(commandTag = "DROP");
> -
>                   foreach(arg, args)
>                   {
>                       relname = strVal(lfirst(arg));
> --- 226,231 ----
> *************** ProcessUtility(Node *parsetree,
> *** 296,303 ****
>               {
>                   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",
> --- 286,291 ----
> *************** ProcessUtility(Node *parsetree,
> *** 325,332 ****
>
>                   statement = ((CommentStmt *) parsetree);
>
> -                 set_ps_display(commandTag = "COMMENT");
> -
>                   CommentObject(statement->objtype, statement->objname,
>                                 statement->objproperty, statement->objlist,
>                                 statement->comment);
> --- 313,318 ----
> *************** ProcessUtility(Node *parsetree,
> *** 337,344 ****
>               {
>                   CopyStmt   *stmt = (CopyStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "COPY");
> -
>                   if (stmt->direction != FROM)
>                       SetQuerySnapshot();
>
> --- 323,328 ----
> *************** ProcessUtility(Node *parsetree,
> *** 365,372 ****
>               {
>                   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",
> --- 349,354 ----
> *************** ProcessUtility(Node *parsetree,
> *** 413,420 ****
>               {
>                   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.
> --- 395,400 ----
> *************** ProcessUtility(Node *parsetree,
> *** 475,483 ****
>               {
>                   GrantStmt  *stmt = (GrantStmt *) parsetree;
>
> -                 commandTag = stmt->is_grant ? "GRANT" : "REVOKE";
> -                 set_ps_display(commandTag);
> -
>                   ExecuteGrantStmt(stmt);
>               }
>               break;
> --- 455,460 ----
> *************** ProcessUtility(Node *parsetree,
> *** 491,498 ****
>               {
>                   DefineStmt *stmt = (DefineStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "CREATE");
> -
>                   switch (stmt->defType)
>                   {
>                       case OPERATOR:
> --- 468,473 ----
> *************** ProcessUtility(Node *parsetree,
> *** 514,528 ****
>               {
>                   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;
>
> --- 489,499 ----
> *************** ProcessUtility(Node *parsetree,
> *** 530,537 ****
>               {
>                   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",
> --- 501,506 ----
> *************** ProcessUtility(Node *parsetree,
> *** 559,573 ****
>                   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;
>
> --- 528,539 ----
> *************** ProcessUtility(Node *parsetree,
> *** 576,583 ****
>                   RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
>                   char       *typename = (char *) NULL;
>
> -                 set_ps_display(commandTag = "DROP");
> -
>                   if (stmt->aggtype != NULL)
>                       typename = TypeNameToInternalName((TypeName *) stmt->aggtype);
>
> --- 542,547 ----
> *************** ProcessUtility(Node *parsetree,
> *** 589,596 ****
>               {
>                   RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "DROP");
> -
>                   RemoveFunction(stmt->funcname, stmt->args);
>               }
>               break;
> --- 553,558 ----
> *************** ProcessUtility(Node *parsetree,
> *** 603,610 ****
>                   char       *typename1 = (char *) NULL;
>                   char       *typename2 = (char *) NULL;
>
> -                 set_ps_display(commandTag = "DROP");
> -
>                   if (typenode1 != NULL)
>                       typename1 = TypeNameToInternalName(typenode1);
>                   if (typenode2 != NULL)
> --- 565,570 ----
> *************** ProcessUtility(Node *parsetree,
> *** 622,629 ****
>               {
>                   CreatedbStmt *stmt = (CreatedbStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "CREATE DATABASE");
> -
>                   createdb(stmt->dbname, stmt->dbpath,
>                            stmt->dbtemplate, stmt->encoding);
>               }
> --- 582,587 ----
> *************** ProcessUtility(Node *parsetree,
> *** 633,640 ****
>               {
>                   DropdbStmt *stmt = (DropdbStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "DROP DATABASE");
> -
>                   dropdb(stmt->dbname);
>               }
>               break;
> --- 591,596 ----
> *************** ProcessUtility(Node *parsetree,
> *** 644,651 ****
>               {
>                   NotifyStmt *stmt = (NotifyStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "NOTIFY");
> -
>                   Async_Notify(stmt->relname);
>               }
>               break;
> --- 600,605 ----
> *************** ProcessUtility(Node *parsetree,
> *** 654,661 ****
>               {
>                   ListenStmt *stmt = (ListenStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "LISTEN");
> -
>                   Async_Listen(stmt->relname, MyProcPid);
>               }
>               break;
> --- 608,613 ----
> *************** ProcessUtility(Node *parsetree,
> *** 664,671 ****
>               {
>                   UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "UNLISTEN");
> -
>                   Async_Unlisten(stmt->relname, MyProcPid);
>               }
>               break;
> --- 616,621 ----
> *************** ProcessUtility(Node *parsetree,
> *** 678,685 ****
>               {
>                   LoadStmt   *stmt = (LoadStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "LOAD");
> -
>                   closeAllVfds(); /* probably not necessary... */
>                   load_file(stmt->filename);
>               }
> --- 628,633 ----
> *************** ProcessUtility(Node *parsetree,
> *** 689,696 ****
>               {
>                   ClusterStmt *stmt = (ClusterStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "CLUSTER");
> -
>                   relname = stmt->relname;
>                   if (IsSystemRelationName(relname))
>                       elog(ERROR, "CLUSTER: relation \"%s\" is a system catalog",
> --- 637,642 ----
> *************** ProcessUtility(Node *parsetree,
> *** 703,714 ****
>               break;
>
>           case T_VacuumStmt:
> -             if (((VacuumStmt *) parsetree)->vacuum)
> -                 commandTag = "VACUUM";
> -             else
> -                 commandTag = "ANALYZE";
> -             set_ps_display(commandTag);
> -
>               vacuum((VacuumStmt *) parsetree);
>               break;
>
> --- 649,654 ----
> *************** ProcessUtility(Node *parsetree,
> *** 716,723 ****
>               {
>                   ExplainStmt *stmt = (ExplainStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "EXPLAIN");
> -
>                   ExplainQuery(stmt->query, stmt->verbose, stmt->analyze, dest);
>               }
>               break;
> --- 656,661 ----
> *************** ProcessUtility(Node *parsetree,
> *** 731,738 ****
>               {
>                   RecipeStmt *stmt = (RecipeStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "EXECUTE RECIPE");
> -
>                   beginRecipe(stmt);
>               }
>               break;
> --- 669,674 ----
> *************** ProcessUtility(Node *parsetree,
> *** 746,752 ****
>                   VariableSetStmt *n = (VariableSetStmt *) parsetree;
>
>                   SetPGVariable(n->name, n->args);
> -                 set_ps_display(commandTag = "SET VARIABLE");
>               }
>               break;
>
> --- 682,687 ----
> *************** ProcessUtility(Node *parsetree,
> *** 755,761 ****
>                   VariableShowStmt *n = (VariableShowStmt *) parsetree;
>
>                   GetPGVariable(n->name);
> -                 set_ps_display(commandTag = "SHOW VARIABLE");
>               }
>               break;
>
> --- 690,695 ----
> *************** ProcessUtility(Node *parsetree,
> *** 764,770 ****
>                   VariableResetStmt *n = (VariableResetStmt *) parsetree;
>
>                   ResetPGVariable(n->name);
> -                 set_ps_display(commandTag = "RESET VARIABLE");
>               }
>               break;
>
> --- 698,703 ----
> *************** ProcessUtility(Node *parsetree,
> *** 772,785 ****
>                * ******************************** 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;
>
> --- 705,714 ----
> *************** ProcessUtility(Node *parsetree,
> *** 787,800 ****
>                * ************* 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;
>
> --- 716,725 ----
> *************** ProcessUtility(Node *parsetree,
> *** 803,859 ****
>                *
>                */
>           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);
> --- 728,766 ----
> *************** ProcessUtility(Node *parsetree,
> *** 864,871 ****
>               {
>                   ReindexStmt *stmt = (ReindexStmt *) parsetree;
>
> -                 set_ps_display(commandTag = "REINDEX");
> -
>                   switch (stmt->reindexType)
>                   {
>                       case INDEX:
> --- 771,776 ----
> *************** ProcessUtility(Node *parsetree,
> *** 913,919 ****
>       }
>
>       /*
> !      * tell fe/be or whatever that we're done.
>        */
> !     EndCommand(commandTag, dest);
>   }
> --- 818,826 ----
>       }
>
>       /*
> !      * Note: the "end-of-command" tag is to be sent by the caller,
> !      * if appropriate.
>        */
> !     return;
>   }
> +

>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: Patch to add CREATE OPERATOR CLASS
Next
From: Bruce Momjian
Date:
Subject: Re: PAM patch...