1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

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.
This commit is contained in:
Tom Lane
2002-08-24 15:00:47 +00:00
parent cf4d885c67
commit 976246cc7e
23 changed files with 260 additions and 198 deletions

View File

@ -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));
}
/* ----------------------------------------------------------------