Commit 77903ede authored by Tom Lane's avatar Tom Lane

Fix over-optimistic caching in fetch_array_arg_replace_nulls().

When I rewrote this in commit 56a79a86,
I forgot that it's possible for the input array type to change from one
call to the next (this can happen when applying the function to
pg_statistic columns, for instance).  Fix that.
parent e9f1c01b
...@@ -28,14 +28,19 @@ static ArrayType * ...@@ -28,14 +28,19 @@ static ArrayType *
fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno) fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno)
{ {
ArrayType *v; ArrayType *v;
Oid element_type;
ArrayMetaState *my_extra; ArrayMetaState *my_extra;
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; /* First collect the array value */
if (my_extra == NULL) if (!PG_ARGISNULL(argno))
{
v = PG_GETARG_ARRAYTYPE_P(argno);
element_type = ARR_ELEMTYPE(v);
}
else
{ {
/* First time through, so look up the array type and element type */ /* We have to look up the array type and element type */
Oid arr_typeid = get_fn_expr_argtype(fcinfo->flinfo, argno); Oid arr_typeid = get_fn_expr_argtype(fcinfo->flinfo, argno);
Oid element_type;
if (!OidIsValid(arr_typeid)) if (!OidIsValid(arr_typeid))
ereport(ERROR, ereport(ERROR,
...@@ -47,26 +52,29 @@ fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno) ...@@ -47,26 +52,29 @@ fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno)
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("input data type is not an array"))); errmsg("input data type is not an array")));
v = construct_empty_array(element_type);
}
/* Now cache required info, which might change from call to call */
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
if (my_extra == NULL)
{
my_extra = (ArrayMetaState *) my_extra = (ArrayMetaState *)
MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
sizeof(ArrayMetaState)); sizeof(ArrayMetaState));
my_extra->element_type = element_type; my_extra->element_type = InvalidOid;
fcinfo->flinfo->fn_extra = my_extra;
}
/* Cache info about element type */ if (my_extra->element_type != element_type)
{
get_typlenbyvalalign(element_type, get_typlenbyvalalign(element_type,
&my_extra->typlen, &my_extra->typlen,
&my_extra->typbyval, &my_extra->typbyval,
&my_extra->typalign); &my_extra->typalign);
my_extra->element_type = element_type;
fcinfo->flinfo->fn_extra = my_extra;
} }
/* Now we can collect the array value */
if (PG_ARGISNULL(argno))
v = construct_empty_array(my_extra->element_type);
else
v = PG_GETARG_ARRAYTYPE_P(argno);
return v; return v;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment