aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execExprInterp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execExprInterp.c')
-rw-r--r--src/backend/executor/execExprInterp.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 491ecad8dc6..8a72b5e70a4 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -366,7 +366,9 @@ ExecReadyInterpretedExpr(ExprState *state)
return;
}
else if (step0 == EEOP_CASE_TESTVAL &&
- step1 == EEOP_FUNCEXPR_STRICT)
+ (step1 == EEOP_FUNCEXPR_STRICT ||
+ step1 == EEOP_FUNCEXPR_STRICT_1 ||
+ step1 == EEOP_FUNCEXPR_STRICT_2))
{
state->evalfunc_private = ExecJustApplyFuncToCase;
return;
@@ -498,6 +500,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
&&CASE_EEOP_CONST,
&&CASE_EEOP_FUNCEXPR,
&&CASE_EEOP_FUNCEXPR_STRICT,
+ &&CASE_EEOP_FUNCEXPR_STRICT_1,
+ &&CASE_EEOP_FUNCEXPR_STRICT_2,
&&CASE_EEOP_FUNCEXPR_FUSAGE,
&&CASE_EEOP_FUNCEXPR_STRICT_FUSAGE,
&&CASE_EEOP_BOOL_AND_STEP_FIRST,
@@ -575,6 +579,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
&&CASE_EEOP_AGG_STRICT_DESERIALIZE,
&&CASE_EEOP_AGG_DESERIALIZE,
&&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
+ &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1,
&&CASE_EEOP_AGG_STRICT_INPUT_CHECK_NULLS,
&&CASE_EEOP_AGG_PLAIN_PERGROUP_NULLCHECK,
&&CASE_EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL,
@@ -925,6 +930,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_NEXT();
}
+ /* strict function call with more than two arguments */
EEO_CASE(EEOP_FUNCEXPR_STRICT)
{
FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
@@ -932,6 +938,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
int nargs = op->d.func.nargs;
Datum d;
+ Assert(nargs > 2);
+
/* strict function, so check for NULL args */
for (int argno = 0; argno < nargs; argno++)
{
@@ -950,6 +958,54 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_NEXT();
}
+ /* strict function call with one argument */
+ EEO_CASE(EEOP_FUNCEXPR_STRICT_1)
+ {
+ FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+ NullableDatum *args = fcinfo->args;
+
+ Assert(op->d.func.nargs == 1);
+
+ /* strict function, so check for NULL args */
+ if (args[0].isnull)
+ *op->resnull = true;
+ else
+ {
+ Datum d;
+
+ fcinfo->isnull = false;
+ d = op->d.func.fn_addr(fcinfo);
+ *op->resvalue = d;
+ *op->resnull = fcinfo->isnull;
+ }
+
+ EEO_NEXT();
+ }
+
+ /* strict function call with two arguments */
+ EEO_CASE(EEOP_FUNCEXPR_STRICT_2)
+ {
+ FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
+ NullableDatum *args = fcinfo->args;
+
+ Assert(op->d.func.nargs == 2);
+
+ /* strict function, so check for NULL args */
+ if (args[0].isnull || args[1].isnull)
+ *op->resnull = true;
+ else
+ {
+ Datum d;
+
+ fcinfo->isnull = false;
+ d = op->d.func.fn_addr(fcinfo);
+ *op->resvalue = d;
+ *op->resnull = fcinfo->isnull;
+ }
+
+ EEO_NEXT();
+ }
+
EEO_CASE(EEOP_FUNCEXPR_FUSAGE)
{
/* not common enough to inline */
@@ -1982,11 +2038,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
* input is not NULL.
*/
+ /* when checking more than one argument */
EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_ARGS)
{
NullableDatum *args = op->d.agg_strict_input_check.args;
int nargs = op->d.agg_strict_input_check.nargs;
+ Assert(nargs > 1);
+
for (int argno = 0; argno < nargs; argno++)
{
if (args[argno].isnull)
@@ -1995,6 +2054,19 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_NEXT();
}
+ /* special case for just one argument */
+ EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1)
+ {
+ NullableDatum *args = op->d.agg_strict_input_check.args;
+ PG_USED_FOR_ASSERTS_ONLY int nargs = op->d.agg_strict_input_check.nargs;
+
+ Assert(nargs == 1);
+
+ if (args[0].isnull)
+ EEO_JUMP(op->d.agg_strict_input_check.jumpnull);
+ EEO_NEXT();
+ }
+
EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
{
bool *nulls = op->d.agg_strict_input_check.nulls;