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

Commit70e0191

Browse files
committed
Make hashjoin give the right answer with toasted input data.
1 parent59e0a85 commit70e0191

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.56 2001/03/22 06:16:12 momjian Exp $
10+
*$Id: nodeHash.c,v 1.56.2.1 2001/08/13 19:54:00 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -507,19 +507,23 @@ ExecHashGetBucket(HashJoinTable hashtable,
507507
intbucketno;
508508
Datumkeyval;
509509
boolisNull;
510+
MemoryContextoldContext;
510511

511512
/*
512-
* Get the join attribute value of the tuple
513-
*
514-
* We reset the eval context each time to avoid any possibility of memory
515-
* leaks in the hash function.
513+
* We reset the eval context each time to reclaim any memory leaked
514+
* in the hashkey expression or hashFunc itself.
516515
*/
517516
ResetExprContext(econtext);
518517

519-
keyval=ExecEvalExprSwitchContext(hashkey,econtext,&isNull,NULL);
518+
oldContext=MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
520519

521520
/*
522-
* compute the hash function
521+
* Get the join attribute value of the tuple
522+
*/
523+
keyval=ExecEvalExpr(hashkey,econtext,&isNull,NULL);
524+
525+
/*
526+
* Compute the hash function
523527
*/
524528
if (isNull)
525529
bucketno=0;
@@ -538,6 +542,8 @@ ExecHashGetBucket(HashJoinTable hashtable,
538542
printf("hash(%ld) = %d\n", (long)keyval,bucketno);
539543
#endif
540544

545+
MemoryContextSwitchTo(oldContext);
546+
541547
returnbucketno;
542548
}
543549

@@ -598,17 +604,18 @@ ExecScanHashBucket(HashJoinState *hjstate,
598604
*hashFunc
599605
*
600606
*the hash function, copied from Margo
607+
*
608+
*XXX this probably ought to be replaced with datatype-specific
609+
*hash functions, such as those already implemented for hash indexes.
601610
* ----------------------------------------------------------------
602611
*/
603612
staticint
604613
hashFunc(Datumkey,intlen,boolbyVal)
605614
{
606615
unsignedinth=0;
607-
unsignedchar*k;
608616

609617
if (byVal)
610618
{
611-
612619
/*
613620
* If it's a by-value data type, use the 'len' least significant
614621
* bytes of the Datum value. This should do the right thing on
@@ -623,22 +630,29 @@ hashFunc(Datum key, int len, bool byVal)
623630
}
624631
else
625632
{
626-
627633
/*
628-
* If this is a variable length type, then 'k' points to a "struct
629-
* varlena" and len == -1. NOTE: VARSIZE returns the "real" data
634+
* If this is a variable length type, then 'key' points to a "struct
635+
* varlena" and len == -1.NOTE: VARSIZE returns the "real" data
630636
* length plus the sizeof the "vl_len" attribute of varlena (the
631-
* length information). 'k' points to the beginning of the varlena
637+
* length information). 'key' points to the beginning of the varlena
632638
* struct, so we have to use "VARDATA" to find the beginning of
633-
* the "real" data.
639+
* the "real" data. Also, we have to be careful to detoast the
640+
* datum if it's toasted. (We don't worry about freeing the detoasted
641+
* copy; that happens for free when the per-tuple memory context
642+
* is reset in ExecHashGetBucket.)
634643
*/
635-
if (len==-1)
644+
unsignedchar*k;
645+
646+
if (len<0)
636647
{
637-
len=VARSIZE(key)-VARHDRSZ;
638-
k= (unsignedchar*)VARDATA(key);
648+
structvarlena*vkey=PG_DETOAST_DATUM(key);
649+
650+
len=VARSIZE(vkey)-VARHDRSZ;
651+
k= (unsignedchar*)VARDATA(vkey);
639652
}
640653
else
641-
k= (unsignedchar*)key;
654+
k= (unsignedchar*)DatumGetPointer(key);
655+
642656
while (len-->0)
643657
h= (h*PRIME1) ^ (*k++);
644658
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp