LCOV - differential code coverage report
Current view: top level - contrib/auto_explain - auto_explain.c (source / functions) Coverage Total Hit UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 89.3 % 103 92 11 92
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 6 6 6
Baseline: lcov-20250906-005545-baseline Branches: 48.9 % 92 45 47 45
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 60.0 % 5 3 2 3
(360..) days: 90.8 % 98 89 9 89
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
(360..) days: 100.0 % 5 5 5
Branch coverage date bins:
(360..) days: 48.9 % 92 45 47 45

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * auto_explain.c
                                  4                 :                :  *
                                  5                 :                :  *
                                  6                 :                :  * Copyright (c) 2008-2025, PostgreSQL Global Development Group
                                  7                 :                :  *
                                  8                 :                :  * IDENTIFICATION
                                  9                 :                :  *    contrib/auto_explain/auto_explain.c
                                 10                 :                :  *
                                 11                 :                :  *-------------------------------------------------------------------------
                                 12                 :                :  */
                                 13                 :                : #include "postgres.h"
                                 14                 :                : 
                                 15                 :                : #include <limits.h>
                                 16                 :                : 
                                 17                 :                : #include "access/parallel.h"
                                 18                 :                : #include "commands/explain.h"
                                 19                 :                : #include "commands/explain_format.h"
                                 20                 :                : #include "commands/explain_state.h"
                                 21                 :                : #include "common/pg_prng.h"
                                 22                 :                : #include "executor/instrument.h"
                                 23                 :                : #include "utils/guc.h"
                                 24                 :                : 
  164 tgl@sss.pgh.pa.us          25                 :CBC          11 : PG_MODULE_MAGIC_EXT(
                                 26                 :                :                     .name = "auto_explain",
                                 27                 :                :                     .version = PG_VERSION
                                 28                 :                : );
                                 29                 :                : 
                                 30                 :                : /* GUC variables */
                                 31                 :                : static int  auto_explain_log_min_duration = -1; /* msec or -1 */
                                 32                 :                : static int  auto_explain_log_parameter_max_length = -1; /* bytes or -1 */
                                 33                 :                : static bool auto_explain_log_analyze = false;
                                 34                 :                : static bool auto_explain_log_verbose = false;
                                 35                 :                : static bool auto_explain_log_buffers = false;
                                 36                 :                : static bool auto_explain_log_wal = false;
                                 37                 :                : static bool auto_explain_log_triggers = false;
                                 38                 :                : static bool auto_explain_log_timing = true;
                                 39                 :                : static bool auto_explain_log_settings = false;
                                 40                 :                : static int  auto_explain_log_format = EXPLAIN_FORMAT_TEXT;
                                 41                 :                : static int  auto_explain_log_level = LOG;
                                 42                 :                : static bool auto_explain_log_nested_statements = false;
                                 43                 :                : static double auto_explain_sample_rate = 1;
                                 44                 :                : 
                                 45                 :                : static const struct config_enum_entry format_options[] = {
                                 46                 :                :     {"text", EXPLAIN_FORMAT_TEXT, false},
                                 47                 :                :     {"xml", EXPLAIN_FORMAT_XML, false},
                                 48                 :                :     {"json", EXPLAIN_FORMAT_JSON, false},
                                 49                 :                :     {"yaml", EXPLAIN_FORMAT_YAML, false},
                                 50                 :                :     {NULL, 0, false}
                                 51                 :                : };
                                 52                 :                : 
                                 53                 :                : static const struct config_enum_entry loglevel_options[] = {
                                 54                 :                :     {"debug5", DEBUG5, false},
                                 55                 :                :     {"debug4", DEBUG4, false},
                                 56                 :                :     {"debug3", DEBUG3, false},
                                 57                 :                :     {"debug2", DEBUG2, false},
                                 58                 :                :     {"debug1", DEBUG1, false},
                                 59                 :                :     {"debug", DEBUG2, true},
                                 60                 :                :     {"info", INFO, false},
                                 61                 :                :     {"notice", NOTICE, false},
                                 62                 :                :     {"warning", WARNING, false},
                                 63                 :                :     {"log", LOG, false},
                                 64                 :                :     {NULL, 0, false}
                                 65                 :                : };
                                 66                 :                : 
                                 67                 :                : /* Current nesting depth of ExecutorRun calls */
                                 68                 :                : static int  nesting_level = 0;
                                 69                 :                : 
                                 70                 :                : /* Is the current top-level query to be sampled? */
                                 71                 :                : static bool current_query_sampled = false;
                                 72                 :                : 
                                 73                 :                : #define auto_explain_enabled() \
                                 74                 :                :     (auto_explain_log_min_duration >= 0 && \
                                 75                 :                :      (nesting_level == 0 || auto_explain_log_nested_statements) && \
                                 76                 :                :      current_query_sampled)
                                 77                 :                : 
                                 78                 :                : /* Saved hook values */
                                 79                 :                : static ExecutorStart_hook_type prev_ExecutorStart = NULL;
                                 80                 :                : static ExecutorRun_hook_type prev_ExecutorRun = NULL;
                                 81                 :                : static ExecutorFinish_hook_type prev_ExecutorFinish = NULL;
                                 82                 :                : static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
                                 83                 :                : 
                                 84                 :                : static void explain_ExecutorStart(QueryDesc *queryDesc, int eflags);
                                 85                 :                : static void explain_ExecutorRun(QueryDesc *queryDesc,
                                 86                 :                :                                 ScanDirection direction,
                                 87                 :                :                                 uint64 count);
                                 88                 :                : static void explain_ExecutorFinish(QueryDesc *queryDesc);
                                 89                 :                : static void explain_ExecutorEnd(QueryDesc *queryDesc);
                                 90                 :                : 
                                 91                 :                : 
                                 92                 :                : /*
                                 93                 :                :  * Module load callback
                                 94                 :                :  */
                                 95                 :                : void
 6135                            96                 :             11 : _PG_init(void)
                                 97                 :                : {
                                 98                 :                :     /* Define custom GUC variables. */
 6091                            99                 :             11 :     DefineCustomIntVariable("auto_explain.log_min_duration",
                                100                 :                :                             "Sets the minimum execution time above which plans will be logged.",
                                101                 :                :                             "-1 disables logging plans. 0 means log all plans.",
                                102                 :                :                             &auto_explain_log_min_duration,
                                103                 :                :                             -1,
                                104                 :                :                             -1, INT_MAX,
                                105                 :                :                             PGC_SUSET,
                                106                 :                :                             GUC_UNIT_MS,
                                107                 :                :                             NULL,
                                108                 :                :                             NULL,
                                109                 :                :                             NULL);
                                110                 :                : 
 1158 michael@paquier.xyz       111                 :             11 :     DefineCustomIntVariable("auto_explain.log_parameter_max_length",
                                112                 :                :                             "Sets the maximum length of query parameter values to log.",
                                113                 :                :                             "-1 means log values in full.",
                                114                 :                :                             &auto_explain_log_parameter_max_length,
                                115                 :                :                             -1,
                                116                 :                :                             -1, INT_MAX,
                                117                 :                :                             PGC_SUSET,
                                118                 :                :                             GUC_UNIT_BYTE,
                                119                 :                :                             NULL,
                                120                 :                :                             NULL,
                                121                 :                :                             NULL);
                                122                 :                : 
 6091 tgl@sss.pgh.pa.us         123                 :             11 :     DefineCustomBoolVariable("auto_explain.log_analyze",
                                124                 :                :                              "Use EXPLAIN ANALYZE for plan logging.",
                                125                 :                :                              NULL,
                                126                 :                :                              &auto_explain_log_analyze,
                                127                 :                :                              false,
                                128                 :                :                              PGC_SUSET,
                                129                 :                :                              0,
                                130                 :                :                              NULL,
                                131                 :                :                              NULL,
                                132                 :                :                              NULL);
                                133                 :                : 
 2347 tomas.vondra@postgre      134                 :             11 :     DefineCustomBoolVariable("auto_explain.log_settings",
                                135                 :                :                              "Log modified configuration parameters affecting query planning.",
                                136                 :                :                              NULL,
                                137                 :                :                              &auto_explain_log_settings,
                                138                 :                :                              false,
                                139                 :                :                              PGC_SUSET,
                                140                 :                :                              0,
                                141                 :                :                              NULL,
                                142                 :                :                              NULL,
                                143                 :                :                              NULL);
                                144                 :                : 
 6091 tgl@sss.pgh.pa.us         145                 :             11 :     DefineCustomBoolVariable("auto_explain.log_verbose",
                                146                 :                :                              "Use EXPLAIN VERBOSE for plan logging.",
                                147                 :                :                              NULL,
                                148                 :                :                              &auto_explain_log_verbose,
                                149                 :                :                              false,
                                150                 :                :                              PGC_SUSET,
                                151                 :                :                              0,
                                152                 :                :                              NULL,
                                153                 :                :                              NULL,
                                154                 :                :                              NULL);
                                155                 :                : 
 5744 rhaas@postgresql.org      156                 :             11 :     DefineCustomBoolVariable("auto_explain.log_buffers",
                                157                 :                :                              "Log buffers usage.",
                                158                 :                :                              NULL,
                                159                 :                :                              &auto_explain_log_buffers,
                                160                 :                :                              false,
                                161                 :                :                              PGC_SUSET,
                                162                 :                :                              0,
                                163                 :                :                              NULL,
                                164                 :                :                              NULL,
                                165                 :                :                              NULL);
                                166                 :                : 
 1979 akapila@postgresql.o      167                 :             11 :     DefineCustomBoolVariable("auto_explain.log_wal",
                                168                 :                :                              "Log WAL usage.",
                                169                 :                :                              NULL,
                                170                 :                :                              &auto_explain_log_wal,
                                171                 :                :                              false,
                                172                 :                :                              PGC_SUSET,
                                173                 :                :                              0,
                                174                 :                :                              NULL,
                                175                 :                :                              NULL,
                                176                 :                :                              NULL);
                                177                 :                : 
 4204 alvherre@alvh.no-ip.      178                 :             11 :     DefineCustomBoolVariable("auto_explain.log_triggers",
                                179                 :                :                              "Include trigger statistics in plans.",
                                180                 :                :                              "This has no effect unless log_analyze is also set.",
                                181                 :                :                              &auto_explain_log_triggers,
                                182                 :                :                              false,
                                183                 :                :                              PGC_SUSET,
                                184                 :                :                              0,
                                185                 :                :                              NULL,
                                186                 :                :                              NULL,
                                187                 :                :                              NULL);
                                188                 :                : 
 5871 tgl@sss.pgh.pa.us         189                 :             11 :     DefineCustomEnumVariable("auto_explain.log_format",
                                190                 :                :                              "EXPLAIN format to be used for plan logging.",
                                191                 :                :                              NULL,
                                192                 :                :                              &auto_explain_log_format,
                                193                 :                :                              EXPLAIN_FORMAT_TEXT,
                                194                 :                :                              format_options,
                                195                 :                :                              PGC_SUSET,
                                196                 :                :                              0,
                                197                 :                :                              NULL,
                                198                 :                :                              NULL,
                                199                 :                :                              NULL);
                                200                 :                : 
 2594 andrew@dunslane.net       201                 :             11 :     DefineCustomEnumVariable("auto_explain.log_level",
                                202                 :                :                              "Log level for the plan.",
                                203                 :                :                              NULL,
                                204                 :                :                              &auto_explain_log_level,
                                205                 :                :                              LOG,
                                206                 :                :                              loglevel_options,
                                207                 :                :                              PGC_SUSET,
                                208                 :                :                              0,
                                209                 :                :                              NULL,
                                210                 :                :                              NULL,
                                211                 :                :                              NULL);
                                212                 :                : 
 6091 tgl@sss.pgh.pa.us         213                 :             11 :     DefineCustomBoolVariable("auto_explain.log_nested_statements",
                                214                 :                :                              "Log nested statements.",
                                215                 :                :                              NULL,
                                216                 :                :                              &auto_explain_log_nested_statements,
                                217                 :                :                              false,
                                218                 :                :                              PGC_SUSET,
                                219                 :                :                              0,
                                220                 :                :                              NULL,
                                221                 :                :                              NULL,
                                222                 :                :                              NULL);
                                223                 :                : 
 4960 rhaas@postgresql.org      224                 :             11 :     DefineCustomBoolVariable("auto_explain.log_timing",
                                225                 :                :                              "Collect timing data, not just row counts.",
                                226                 :                :                              NULL,
                                227                 :                :                              &auto_explain_log_timing,
                                228                 :                :                              true,
                                229                 :                :                              PGC_SUSET,
                                230                 :                :                              0,
                                231                 :                :                              NULL,
                                232                 :                :                              NULL,
                                233                 :                :                              NULL);
                                234                 :                : 
 3464 magnus@hagander.net       235                 :             11 :     DefineCustomRealVariable("auto_explain.sample_rate",
                                236                 :                :                              "Fraction of queries to process.",
                                237                 :                :                              NULL,
                                238                 :                :                              &auto_explain_sample_rate,
                                239                 :                :                              1.0,
                                240                 :                :                              0.0,
                                241                 :                :                              1.0,
                                242                 :                :                              PGC_SUSET,
                                243                 :                :                              0,
                                244                 :                :                              NULL,
                                245                 :                :                              NULL,
                                246                 :                :                              NULL);
                                247                 :                : 
 1293 tgl@sss.pgh.pa.us         248                 :             11 :     MarkGUCPrefixReserved("auto_explain");
                                249                 :                : 
                                250                 :                :     /* Install hooks. */
 6135                           251                 :             11 :     prev_ExecutorStart = ExecutorStart_hook;
                                252                 :             11 :     ExecutorStart_hook = explain_ExecutorStart;
                                253                 :             11 :     prev_ExecutorRun = ExecutorRun_hook;
                                254                 :             11 :     ExecutorRun_hook = explain_ExecutorRun;
 5305                           255                 :             11 :     prev_ExecutorFinish = ExecutorFinish_hook;
                                256                 :             11 :     ExecutorFinish_hook = explain_ExecutorFinish;
 6135                           257                 :             11 :     prev_ExecutorEnd = ExecutorEnd_hook;
                                258                 :             11 :     ExecutorEnd_hook = explain_ExecutorEnd;
                                259                 :             11 : }
                                260                 :                : 
                                261                 :                : /*
                                262                 :                :  * ExecutorStart hook: start up logging if needed
                                263                 :                :  */
                                264                 :                : static void
                                265                 :              9 : explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
                                266                 :                : {
                                267                 :                :     /*
                                268                 :                :      * At the beginning of each top-level statement, decide whether we'll
                                269                 :                :      * sample this statement.  If nested-statement explaining is enabled,
                                270                 :                :      * either all nested statements will be explained or none will.
                                271                 :                :      *
                                272                 :                :      * When in a parallel worker, we should do nothing, which we can implement
                                273                 :                :      * cheaply by pretending we decided not to sample the current statement.
                                274                 :                :      * If EXPLAIN is active in the parent session, data will be collected and
                                275                 :                :      * reported back to the parent, and it's no business of ours to interfere.
                                276                 :                :      */
 2287                           277         [ +  - ]:              9 :     if (nesting_level == 0)
                                278                 :                :     {
                                279   [ +  -  +  - ]:              9 :         if (auto_explain_log_min_duration >= 0 && !IsParallelWorker())
 1378                           280                 :              9 :             current_query_sampled = (pg_prng_double(&pg_global_prng_state) < auto_explain_sample_rate);
                                281                 :                :         else
 2287 tgl@sss.pgh.pa.us         282                 :UBC           0 :             current_query_sampled = false;
                                283                 :                :     }
                                284                 :                : 
 2287 tgl@sss.pgh.pa.us         285   [ +  -  -  +  :CBC           9 :     if (auto_explain_enabled())
                                        -  -  +  - ]
                                286                 :                :     {
                                287                 :                :         /* Enable per-node instrumentation iff log_analyze is required. */
 6091                           288   [ +  -  +  - ]:              9 :         if (auto_explain_log_analyze && (eflags & EXEC_FLAG_EXPLAIN_ONLY) == 0)
                                289                 :                :         {
 4960 rhaas@postgresql.org      290         [ +  - ]:              9 :             if (auto_explain_log_timing)
                                291                 :              9 :                 queryDesc->instrument_options |= INSTRUMENT_TIMER;
                                292                 :                :             else
 4960 rhaas@postgresql.org      293                 :UBC           0 :                 queryDesc->instrument_options |= INSTRUMENT_ROWS;
 5744 rhaas@postgresql.org      294         [ -  + ]:CBC           9 :             if (auto_explain_log_buffers)
 5744 rhaas@postgresql.org      295                 :UBC           0 :                 queryDesc->instrument_options |= INSTRUMENT_BUFFERS;
 1979 akapila@postgresql.o      296         [ -  + ]:CBC           9 :             if (auto_explain_log_wal)
 1979 akapila@postgresql.o      297                 :UBC           0 :                 queryDesc->instrument_options |= INSTRUMENT_WAL;
                                298                 :                :         }
                                299                 :                :     }
                                300                 :                : 
 6135 tgl@sss.pgh.pa.us         301         [ -  + ]:CBC           9 :     if (prev_ExecutorStart)
  107 amitlan@postgresql.o      302                 :UBC           0 :         prev_ExecutorStart(queryDesc, eflags);
                                303                 :                :     else
  107 amitlan@postgresql.o      304                 :CBC           9 :         standard_ExecutorStart(queryDesc, eflags);
                                305                 :                : 
 2287 tgl@sss.pgh.pa.us         306   [ +  -  -  +  :              9 :     if (auto_explain_enabled())
                                        -  -  +  - ]
                                307                 :                :     {
                                308                 :                :         /*
                                309                 :                :          * Set up to track total elapsed time in ExecutorRun.  Make sure the
                                310                 :                :          * space is allocated in the per-query context so it will go away at
                                311                 :                :          * ExecutorEnd.
                                312                 :                :          */
 6135                           313         [ +  - ]:              9 :         if (queryDesc->totaltime == NULL)
                                314                 :                :         {
                                315                 :                :             MemoryContext oldcxt;
                                316                 :                : 
                                317                 :              9 :             oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
 1578 efujita@postgresql.o      318                 :              9 :             queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL, false);
 6135 tgl@sss.pgh.pa.us         319                 :              9 :             MemoryContextSwitchTo(oldcxt);
                                320                 :                :         }
                                321                 :                :     }
                                322                 :              9 : }
                                323                 :                : 
                                324                 :                : /*
                                325                 :                :  * ExecutorRun hook: all we need do is track nesting depth
                                326                 :                :  */
                                327                 :                : static void
 3089 rhaas@postgresql.org      328                 :              9 : explain_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction,
                                329                 :                :                     uint64 count)
                                330                 :                : {
 6135 tgl@sss.pgh.pa.us         331                 :              9 :     nesting_level++;
                                332         [ +  - ]:              9 :     PG_TRY();
                                333                 :                :     {
                                334         [ -  + ]:              9 :         if (prev_ExecutorRun)
  271 tgl@sss.pgh.pa.us         335                 :UBC           0 :             prev_ExecutorRun(queryDesc, direction, count);
                                336                 :                :         else
  271 tgl@sss.pgh.pa.us         337                 :CBC           9 :             standard_ExecutorRun(queryDesc, direction, count);
                                338                 :                :     }
 2136 peter@eisentraut.org      339                 :UBC           0 :     PG_FINALLY();
                                340                 :                :     {
 6135 tgl@sss.pgh.pa.us         341                 :CBC           9 :         nesting_level--;
                                342                 :                :     }
                                343         [ -  + ]:              9 :     PG_END_TRY();
                                344                 :              9 : }
                                345                 :                : 
                                346                 :                : /*
                                347                 :                :  * ExecutorFinish hook: all we need do is track nesting depth
                                348                 :                :  */
                                349                 :                : static void
 5305                           350                 :              9 : explain_ExecutorFinish(QueryDesc *queryDesc)
                                351                 :                : {
                                352                 :              9 :     nesting_level++;
                                353         [ +  - ]:              9 :     PG_TRY();
                                354                 :                :     {
                                355         [ -  + ]:              9 :         if (prev_ExecutorFinish)
 5305 tgl@sss.pgh.pa.us         356                 :UBC           0 :             prev_ExecutorFinish(queryDesc);
                                357                 :                :         else
 5305 tgl@sss.pgh.pa.us         358                 :CBC           9 :             standard_ExecutorFinish(queryDesc);
                                359                 :                :     }
 2136 peter@eisentraut.org      360                 :UBC           0 :     PG_FINALLY();
                                361                 :                :     {
 5305 tgl@sss.pgh.pa.us         362                 :CBC           9 :         nesting_level--;
                                363                 :                :     }
                                364         [ -  + ]:              9 :     PG_END_TRY();
                                365                 :              9 : }
                                366                 :                : 
                                367                 :                : /*
                                368                 :                :  * ExecutorEnd hook: log results if needed
                                369                 :                :  */
                                370                 :                : static void
 6135                           371                 :              9 : explain_ExecutorEnd(QueryDesc *queryDesc)
                                372                 :                : {
 2287                           373   [ +  -  +  -  :              9 :     if (queryDesc->totaltime && auto_explain_enabled())
                                     -  +  -  -  +  
                                                 - ]
                                374                 :                :     {
                                375                 :                :         MemoryContext oldcxt;
                                376                 :                :         double      msec;
                                377                 :                : 
                                378                 :                :         /*
                                379                 :                :          * Make sure we operate in the per-query context, so any cruft will be
                                380                 :                :          * discarded later during ExecutorEnd.
                                381                 :                :          */
 1677                           382                 :              9 :         oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
                                383                 :                : 
                                384                 :                :         /*
                                385                 :                :          * Make sure stats accumulation is done.  (Note: it's okay if several
                                386                 :                :          * levels of hook all do this.)
                                387                 :                :          */
 6135                           388                 :              9 :         InstrEndLoop(queryDesc->totaltime);
                                389                 :                : 
                                390                 :                :         /* Log plan if duration is exceeded. */
                                391                 :              9 :         msec = queryDesc->totaltime->total * 1000.0;
 6091                           392         [ +  - ]:              9 :         if (msec >= auto_explain_log_min_duration)
                                393                 :                :         {
 3887                           394                 :              9 :             ExplainState *es = NewExplainState();
                                395                 :                : 
                                396   [ +  -  +  - ]:              9 :             es->analyze = (queryDesc->instrument_options && auto_explain_log_analyze);
                                397                 :              9 :             es->verbose = auto_explain_log_verbose;
                                398   [ +  -  -  + ]:              9 :             es->buffers = (es->analyze && auto_explain_log_buffers);
 1979 akapila@postgresql.o      399   [ +  -  -  + ]:              9 :             es->wal = (es->analyze && auto_explain_log_wal);
 3887 tgl@sss.pgh.pa.us         400   [ +  -  +  - ]:              9 :             es->timing = (es->analyze && auto_explain_log_timing);
                                401                 :              9 :             es->summary = es->analyze;
                                402                 :                :             /* No support for MEMORY */
                                403                 :                :             /* es->memory = false; */
                                404                 :              9 :             es->format = auto_explain_log_format;
 2347 tomas.vondra@postgre      405                 :              9 :             es->settings = auto_explain_log_settings;
                                406                 :                : 
 3887 tgl@sss.pgh.pa.us         407                 :              9 :             ExplainBeginOutput(es);
                                408                 :              9 :             ExplainQueryText(es, queryDesc);
 1158 michael@paquier.xyz       409                 :              9 :             ExplainQueryParameters(es, queryDesc->params, auto_explain_log_parameter_max_length);
 3887 tgl@sss.pgh.pa.us         410                 :              9 :             ExplainPrintPlan(es, queryDesc);
                                411   [ +  -  -  + ]:              9 :             if (es->analyze && auto_explain_log_triggers)
 3887 tgl@sss.pgh.pa.us         412                 :UBC           0 :                 ExplainPrintTriggers(es, queryDesc);
 2538 andres@anarazel.de        413         [ +  - ]:CBC           9 :             if (es->costs)
 2530                           414                 :              9 :                 ExplainPrintJITSummary(es, queryDesc);
 3887 tgl@sss.pgh.pa.us         415                 :              9 :             ExplainEndOutput(es);
                                416                 :                : 
                                417                 :                :             /* Remove last line break */
                                418   [ +  -  +  + ]:              9 :             if (es->str->len > 0 && es->str->data[es->str->len - 1] == '\n')
                                419                 :              7 :                 es->str->data[--es->str->len] = '\0';
                                420                 :                : 
                                421                 :                :             /* Fix JSON to output an object */
 4954 andrew@dunslane.net       422         [ +  + ]:              9 :             if (auto_explain_log_format == EXPLAIN_FORMAT_JSON)
                                423                 :                :             {
 3887 tgl@sss.pgh.pa.us         424                 :              2 :                 es->str->data[0] = '{';
                                425                 :              2 :                 es->str->data[es->str->len - 1] = '}';
                                426                 :                :             }
                                427                 :                : 
                                428                 :                :             /*
                                429                 :                :              * Note: we rely on the existing logging of context or
                                430                 :                :              * debug_query_string to identify just which statement is being
                                431                 :                :              * reported.  This isn't ideal but trying to do it here would
                                432                 :                :              * often result in duplication.
                                433                 :                :              */
 2594 andrew@dunslane.net       434         [ +  - ]:              9 :             ereport(auto_explain_log_level,
                                435                 :                :                     (errmsg("duration: %.3f ms  plan:\n%s",
                                436                 :                :                             msec, es->str->data),
                                437                 :                :                      errhidestmt(true)));
                                438                 :                :         }
                                439                 :                : 
 1677 tgl@sss.pgh.pa.us         440                 :              9 :         MemoryContextSwitchTo(oldcxt);
                                441                 :                :     }
                                442                 :                : 
 6135                           443         [ -  + ]:              9 :     if (prev_ExecutorEnd)
 6135 tgl@sss.pgh.pa.us         444                 :UBC           0 :         prev_ExecutorEnd(queryDesc);
                                445                 :                :     else
 6135 tgl@sss.pgh.pa.us         446                 :CBC           9 :         standard_ExecutorEnd(queryDesc);
                                447                 :              9 : }
        

Generated by: LCOV version 2.4-beta