aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/nodeAgg.c1
-rw-r--r--src/backend/utils/adt/arrayfuncs.c28
-rw-r--r--src/backend/utils/adt/rowtypes.c7
-rw-r--r--src/include/fmgr.h5
4 files changed, 29 insertions, 12 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 44587a84bae..9f4229de600 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -1172,6 +1172,7 @@ finalize_partialaggregate(AggState *aggstate,
pergroupstate->transValueIsNull,
pertrans->transtypeLen);
fcinfo->args[0].isnull = pergroupstate->transValueIsNull;
+ fcinfo->isnull = false;
*resultVal = FunctionCallInvoke(fcinfo);
*resultIsNull = fcinfo->isnull;
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 11987c8f3ba..800107d4e72 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -3668,7 +3668,7 @@ array_eq(PG_FUNCTION_ARGS)
}
/*
- * Apply the operator to the element pair
+ * Apply the operator to the element pair; treat NULL as false
*/
locfcinfo->args[0].value = elt1;
locfcinfo->args[0].isnull = false;
@@ -3676,7 +3676,7 @@ array_eq(PG_FUNCTION_ARGS)
locfcinfo->args[1].isnull = false;
locfcinfo->isnull = false;
oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo));
- if (!oprresult)
+ if (locfcinfo->isnull || !oprresult)
{
result = false;
break;
@@ -3841,9 +3841,11 @@ array_cmp(FunctionCallInfo fcinfo)
locfcinfo->args[0].isnull = false;
locfcinfo->args[1].value = elt2;
locfcinfo->args[1].isnull = false;
- locfcinfo->isnull = false;
cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo));
+ /* We don't expect comparison support functions to return null */
+ Assert(!locfcinfo->isnull);
+
if (cmpresult == 0)
continue; /* equal */
@@ -3983,8 +3985,9 @@ hash_array(PG_FUNCTION_ARGS)
/* Apply the hash function */
locfcinfo->args[0].value = elt;
locfcinfo->args[0].isnull = false;
- locfcinfo->isnull = false;
elthash = DatumGetUInt32(FunctionCallInvoke(locfcinfo));
+ /* We don't expect hash functions to return null */
+ Assert(!locfcinfo->isnull);
}
/*
@@ -4074,6 +4077,8 @@ hash_array_extended(PG_FUNCTION_ARGS)
locfcinfo->args[1].value = Int64GetDatum(seed);
locfcinfo->args[1].isnull = false;
elthash = DatumGetUInt64(FunctionCallInvoke(locfcinfo));
+ /* We don't expect hash functions to return null */
+ Assert(!locfcinfo->isnull);
}
result = (result << 5) - result + elthash;
@@ -4207,7 +4212,7 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation,
continue; /* can't match */
/*
- * Apply the operator to the element pair
+ * Apply the operator to the element pair; treat NULL as false
*/
locfcinfo->args[0].value = elt1;
locfcinfo->args[0].isnull = false;
@@ -4215,7 +4220,7 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation,
locfcinfo->args[1].isnull = false;
locfcinfo->isnull = false;
oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo));
- if (oprresult)
+ if (!locfcinfo->isnull && oprresult)
break;
}
@@ -6202,7 +6207,7 @@ array_replace_internal(ArrayType *array,
else
{
/*
- * Apply the operator to the element pair
+ * Apply the operator to the element pair; treat NULL as false
*/
locfcinfo->args[0].value = elt;
locfcinfo->args[0].isnull = false;
@@ -6210,7 +6215,7 @@ array_replace_internal(ArrayType *array,
locfcinfo->args[1].isnull = false;
locfcinfo->isnull = false;
oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo));
- if (!oprresult)
+ if (locfcinfo->isnull || !oprresult)
{
/* no match, keep element */
values[nresult] = elt;
@@ -6517,10 +6522,12 @@ width_bucket_array_fixed(Datum operand,
locfcinfo->args[0].isnull = false;
locfcinfo->args[1].value = fetch_att(ptr, typbyval, typlen);
locfcinfo->args[1].isnull = false;
- locfcinfo->isnull = false;
cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo));
+ /* We don't expect comparison support functions to return null */
+ Assert(!locfcinfo->isnull);
+
if (cmpresult < 0)
right = mid;
else
@@ -6577,6 +6584,9 @@ width_bucket_array_variable(Datum operand,
cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo));
+ /* We don't expect comparison support functions to return null */
+ Assert(!locfcinfo->isnull);
+
if (cmpresult < 0)
right = mid;
else
diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c
index 06ad83d7cae..80cba2f4c26 100644
--- a/src/backend/utils/adt/rowtypes.c
+++ b/src/backend/utils/adt/rowtypes.c
@@ -966,9 +966,11 @@ record_cmp(FunctionCallInfo fcinfo)
locfcinfo->args[0].isnull = false;
locfcinfo->args[1].value = values2[i2];
locfcinfo->args[1].isnull = false;
- locfcinfo->isnull = false;
cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo));
+ /* We don't expect comparison support functions to return null */
+ Assert(!locfcinfo->isnull);
+
if (cmpresult < 0)
{
/* arg1 is less than arg2 */
@@ -1200,9 +1202,8 @@ record_eq(PG_FUNCTION_ARGS)
locfcinfo->args[0].isnull = false;
locfcinfo->args[1].value = values2[i2];
locfcinfo->args[1].isnull = false;
- locfcinfo->isnull = false;
oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo));
- if (!oprresult)
+ if (locfcinfo->isnull || !oprresult)
{
result = false;
break;
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index a4249994b92..d349510b7c7 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -163,6 +163,11 @@ extern void fmgr_symbol(Oid functionId, char **mod, char **fn);
* caller must still check fcinfo->isnull! Also, if function is strict,
* it is caller's responsibility to verify that no null arguments are present
* before calling.
+ *
+ * Some code performs multiple calls without redoing InitFunctionCallInfoData,
+ * possibly altering the argument values. This is okay, but be sure to reset
+ * the fcinfo->isnull flag before each call, since callees are permitted to
+ * assume that starts out false.
*/
#define FunctionCallInvoke(fcinfo) ((* (fcinfo)->flinfo->fn_addr) (fcinfo))