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

Commitef71375

Browse files
committed
Coerce 'unknown' type parameters to the right type in the fixed-params
parse_analyze() function. That case occurs e.g with PL/pgSQLEXECUTE ... USING 'stringconstant'.The coercion with a CoerceViaIO node. The result is similar to the coercionvia input function performed for unknown constants in coerce_type(),except that this happens at runtime.Backpatch to 9.0. The issue is present in 8.4 as well, but the coerce paramhook infrastructure this patch relies on was introduced in 9.0. Given thelack of user reports and harmlessness of the bug, it's not worth attemptinga different fix just for 8.4.
1 parent9a8d15b commitef71375

File tree

1 file changed

+84
-2
lines changed

1 file changed

+84
-2
lines changed

‎src/backend/parser/parse_param.c

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*
1818
*
1919
* IDENTIFICATION
20-
* $PostgreSQL: pgsql/src/backend/parser/parse_param.c,v 2.4 2010/02/26 02:00:52 momjian Exp $
20+
* $PostgreSQL: pgsql/src/backend/parser/parse_param.c,v 2.5 2010/08/18 12:20:15 heikki Exp $
2121
*
2222
*-------------------------------------------------------------------------
2323
*/
@@ -36,6 +36,7 @@ typedef struct FixedParamState
3636
{
3737
Oid*paramTypes;/* array of parameter type OIDs */
3838
intnumParams;/* number of array entries */
39+
Oid*unknownParamTypes;/* resolved types of 'unknown' params */
3940
}FixedParamState;
4041

4142
/*
@@ -55,6 +56,9 @@ static Node *variable_paramref_hook(ParseState *pstate, ParamRef *pref);
5556
staticNode*variable_coerce_param_hook(ParseState*pstate,Param*param,
5657
OidtargetTypeId,int32targetTypeMod,
5758
intlocation);
59+
staticNode*fixed_coerce_param_hook(ParseState*pstate,Param*param,
60+
OidtargetTypeId,int32targetTypeMod,
61+
intlocation);
5862
staticboolcheck_parameter_resolution_walker(Node*node,ParseState*pstate);
5963

6064

@@ -69,9 +73,10 @@ parse_fixed_parameters(ParseState *pstate,
6973

7074
parstate->paramTypes=paramTypes;
7175
parstate->numParams=numParams;
76+
parstate->unknownParamTypes=NULL;
7277
pstate->p_ref_hook_state= (void*)parstate;
7378
pstate->p_paramref_hook=fixed_paramref_hook;
74-
/* no need to usep_coerce_param_hook*/
79+
pstate->p_coerce_param_hook=fixed_coerce_param_hook;
7580
}
7681

7782
/*
@@ -170,6 +175,83 @@ variable_paramref_hook(ParseState *pstate, ParamRef *pref)
170175
return (Node*)param;
171176
}
172177

178+
/*
179+
* Coerce a Param to a query-requested datatype, in the fixed params case.
180+
*
181+
* 'unknown' type params are coerced to the type requested, analogous to the
182+
* coercion of unknown constants performed in coerce_type(). We can't change
183+
* the param types like we do in the varparams case, so the coercion is done
184+
* at runtime using CoerceViaIO nodes.
185+
*/
186+
staticNode*
187+
fixed_coerce_param_hook(ParseState*pstate,Param*param,
188+
OidtargetTypeId,int32targetTypeMode,
189+
intlocation)
190+
{
191+
if (param->paramkind==PARAM_EXTERN&&param->paramtype==UNKNOWNOID)
192+
{
193+
FixedParamState*parstate= (FixedParamState*)pstate->p_ref_hook_state;
194+
Oid*unknownParamTypes=parstate->unknownParamTypes;
195+
intparamno=param->paramid;
196+
CoerceViaIO*iocoerce;
197+
198+
if (paramno <=0||/* shouldn't happen, but... */
199+
paramno>parstate->numParams)
200+
ereport(ERROR,
201+
(errcode(ERRCODE_UNDEFINED_PARAMETER),
202+
errmsg("there is no parameter $%d",paramno),
203+
parser_errposition(pstate,param->location)));
204+
205+
/* Allocate the array on first use */
206+
if (unknownParamTypes==NULL)
207+
{
208+
unknownParamTypes=palloc0(parstate->numParams*sizeof(Oid));
209+
parstate->unknownParamTypes=unknownParamTypes;
210+
}
211+
212+
/*
213+
* If the same parameter is used multiple times in the query, make
214+
* sure it's always resolved to the same type. The code would cope
215+
* with differing interpretations, but it might lead to surprising
216+
* results. The varparams code forbids that anyway, so better be
217+
* consistent.
218+
*/
219+
if (unknownParamTypes[paramno-1]==InvalidOid)
220+
{
221+
/* We've successfully resolved the type */
222+
unknownParamTypes[paramno-1]=targetTypeId;
223+
}
224+
elseif (unknownParamTypes[paramno-1]==targetTypeId)
225+
{
226+
/* We previously resolved the type, and it matches */
227+
}
228+
else
229+
{
230+
/* Ooops */
231+
ereport(ERROR,
232+
(errcode(ERRCODE_AMBIGUOUS_PARAMETER),
233+
errmsg("inconsistent types deduced for parameter $%d",
234+
paramno),
235+
errdetail("%s versus %s",
236+
format_type_be(unknownParamTypes[paramno-1]),
237+
format_type_be(targetTypeId)),
238+
parser_errposition(pstate,param->location)));
239+
}
240+
241+
/* Build a CoerceViaIO node */
242+
iocoerce=makeNode(CoerceViaIO);
243+
iocoerce->arg= (Expr*)param;
244+
iocoerce->resulttype=targetTypeId;
245+
iocoerce->coerceformat=COERCE_IMPLICIT_CAST;
246+
iocoerce->location=location;
247+
248+
return (Node*)iocoerce;
249+
}
250+
251+
/* Else signal to proceed with normal coercion */
252+
returnNULL;
253+
}
254+
173255
/*
174256
* Coerce a Param to a query-requested datatype, in the varparams case.
175257
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp