PostgreSQL Source Code  git master
hashfunc.c File Reference
#include "postgres.h"
#include "access/hash.h"
#include "catalog/pg_collation.h"
#include "common/hashfn.h"
#include "utils/builtins.h"
#include "utils/float.h"
#include "utils/pg_locale.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)
 

Function Documentation

◆ 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 }
signed int int32
Definition: c.h:429
#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:283
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 }
unsigned int uint32
Definition: c.h:441
#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)
152  PG_RETURN_UINT32(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))
171  key8 = get_float8_nan();
172 
173  return hash_any((unsigned char *) &key8, sizeof(key8));
174 }
double float8
Definition: c.h:565
float float4
Definition: c.h:564
static float8 get_float8_nan(void)
Definition: float.h:122
#define PG_RETURN_UINT32(x)
Definition: fmgr.h:355
#define PG_GETARG_FLOAT4(n)
Definition: fmgr.h:281
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31

References get_float8_nan(), hash_any(), sort-test::key, 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))
188  key8 = get_float8_nan();
189 
190  return hash_any_extended((unsigned char *) &key8, sizeof(key8), seed);
191 }
#define PG_RETURN_UINT64(x)
Definition: fmgr.h:369
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.h:37

References get_float8_nan(), hash_any_extended(), sort-test::key, 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)
204  PG_RETURN_UINT32(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))
212  key = get_float8_nan();
213 
214  return hash_any((unsigned char *) &key, sizeof(key));
215 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282

References get_float8_nan(), hash_any(), sort-test::key, 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))
227  key = get_float8_nan();
228 
229  return hash_any_extended((unsigned char *) &key, sizeof(key), seed);
230 }

References get_float8_nan(), hash_any_extended(), sort-test::key, 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 {
62  return hash_uint32((int32) PG_GETARG_INT16(0));
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.

67 {
69 }

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 {
74  return hash_uint32(PG_GETARG_INT32(0));
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.

79 {
81 }

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  */
94  int64 val = PG_GETARG_INT64(0);
95  uint32 lohalf = (uint32) val;
96  uint32 hihalf = (uint32) (val >> 32);
97 
98  lohalf ^= (val >= 0) ? hihalf : ~hihalf;
99 
100  return hash_uint32(lohalf);
101 }
long val
Definition: informix.c:664

References hash_uint32(), PG_GETARG_INT64, and val.

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

◆ hashint8extended()

Datum hashint8extended ( PG_FUNCTION_ARGS  )

Definition at line 104 of file hashfunc.c.

105 {
106  /* Same approach as hashint8 */
107  int64 val = PG_GETARG_INT64(0);
108  uint32 lohalf = (uint32) val;
109  uint32 hihalf = (uint32) (val >> 32);
110 
111  lohalf ^= (val >= 0) ? hihalf : ~hihalf;
112 
113  return hash_uint32_extended(lohalf, PG_GETARG_INT64(1));
114 }

References hash_uint32_extended(), PG_GETARG_INT64, and val.

Referenced by interval_hash_extended(), pg_lsn_hash_extended(), time_hash_extended(), timestamp_hash_extended(), and timetz_hash_extended().

◆ hashname()

Datum hashname ( PG_FUNCTION_ARGS  )

Definition at line 251 of file hashfunc.c.

252 {
253  char *key = NameStr(*PG_GETARG_NAME(0));
254 
255  return hash_any((unsigned char *) key, strlen(key));
256 }
#define NameStr(name)
Definition: c.h:681
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

References hash_any(), sort-test::key, NameStr, and PG_GETARG_NAME.

◆ hashnameextended()

Datum hashnameextended ( PG_FUNCTION_ARGS  )

Definition at line 259 of file hashfunc.c.

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

References hash_any_extended(), sort-test::key, 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 
237  return hash_any((unsigned char *) key->values, key->dim1 * sizeof(Oid));
238 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
unsigned int Oid
Definition: postgres_ext.h:31
Definition: c.h:661

References hash_any(), sort-test::key, and PG_GETARG_POINTER.

Referenced by oidvectorhashfast().

◆ hashoidvectorextended()

Datum hashoidvectorextended ( PG_FUNCTION_ARGS  )

Definition at line 241 of file hashfunc.c.

242 {
244 
245  return hash_any_extended((unsigned char *) key->values,
246  key->dim1 * sizeof(Oid),
247  PG_GETARG_INT64(1));
248 }

References hash_any_extended(), sort-test::key, PG_GETARG_INT64, and PG_GETARG_POINTER.

◆ hashtext()

Datum hashtext ( PG_FUNCTION_ARGS  )

Definition at line 268 of file hashfunc.c.

269 {
270  text *key = PG_GETARG_TEXT_PP(0);
271  Oid collid = PG_GET_COLLATION();
272  pg_locale_t mylocale = 0;
273  Datum result;
274 
275  if (!collid)
276  ereport(ERROR,
277  (errcode(ERRCODE_INDETERMINATE_COLLATION),
278  errmsg("could not determine which collation to use for string hashing"),
279  errhint("Use the COLLATE clause to set the collation explicitly.")));
280 
281  if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID)
282  mylocale = pg_newlocale_from_collation(collid);
283 
284  if (!mylocale || mylocale->deterministic)
285  {
286  result = hash_any((unsigned char *) VARDATA_ANY(key),
288  }
289  else
290  {
291 #ifdef USE_ICU
292  if (mylocale->provider == COLLPROVIDER_ICU)
293  {
294  int32_t ulen = -1;
295  UChar *uchar = NULL;
296  Size bsize;
297  uint8_t *buf;
298 
299  ulen = icu_to_uchar(&uchar, VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
300 
301  bsize = ucol_getSortKey(mylocale->info.icu.ucol,
302  uchar, ulen, NULL, 0);
303  buf = palloc(bsize);
304  ucol_getSortKey(mylocale->info.icu.ucol,
305  uchar, ulen, buf, bsize);
306 
307  result = hash_any(buf, bsize);
308 
309  pfree(buf);
310  }
311  else
312 #endif
313  /* shouldn't happen */
314  elog(ERROR, "unsupported collprovider: %c", mylocale->provider);
315  }
316 
317  /* Avoid leaking memory for toasted inputs */
318  PG_FREE_IF_COPY(key, 0);
319 
320  return result;
321 }
size_t Size
Definition: c.h:540
int errhint(const char *fmt,...)
Definition: elog.c:1156
int errcode(int sqlerrcode)
Definition: elog.c:698
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
#define ereport(elevel,...)
Definition: elog.h:143
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GET_COLLATION()
Definition: fmgr.h:198
void pfree(void *pointer)
Definition: mcxt.c:1169
void * palloc(Size size)
Definition: mcxt.c:1062
bool lc_collate_is_c(Oid collation)
Definition: pg_locale.c:1321
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1468
static char * buf
Definition: pg_test_fsync.c:69
uintptr_t Datum
Definition: postgres.h:411
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
bool deterministic
Definition: pg_locale.h:85
union pg_locale_struct::@141 info
Definition: c.h:622

References buf, pg_locale_struct::deterministic, elog, ereport, errcode(), errhint(), errmsg(), ERROR, hash_any(), pg_locale_struct::info, sort-test::key, lc_collate_is_c(), palloc(), pfree(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, pg_newlocale_from_collation(), pg_locale_struct::provider, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by texthashfast().

◆ hashtextextended()

Datum hashtextextended ( PG_FUNCTION_ARGS  )

Definition at line 324 of file hashfunc.c.

325 {
326  text *key = PG_GETARG_TEXT_PP(0);
327  Oid collid = PG_GET_COLLATION();
328  pg_locale_t mylocale = 0;
329  Datum result;
330 
331  if (!collid)
332  ereport(ERROR,
333  (errcode(ERRCODE_INDETERMINATE_COLLATION),
334  errmsg("could not determine which collation to use for string hashing"),
335  errhint("Use the COLLATE clause to set the collation explicitly.")));
336 
337  if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID)
338  mylocale = pg_newlocale_from_collation(collid);
339 
340  if (!mylocale || mylocale->deterministic)
341  {
342  result = hash_any_extended((unsigned char *) VARDATA_ANY(key),
344  PG_GETARG_INT64(1));
345  }
346  else
347  {
348 #ifdef USE_ICU
349  if (mylocale->provider == COLLPROVIDER_ICU)
350  {
351  int32_t ulen = -1;
352  UChar *uchar = NULL;
353  Size bsize;
354  uint8_t *buf;
355 
356  ulen = icu_to_uchar(&uchar, VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
357 
358  bsize = ucol_getSortKey(mylocale->info.icu.ucol,
359  uchar, ulen, NULL, 0);
360  buf = palloc(bsize);
361  ucol_getSortKey(mylocale->info.icu.ucol,
362  uchar, ulen, buf, bsize);
363 
364  result = hash_any_extended(buf, bsize, PG_GETARG_INT64(1));
365 
366  pfree(buf);
367  }
368  else
369 #endif
370  /* shouldn't happen */
371  elog(ERROR, "unsupported collprovider: %c", mylocale->provider);
372  }
373 
374  PG_FREE_IF_COPY(key, 0);
375 
376  return result;
377 }

References buf, pg_locale_struct::deterministic, elog, ereport, errcode(), errhint(), errmsg(), ERROR, hash_any_extended(), pg_locale_struct::info, sort-test::key, lc_collate_is_c(), palloc(), pfree(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_INT64, PG_GETARG_TEXT_PP, pg_newlocale_from_collation(), pg_locale_struct::provider, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ hashvarlena()

Datum hashvarlena ( PG_FUNCTION_ARGS  )

Definition at line 384 of file hashfunc.c.

385 {
386  struct varlena *key = PG_GETARG_VARLENA_PP(0);
387  Datum result;
388 
389  result = hash_any((unsigned char *) VARDATA_ANY(key),
391 
392  /* Avoid leaking memory for toasted inputs */
393  PG_FREE_IF_COPY(key, 0);
394 
395  return result;
396 }
#define PG_GETARG_VARLENA_PP(n)
Definition: fmgr.h:289

References hash_any(), sort-test::key, PG_FREE_IF_COPY, PG_GETARG_VARLENA_PP, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ hashvarlenaextended()

Datum hashvarlenaextended ( PG_FUNCTION_ARGS  )

Definition at line 399 of file hashfunc.c.

400 {
401  struct varlena *key = PG_GETARG_VARLENA_PP(0);
402  Datum result;
403 
404  result = hash_any_extended((unsigned char *) VARDATA_ANY(key),
406  PG_GETARG_INT64(1));
407 
408  PG_FREE_IF_COPY(key, 0);
409 
410  return result;
411 }

References hash_any_extended(), sort-test::key, PG_FREE_IF_COPY, PG_GETARG_INT64, PG_GETARG_VARLENA_PP, VARDATA_ANY, and VARSIZE_ANY_EXHDR.