Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit87f81a5

Browse files
committed
Fix hypothetical bug in ExprState building for hashing
adf97c1 gave ExprStates the ability to hash expressions and return asingle hash value. That commit supports seeding the hash value with aninitial value to have that blended into the final hash value.Here we fix a hypothetical bug where if there are zero expressions tohash, the initial value is stored in the wrong location. The existingcode stored the initial value in an intermediate location expecting thatwhen the expressions were hashed that those steps would store the finalhash value in the ExprState.resvalue field. However, that wouldn't happenwhen there are zero expressions to hash. The correct thing to do insteadis to have a special case for zero expressions and when we hit that case,store the initial value directly in the ExprState.resvalue. The reasonthat this is a hypothetical bug is that no code currently callsExecBuildHash32Expr passing a non-zero initial value.Discussion:https://postgr.es/m/CAApHDvpMAL_zxbMRr1LOex3O7Y7R7ZN2i8iUFLQhqQiJMAg3qw@mail.gmail.com
1 parent7bdaa4b commit87f81a5

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4004,20 +4004,21 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
40044004
ListCell*lc2;
40054005
intptr_tstrict_opcode;
40064006
intptr_topcode;
4007+
intnum_exprs=list_length(hash_exprs);
40074008

4008-
Assert(list_length(hash_exprs)==list_length(collations));
4009+
Assert(num_exprs==list_length(collations));
40094010

40104011
state->parent=parent;
40114012

40124013
/* Insert setup steps as needed. */
40134014
ExecCreateExprSetupSteps(state, (Node*)hash_exprs);
40144015

40154016
/*
4016-
*When hashing more than 1 expression or if we have an init value, we
4017-
*need somewhere to store the intermediate hash value so that it's
4018-
*availabletobe combined with the result of subsequent hashing.
4017+
*Make a place to store intermediate hash values between subsequent
4018+
*hashing of individual expressions. We only need this if there is more
4019+
*than one expressiontohash or an initial value plus one expression.
40194020
*/
4020-
if (list_length(hash_exprs)>1||init_value!=0)
4021+
if ((int64)num_exprs+ (init_value!=0)>1)
40214022
iresult=palloc(sizeof(NullableDatum));
40224023

40234024
if (init_value==0)
@@ -4032,11 +4033,15 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
40324033
}
40334034
else
40344035
{
4035-
/* Set up operation to set the initial value. */
4036+
/*
4037+
* Set up operation to set the initial value. Normally we store this
4038+
* in the intermediate hash value location, but if there are no exprs
4039+
* to hash, store it in the ExprState's result field.
4040+
*/
40364041
scratch.opcode=EEOP_HASHDATUM_SET_INITVAL;
40374042
scratch.d.hashdatum_initvalue.init_value=UInt32GetDatum(init_value);
4038-
scratch.resvalue=&iresult->value;
4039-
scratch.resnull=&iresult->isnull;
4043+
scratch.resvalue=num_exprs>0 ?&iresult->value :&state->resvalue;
4044+
scratch.resnull=num_exprs>0 ?&iresult->isnull :&state->resnull;
40404045

40414046
ExprEvalPushStep(state,&scratch);
40424047

@@ -4074,7 +4079,7 @@ ExecBuildHash32Expr(TupleDesc desc, const TupleTableSlotOps *ops,
40744079
&fcinfo->args[0].value,
40754080
&fcinfo->args[0].isnull);
40764081

4077-
if (i==list_length(hash_exprs)-1)
4082+
if (i==num_exprs-1)
40784083
{
40794084
/* the result for hashing the final expr is stored in the state */
40804085
scratch.resvalue=&state->resvalue;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp