diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-04-02 15:04:51 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-04-02 15:04:51 -0400 |
commit | 0b34e7d307e6a142ee94800e6d5f3e73449eeffd (patch) | |
tree | 44e10638357e0c9447cec80e4d94421855083cdf /src/backend/tcop/postgres.c | |
parent | 2c220ca46f3f6de0611367312bec0daef99b29eb (diff) | |
download | postgresql-0b34e7d307e6a142ee94800e6d5f3e73449eeffd.tar.gz postgresql-0b34e7d307e6a142ee94800e6d5f3e73449eeffd.zip |
Improve user control over truncation of logged bind-parameter values.
This patch replaces the boolean GUC log_parameters_on_error introduced
by commit ba79cb5dc with an integer log_parameter_max_length_on_error,
adding the ability to specify how many bytes to trim each logged
parameter value to. (The previous coding hard-wired that choice at
64 bytes.)
In addition, add a new parameter log_parameter_max_length that provides
similar control over truncation of query parameters that are logged in
response to statement-logging options, as opposed to errors. Previous
releases always logged such parameters in full, possibly causing log
bloat.
For backwards compatibility with prior releases,
log_parameter_max_length defaults to -1 (log in full), while
log_parameter_max_length_on_error defaults to 0 (no logging).
Per discussion, log_parameter_max_length is SUSET since the DBA should
control routine logging behavior, but log_parameter_max_length_on_error
is USERSET because it also affects errcontext data sent back to the
client.
Alexey Bashtanov, editorialized a little by me
Discussion: https://postgr.es/m/b10493cc-a399-a03a-67c7-068f2791ee50@imap.cc
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 5b677863b9c..8958ec8103e 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -1763,7 +1763,7 @@ exec_bind_message(StringInfo input_message) */ if (numParams > 0) { - char **knownTextValues = NULL; /* allocate on first use */ + char **knownTextValues = NULL; /* allocate on first use */ params = makeParamList(numParams); @@ -1833,26 +1833,39 @@ exec_bind_message(StringInfo input_message) pval = OidInputFunctionCall(typinput, pstring, typioparam, -1); /* - * Free result of encoding conversion, if any, and save a copy - * for later when logging parameters. + * If we might need to log parameters later, save a copy of + * the converted string in MessageContext; then free the + * result of encoding conversion, if any was done. */ if (pstring) { - if (log_parameters_on_error) + if (log_parameter_max_length_on_error != 0) { - MemoryContext oldcxt; + MemoryContext oldcxt; oldcxt = MemoryContextSwitchTo(MessageContext); + if (knownTextValues == NULL) knownTextValues = palloc0(numParams * sizeof(char *)); - /* - * Note: must copy at least two more full characters - * than BuildParamLogString wants to see; otherwise it - * might fail to include the ellipsis. - */ - knownTextValues[paramno] = - pnstrdup(pstring, 64 + 2 * MAX_MULTIBYTE_CHAR_LEN); + + if (log_parameter_max_length_on_error < 0) + knownTextValues[paramno] = pstrdup(pstring); + else + { + /* + * We can trim the saved string, knowing that we + * won't print all of it. But we must copy at + * least two more full characters than + * BuildParamLogString wants to use; otherwise it + * might fail to include the trailing ellipsis. + */ + knownTextValues[paramno] = + pnstrdup(pstring, + log_parameter_max_length_on_error + + 2 * MAX_MULTIBYTE_CHAR_LEN); + } + MemoryContextSwitchTo(oldcxt); } if (pstring != pbuf.data) @@ -1909,13 +1922,15 @@ exec_bind_message(StringInfo input_message) } /* - * Once all parameters have been received, prepare for printing them in - * errors, if configured to do so. (This is saved in the portal, so - * that they'll appear when the query is executed later.) + * Once all parameters have been received, prepare for printing them + * in errors, if configured to do so. (This is saved in the portal, + * so that they'll appear when the query is executed later.) */ - if (log_parameters_on_error) + if (log_parameter_max_length_on_error != 0) params->paramValuesStr = - BuildParamLogString(params, knownTextValues, 64); + BuildParamLogString(params, + knownTextValues, + log_parameter_max_length_on_error); } else params = NULL; @@ -2396,15 +2411,17 @@ errdetail_execute(List *raw_parsetree_list) * errdetail_params * * Add an errdetail() line showing bind-parameter data, if available. + * Note that this is only used for statement logging, so it is controlled + * by log_parameter_max_length not log_parameter_max_length_on_error. */ static int errdetail_params(ParamListInfo params) { - if (params && params->numParams > 0) + if (params && params->numParams > 0 && log_parameter_max_length != 0) { - char *str; + char *str; - str = BuildParamLogString(params, NULL, 0); + str = BuildParamLogString(params, NULL, log_parameter_max_length); if (str && str[0] != '\0') errdetail("parameters: %s", str); } |