Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter
От | Tom Lane |
---|---|
Тема | Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter |
Дата | |
Msg-id | 4048043.1662653834@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter (Japin Li <japinli@hotmail.com>) |
Ответы |
Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter
|
Список | pgsql-bugs |
Japin Li <japinli@hotmail.com> writes: > On Thu, 08 Sep 2022 at 18:19, PG Bug reporting form <noreply@postgresql.org> wrote: >> The SQL code at the end of this bug report ends with the following error: >> 2022-09-08 10:09:02.173 GMT [174] ERROR: type of parameter 1 >> (composite_type_2) does not match that when preparing the plan >> (composite_type_1) > The documentation says: > The mutable nature of record variables presents another problem in this > connection. When fields of a record variable are used in expressions or > statements, **the data types of the fields must not change from one call > of the function to the next**, since each expression will be analyzed > using the data type that is present when the expression is first reached. I think that is specifically referring to function internal variables of type RECORD, which are handled specially. For function input arguments, we could get around this by treating RECORD like a polymorphic type, as attached. (For some reason I thought we already did that, but nope.) regards, tom lane diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 61fbdf0686..4d68f030e4 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -2498,9 +2498,15 @@ compute_function_hashkey(FunctionCallInfo fcinfo, /* * This is the same as the standard resolve_polymorphic_argtypes() function, - * but with a special case for validation: assume that polymorphic arguments - * are integer, integer-array or integer-range. Also, we go ahead and report - * the error if we can't resolve the types. + * except that: + * 1. We go ahead and report the error if we can't resolve the types. + * 2. We treat RECORD-type input parameters (not output parameters) as if + * they were polymorphic, replacing their types with the actual input + * types if we can determine those. This allows us to create a separate + * function cache entry for each named composite type passed to such a + * parameter. + * 3. In validation mode, we have no inputs to look at, so assume that + * polymorphic arguments are integer, integer-array or integer-range. */ static void plpgsql_resolve_polymorphic_argtypes(int numargs, @@ -2512,6 +2518,8 @@ plpgsql_resolve_polymorphic_argtypes(int numargs, if (!forValidator) { + int inargno; + /* normal case, pass to standard routine */ if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes, call_expr)) @@ -2520,10 +2528,28 @@ plpgsql_resolve_polymorphic_argtypes(int numargs, errmsg("could not determine actual argument " "type for polymorphic function \"%s\"", proname))); + /* also, treat RECORD inputs (but not outputs) as polymorphic */ + inargno = 0; + for (i = 0; i < numargs; i++) + { + char argmode = argmodes ? argmodes[i] : PROARGMODE_IN; + + if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE) + continue; + if (argtypes[i] == RECORDOID || argtypes[i] == RECORDARRAYOID) + { + Oid resolvedtype = get_call_expr_argtype(call_expr, + inargno); + + if (OidIsValid(resolvedtype)) + argtypes[i] = resolvedtype; + } + inargno++; + } } else { - /* special validation case */ + /* special validation case (no need to do anything for RECORD) */ for (i = 0; i < numargs; i++) { switch (argtypes[i])
В списке pgsql-bugs по дате отправления:
Предыдущее
От: Japin LiДата:
Сообщение: Re: BUG #17610: Use of multiple composite types incompatible with record-typed function parameter