1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-17 17:02:08 +03:00

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
This commit is contained in:
Tom Lane
2020-04-02 15:04:51 -04:00
parent 2c220ca46f
commit 0b34e7d307
9 changed files with 207 additions and 63 deletions

View File

@ -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);
}