Re: contrib/pg_stat_statements
От | Martin Pihlak |
---|---|
Тема | Re: contrib/pg_stat_statements |
Дата | |
Msg-id | [email protected] обсуждение исходный текст |
Ответ на | Re: contrib/pg_stat_statements (ITAGAKI Takahiro <[email protected]>) |
Ответы |
Re: contrib/pg_stat_statements
|
Список | pgsql-hackers |
ITAGAKI Takahiro wrote: >> But is the idea of extending QueryDesc generally acceptable? Is it OK >> to make a copy of the query string? > > The only thing I'm worried about is that QueryDesc lives longer than > its queryText. Can I assume it never occurs? > I just finished validating this -- it seems OK. All of the query strings that make it to CreateQueryDesc are either pstrdup-ed to Portal, in long lived memory context or just literals. So no need to make extra copies :) regards, Martin *** a/src/backend/commands/copy.c --- b/src/backend/commands/copy.c *************** *** 1056,1062 **** DoCopy(const CopyStmt *stmt, const char *queryString) /* Create a QueryDesc requesting no output */ cstate->queryDesc = CreateQueryDesc(plan, GetActiveSnapshot(), InvalidSnapshot, ! dest, NULL, false); /* * Call ExecutorStart to prepare the plan for execution. --- 1056,1062 ---- /* Create a QueryDesc requesting no output */ cstate->queryDesc = CreateQueryDesc(plan, GetActiveSnapshot(), InvalidSnapshot, ! dest, NULL, false, queryString); /* * Call ExecutorStart to prepare the plan for execution. *** a/src/backend/commands/explain.c --- b/src/backend/commands/explain.c *************** *** 172,178 **** 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); } } --- 172,178 ---- plan = pg_plan_query(query, 0, params); /* run it (if needed) and produce output */ ! ExplainOnePlan(plan, params, stmt, tstate, queryString); } } *************** *** 219,225 **** ExplainOneUtility(Node *utilityStmt, ExplainStmt *stmt, */ void ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, ! ExplainStmt *stmt, TupOutputState *tstate) { QueryDesc *queryDesc; instr_time starttime; --- 219,226 ---- */ void ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, ! ExplainStmt *stmt, TupOutputState *tstate, ! const char *queryString) { QueryDesc *queryDesc; instr_time starttime; *************** *** 238,244 **** ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, queryDesc = CreateQueryDesc(plannedstmt, GetActiveSnapshot(), InvalidSnapshot, None_Receiver, params, ! stmt->analyze); INSTR_TIME_SET_CURRENT(starttime); --- 239,245 ---- queryDesc = CreateQueryDesc(plannedstmt, GetActiveSnapshot(), InvalidSnapshot, None_Receiver, params, ! stmt->analyze, queryString); INSTR_TIME_SET_CURRENT(starttime); *** a/src/backend/commands/prepare.c --- b/src/backend/commands/prepare.c *************** *** 697,703 **** ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt, pstmt->intoClause = execstmt->into; } ! ExplainOnePlan(pstmt, paramLI, stmt, tstate); } else { --- 697,703 ---- pstmt->intoClause = execstmt->into; } ! ExplainOnePlan(pstmt, paramLI, stmt, tstate, queryString); } else { *** a/src/backend/executor/functions.c --- b/src/backend/executor/functions.c *************** *** 309,320 **** postquel_start(execution_state *es, SQLFunctionCachePtr fcache) es->qd = CreateQueryDesc((PlannedStmt *) es->stmt, snapshot, InvalidSnapshot, None_Receiver, ! fcache->paramLI, false); else es->qd = CreateUtilityQueryDesc(es->stmt, snapshot, None_Receiver, ! fcache->paramLI); /* We assume we don't need to set up ActiveSnapshot for ExecutorStart */ --- 309,320 ---- es->qd = CreateQueryDesc((PlannedStmt *) es->stmt, snapshot, InvalidSnapshot, None_Receiver, ! fcache->paramLI, false, fcache->src); else es->qd = CreateUtilityQueryDesc(es->stmt, snapshot, None_Receiver, ! fcache->paramLI, fcache->src); /* We assume we don't need to set up ActiveSnapshot for ExecutorStart */ *** a/src/backend/executor/spi.c --- b/src/backend/executor/spi.c *************** *** 1795,1801 **** _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, qdesc = CreateQueryDesc((PlannedStmt *) stmt, snap, crosscheck_snapshot, dest, ! paramLI, false); res = _SPI_pquery(qdesc, fire_triggers, canSetTag ? tcount : 0); FreeQueryDesc(qdesc); --- 1795,1802 ---- qdesc = CreateQueryDesc((PlannedStmt *) stmt, snap, crosscheck_snapshot, dest, ! paramLI, false, ! plansource->query_string); res = _SPI_pquery(qdesc, fire_triggers, canSetTag ? tcount : 0); FreeQueryDesc(qdesc); *** a/src/backend/tcop/pquery.c --- b/src/backend/tcop/pquery.c *************** *** 37,43 **** Portal ActivePortal = NULL; static void ProcessQuery(PlannedStmt *plan, ParamListInfo params, DestReceiver *dest, ! char *completionTag); static void FillPortalStore(Portal portal, bool isTopLevel); static uint32 RunFromStore(Portal portal, ScanDirection direction, long count, DestReceiver *dest); --- 37,44 ---- static void ProcessQuery(PlannedStmt *plan, ParamListInfo params, DestReceiver *dest, ! char *completionTag, ! const char *sourceText); static void FillPortalStore(Portal portal, bool isTopLevel); static uint32 RunFromStore(Portal portal, ScanDirection direction, long count, DestReceiver *dest); *************** *** 64,70 **** CreateQueryDesc(PlannedStmt *plannedstmt, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, ! bool doInstrument) { QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc)); --- 65,72 ---- Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, ! bool doInstrument, ! const char *sourceText) { QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc)); *************** *** 77,82 **** CreateQueryDesc(PlannedStmt *plannedstmt, --- 79,85 ---- qd->dest = dest; /* output dest */ qd->params = params; /* parameter values passed into query */ qd->doInstrument = doInstrument; /* instrumentation wanted? */ + qd->sourceText = sourceText; /* null these fields until set by ExecutorStart */ qd->tupDesc = NULL; *************** *** 93,99 **** QueryDesc * CreateUtilityQueryDesc(Node *utilitystmt, Snapshot snapshot, DestReceiver *dest, ! ParamListInfo params) { QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc)); --- 96,103 ---- CreateUtilityQueryDesc(Node *utilitystmt, Snapshot snapshot, DestReceiver *dest, ! ParamListInfo params, ! const char *sourceText) { QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc)); *************** *** 105,110 **** CreateUtilityQueryDesc(Node *utilitystmt, --- 109,115 ---- qd->dest = dest; /* output dest */ qd->params = params; /* parameter values passed into query */ qd->doInstrument = false; /* uninteresting for utilities */ + qd->sourceText = sourceText; /* null these fields until set by ExecutorStart */ qd->tupDesc = NULL; *************** *** 152,158 **** static void ProcessQuery(PlannedStmt *plan, ParamListInfo params, DestReceiver *dest, ! char *completionTag) { QueryDesc *queryDesc; --- 157,164 ---- ProcessQuery(PlannedStmt *plan, ParamListInfo params, DestReceiver *dest, ! char *completionTag, ! const char *sourceText) { QueryDesc *queryDesc; *************** *** 168,174 **** ProcessQuery(PlannedStmt *plan, */ queryDesc = CreateQueryDesc(plan, GetActiveSnapshot(), InvalidSnapshot, ! dest, params, false); /* * Set up to collect AFTER triggers --- 174,180 ---- */ queryDesc = CreateQueryDesc(plan, GetActiveSnapshot(), InvalidSnapshot, ! dest, params, false, sourceText); /* * Set up to collect AFTER triggers *************** *** 504,510 **** PortalStart(Portal portal, ParamListInfo params, Snapshot snapshot) InvalidSnapshot, None_Receiver, params, ! false); /* * We do *not* call AfterTriggerBeginQuery() here. We assume --- 510,517 ---- InvalidSnapshot, None_Receiver, params, ! false, ! portal->sourceText); /* * We do *not* call AfterTriggerBeginQuery() here. We assume *************** *** 1252,1265 **** PortalRunMulti(Portal portal, bool isTopLevel, /* statement can set tag string */ ProcessQuery(pstmt, portal->portalParams, ! dest, completionTag); } else { /* stmt added by rewrite cannot set tag */ ProcessQuery(pstmt, portal->portalParams, ! altdest, NULL); } if (log_executor_stats) --- 1259,1272 ---- /* statement can set tag string */ ProcessQuery(pstmt, portal->portalParams, ! dest, completionTag, portal->sourceText); } else { /* stmt added by rewrite cannot set tag */ ProcessQuery(pstmt, portal->portalParams, ! altdest, NULL, portal->sourceText); } if (log_executor_stats) *** a/src/include/commands/explain.h --- b/src/include/commands/explain.h *************** *** 39,44 **** extern void ExplainOneUtility(Node *utilityStmt, ExplainStmt *stmt, TupOutputState *tstate); extern void ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, ! ExplainStmt *stmt, TupOutputState *tstate); #endif /* EXPLAIN_H */ --- 39,45 ---- TupOutputState *tstate); extern void ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params, ! ExplainStmt *stmt, TupOutputState *tstate, ! const char *queryString); #endif /* EXPLAIN_H */ *** a/src/include/executor/execdesc.h --- b/src/include/executor/execdesc.h *************** *** 42,47 **** typedef struct QueryDesc --- 42,48 ---- DestReceiver *dest; /* the destination for tuple output */ ParamListInfo params; /* param values being passed in */ bool doInstrument; /* TRUE requests runtime instrumentation */ + const char *sourceText; /* Source text for the query */ /* These fields are set by ExecutorStart */ TupleDesc tupDesc; /* descriptor for result tuples */ *************** *** 55,66 **** extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, ! bool doInstrument); extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt, Snapshot snapshot, DestReceiver *dest, ! ParamListInfo params); extern void FreeQueryDesc(QueryDesc *qdesc); --- 56,69 ---- Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, ! bool doInstrument, ! const char *sourceText); extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt, Snapshot snapshot, DestReceiver *dest, ! ParamListInfo params, ! const char *sourceText); extern void FreeQueryDesc(QueryDesc *qdesc);
В списке pgsql-hackers по дате отправления: