Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1ea3963

Browse files
committed
Improve logging of bad parameter values in BIND messages.
Since commitba79cb5, values of bind parameters have been loggedduring errors in extended query mode. However, we only did that afterwe'd collected and converted all the parameter values, thus failing tooffer any useful localization of invalid-parameter problems. Add aseparate callback that's used during parameter collection, and have itprint the parameter number, along with the input string if text inputformat is used.Justin Pryzby and Tom LaneDiscussion:https://postgr.es/m/20210104170939.GH9712@telsasoft.comDiscussion:https://postgr.es/m/CANfkH5k-6nNt-4cSv1vPB80nq2BZCzhFVR5O4VznYbsX0wZmow@mail.gmail.com
1 parent0150616 commit1ea3963

File tree

2 files changed

+107
-3
lines changed

2 files changed

+107
-3
lines changed

‎src/backend/tcop/postgres.c

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,18 @@ intmax_stack_depth = 100;
102102
/* wait N seconds to allow attach from a debugger */
103103
intPostAuthDelay=0;
104104

105+
/* ----------------
106+
*private typedefs etc
107+
* ----------------
108+
*/
105109

110+
/* type of argument for bind_param_error_callback */
111+
typedefstructBindParamCbData
112+
{
113+
constchar*portalName;
114+
intparamno;/* zero-based param number, or -1 initially */
115+
constchar*paramval;/* textual input string, if available */
116+
}BindParamCbData;
106117

107118
/* ----------------
108119
*private variables
@@ -183,6 +194,7 @@ static interrdetail_execute(List *raw_parsetree_list);
183194
staticinterrdetail_params(ParamListInfoparams);
184195
staticinterrdetail_abort(void);
185196
staticinterrdetail_recovery_conflict(void);
197+
staticvoidbind_param_error_callback(void*arg);
186198
staticvoidstart_xact_command(void);
187199
staticvoidfinish_xact_command(void);
188200
staticboolIsTransactionExitStmt(Node*parsetree);
@@ -1698,6 +1710,19 @@ exec_bind_message(StringInfo input_message)
16981710
if (numParams>0)
16991711
{
17001712
char**knownTextValues=NULL;/* allocate on first use */
1713+
BindParamCbDataone_param_data;
1714+
1715+
/*
1716+
* Set up an error callback so that if there's an error in this phase,
1717+
* we can report the specific parameter causing the problem.
1718+
*/
1719+
one_param_data.portalName=portal->name;
1720+
one_param_data.paramno=-1;
1721+
one_param_data.paramval=NULL;
1722+
params_errcxt.previous=error_context_stack;
1723+
params_errcxt.callback=bind_param_error_callback;
1724+
params_errcxt.arg= (void*)&one_param_data;
1725+
error_context_stack=&params_errcxt;
17011726

17021727
params=makeParamList(numParams);
17031728

@@ -1711,6 +1736,9 @@ exec_bind_message(StringInfo input_message)
17111736
charcsave;
17121737
int16pformat;
17131738

1739+
one_param_data.paramno=paramno;
1740+
one_param_data.paramval=NULL;
1741+
17141742
plength=pq_getmsgint(input_message,4);
17151743
isNull= (plength==-1);
17161744

@@ -1764,8 +1792,13 @@ exec_bind_message(StringInfo input_message)
17641792
else
17651793
pstring=pg_client_to_server(pbuf.data,plength);
17661794

1795+
/* Now we can log the input string in case of error */
1796+
one_param_data.paramval=pstring;
1797+
17671798
pval=OidInputFunctionCall(typinput,pstring,typioparam,-1);
17681799

1800+
one_param_data.paramval=NULL;
1801+
17691802
/*
17701803
* If we might need to log parameters later, save a copy of
17711804
* the converted string in MessageContext; then free the
@@ -1855,10 +1888,13 @@ exec_bind_message(StringInfo input_message)
18551888
params->params[paramno].ptype=ptype;
18561889
}
18571890

1891+
/* Pop the per-parameter error callback */
1892+
error_context_stack=error_context_stack->previous;
1893+
18581894
/*
18591895
* Once all parameters have been received, prepare for printing them
1860-
* in errors, if configured to do so. (This is saved in the portal,
1861-
* so that they'll appear when the query is executed later.)
1896+
* infutureerrors, if configured to do so. (This is saved in the
1897+
*portal,so that they'll appear when the query is executed later.)
18621898
*/
18631899
if (log_parameter_max_length_on_error!=0)
18641900
params->paramValuesStr=
@@ -1872,7 +1908,10 @@ exec_bind_message(StringInfo input_message)
18721908
/* Done storing stuff in portal's context */
18731909
MemoryContextSwitchTo(oldContext);
18741910

1875-
/* Set the error callback so that parameters are logged, as needed */
1911+
/*
1912+
* Set up another error callback so that all the parameters are logged if
1913+
* we get an error during the rest of the BIND processing.
1914+
*/
18761915
params_data.portalName=portal->name;
18771916
params_data.params=params;
18781917
params_errcxt.previous=error_context_stack;
@@ -2413,6 +2452,55 @@ errdetail_recovery_conflict(void)
24132452
return0;
24142453
}
24152454

2455+
/*
2456+
* bind_param_error_callback
2457+
*
2458+
* Error context callback used while parsing parameters in a Bind message
2459+
*/
2460+
staticvoid
2461+
bind_param_error_callback(void*arg)
2462+
{
2463+
BindParamCbData*data= (BindParamCbData*)arg;
2464+
StringInfoDatabuf;
2465+
char*quotedval;
2466+
2467+
if (data->paramno<0)
2468+
return;
2469+
2470+
/* If we have a textual value, quote it, and trim if necessary */
2471+
if (data->paramval)
2472+
{
2473+
initStringInfo(&buf);
2474+
appendStringInfoStringQuoted(&buf,data->paramval,
2475+
log_parameter_max_length_on_error);
2476+
quotedval=buf.data;
2477+
}
2478+
else
2479+
quotedval=NULL;
2480+
2481+
if (data->portalName&&data->portalName[0]!='\0')
2482+
{
2483+
if (quotedval)
2484+
errcontext("portal \"%s\" parameter $%d = %s",
2485+
data->portalName,data->paramno+1,quotedval);
2486+
else
2487+
errcontext("portal \"%s\" parameter $%d",
2488+
data->portalName,data->paramno+1);
2489+
}
2490+
else
2491+
{
2492+
if (quotedval)
2493+
errcontext("unnamed portal parameter $%d = %s",
2494+
data->paramno+1,quotedval);
2495+
else
2496+
errcontext("unnamed portal parameter $%d",
2497+
data->paramno+1);
2498+
}
2499+
2500+
if (quotedval)
2501+
pfree(quotedval);
2502+
}
2503+
24162504
/*
24172505
* exec_describe_statement_message
24182506
*

‎src/bin/pgbench/t/001_pgbench_with_server.pl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,22 @@ sub pgbench
389389
"parameter report truncates");
390390
$log =undef;
391391

392+
# Check that bad parameters are reported during typinput phase of BIND
393+
pgbench(
394+
'-n -t1 -c1 -M prepared',
395+
2,
396+
[],
397+
[
398+
qr{ERROR: invalid input syntax for type smallint: "1a"},
399+
qr{CONTEXT: unnamed portal parameter\$2 = '1a'}
400+
],
401+
'server parameter logging',
402+
{
403+
'001_param_6'=>q{select 42 as value1, '1a' as value2 \gset
404+
select :value1::smallint, :value2::smallint;
405+
}
406+
});
407+
392408
# Restore default logging config
393409
$node->append_conf('postgresql.conf',
394410
"log_min_duration_statement = -1\n"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp