aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/execExpr.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 45954d979f6..8f7a5340059 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -4004,8 +4004,9 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
ListCell *lc2;
intptr_t strict_opcode;
intptr_t opcode;
+ int num_exprs = list_length(hash_exprs);
- Assert(list_length(hash_exprs) == list_length(collations));
+ Assert(num_exprs == list_length(collations));
state->parent = parent;
@@ -4013,11 +4014,11 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
ExecCreateExprSetupSteps(state, (Node *) hash_exprs);
/*
- * When hashing more than 1 expression or if we have an init value, we
- * need somewhere to store the intermediate hash value so that it's
- * available to be combined with the result of subsequent hashing.
+ * Make a place to store intermediate hash values between subsequent
+ * hashing of individual expressions. We only need this if there is more
+ * than one expression to hash or an initial value plus one expression.
*/
- if (list_length(hash_exprs) > 1 || init_value != 0)
+ if ((int64) num_exprs + (init_value != 0) > 1)
iresult = palloc(sizeof(NullableDatum));
if (init_value == 0)
@@ -4032,11 +4033,15 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
}
else
{
- /* Set up operation to set the initial value. */
+ /*
+ * Set up operation to set the initial value. Normally we store this
+ * in the intermediate hash value location, but if there are no exprs
+ * to hash, store it in the ExprState's result field.
+ */
scratch.opcode = EEOP_HASHDATUM_SET_INITVAL;
scratch.d.hashdatum_initvalue.init_value = UInt32GetDatum(init_value);
- scratch.resvalue = &iresult->value;
- scratch.resnull = &iresult->isnull;
+ scratch.resvalue = num_exprs > 0 ? &iresult->value : &state->resvalue;
+ scratch.resnull = num_exprs > 0 ? &iresult->isnull : &state->resnull;
ExprEvalPushStep(state, &scratch);
@@ -4074,7 +4079,7 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
&fcinfo->args[0].value,
&fcinfo->args[0].isnull);
- if (i == list_length(hash_exprs) - 1)
+ if (i == num_exprs - 1)
{
/* the result for hashing the final expr is stored in the state */
scratch.resvalue = &state->resvalue;