Re: contrib/pg_stat_statements

Поиск
Список
Период
Сортировка
От Martin Pihlak
Тема Re: contrib/pg_stat_statements
Дата
Msg-id 490A00A8.7050708@gmail.com
обсуждение исходный текст
Ответ на Re: contrib/pg_stat_statements  (ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp>)
Ответы Re: contrib/pg_stat_statements  (Tom Lane <tgl@sss.pgh.pa.us>)
Список 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 по дате отправления:

Предыдущее
От: Martijn van Oosterhout
Дата:
Сообщение: Re: Block-level CRC checks
Следующее
От: Zdenek Kotala
Дата:
Сообщение: PG_PAGE_LAYOUT_VERSION 5 - time for change