Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit af87148

Browse files
committed
Fix some more hashjoin-related bugs in pg_operator. Fix
hashjoin's hashFunc() so that it does the right thing with pass-by-value data types (the old code would always return 0 for int2 or char values, which would work but would slow things down a lot). Extend opr_sanity regress test to catch more kinds of errors.
1 parent 1819e89 commit af87148

File tree

4 files changed

+125
-100
lines changed

4 files changed

+125
-100
lines changed

src/backend/executor/nodeHash.c

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Copyright (c) 1994, Regents of the University of California
77
*
88
*
9-
* $Id: nodeHash.c,v 1.31 1999/02/13 23:15:22 momjian Exp $
9+
* $Id: nodeHash.c,v 1.32 1999/04/07 23:33:30 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -41,7 +41,7 @@ extern int NBuffers;
4141
static int HashTBSize;
4242

4343
static void mk_hj_temp(char *tempname);
44-
static int hashFunc(char *key, int len);
44+
static int hashFunc(Datum key, int len, bool byVal);
4545
static int ExecHashPartition(Hash *node);
4646
static RelativeAddr hashTableAlloc(int size, HashJoinTable hashtable);
4747
static void ExecHashOverflowInsert(HashJoinTable hashtable,
@@ -580,10 +580,8 @@ ExecHashGetBucket(HashJoinTable hashtable,
580580
* compute the hash function
581581
* ------------------
582582
*/
583-
if (execConstByVal)
584-
bucketno = hashFunc((char *) &keyval, execConstLen) % hashtable->totalbuckets;
585-
else
586-
bucketno = hashFunc((char *) keyval, execConstLen) % hashtable->totalbuckets;
583+
bucketno = hashFunc(keyval, execConstLen, execConstByVal) % hashtable->totalbuckets;
584+
587585
#ifdef HJDEBUG
588586
if (bucketno >= hashtable->nbuckets)
589587
printf("hash(%d) = %d SAVED\n", keyval, bucketno);
@@ -771,41 +769,45 @@ ExecScanHashBucket(HashJoinState *hjstate,
771769
* ----------------------------------------------------------------
772770
*/
773771
static int
774-
hashFunc(char *key, int len)
772+
hashFunc(Datum key, int len, bool byVal)
775773
{
776-
unsigned int h;
777-
int l;
778-
unsigned char *k;
774+
unsigned int h = 0;
775+
unsigned char *k;
779776

780-
/*
781-
* If this is a variable length type, then 'k' points to a "struct
782-
* varlena" and len == -1. NOTE: VARSIZE returns the "real" data
783-
* length plus the sizeof the "vl_len" attribute of varlena (the
784-
* length information). 'k' points to the beginning of the varlena
785-
* struct, so we have to use "VARDATA" to find the beginning of the
786-
* "real" data.
787-
*/
788-
if (len == -1)
789-
{
790-
l = VARSIZE(key) - VARHDRSZ;
791-
k = (unsigned char *) VARDATA(key);
792-
}
793-
else
794-
{
795-
l = len;
796-
k = (unsigned char *) key;
777+
if (byVal) {
778+
/*
779+
* If it's a by-value data type, use the 'len' least significant bytes
780+
* of the Datum value. This should do the right thing on either
781+
* bigendian or littleendian hardware --- see the Datum access
782+
* macros in c.h.
783+
*/
784+
while (len-- > 0) {
785+
h = (h * PRIME1) ^ (key & 0xFF);
786+
key >>= 8;
787+
}
788+
} else {
789+
/*
790+
* If this is a variable length type, then 'k' points to a "struct
791+
* varlena" and len == -1. NOTE: VARSIZE returns the "real" data
792+
* length plus the sizeof the "vl_len" attribute of varlena (the
793+
* length information). 'k' points to the beginning of the varlena
794+
* struct, so we have to use "VARDATA" to find the beginning of the
795+
* "real" data.
796+
*/
797+
if (len == -1)
798+
{
799+
len = VARSIZE(key) - VARHDRSZ;
800+
k = (unsigned char *) VARDATA(key);
801+
}
802+
else
803+
{
804+
k = (unsigned char *) key;
805+
}
806+
while (len-- > 0)
807+
h = (h * PRIME1) ^ (*k++);
797808
}
798809

799-
h = 0;
800-
801-
/*
802-
* Convert string to integer
803-
*/
804-
while (l--)
805-
h = h * PRIME1 ^ (*k++);
806-
h %= PRIME2;
807-
808-
return h;
810+
return h % PRIME2;
809811
}
810812

811813
/* ----------------------------------------------------------------

0 commit comments

Comments
 (0)