Fix issuing of multiple command completions per command - Mailing list pgsql-patches
From | Fernando Nasser |
---|---|
Subject | Fix issuing of multiple command completions per command |
Date | |
Msg-id | 3C765811.71C714C8@redhat.com Whole thread Raw |
Responses |
Re: Fix issuing of multiple command completions per command
Re: Fix issuing of multiple command completions per command Re: Fix issuing of multiple command completions per command |
List | pgsql-patches |
(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 2C9Index: 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; } +
pgsql-patches by date: