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

Commitff645bf

Browse files
committed
Revert patch to coerce 'unknown' type parameters in the backend. As Tom
pointed out, it would need a 2nd pass after the whole query is processed tocorrectly check that an unknown Param is coerced to the same target typeeverywhere. Adding the 2nd pass would add a lot more code, which doesn'tseem worth the risk given that there isn't much of a use case for passingunknown Params in the first place. The code would work without that check,but it might be confusing and the behavior would be different from thevarparams case.Instead, just coerce all unknown params in a PL/pgSQL USING clause to text.That's simple, and is usually what users expect.Revert the patch in CVS HEAD and master, and backpatch the new solution to8.4. Unlike the previous solution, this applies easily to 8.4 too.
1 parentbc7cb8f commitff645bf

File tree

2 files changed

+18
-86
lines changed

2 files changed

+18
-86
lines changed

‎src/backend/parser/parse_param.c

Lines changed: 2 additions & 84 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.5 2010/08/18 12:20:15 heikki Exp $
20+
* $PostgreSQL: pgsql/src/backend/parser/parse_param.c,v 2.6 2010/08/19 16:54:43 heikki Exp $
2121
*
2222
*-------------------------------------------------------------------------
2323
*/
@@ -36,7 +36,6 @@ 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 */
4039
}FixedParamState;
4140

4241
/*
@@ -56,9 +55,6 @@ static Node *variable_paramref_hook(ParseState *pstate, ParamRef *pref);
5655
staticNode*variable_coerce_param_hook(ParseState*pstate,Param*param,
5756
OidtargetTypeId,int32targetTypeMod,
5857
intlocation);
59-
staticNode*fixed_coerce_param_hook(ParseState*pstate,Param*param,
60-
OidtargetTypeId,int32targetTypeMod,
61-
intlocation);
6258
staticboolcheck_parameter_resolution_walker(Node*node,ParseState*pstate);
6359

6460

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

7470
parstate->paramTypes=paramTypes;
7571
parstate->numParams=numParams;
76-
parstate->unknownParamTypes=NULL;
7772
pstate->p_ref_hook_state= (void*)parstate;
7873
pstate->p_paramref_hook=fixed_paramref_hook;
79-
pstate->p_coerce_param_hook=fixed_coerce_param_hook;
74+
/* no need to use p_coerce_param_hook */
8075
}
8176

8277
/*
@@ -175,83 +170,6 @@ variable_paramref_hook(ParseState *pstate, ParamRef *pref)
175170
return (Node*)param;
176171
}
177172

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-
255173
/*
256174
* Coerce a Param to a query-requested datatype, in the varparams case.
257175
*/

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.263 2010/08/09 18:50:10 tgl Exp $
11+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.264 2010/08/19 16:54:43 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -5521,8 +5521,22 @@ exec_eval_using_params(PLpgSQL_execstate *estate, List *params)
55215521
ppd->nulls[i]=isnull ?'n' :' ';
55225522
ppd->freevals[i]= false;
55235523

5524+
if (ppd->types[i]==UNKNOWNOID)
5525+
{
5526+
/*
5527+
* Treat 'unknown' parameters as text, that's what most people
5528+
* would expect. The backend can coerce unknown constants in a
5529+
* more intelligent way, but not unknown Params.
5530+
*/
5531+
ppd->types[i]=TEXTOID;
5532+
if (!isnull)
5533+
{
5534+
ppd->values[i]=CStringGetTextDatum((char*)ppd->values[i]);
5535+
ppd->freevals[i]= true;
5536+
}
5537+
}
55245538
/* pass-by-ref non null values must be copied into plpgsql context */
5525-
if (!isnull)
5539+
elseif (!isnull)
55265540
{
55275541
int16typLen;
55285542
booltypByVal;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp