Skip to content

Commit 77903ed

Browse files
committed
Fix over-optimistic caching in fetch_array_arg_replace_nulls().
When I rewrote this in commit 56a79a8, 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.
1 parent e9f1c01 commit 77903ed

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

src/backend/utils/adt/array_userfuncs.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,19 @@ static ArrayType *
2828
fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno)
2929
{
3030
ArrayType *v;
31+
Oid element_type;
3132
ArrayMetaState *my_extra;
3233

33-
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
34-
if (my_extra == NULL)
34+
/* First collect the array value */
35+
if (!PG_ARGISNULL(argno))
36+
{
37+
v = PG_GETARG_ARRAYTYPE_P(argno);
38+
element_type = ARR_ELEMTYPE(v);
39+
}
40+
else
3541
{
36-
/* First time through, so look up the array type and element type */
42+
/* We have to look up the array type and element type */
3743
Oid arr_typeid = get_fn_expr_argtype(fcinfo->flinfo, argno);
38-
Oid element_type;
3944

4045
if (!OidIsValid(arr_typeid))
4146
ereport(ERROR,
@@ -47,26 +52,29 @@ fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno)
4752
(errcode(ERRCODE_DATATYPE_MISMATCH),
4853
errmsg("input data type is not an array")));
4954

55+
v = construct_empty_array(element_type);
56+
}
57+
58+
/* Now cache required info, which might change from call to call */
59+
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
60+
if (my_extra == NULL)
61+
{
5062
my_extra = (ArrayMetaState *)
5163
MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5264
sizeof(ArrayMetaState));
53-
my_extra->element_type = element_type;
65+
my_extra->element_type = InvalidOid;
66+
fcinfo->flinfo->fn_extra = my_extra;
67+
}
5468

55-
/* Cache info about element type */
69+
if (my_extra->element_type != element_type)
70+
{
5671
get_typlenbyvalalign(element_type,
5772
&my_extra->typlen,
5873
&my_extra->typbyval,
5974
&my_extra->typalign);
60-
61-
fcinfo->flinfo->fn_extra = my_extra;
75+
my_extra->element_type = element_type;
6276
}
6377

64-
/* Now we can collect the array value */
65-
if (PG_ARGISNULL(argno))
66-
v = construct_empty_array(my_extra->element_type);
67-
else
68-
v = PG_GETARG_ARRAYTYPE_P(argno);
69-
7078
return v;
7179
}
7280

0 commit comments

Comments
 (0)