diff --git a/src/backend/parser/parse_param.c b/src/backend/parser/parse_param.c index 20abf00..f4381fc 100644 --- a/src/backend/parser/parse_param.c +++ b/src/backend/parser/parse_param.c @@ -55,6 +55,9 @@ static Node *variable_paramref_hook(ParseState *pstate, ParamRef *pref); static Node *variable_coerce_param_hook(ParseState *pstate, Param *param, Oid targetTypeId, int32 targetTypeMod, int location); +static Node *fixed_coerce_param_hook(ParseState *pstate, Param *param, + Oid targetTypeId, int32 targetTypeMod, + int location); static bool check_parameter_resolution_walker(Node *node, ParseState *pstate); @@ -71,7 +74,7 @@ parse_fixed_parameters(ParseState *pstate, parstate->numParams = numParams; pstate->p_ref_hook_state = (void *) parstate; pstate->p_paramref_hook = fixed_paramref_hook; - /* no need to use p_coerce_param_hook */ + pstate->p_coerce_param_hook = fixed_coerce_param_hook; } /* @@ -170,6 +173,43 @@ variable_paramref_hook(ParseState *pstate, ParamRef *pref) return (Node *) param; } +static Node * +fixed_coerce_param_hook(ParseState *pstate, Param *param, + Oid targetTypeId, int32 targetTypeMode, + int location) +{ + if (param->paramkind == PARAM_EXTERN && param->paramtype == UNKNOWNOID) + { + /* + * Input is a Param of previously undetermined type, and we want to + * update our knowledge of the Param's type. + */ + FixedParamState *parstate = (FixedParamState *) pstate->p_ref_hook_state; + int paramno = param->paramid; + CoerceViaIO *iocoerce; + + if (paramno <= 0 || /* shouldn't happen, but... */ + paramno > parstate->numParams) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_PARAMETER), + errmsg("there is no parameter $%d", paramno), + parser_errposition(pstate, param->location))); + + /* Build a CoerceViaIO node */ + iocoerce = makeNode(CoerceViaIO); + iocoerce->arg = (Expr *) param; + iocoerce->resulttype = targetTypeId; + iocoerce->coerceformat = COERCE_IMPLICIT_CAST; + iocoerce->location = location; + + return (Node *) iocoerce; + } + + /* Else signal to proceed with normal coercion */ + return NULL; +} + + /* * Coerce a Param to a query-requested datatype, in the varparams case. */