mirror of
https://github.com/postgres/postgres.git
synced 2025-11-22 12:22:45 +03:00
Simplify executor's handling of CaseTestExpr & CoerceToDomainValue.
Instead of deciding at runtime whether to read from casetest.value or caseValue_datum, split EEOP_CASE_TESTVAL into two opcodes and make the decision during expression compilation. Similarly for EEOP_DOMAIN_TESTVAL. This actually results in net less code, mainly because llvmjit_expr.c's code for handling these opcodes gets shorter. The performance gain is doubtless negligible, but this seems worth changing anyway on grounds of simplicity and understandability. Author: Andreas Karlsson <andreas@proxel.se> Co-authored-by: Xing Guo <higuoxing@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CACpMh+AiBYAWn+D1aU7Rsy-V1tox06Cbc0H3qA7rwL5zdJ=anQ@mail.gmail.com
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user