PostgreSQL Source Code git master
Loading...
Searching...
No Matches
hashfunc.c File Reference
#include "postgres.h"
#include "common/hashfn.h"
#include "utils/builtins.h"
#include "utils/float.h"
#include "utils/fmgrprotos.h"
#include "utils/pg_locale.h"
#include "varatt.h"
Include dependency graph for hashfunc.c:

Go to the source code of this file.

Functions

Datum hashchar (PG_FUNCTION_ARGS)
 
Datum hashcharextended (PG_FUNCTION_ARGS)
 
Datum hashint2 (PG_FUNCTION_ARGS)
 
Datum hashint2extended (PG_FUNCTION_ARGS)
 
Datum hashint4 (PG_FUNCTION_ARGS)
 
Datum hashint4extended (PG_FUNCTION_ARGS)
 
Datum hashint8 (PG_FUNCTION_ARGS)
 
Datum hashint8extended (PG_FUNCTION_ARGS)
 
Datum hashoid (PG_FUNCTION_ARGS)
 
Datum hashoidextended (PG_FUNCTION_ARGS)
 
Datum hashenum (PG_FUNCTION_ARGS)
 
Datum hashenumextended (PG_FUNCTION_ARGS)
 
Datum hashfloat4 (PG_FUNCTION_ARGS)
 
Datum hashfloat4extended (PG_FUNCTION_ARGS)
 
Datum hashfloat8 (PG_FUNCTION_ARGS)
 
Datum hashfloat8extended (PG_FUNCTION_ARGS)
 
Datum hashoidvector (PG_FUNCTION_ARGS)
 
Datum hashoidvectorextended (PG_FUNCTION_ARGS)
 
Datum hashname (PG_FUNCTION_ARGS)
 
Datum hashnameextended (PG_FUNCTION_ARGS)
 
Datum hashtext (PG_FUNCTION_ARGS)
 
Datum hashtextextended (PG_FUNCTION_ARGS)
 
Datum hashvarlena (PG_FUNCTION_ARGS)
 
Datum hashvarlenaextended (PG_FUNCTION_ARGS)
 
Datum hashbytea (PG_FUNCTION_ARGS)
 
Datum hashbyteaextended (PG_FUNCTION_ARGS)
 

Function Documentation

◆ hashbytea()

Datum hashbytea ( PG_FUNCTION_ARGS  )

Definition at line 419 of file hashfunc.c.

420{
421 return hashvarlena(fcinfo);
422}
Datum hashvarlena(PG_FUNCTION_ARGS)
Definition hashfunc.c:389

References hashvarlena().

◆ hashbyteaextended()

Datum hashbyteaextended ( PG_FUNCTION_ARGS  )

Definition at line 425 of file hashfunc.c.

426{
427 return hashvarlenaextended(fcinfo);
428}
Datum hashvarlenaextended(PG_FUNCTION_ARGS)
Definition hashfunc.c:404

References hashvarlenaextended().

◆ hashchar()

Datum hashchar ( PG_FUNCTION_ARGS  )

Definition at line 48 of file hashfunc.c.

49{
50 return hash_uint32((int32) PG_GETARG_CHAR(0));
51}
int32_t int32
Definition c.h:554
#define PG_GETARG_CHAR(n)
Definition fmgr.h:273
static Datum hash_uint32(uint32 k)
Definition hashfn.h:43

References hash_uint32(), and PG_GETARG_CHAR.

◆ hashcharextended()

Datum hashcharextended ( PG_FUNCTION_ARGS  )

Definition at line 54 of file hashfunc.c.

55{
57}
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
static Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition hashfn.h:49

References hash_uint32_extended(), PG_GETARG_CHAR, and PG_GETARG_INT64.

Referenced by JsonbHashScalarValueExtended().

◆ hashenum()

Datum hashenum ( PG_FUNCTION_ARGS  )

Definition at line 129 of file hashfunc.c.

130{
131 return hash_uint32((uint32) PG_GETARG_OID(0));
132}
uint32_t uint32
Definition c.h:558
#define PG_GETARG_OID(n)
Definition fmgr.h:275

References hash_uint32(), and PG_GETARG_OID.

◆ hashenumextended()

Datum hashenumextended ( PG_FUNCTION_ARGS  )

Definition at line 135 of file hashfunc.c.

136{
138}

References hash_uint32_extended(), PG_GETARG_INT64, and PG_GETARG_OID.

◆ hashfloat4()

Datum hashfloat4 ( PG_FUNCTION_ARGS  )

Definition at line 141 of file hashfunc.c.

142{
144 float8 key8;
145
146 /*
147 * On IEEE-float machines, minus zero and zero have different bit patterns
148 * but should compare as equal. We must ensure that they have the same
149 * hash value, which is most reliably done this way:
150 */
151 if (key == (float4) 0)
153
154 /*
155 * To support cross-type hashing of float8 and float4, we want to return
156 * the same hash value hashfloat8 would produce for an equal float8 value.
157 * So, widen the value to float8 and hash that. (We must do this rather
158 * than have hashfloat8 try to narrow its value to float4; that could fail
159 * on overflow.)
160 */
161 key8 = key;
162
163 /*
164 * Similarly, NaNs can have different bit patterns but they should all
165 * compare as equal. For backwards-compatibility reasons we force them to
166 * have the hash value of a standard float8 NaN. (You'd think we could
167 * replace key with a float4 NaN and then widen it; but on some old
168 * platforms, that way produces a different bit pattern.)
169 */
170 if (isnan(key8))
172
173 return hash_any((unsigned char *) &key8, sizeof(key8));
174}
double float8
Definition c.h:656
float float4
Definition c.h:655
static float8 get_float8_nan(void)
Definition float.h:84
#define PG_RETURN_UINT32(x)
Definition fmgr.h:356
#define PG_GETARG_FLOAT4(n)
Definition fmgr.h:282
static Datum hash_any(const unsigned char *k, int keylen)
Definition hashfn.h:31
static int fb(int x)

References fb(), get_float8_nan(), hash_any(), PG_GETARG_FLOAT4, and PG_RETURN_UINT32.

◆ hashfloat4extended()

Datum hashfloat4extended ( PG_FUNCTION_ARGS  )

Definition at line 177 of file hashfunc.c.

178{
180 uint64 seed = PG_GETARG_INT64(1);
181 float8 key8;
182
183 /* Same approach as hashfloat4 */
184 if (key == (float4) 0)
185 PG_RETURN_UINT64(seed);
186 key8 = key;
187 if (isnan(key8))
189
190 return hash_any_extended((unsigned char *) &key8, sizeof(key8), seed);
191}
uint64_t uint64
Definition c.h:559
#define PG_RETURN_UINT64(x)
Definition fmgr.h:371
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition hashfn.h:37

References fb(), get_float8_nan(), hash_any_extended(), PG_GETARG_FLOAT4, PG_GETARG_INT64, and PG_RETURN_UINT64.

◆ hashfloat8()

Datum hashfloat8 ( PG_FUNCTION_ARGS  )

Definition at line 194 of file hashfunc.c.

195{
197
198 /*
199 * On IEEE-float machines, minus zero and zero have different bit patterns
200 * but should compare as equal. We must ensure that they have the same
201 * hash value, which is most reliably done this way:
202 */
203 if (key == (float8) 0)
205
206 /*
207 * Similarly, NaNs can have different bit patterns but they should all
208 * compare as equal. For backwards-compatibility reasons we force them to
209 * have the hash value of a standard NaN.
210 */
211 if (isnan(key))
213
214 return hash_any((unsigned char *) &key, sizeof(key));
215}
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283

References fb(), get_float8_nan(), hash_any(), PG_GETARG_FLOAT8, and PG_RETURN_UINT32.

Referenced by tablesample_init().

◆ hashfloat8extended()

Datum hashfloat8extended ( PG_FUNCTION_ARGS  )

Definition at line 218 of file hashfunc.c.

219{
221 uint64 seed = PG_GETARG_INT64(1);
222
223 /* Same approach as hashfloat8 */
224 if (key == (float8) 0)
225 PG_RETURN_UINT64(seed);
226 if (isnan(key))
228
229 return hash_any_extended((unsigned char *) &key, sizeof(key), seed);
230}

References fb(), get_float8_nan(), hash_any_extended(), PG_GETARG_FLOAT8, PG_GETARG_INT64, and PG_RETURN_UINT64.

◆ hashint2()

Datum hashint2 ( PG_FUNCTION_ARGS  )

Definition at line 60 of file hashfunc.c.

61{
63}
#define PG_GETARG_INT16(n)
Definition fmgr.h:271

References hash_uint32(), and PG_GETARG_INT16.

◆ hashint2extended()

Datum hashint2extended ( PG_FUNCTION_ARGS  )

Definition at line 66 of file hashfunc.c.

References hash_uint32_extended(), PG_GETARG_INT16, and PG_GETARG_INT64.

◆ hashint4()

Datum hashint4 ( PG_FUNCTION_ARGS  )

Definition at line 72 of file hashfunc.c.

73{
75}
#define PG_GETARG_INT32(n)
Definition fmgr.h:269

References hash_uint32(), and PG_GETARG_INT32.

◆ hashint4extended()

Datum hashint4extended ( PG_FUNCTION_ARGS  )

Definition at line 78 of file hashfunc.c.

References hash_uint32_extended(), PG_GETARG_INT32, and PG_GETARG_INT64.

◆ hashint8()

Datum hashint8 ( PG_FUNCTION_ARGS  )

Definition at line 84 of file hashfunc.c.

85{
86 /*
87 * The idea here is to produce a hash value compatible with the values
88 * produced by hashint4 and hashint2 for logically equal inputs; this is
89 * necessary to support cross-type hash joins across these input types.
90 * Since all three types are signed, we can xor the high half of the int8
91 * value if the sign is positive, or the complement of the high half when
92 * the sign is negative.
93 */
96 uint32 hihalf = (uint32) (val >> 32);
97
98 lohalf ^= (val >= 0) ? hihalf : ~hihalf;
99
100 return hash_uint32(lohalf);
101}
int64_t int64
Definition c.h:555
long val
Definition informix.c:689

References fb(), hash_uint32(), PG_GETARG_INT64, and val.

Referenced by hashoid8(), hashxid8(), interval_hash(), pg_lsn_hash(), time_hash(), timestamp_hash(), timestamptz_hash(), and timetz_hash().

◆ hashint8extended()

Datum hashint8extended ( PG_FUNCTION_ARGS  )

◆ hashname()

Datum hashname ( PG_FUNCTION_ARGS  )

Definition at line 253 of file hashfunc.c.

254{
255 char *key = NameStr(*PG_GETARG_NAME(0));
256
257 return hash_any((unsigned char *) key, strlen(key));
258}
#define NameStr(name)
Definition c.h:777
#define PG_GETARG_NAME(n)
Definition fmgr.h:279

References fb(), hash_any(), NameStr, and PG_GETARG_NAME.

◆ hashnameextended()

Datum hashnameextended ( PG_FUNCTION_ARGS  )

Definition at line 261 of file hashfunc.c.

262{
263 char *key = NameStr(*PG_GETARG_NAME(0));
264
265 return hash_any_extended((unsigned char *) key, strlen(key),
266 PG_GETARG_INT64(1));
267}

References fb(), hash_any_extended(), NameStr, PG_GETARG_INT64, and PG_GETARG_NAME.

◆ hashoid()

Datum hashoid ( PG_FUNCTION_ARGS  )

Definition at line 117 of file hashfunc.c.

118{
119 return hash_uint32((uint32) PG_GETARG_OID(0));
120}

References hash_uint32(), and PG_GETARG_OID.

◆ hashoidextended()

Datum hashoidextended ( PG_FUNCTION_ARGS  )

Definition at line 123 of file hashfunc.c.

124{
126}

References hash_uint32_extended(), PG_GETARG_INT64, and PG_GETARG_OID.

◆ hashoidvector()

Datum hashoidvector ( PG_FUNCTION_ARGS  )

Definition at line 233 of file hashfunc.c.

234{
236
238 return hash_any((unsigned char *) key->values, key->dim1 * sizeof(Oid));
239}
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
void check_valid_oidvector(const oidvector *oidArray)
Definition oid.c:118
unsigned int Oid
Definition c.h:757

References check_valid_oidvector(), hash_any(), and PG_GETARG_POINTER.

Referenced by oidvectorhashfast().

◆ hashoidvectorextended()

Datum hashoidvectorextended ( PG_FUNCTION_ARGS  )

Definition at line 242 of file hashfunc.c.

243{
245
247 return hash_any_extended((unsigned char *) key->values,
248 key->dim1 * sizeof(Oid),
249 PG_GETARG_INT64(1));
250}

References check_valid_oidvector(), hash_any_extended(), PG_GETARG_INT64, and PG_GETARG_POINTER.

◆ hashtext()

Datum hashtext ( PG_FUNCTION_ARGS  )

Definition at line 270 of file hashfunc.c.

271{
275 Datum result;
276
277 if (!collid)
280 errmsg("could not determine which collation to use for string hashing"),
281 errhint("Use the COLLATE clause to set the collation explicitly.")));
282
284
285 if (mylocale->deterministic)
286 {
287 result = hash_any((unsigned char *) VARDATA_ANY(key),
288 VARSIZE_ANY_EXHDR(key));
289 }
290 else
291 {
292 Size bsize,
293 rsize;
294 char *buf;
295 const char *keydata = VARDATA_ANY(key);
296 size_t keylen = VARSIZE_ANY_EXHDR(key);
297
298
299 bsize = pg_strnxfrm(NULL, 0, keydata, keylen, mylocale);
300 buf = palloc(bsize + 1);
301
302 rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale);
303
304 /* the second call may return a smaller value than the first */
305 if (rsize > bsize)
306 elog(ERROR, "pg_strnxfrm() returned unexpected result");
307
308 /*
309 * In principle, there's no reason to include the terminating NUL
310 * character in the hash, but it was done before and the behavior must
311 * be preserved.
312 */
313 result = hash_any((uint8_t *) buf, bsize + 1);
314
315 pfree(buf);
316 }
317
318 /* Avoid leaking memory for toasted inputs */
319 PG_FREE_IF_COPY(key, 0);
320
321 return result;
322}
size_t Size
Definition c.h:631
Oid collid
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
int errhint(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define PG_FREE_IF_COPY(ptr, n)
Definition fmgr.h:260
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
#define PG_GET_COLLATION()
Definition fmgr.h:198
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
size_t pg_strnxfrm(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale)
Definition pg_locale.c:1459
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition pg_locale.c:1189
static char buf[DEFAULT_XLOG_SEG_SIZE]
uint64_t Datum
Definition postgres.h:70
Definition c.h:718
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486

References buf, collid, elog, ereport, errcode(), errhint(), errmsg(), ERROR, fb(), hash_any(), palloc(), pfree(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, pg_newlocale_from_collation(), pg_strnxfrm(), VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by texthashfast().

◆ hashtextextended()

Datum hashtextextended ( PG_FUNCTION_ARGS  )

Definition at line 325 of file hashfunc.c.

326{
330 Datum result;
331
332 if (!collid)
335 errmsg("could not determine which collation to use for string hashing"),
336 errhint("Use the COLLATE clause to set the collation explicitly.")));
337
339
340 if (mylocale->deterministic)
341 {
342 result = hash_any_extended((unsigned char *) VARDATA_ANY(key),
344 PG_GETARG_INT64(1));
345 }
346 else
347 {
348 Size bsize,
349 rsize;
350 char *buf;
351 const char *keydata = VARDATA_ANY(key);
352 size_t keylen = VARSIZE_ANY_EXHDR(key);
353
354 bsize = pg_strnxfrm(NULL, 0, keydata, keylen, mylocale);
355 buf = palloc(bsize + 1);
356
357 rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale);
358
359 /* the second call may return a smaller value than the first */
360 if (rsize > bsize)
361 elog(ERROR, "pg_strnxfrm() returned unexpected result");
362
363 /*
364 * In principle, there's no reason to include the terminating NUL
365 * character in the hash, but it was done before and the behavior must
366 * be preserved.
367 */
368 result = hash_any_extended((uint8_t *) buf, bsize + 1,
369 PG_GETARG_INT64(1));
370
371 pfree(buf);
372 }
373
374 PG_FREE_IF_COPY(key, 0);
375
376 return result;
377}

References buf, collid, elog, ereport, errcode(), errhint(), errmsg(), ERROR, fb(), hash_any_extended(), palloc(), pfree(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_INT64, PG_GETARG_TEXT_PP, pg_newlocale_from_collation(), pg_strnxfrm(), VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ hashvarlena()

Datum hashvarlena ( PG_FUNCTION_ARGS  )

Definition at line 389 of file hashfunc.c.

390{
392 Datum result;
393
394 result = hash_any((unsigned char *) VARDATA_ANY(key),
395 VARSIZE_ANY_EXHDR(key));
396
397 /* Avoid leaking memory for toasted inputs */
398 PG_FREE_IF_COPY(key, 0);
399
400 return result;
401}
#define PG_GETARG_VARLENA_PP(n)
Definition fmgr.h:290

References hash_any(), PG_FREE_IF_COPY, PG_GETARG_VARLENA_PP, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by hashbytea().

◆ hashvarlenaextended()

Datum hashvarlenaextended ( PG_FUNCTION_ARGS  )

Definition at line 404 of file hashfunc.c.

405{
407 Datum result;
408
409 result = hash_any_extended((unsigned char *) VARDATA_ANY(key),
411 PG_GETARG_INT64(1));
412
413 PG_FREE_IF_COPY(key, 0);
414
415 return result;
416}

References hash_any_extended(), PG_FREE_IF_COPY, PG_GETARG_INT64, PG_GETARG_VARLENA_PP, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by hashbyteaextended().