diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execExpr.c | 34 | ||||
-rw-r--r-- | src/backend/executor/execExprInterp.c | 59 |
2 files changed, 45 insertions, 48 deletions
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index 8f28da4bf94..03566c4d181 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -1901,13 +1901,17 @@ ExecInitExprRec(Expr *node, ExprState *state, * actually within a CaseExpr, ArrayCoerceExpr, etc structure. * That can happen because some parts of the system abuse * CaseTestExpr to cause a read of a value externally supplied - * in econtext->caseValue_datum. We'll take care of that - * scenario at runtime. + * in econtext->caseValue_datum. We'll take care of that by + * generating a specialized operation. */ - scratch.opcode = EEOP_CASE_TESTVAL; - scratch.d.casetest.value = state->innermost_caseval; - scratch.d.casetest.isnull = state->innermost_casenull; - + if (state->innermost_caseval == NULL) + scratch.opcode = EEOP_CASE_TESTVAL_EXT; + else + { + scratch.opcode = EEOP_CASE_TESTVAL; + scratch.d.casetest.value = state->innermost_caseval; + scratch.d.casetest.isnull = state->innermost_casenull; + } ExprEvalPushStep(state, &scratch); break; } @@ -2594,14 +2598,18 @@ ExecInitExprRec(Expr *node, ExprState *state, * that innermost_domainval could be NULL, if we're compiling * a standalone domain check rather than one embedded in a * larger expression. In that case we must read from - * econtext->domainValue_datum. We'll take care of that - * scenario at runtime. + * econtext->domainValue_datum. We'll take care of that by + * generating a specialized operation. */ - scratch.opcode = EEOP_DOMAIN_TESTVAL; - /* we share instruction union variant with case testval */ - scratch.d.casetest.value = state->innermost_domainval; - scratch.d.casetest.isnull = state->innermost_domainnull; - + if (state->innermost_domainval == NULL) + scratch.opcode = EEOP_DOMAIN_TESTVAL_EXT; + else + { + scratch.opcode = EEOP_DOMAIN_TESTVAL; + /* we share instruction union variant with case testval */ + scratch.d.casetest.value = state->innermost_domainval; + scratch.d.casetest.isnull = state->innermost_domainnull; + } ExprEvalPushStep(state, &scratch); break; } diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 1127e6f11eb..09f6a5f14c1 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -365,8 +365,7 @@ ExecReadyInterpretedExpr(ExprState *state) return; } else if (step0 == EEOP_CASE_TESTVAL && - step1 == EEOP_FUNCEXPR_STRICT && - state->steps[0].d.casetest.value) + step1 == EEOP_FUNCEXPR_STRICT) { state->evalfunc_private = ExecJustApplyFuncToCase; return; @@ -524,6 +523,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_PARAM_CALLBACK, &&CASE_EEOP_PARAM_SET, &&CASE_EEOP_CASE_TESTVAL, + &&CASE_EEOP_CASE_TESTVAL_EXT, &&CASE_EEOP_MAKE_READONLY, &&CASE_EEOP_IOCOERCE, &&CASE_EEOP_IOCOERCE_SAFE, @@ -548,6 +548,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_SBSREF_ASSIGN, &&CASE_EEOP_SBSREF_FETCH, &&CASE_EEOP_DOMAIN_TESTVAL, + &&CASE_EEOP_DOMAIN_TESTVAL_EXT, &&CASE_EEOP_DOMAIN_NOTNULL, &&CASE_EEOP_DOMAIN_CHECK, &&CASE_EEOP_HASHDATUM_SET_INITVAL, @@ -1273,44 +1274,16 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_CASE(EEOP_CASE_TESTVAL) { - /* - * Normally upper parts of the expression tree have setup the - * values to be returned here, but some parts of the system - * currently misuse {caseValue,domainValue}_{datum,isNull} to set - * run-time data. So if no values have been set-up, use - * ExprContext's. This isn't pretty, but also not *that* ugly, - * and this is unlikely to be performance sensitive enough to - * worry about an extra branch. - */ - if (op->d.casetest.value) - { - *op->resvalue = *op->d.casetest.value; - *op->resnull = *op->d.casetest.isnull; - } - else - { - *op->resvalue = econtext->caseValue_datum; - *op->resnull = econtext->caseValue_isNull; - } + *op->resvalue = *op->d.casetest.value; + *op->resnull = *op->d.casetest.isnull; EEO_NEXT(); } - EEO_CASE(EEOP_DOMAIN_TESTVAL) + EEO_CASE(EEOP_CASE_TESTVAL_EXT) { - /* - * See EEOP_CASE_TESTVAL comment. - */ - if (op->d.casetest.value) - { - *op->resvalue = *op->d.casetest.value; - *op->resnull = *op->d.casetest.isnull; - } - else - { - *op->resvalue = econtext->domainValue_datum; - *op->resnull = econtext->domainValue_isNull; - } + *op->resvalue = econtext->caseValue_datum; + *op->resnull = econtext->caseValue_isNull; EEO_NEXT(); } @@ -1726,6 +1699,22 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_NEXT(); } + EEO_CASE(EEOP_DOMAIN_TESTVAL) + { + *op->resvalue = *op->d.casetest.value; + *op->resnull = *op->d.casetest.isnull; + + EEO_NEXT(); + } + + EEO_CASE(EEOP_DOMAIN_TESTVAL_EXT) + { + *op->resvalue = econtext->domainValue_datum; + *op->resnull = econtext->domainValue_isNull; + + EEO_NEXT(); + } + EEO_CASE(EEOP_DOMAIN_NOTNULL) { /* too complex for an inline implementation */ |