From bbeb0bbf6b3e5fdb7cff1a87885f43139ace5c4b Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 2 Jan 2009 20:42:00 +0000 Subject: [PATCH] Include a pointer to the query's source text in QueryDesc structs. This is practically free given prior 8.4 changes in plancache and portal management, and it makes it a lot easier for ExecutorStart/Run/End hooks to get at the query text. Extracted from Itagaki Takahiro's pg_stat_statements patch, with minor editorialization. --- src/backend/commands/copy.c | 5 +++-- src/backend/commands/explain.c | 11 ++++++----- src/backend/commands/prepare.c | 13 ++++++++++--- src/backend/executor/functions.c | 4 +++- src/backend/executor/spi.c | 3 ++- src/backend/tcop/pquery.c | 14 ++++++++++++-- src/include/commands/explain.h | 8 +++++--- src/include/executor/execdesc.h | 5 ++++- 8 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 0b38ee0bb7..c2e2c82205 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.303 2009/01/01 17:23:37 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.304 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1054,7 +1054,8 @@ DoCopy(const CopyStmt *stmt, const char *queryString) ((DR_copy *) dest)->cstate = cstate; /* Create a QueryDesc requesting no output */ - cstate->queryDesc = CreateQueryDesc(plan, GetActiveSnapshot(), + cstate->queryDesc = CreateQueryDesc(plan, queryString, + GetActiveSnapshot(), InvalidSnapshot, dest, NULL, false); diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 4f520ccb5c..8ad877e165 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994-5, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.183 2009/01/01 17:23:37 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.184 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -172,7 +172,7 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, const char *queryString, plan = pg_plan_query(query, 0, params); /* run it (if needed) and produce output */ - ExplainOnePlan(plan, params, stmt, tstate); + ExplainOnePlan(plan, stmt, queryString, params, tstate); } } @@ -218,8 +218,9 @@ ExplainOneUtility(Node *utilityStmt, ExplainStmt *stmt, * to call it. */ void -ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, - ExplainStmt *stmt, TupOutputState *tstate) +ExplainOnePlan(PlannedStmt *plannedstmt, ExplainStmt *stmt, + const char *queryString, ParamListInfo params, + TupOutputState *tstate) { QueryDesc *queryDesc; instr_time starttime; @@ -234,7 +235,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, PushUpdatedSnapshot(GetActiveSnapshot()); /* Create a QueryDesc requesting no output */ - queryDesc = CreateQueryDesc(plannedstmt, + queryDesc = CreateQueryDesc(plannedstmt, queryString, GetActiveSnapshot(), InvalidSnapshot, None_Receiver, params, stmt->analyze); diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c index 29f3df711a..e1c0edb8e8 100644 --- a/src/backend/commands/prepare.c +++ b/src/backend/commands/prepare.c @@ -10,7 +10,7 @@ * Copyright (c) 2002-2009, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.95 2009/01/01 17:23:39 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.96 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -636,6 +636,9 @@ DropAllPreparedStatements(void) /* * Implements the 'EXPLAIN EXECUTE' utility statement. + * + * Note: the passed-in queryString is that of the EXPLAIN EXECUTE, + * not the original PREPARE; we get the latter string from the plancache. */ void ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, @@ -643,6 +646,7 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, ParamListInfo params, TupOutputState *tstate) { PreparedStatement *entry; + const char *query_string; CachedPlan *cplan; List *plan_list; ListCell *p; @@ -659,6 +663,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, if (!entry->plansource->fixed_result) elog(ERROR, "EXPLAIN EXECUTE does not support variable-result cached plans"); + query_string = entry->plansource->query_string; + /* Replan if needed, and acquire a transient refcount */ cplan = RevalidateCachedPlan(entry->plansource, true); @@ -701,11 +707,12 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, pstmt->intoClause = execstmt->into; } - ExplainOnePlan(pstmt, paramLI, stmt, tstate); + ExplainOnePlan(pstmt, stmt, query_string, + paramLI, tstate); } else { - ExplainOneUtility((Node *) pstmt, stmt, queryString, + ExplainOneUtility((Node *) pstmt, stmt, query_string, params, tstate); } diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index a2eac5af8b..a8673b1f60 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.131 2009/01/01 17:23:41 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.132 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -411,11 +411,13 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache) if (IsA(es->stmt, PlannedStmt)) es->qd = CreateQueryDesc((PlannedStmt *) es->stmt, + fcache->src, snapshot, InvalidSnapshot, dest, fcache->paramLI, false); else es->qd = CreateUtilityQueryDesc(es->stmt, + fcache->src, snapshot, dest, fcache->paramLI); diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index c3b4f619bc..4bc45dc17f 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.203 2009/01/01 17:23:42 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.204 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1791,6 +1791,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, snap = InvalidSnapshot; qdesc = CreateQueryDesc((PlannedStmt *) stmt, + plansource->query_string, snap, crosscheck_snapshot, dest, paramLI, false); diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index c4481d7790..062881858c 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.128 2009/01/01 17:23:48 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.129 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,6 +36,7 @@ Portal ActivePortal = NULL; static void ProcessQuery(PlannedStmt *plan, + const char *sourceText, ParamListInfo params, DestReceiver *dest, char *completionTag); @@ -61,6 +62,7 @@ static void DoPortalRewind(Portal portal); */ QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, + const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, @@ -72,6 +74,7 @@ CreateQueryDesc(PlannedStmt *plannedstmt, qd->operation = plannedstmt->commandType; /* operation */ qd->plannedstmt = plannedstmt; /* plan */ qd->utilitystmt = plannedstmt->utilityStmt; /* in case DECLARE CURSOR */ + qd->sourceText = sourceText; /* query text */ qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */ /* RI check snapshot */ qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot); @@ -93,6 +96,7 @@ CreateQueryDesc(PlannedStmt *plannedstmt, */ QueryDesc * CreateUtilityQueryDesc(Node *utilitystmt, + const char *sourceText, Snapshot snapshot, DestReceiver *dest, ParamListInfo params) @@ -102,6 +106,7 @@ CreateUtilityQueryDesc(Node *utilitystmt, qd->operation = CMD_UTILITY; /* operation */ qd->plannedstmt = NULL; qd->utilitystmt = utilitystmt; /* utility command */ + qd->sourceText = sourceText; /* query text */ qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */ qd->crosscheck_snapshot = InvalidSnapshot; /* RI check snapshot */ qd->dest = dest; /* output dest */ @@ -141,6 +146,7 @@ FreeQueryDesc(QueryDesc *qdesc) * or PORTAL_ONE_RETURNING portal * * plan: the plan tree for the query + * sourceText: the source text of the query * params: any parameters needed * dest: where to send results * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE @@ -153,6 +159,7 @@ FreeQueryDesc(QueryDesc *qdesc) */ static void ProcessQuery(PlannedStmt *plan, + const char *sourceText, ParamListInfo params, DestReceiver *dest, char *completionTag) @@ -169,7 +176,7 @@ ProcessQuery(PlannedStmt *plan, /* * Create the QueryDesc object */ - queryDesc = CreateQueryDesc(plan, + queryDesc = CreateQueryDesc(plan, sourceText, GetActiveSnapshot(), InvalidSnapshot, dest, params, false); @@ -503,6 +510,7 @@ PortalStart(Portal portal, ParamListInfo params, Snapshot snapshot) * the destination to DestNone. */ queryDesc = CreateQueryDesc((PlannedStmt *) linitial(portal->stmts), + portal->sourceText, GetActiveSnapshot(), InvalidSnapshot, None_Receiver, @@ -1258,6 +1266,7 @@ PortalRunMulti(Portal portal, bool isTopLevel, { /* statement can set tag string */ ProcessQuery(pstmt, + portal->sourceText, portal->portalParams, dest, completionTag); } @@ -1265,6 +1274,7 @@ PortalRunMulti(Portal portal, bool isTopLevel, { /* stmt added by rewrite cannot set tag */ ProcessQuery(pstmt, + portal->sourceText, portal->portalParams, altdest, NULL); } diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h index e3a2a65004..2903d394ba 100644 --- a/src/include/commands/explain.h +++ b/src/include/commands/explain.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.37 2009/01/01 17:23:58 momjian Exp $ + * $PostgreSQL: pgsql/src/include/commands/explain.h,v 1.38 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -38,8 +38,10 @@ extern void ExplainOneUtility(Node *utilityStmt, ExplainStmt *stmt, ParamListInfo params, TupOutputState *tstate); -extern void ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, - ExplainStmt *stmt, TupOutputState *tstate); +extern void ExplainOnePlan(PlannedStmt *plannedstmt, ExplainStmt *stmt, + const char *queryString, + ParamListInfo params, + TupOutputState *tstate); extern void ExplainPrintPlan(StringInfo str, QueryDesc *queryDesc, bool analyze, bool verbose); diff --git a/src/include/executor/execdesc.h b/src/include/executor/execdesc.h index fb3f56b786..9682c4b73a 100644 --- a/src/include/executor/execdesc.h +++ b/src/include/executor/execdesc.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/executor/execdesc.h,v 1.39 2009/01/01 17:23:59 momjian Exp $ + * $PostgreSQL: pgsql/src/include/executor/execdesc.h,v 1.40 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -37,6 +37,7 @@ typedef struct QueryDesc CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */ PlannedStmt *plannedstmt; /* planner's output, or null if utility */ Node *utilitystmt; /* utility statement, or null */ + const char *sourceText; /* source text of the query */ Snapshot snapshot; /* snapshot to use for query */ Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */ DestReceiver *dest; /* the destination for tuple output */ @@ -54,6 +55,7 @@ typedef struct QueryDesc /* in pquery.c */ extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt, + const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, @@ -61,6 +63,7 @@ extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt, bool doInstrument); extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt, + const char *sourceText, Snapshot snapshot, DestReceiver *dest, ParamListInfo params);