1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

autho_explain: Add GUC to log query parameters

auto_explain.log_parameter_max_length is a new GUC part of the
extension, similar to the corresponding core setting, that controls the
inclusion of query parameters in the logged explain output.

More tests are added to check the behavior of this new parameter: when
parameters logged in full (the default of -1), when disabled (value of
0) and when partially truncated (value different than the two others).

Author: Dagfinn Ilmari Mannsåker
Discussion: https://postgr.es/m/87ee09mohb.fsf@wibble.ilmari.org
This commit is contained in:
Michael Paquier
2022-07-06 09:55:30 +09:00
parent 08385ed261
commit d4bfe41281
5 changed files with 105 additions and 0 deletions

View File

@ -19,12 +19,14 @@
#include "common/pg_prng.h"
#include "executor/instrument.h"
#include "jit/jit.h"
#include "nodes/params.h"
#include "utils/guc.h"
PG_MODULE_MAGIC;
/* GUC variables */
static int auto_explain_log_min_duration = -1; /* msec or -1 */
static int auto_explain_log_parameter_max_length = -1; /* bytes or -1 */
static bool auto_explain_log_analyze = false;
static bool auto_explain_log_verbose = false;
static bool auto_explain_log_buffers = false;
@ -105,6 +107,18 @@ _PG_init(void)
NULL,
NULL);
DefineCustomIntVariable("auto_explain.log_parameter_max_length",
"Sets the maximum length of query parameters to log.",
"Zero logs no query parameters, -1 logs them in full.",
&auto_explain_log_parameter_max_length,
-1,
-1, INT_MAX,
PGC_SUSET,
GUC_UNIT_BYTE,
NULL,
NULL,
NULL);
DefineCustomBoolVariable("auto_explain.log_analyze",
"Use EXPLAIN ANALYZE for plan logging.",
NULL,
@ -389,6 +403,7 @@ explain_ExecutorEnd(QueryDesc *queryDesc)
ExplainBeginOutput(es);
ExplainQueryText(es, queryDesc);
ExplainQueryParameters(es, queryDesc->params, auto_explain_log_parameter_max_length);
ExplainPrintPlan(es, queryDesc);
if (es->analyze && auto_explain_log_triggers)
ExplainPrintTriggers(es, queryDesc);

View File

@ -60,6 +60,11 @@ like(
qr/Query Text: SELECT \* FROM pg_class;/,
"query text logged, text mode");
unlike(
$log_contents,
qr/Query Parameters:/,
"no query parameters logged when none, text mode");
like(
$log_contents,
qr/Seq Scan on pg_class/,
@ -75,11 +80,49 @@ like(
qr/Query Text: PREPARE get_proc\(name\) AS SELECT \* FROM pg_proc WHERE proname = \$1;/,
"prepared query text logged, text mode");
like(
$log_contents,
qr/Query Parameters: \$1 = 'int4pl'/,
"query parameters logged, text mode");
like(
$log_contents,
qr/Index Scan using pg_proc_proname_args_nsp_index on pg_proc/,
"index scan logged, text mode");
# Prepared query with truncated parameters.
$log_contents = query_log(
$node,
q{PREPARE get_type(name) AS SELECT * FROM pg_type WHERE typname = $1; EXECUTE get_type('float8');},
{ "auto_explain.log_parameter_max_length" => 3 });
like(
$log_contents,
qr/Query Text: PREPARE get_type\(name\) AS SELECT \* FROM pg_type WHERE typname = \$1;/,
"prepared query text logged, text mode");
like(
$log_contents,
qr/Query Parameters: \$1 = 'flo\.\.\.'/,
"query parameters truncated, text mode");
# Prepared query with parameter logging disabled.
$log_contents = query_log(
$node,
q{PREPARE get_type(name) AS SELECT * FROM pg_type WHERE typname = $1; EXECUTE get_type('float8');},
{ "auto_explain.log_parameter_max_length" => 0 });
like(
$log_contents,
qr/Query Text: PREPARE get_type\(name\) AS SELECT \* FROM pg_type WHERE typname = \$1;/,
"prepared query text logged, text mode");
unlike(
$log_contents,
qr/Query Parameters:/,
"query parameters not logged when disabled, text mode");
# JSON format.
$log_contents = query_log(
$node,
@ -91,6 +134,11 @@ like(
qr/"Query Text": "SELECT \* FROM pg_proc;"/,
"query text logged, json mode");
unlike(
$log_contents,
qr/"Query Parameters":/,
"query parameters not logged when none, json mode");
like(
$log_contents,
qr/"Node Type": "Seq Scan"[^}]*"Relation Name": "pg_proc"/s,

View File

@ -63,6 +63,25 @@ LOAD 'auto_explain';
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>auto_explain.log_parameter_max_length</varname> (<type>integer</type>)
<indexterm>
<primary><varname>auto_explain.log_parameter_max_length</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
<varname>auto_explain.log_parameter_max_length</varname> controls the
logging of query parameter values. A value of<literal>-1</literal> (the
default) logs the parameter values in full. <literal>0</literal> disables
logging of parameter values. A value greater than zero truncates each
parameter value to that many bytes. Only superusers can change this
setting.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>auto_explain.log_analyze</varname> (<type>boolean</type>)

View File

@ -972,6 +972,28 @@ ExplainQueryText(ExplainState *es, QueryDesc *queryDesc)
ExplainPropertyText("Query Text", queryDesc->sourceText, es);
}
/*
* ExplainQueryParameters -
* add a "Query Parameters" node that describes the parameters of the query
*
* The caller should have set up the options fields of *es, as well as
* initializing the output buffer es->str.
*
*/
void
ExplainQueryParameters(ExplainState *es, ParamListInfo params, int maxlen)
{
char *str;
/* This check is consistent with errdetail_params() */
if (params == NULL || params->numParams <= 0 || maxlen == 0)
return;
str = BuildParamLogString(params, NULL, maxlen);
if (str && str[0] != '\0')
ExplainPropertyText("Query Parameters", str, es);
}
/*
* report_triggers -
* report execution stats for a single relation's triggers

View File

@ -99,6 +99,7 @@ extern void ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc);
extern void ExplainPrintJITSummary(ExplainState *es, QueryDesc *queryDesc);
extern void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc);
extern void ExplainQueryParameters(ExplainState *es, ParamListInfo params, int maxlen);
extern void ExplainBeginOutput(ExplainState *es);
extern void ExplainEndOutput(ExplainState *es);