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

Commit38cfc95

Browse files
committed
Make hashjoin give the right answer with toasted input data.
1 parent95f8901 commit38cfc95

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

‎src/backend/executor/nodeHash.c

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
*
10-
*$Id: nodeHash.c,v 1.58 2001/06/11 00:17:07 tgl Exp $
10+
*$Id: nodeHash.c,v 1.59 2001/08/13 19:50:11 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -533,19 +533,23 @@ ExecHashGetBucket(HashJoinTable hashtable,
533533
intbucketno;
534534
Datumkeyval;
535535
boolisNull;
536+
MemoryContextoldContext;
536537

537538
/*
538-
* Get the join attribute value of the tuple
539-
*
540-
* We reset the eval context each time to avoid any possibility of memory
541-
* leaks in the hash function.
539+
* We reset the eval context each time to reclaim any memory leaked
540+
* in the hashkey expression or hashFunc itself.
542541
*/
543542
ResetExprContext(econtext);
544543

545-
keyval=ExecEvalExprSwitchContext(hashkey,econtext,&isNull,NULL);
544+
oldContext=MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
546545

547546
/*
548-
* compute the hash function
547+
* Get the join attribute value of the tuple
548+
*/
549+
keyval=ExecEvalExpr(hashkey,econtext,&isNull,NULL);
550+
551+
/*
552+
* Compute the hash function
549553
*/
550554
if (isNull)
551555
bucketno=0;
@@ -564,6 +568,8 @@ ExecHashGetBucket(HashJoinTable hashtable,
564568
printf("hash(%ld) = %d\n", (long)keyval,bucketno);
565569
#endif
566570

571+
MemoryContextSwitchTo(oldContext);
572+
567573
returnbucketno;
568574
}
569575

@@ -624,17 +630,18 @@ ExecScanHashBucket(HashJoinState *hjstate,
624630
*hashFunc
625631
*
626632
*the hash function, copied from Margo
633+
*
634+
*XXX this probably ought to be replaced with datatype-specific
635+
*hash functions, such as those already implemented for hash indexes.
627636
* ----------------------------------------------------------------
628637
*/
629638
staticint
630639
hashFunc(Datumkey,intlen,boolbyVal)
631640
{
632641
unsignedinth=0;
633-
unsignedchar*k;
634642

635643
if (byVal)
636644
{
637-
638645
/*
639646
* If it's a by-value data type, use the 'len' least significant
640647
* bytes of the Datum value. This should do the right thing on
@@ -649,22 +656,29 @@ hashFunc(Datum key, int len, bool byVal)
649656
}
650657
else
651658
{
652-
653659
/*
654-
* If this is a variable length type, then 'k' points to a "struct
655-
* varlena" and len == -1. NOTE: VARSIZE returns the "real" data
660+
* If this is a variable length type, then 'key' points to a "struct
661+
* varlena" and len == -1.NOTE: VARSIZE returns the "real" data
656662
* length plus the sizeof the "vl_len" attribute of varlena (the
657-
* length information). 'k' points to the beginning of the varlena
663+
* length information). 'key' points to the beginning of the varlena
658664
* struct, so we have to use "VARDATA" to find the beginning of
659-
* the "real" data.
665+
* the "real" data. Also, we have to be careful to detoast the
666+
* datum if it's toasted. (We don't worry about freeing the detoasted
667+
* copy; that happens for free when the per-tuple memory context
668+
* is reset in ExecHashGetBucket.)
660669
*/
661-
if (len==-1)
670+
unsignedchar*k;
671+
672+
if (len<0)
662673
{
663-
len=VARSIZE(key)-VARHDRSZ;
664-
k= (unsignedchar*)VARDATA(key);
674+
structvarlena*vkey=PG_DETOAST_DATUM(key);
675+
676+
len=VARSIZE(vkey)-VARHDRSZ;
677+
k= (unsignedchar*)VARDATA(vkey);
665678
}
666679
else
667-
k= (unsignedchar*)key;
680+
k= (unsignedchar*)DatumGetPointer(key);
681+
668682
while (len-->0)
669683
h= (h*PRIME1) ^ (*k++);
670684
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp