diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-08-24 15:00:47 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-08-24 15:00:47 +0000 |
commit | 976246cc7e4d8b673fc62fe6daa61c76d94af1af (patch) | |
tree | b61ea3f5bbd8fa025587754bc90c3fd43889337c /src/backend/executor/nodeHash.c | |
parent | cf4d885c67744637d82f6fec657e8205578c5905 (diff) | |
download | postgresql-976246cc7e4d8b673fc62fe6daa61c76d94af1af.tar.gz postgresql-976246cc7e4d8b673fc62fe6daa61c76d94af1af.zip |
The cstring datatype can now be copied, passed around, etc. The typlen
value '-2' is used to indicate a variable-width type whose width is
computed as strlen(datum)+1. Everything that looks at typlen is updated
except for array support, which Joe Conway is working on; at the moment
it wouldn't work to try to create an array of cstring.
Diffstat (limited to 'src/backend/executor/nodeHash.c')
-rw-r--r-- | src/backend/executor/nodeHash.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c index b91c70ab10a..92102486c21 100644 --- a/src/backend/executor/nodeHash.c +++ b/src/backend/executor/nodeHash.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * - * $Id: nodeHash.c,v 1.63 2002/06/20 20:29:28 momjian Exp $ + * $Id: nodeHash.c,v 1.64 2002/08/24 15:00:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,7 +32,7 @@ #include "utils/lsyscache.h" -static uint32 hashFunc(Datum key, int len, bool byVal); +static uint32 hashFunc(Datum key, int typLen, bool byVal); /* ---------------------------------------------------------------- * ExecHash @@ -632,7 +632,7 @@ ExecScanHashBucket(HashJoinState *hjstate, * ---------------------------------------------------------------- */ static uint32 -hashFunc(Datum key, int len, bool byVal) +hashFunc(Datum key, int typLen, bool byVal) { unsigned char *k; @@ -647,33 +647,47 @@ hashFunc(Datum key, int len, bool byVal) * would get the wrong bytes on a big-endian machine. */ k = (unsigned char *) &key; - len = sizeof(Datum); + typLen = sizeof(Datum); } else { - /* - * If this is a variable length type, then 'key' points to a - * "struct varlena" and len == -1. NOTE: VARSIZE returns the - * "real" data length plus the sizeof the "vl_len" attribute of - * varlena (the length information). 'key' points to the beginning - * of the varlena struct, so we have to use "VARDATA" to find the - * beginning of the "real" data. Also, we have to be careful to - * detoast the datum if it's toasted. (We don't worry about - * freeing the detoasted copy; that happens for free when the - * per-tuple memory context is reset in ExecHashGetBucket.) - */ - if (len < 0) + if (typLen > 0) + { + /* fixed-width pass-by-reference type */ + k = (unsigned char *) DatumGetPointer(key); + } + else if (typLen == -1) { + /* + * It's a varlena type, so 'key' points to a + * "struct varlena". NOTE: VARSIZE returns the + * "real" data length plus the sizeof the "vl_len" attribute of + * varlena (the length information). 'key' points to the beginning + * of the varlena struct, so we have to use "VARDATA" to find the + * beginning of the "real" data. Also, we have to be careful to + * detoast the datum if it's toasted. (We don't worry about + * freeing the detoasted copy; that happens for free when the + * per-tuple memory context is reset in ExecHashGetBucket.) + */ struct varlena *vkey = PG_DETOAST_DATUM(key); - len = VARSIZE(vkey) - VARHDRSZ; + typLen = VARSIZE(vkey) - VARHDRSZ; k = (unsigned char *) VARDATA(vkey); } - else + else if (typLen == -2) + { + /* It's a null-terminated C string */ + typLen = strlen(DatumGetCString(key)) + 1; k = (unsigned char *) DatumGetPointer(key); + } + else + { + elog(ERROR, "hashFunc: Invalid typLen %d", typLen); + k = NULL; /* keep compiler quiet */ + } } - return DatumGetUInt32(hash_any(k, len)); + return DatumGetUInt32(hash_any(k, typLen)); } /* ---------------------------------------------------------------- |