Commit bbeb0bbf authored by Tom Lane's avatar Tom Lane

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.
parent ccd31eb8
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -1054,7 +1054,8 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
((DR_copy *) dest)->cstate = cstate; ((DR_copy *) dest)->cstate = cstate;
/* Create a QueryDesc requesting no output */ /* Create a QueryDesc requesting no output */
cstate->queryDesc = CreateQueryDesc(plan, GetActiveSnapshot(), cstate->queryDesc = CreateQueryDesc(plan, queryString,
GetActiveSnapshot(),
InvalidSnapshot, InvalidSnapshot,
dest, NULL, false); dest, NULL, false);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California * Portions Copyright (c) 1994-5, Regents of the University of California
* *
* IDENTIFICATION * 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, ...@@ -172,7 +172,7 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, const char *queryString,
plan = pg_plan_query(query, 0, params); plan = pg_plan_query(query, 0, params);
/* run it (if needed) and produce output */ /* 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, ...@@ -218,8 +218,9 @@ ExplainOneUtility(Node *utilityStmt, ExplainStmt *stmt,
* to call it. * to call it.
*/ */
void void
ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, ExplainOnePlan(PlannedStmt *plannedstmt, ExplainStmt *stmt,
ExplainStmt *stmt, TupOutputState *tstate) const char *queryString, ParamListInfo params,
TupOutputState *tstate)
{ {
QueryDesc *queryDesc; QueryDesc *queryDesc;
instr_time starttime; instr_time starttime;
...@@ -234,7 +235,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, ...@@ -234,7 +235,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params,
PushUpdatedSnapshot(GetActiveSnapshot()); PushUpdatedSnapshot(GetActiveSnapshot());
/* Create a QueryDesc requesting no output */ /* Create a QueryDesc requesting no output */
queryDesc = CreateQueryDesc(plannedstmt, queryDesc = CreateQueryDesc(plannedstmt, queryString,
GetActiveSnapshot(), InvalidSnapshot, GetActiveSnapshot(), InvalidSnapshot,
None_Receiver, params, None_Receiver, params,
stmt->analyze); stmt->analyze);
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Copyright (c) 2002-2009, PostgreSQL Global Development Group * Copyright (c) 2002-2009, PostgreSQL Global Development Group
* *
* IDENTIFICATION * 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) ...@@ -636,6 +636,9 @@ DropAllPreparedStatements(void)
/* /*
* Implements the 'EXPLAIN EXECUTE' utility statement. * 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 void
ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt,
...@@ -643,6 +646,7 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, ...@@ -643,6 +646,7 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt,
ParamListInfo params, TupOutputState *tstate) ParamListInfo params, TupOutputState *tstate)
{ {
PreparedStatement *entry; PreparedStatement *entry;
const char *query_string;
CachedPlan *cplan; CachedPlan *cplan;
List *plan_list; List *plan_list;
ListCell *p; ListCell *p;
...@@ -659,6 +663,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, ...@@ -659,6 +663,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt,
if (!entry->plansource->fixed_result) if (!entry->plansource->fixed_result)
elog(ERROR, "EXPLAIN EXECUTE does not support variable-result cached plans"); 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 */ /* Replan if needed, and acquire a transient refcount */
cplan = RevalidateCachedPlan(entry->plansource, true); cplan = RevalidateCachedPlan(entry->plansource, true);
...@@ -701,11 +707,12 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, ...@@ -701,11 +707,12 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt,
pstmt->intoClause = execstmt->into; pstmt->intoClause = execstmt->into;
} }
ExplainOnePlan(pstmt, paramLI, stmt, tstate); ExplainOnePlan(pstmt, stmt, query_string,
paramLI, tstate);
} }
else else
{ {
ExplainOneUtility((Node *) pstmt, stmt, queryString, ExplainOneUtility((Node *) pstmt, stmt, query_string,
params, tstate); params, tstate);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -411,11 +411,13 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
if (IsA(es->stmt, PlannedStmt)) if (IsA(es->stmt, PlannedStmt))
es->qd = CreateQueryDesc((PlannedStmt *) es->stmt, es->qd = CreateQueryDesc((PlannedStmt *) es->stmt,
fcache->src,
snapshot, InvalidSnapshot, snapshot, InvalidSnapshot,
dest, dest,
fcache->paramLI, false); fcache->paramLI, false);
else else
es->qd = CreateUtilityQueryDesc(es->stmt, es->qd = CreateUtilityQueryDesc(es->stmt,
fcache->src,
snapshot, snapshot,
dest, dest,
fcache->paramLI); fcache->paramLI);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -1791,6 +1791,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
snap = InvalidSnapshot; snap = InvalidSnapshot;
qdesc = CreateQueryDesc((PlannedStmt *) stmt, qdesc = CreateQueryDesc((PlannedStmt *) stmt,
plansource->query_string,
snap, crosscheck_snapshot, snap, crosscheck_snapshot,
dest, dest,
paramLI, false); paramLI, false);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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; ...@@ -36,6 +36,7 @@ Portal ActivePortal = NULL;
static void ProcessQuery(PlannedStmt *plan, static void ProcessQuery(PlannedStmt *plan,
const char *sourceText,
ParamListInfo params, ParamListInfo params,
DestReceiver *dest, DestReceiver *dest,
char *completionTag); char *completionTag);
...@@ -61,6 +62,7 @@ static void DoPortalRewind(Portal portal); ...@@ -61,6 +62,7 @@ static void DoPortalRewind(Portal portal);
*/ */
QueryDesc * QueryDesc *
CreateQueryDesc(PlannedStmt *plannedstmt, CreateQueryDesc(PlannedStmt *plannedstmt,
const char *sourceText,
Snapshot snapshot, Snapshot snapshot,
Snapshot crosscheck_snapshot, Snapshot crosscheck_snapshot,
DestReceiver *dest, DestReceiver *dest,
...@@ -72,6 +74,7 @@ CreateQueryDesc(PlannedStmt *plannedstmt, ...@@ -72,6 +74,7 @@ CreateQueryDesc(PlannedStmt *plannedstmt,
qd->operation = plannedstmt->commandType; /* operation */ qd->operation = plannedstmt->commandType; /* operation */
qd->plannedstmt = plannedstmt; /* plan */ qd->plannedstmt = plannedstmt; /* plan */
qd->utilitystmt = plannedstmt->utilityStmt; /* in case DECLARE CURSOR */ qd->utilitystmt = plannedstmt->utilityStmt; /* in case DECLARE CURSOR */
qd->sourceText = sourceText; /* query text */
qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */ qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */
/* RI check snapshot */ /* RI check snapshot */
qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot); qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot);
...@@ -93,6 +96,7 @@ CreateQueryDesc(PlannedStmt *plannedstmt, ...@@ -93,6 +96,7 @@ CreateQueryDesc(PlannedStmt *plannedstmt,
*/ */
QueryDesc * QueryDesc *
CreateUtilityQueryDesc(Node *utilitystmt, CreateUtilityQueryDesc(Node *utilitystmt,
const char *sourceText,
Snapshot snapshot, Snapshot snapshot,
DestReceiver *dest, DestReceiver *dest,
ParamListInfo params) ParamListInfo params)
...@@ -102,6 +106,7 @@ CreateUtilityQueryDesc(Node *utilitystmt, ...@@ -102,6 +106,7 @@ CreateUtilityQueryDesc(Node *utilitystmt,
qd->operation = CMD_UTILITY; /* operation */ qd->operation = CMD_UTILITY; /* operation */
qd->plannedstmt = NULL; qd->plannedstmt = NULL;
qd->utilitystmt = utilitystmt; /* utility command */ qd->utilitystmt = utilitystmt; /* utility command */
qd->sourceText = sourceText; /* query text */
qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */ qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */
qd->crosscheck_snapshot = InvalidSnapshot; /* RI check snapshot */ qd->crosscheck_snapshot = InvalidSnapshot; /* RI check snapshot */
qd->dest = dest; /* output dest */ qd->dest = dest; /* output dest */
...@@ -141,6 +146,7 @@ FreeQueryDesc(QueryDesc *qdesc) ...@@ -141,6 +146,7 @@ FreeQueryDesc(QueryDesc *qdesc)
* or PORTAL_ONE_RETURNING portal * or PORTAL_ONE_RETURNING portal
* *
* plan: the plan tree for the query * plan: the plan tree for the query
* sourceText: the source text of the query
* params: any parameters needed * params: any parameters needed
* dest: where to send results * dest: where to send results
* completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
...@@ -153,6 +159,7 @@ FreeQueryDesc(QueryDesc *qdesc) ...@@ -153,6 +159,7 @@ FreeQueryDesc(QueryDesc *qdesc)
*/ */
static void static void
ProcessQuery(PlannedStmt *plan, ProcessQuery(PlannedStmt *plan,
const char *sourceText,
ParamListInfo params, ParamListInfo params,
DestReceiver *dest, DestReceiver *dest,
char *completionTag) char *completionTag)
...@@ -169,7 +176,7 @@ ProcessQuery(PlannedStmt *plan, ...@@ -169,7 +176,7 @@ ProcessQuery(PlannedStmt *plan,
/* /*
* Create the QueryDesc object * Create the QueryDesc object
*/ */
queryDesc = CreateQueryDesc(plan, queryDesc = CreateQueryDesc(plan, sourceText,
GetActiveSnapshot(), InvalidSnapshot, GetActiveSnapshot(), InvalidSnapshot,
dest, params, false); dest, params, false);
...@@ -503,6 +510,7 @@ PortalStart(Portal portal, ParamListInfo params, Snapshot snapshot) ...@@ -503,6 +510,7 @@ PortalStart(Portal portal, ParamListInfo params, Snapshot snapshot)
* the destination to DestNone. * the destination to DestNone.
*/ */
queryDesc = CreateQueryDesc((PlannedStmt *) linitial(portal->stmts), queryDesc = CreateQueryDesc((PlannedStmt *) linitial(portal->stmts),
portal->sourceText,
GetActiveSnapshot(), GetActiveSnapshot(),
InvalidSnapshot, InvalidSnapshot,
None_Receiver, None_Receiver,
...@@ -1258,6 +1266,7 @@ PortalRunMulti(Portal portal, bool isTopLevel, ...@@ -1258,6 +1266,7 @@ PortalRunMulti(Portal portal, bool isTopLevel,
{ {
/* statement can set tag string */ /* statement can set tag string */
ProcessQuery(pstmt, ProcessQuery(pstmt,
portal->sourceText,
portal->portalParams, portal->portalParams,
dest, completionTag); dest, completionTag);
} }
...@@ -1265,6 +1274,7 @@ PortalRunMulti(Portal portal, bool isTopLevel, ...@@ -1265,6 +1274,7 @@ PortalRunMulti(Portal portal, bool isTopLevel,
{ {
/* stmt added by rewrite cannot set tag */ /* stmt added by rewrite cannot set tag */
ProcessQuery(pstmt, ProcessQuery(pstmt,
portal->sourceText,
portal->portalParams, portal->portalParams,
altdest, NULL); altdest, NULL);
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994-5, Regents of the University of California * 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, ...@@ -38,8 +38,10 @@ extern void ExplainOneUtility(Node *utilityStmt, ExplainStmt *stmt,
ParamListInfo params, ParamListInfo params,
TupOutputState *tstate); TupOutputState *tstate);
extern void ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, extern void ExplainOnePlan(PlannedStmt *plannedstmt, ExplainStmt *stmt,
ExplainStmt *stmt, TupOutputState *tstate); const char *queryString,
ParamListInfo params,
TupOutputState *tstate);
extern void ExplainPrintPlan(StringInfo str, QueryDesc *queryDesc, extern void ExplainPrintPlan(StringInfo str, QueryDesc *queryDesc,
bool analyze, bool verbose); bool analyze, bool verbose);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -37,6 +37,7 @@ typedef struct QueryDesc
CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */ CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */
PlannedStmt *plannedstmt; /* planner's output, or null if utility */ PlannedStmt *plannedstmt; /* planner's output, or null if utility */
Node *utilitystmt; /* utility statement, or null */ Node *utilitystmt; /* utility statement, or null */
const char *sourceText; /* source text of the query */
Snapshot snapshot; /* snapshot to use for query */ Snapshot snapshot; /* snapshot to use for query */
Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */ Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */
DestReceiver *dest; /* the destination for tuple output */ DestReceiver *dest; /* the destination for tuple output */
...@@ -54,6 +55,7 @@ typedef struct QueryDesc ...@@ -54,6 +55,7 @@ typedef struct QueryDesc
/* in pquery.c */ /* in pquery.c */
extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt, extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt,
const char *sourceText,
Snapshot snapshot, Snapshot snapshot,
Snapshot crosscheck_snapshot, Snapshot crosscheck_snapshot,
DestReceiver *dest, DestReceiver *dest,
...@@ -61,6 +63,7 @@ extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt, ...@@ -61,6 +63,7 @@ extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt,
bool doInstrument); bool doInstrument);
extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt, extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt,
const char *sourceText,
Snapshot snapshot, Snapshot snapshot,
DestReceiver *dest, DestReceiver *dest,
ParamListInfo params); ParamListInfo params);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment