10000 Make hashjoin give the right answer with toasted input data. · danielcode/postgres@70e0191 · GitHub
[go: up one dir, main page]

Skip to content

Commit 70e0191

Browse files
committed
Make hashjoin give the right answer with toasted input data.
1 parent 59e0a85 commit 70e0191

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
*------------------------------------------- 8000 ------------------------------
1313
*/
@@ -507,19 +507,23 @@ ExecHashGetBucket(HashJoinTable hashtable,
507507
int bucketno;
508508
Datum keyval;
509509
bool isNull;
510+
MemoryContext oldContext;
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
return bucketno;
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
static int
604613
hashFunc(Datum key, int len, bool byVal)
605614
{
606615
unsigned int h = 0;
607-
unsigned char *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.
< 8000 /td>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+
unsigned char *k;
645+
646+
if (len < 0)
636647
{
637-
len = VARSIZE(key) - VARHDRSZ;
638-
k = (unsigned char *) VARDATA(key);
648+
struct varlena *vkey = PG_DETOAST_DATUM(key);
649+
650+
len = VARSIZE(vkey) - VARHDRSZ;
651+
k = (unsigned char *) VARDATA(vkey);
639652
}
640653
else
641-
k = (unsigned char *) key;
654+
k = (unsigned char *) DatumGetPointer(key);
655+
642656
while (len-- > 0)
643657
h = (h * PRIME1) ^ (*k++);
644658
}

0 commit comments

Comments
 (0)
0