aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-04-02 15:04:51 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-04-02 15:04:51 -0400
commit0b34e7d307e6a142ee94800e6d5f3e73449eeffd (patch)
tree44e10638357e0c9447cec80e4d94421855083cdf /src/backend/tcop/postgres.c
parent2c220ca46f3f6de0611367312bec0daef99b29eb (diff)
downloadpostgresql-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.c57
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);
}