PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
datum.c File Reference
#include "postgres.h"
#include "access/detoast.h"
#include "common/hashfn.h"
#include "fmgr.h"
#include "utils/datum.h"
#include "utils/expandeddatum.h"
#include "utils/fmgrprotos.h"
Include dependency graph for datum.c:

Go to the source code of this file.

Functions

Size datumGetSize (Datum value, bool typByVal, int typLen)
 
Datum datumCopy (Datum value, bool typByVal, int typLen)
 
Datum datumTransfer (Datum value, bool typByVal, int typLen)
 
bool datumIsEqual (Datum value1, Datum value2, bool typByVal, int typLen)
 
bool datum_image_eq (Datum value1, Datum value2, bool typByVal, int typLen)
 
uint32 datum_image_hash (Datum value, bool typByVal, int typLen)
 
Datum btequalimage (PG_FUNCTION_ARGS)
 
Size datumEstimateSpace (Datum value, bool isnull, bool typByVal, int typLen)
 
void datumSerialize (Datum value, bool isnull, bool typByVal, int typLen, char **start_address)
 
Datum datumRestore (char **start_address, bool *isnull)
 

Function Documentation

◆ btequalimage()

Datum btequalimage ( PG_FUNCTION_ARGS  )

Definition at line 397 of file datum.c.

398 {
399  /* Oid opcintype = PG_GETARG_OID(0); */
400 
401  PG_RETURN_BOOL(true);
402 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

References PG_RETURN_BOOL.

◆ datum_image_eq()

bool datum_image_eq ( Datum  value1,
Datum  value2,
bool  typByVal,
int  typLen 
)

Definition at line 266 of file datum.c.

267 {
268  Size len1,
269  len2;
270  bool result = true;
271 
272  if (typByVal)
273  {
274  result = (value1 == value2);
275  }
276  else if (typLen > 0)
277  {
278  result = (memcmp(DatumGetPointer(value1),
279  DatumGetPointer(value2),
280  typLen) == 0);
281  }
282  else if (typLen == -1)
283  {
284  len1 = toast_raw_datum_size(value1);
285  len2 = toast_raw_datum_size(value2);
286  /* No need to de-toast if lengths don't match. */
287  if (len1 != len2)
288  result = false;
289  else
290  {
291  struct varlena *arg1val;
292  struct varlena *arg2val;
293 
294  arg1val = PG_DETOAST_DATUM_PACKED(value1);
295  arg2val = PG_DETOAST_DATUM_PACKED(value2);
296 
297  result = (memcmp(VARDATA_ANY(arg1val),
298  VARDATA_ANY(arg2val),
299  len1 - VARHDRSZ) == 0);
300 
301  /* Only free memory if it's a copy made here. */
302  if ((Pointer) arg1val != (Pointer) value1)
303  pfree(arg1val);
304  if ((Pointer) arg2val != (Pointer) value2)
305  pfree(arg2val);
306  }
307  }
308  else if (typLen == -2)
309  {
310  char *s1,
311  *s2;
312 
313  /* Compare cstring datums */
314  s1 = DatumGetCString(value1);
315  s2 = DatumGetCString(value2);
316  len1 = strlen(s1) + 1;
317  len2 = strlen(s2) + 1;
318  if (len1 != len2)
319  return false;
320  result = (memcmp(s1, s2, len1) == 0);
321  }
322  else
323  elog(ERROR, "unexpected typLen: %d", typLen);
324 
325  return result;
326 }
char * Pointer
Definition: c.h:498
#define VARHDRSZ
Definition: c.h:697
size_t Size
Definition: c.h:610
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define PG_DETOAST_DATUM_PACKED(datum)
Definition: fmgr.h:248
void pfree(void *pointer)
Definition: mcxt.c:1521
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
char * s1
char * s2
Definition: c.h:692
#define VARDATA_ANY(PTR)
Definition: varatt.h:324

References DatumGetCString(), DatumGetPointer(), elog, ERROR, pfree(), PG_DETOAST_DATUM_PACKED, s1, s2, toast_raw_datum_size(), VARDATA_ANY, and VARHDRSZ.

Referenced by _bt_keep_natts_fast(), MemoizeHash_equal(), record_image_eq(), and ri_KeysEqual().

◆ datum_image_hash()

uint32 datum_image_hash ( Datum  value,
bool  typByVal,
int  typLen 
)

Definition at line 338 of file datum.c.

339 {
340  Size len;
341  uint32 result;
342 
343  if (typByVal)
344  result = hash_bytes((unsigned char *) &value, sizeof(Datum));
345  else if (typLen > 0)
346  result = hash_bytes((unsigned char *) DatumGetPointer(value), typLen);
347  else if (typLen == -1)
348  {
349  struct varlena *val;
350 
352 
354 
355  result = hash_bytes((unsigned char *) VARDATA_ANY(val), len - VARHDRSZ);
356 
357  /* Only free memory if it's a copy made here. */
358  if ((Pointer) val != (Pointer) value)
359  pfree(val);
360  }
361  else if (typLen == -2)
362  {
363  char *s;
364 
365  s = DatumGetCString(value);
366  len = strlen(s) + 1;
367 
368  result = hash_bytes((unsigned char *) s, len);
369  }
370  else
371  {
372  elog(ERROR, "unexpected typLen: %d", typLen);
373  result = 0; /* keep compiler quiet */
374  }
375 
376  return result;
377 }
unsigned int uint32
Definition: c.h:518
uint32 hash_bytes(const unsigned char *k, int keylen)
Definition: hashfn.c:146
static struct @160 value
long val
Definition: informix.c:689
const void size_t len
uintptr_t Datum
Definition: postgres.h:64

References DatumGetCString(), DatumGetPointer(), elog, ERROR, hash_bytes(), len, pfree(), PG_DETOAST_DATUM_PACKED, toast_raw_datum_size(), val, value, VARDATA_ANY, and VARHDRSZ.

Referenced by MemoizeHash_hash().

◆ datumCopy()

Datum datumCopy ( Datum  value,
bool  typByVal,
int  typLen 
)

Definition at line 132 of file datum.c.

133 {
134  Datum res;
135 
136  if (typByVal)
137  res = value;
138  else if (typLen == -1)
139  {
140  /* It is a varlena datatype */
141  struct varlena *vl = (struct varlena *) DatumGetPointer(value);
142 
144  {
145  /* Flatten into the caller's memory context */
147  Size resultsize;
148  char *resultptr;
149 
150  resultsize = EOH_get_flat_size(eoh);
151  resultptr = (char *) palloc(resultsize);
152  EOH_flatten_into(eoh, (void *) resultptr, resultsize);
153  res = PointerGetDatum(resultptr);
154  }
155  else
156  {
157  /* Otherwise, just copy the varlena datum verbatim */
158  Size realSize;
159  char *resultptr;
160 
161  realSize = (Size) VARSIZE_ANY(vl);
162  resultptr = (char *) palloc(realSize);
163  memcpy(resultptr, vl, realSize);
164  res = PointerGetDatum(resultptr);
165  }
166  }
167  else
168  {
169  /* Pass by reference, but not varlena, so not toasted */
170  Size realSize;
171  char *resultptr;
172 
173  realSize = datumGetSize(value, typByVal, typLen);
174 
175  resultptr = (char *) palloc(realSize);
176  memcpy(resultptr, DatumGetPointer(value), realSize);
177  res = PointerGetDatum(resultptr);
178  }
179  return res;
180 }
Size datumGetSize(Datum value, bool typByVal, int typLen)
Definition: datum.c:65
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
void EOH_flatten_into(ExpandedObjectHeader *eohptr, void *result, Size allocated_size)
Definition: expandeddatum.c:81
Size EOH_get_flat_size(ExpandedObjectHeader *eohptr)
Definition: expandeddatum.c:75
void * palloc(Size size)
Definition: mcxt.c:1317
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: varatt.h:298
#define VARSIZE_ANY(PTR)
Definition: varatt.h:311

References DatumGetEOHP(), DatumGetPointer(), datumGetSize(), EOH_flatten_into(), EOH_get_flat_size(), palloc(), PointerGetDatum(), res, value, VARATT_IS_EXTERNAL_EXPANDED, and VARSIZE_ANY.

Referenced by _copyConst(), accumArrayResult(), advance_transition_function(), advance_windowaggregate(), advance_windowaggregate_base(), array_agg_combine(), array_set_element_expanded(), assign_simple_var(), brin_deform_tuple(), brin_inclusion_add_value(), brin_inclusion_union(), brin_minmax_add_value(), brin_minmax_union(), calculate_frame_offsets(), CatCacheCopyKeys(), collectMatchBitmap(), compute_array_stats(), compute_distinct_stats(), compute_expr_stats(), compute_index_stats(), compute_scalar_stats(), CopyIndexAttOptions(), copyParamList(), create_list_bounds(), create_range_bounds(), CreateTupleDescCopyConstr(), datumTransfer(), eval_const_expressions_mutator(), eval_windowaggregates(), eval_windowfunction(), evaluate_expr(), exec_eval_using_params(), ExecAggCopyTransValue(), ExecAggInitGroup(), ExecComputeStoredGenerated(), ExecEvalPreOrderedDistinctSingle(), expanded_record_set_field_internal(), expanded_record_set_fields(), get_actual_variable_endpoint(), get_attoptions(), get_qual_for_list(), get_stats_slot_range(), get_variable_range(), getDatumCopy(), getmissingattr(), initialize_aggregate(), initialize_windowaggregate(), partition_bounds_copy(), pattern_fixed_prefix(), postquel_get_single_result(), process_ordered_aggregate_single(), range_add_value(), RelationBuildTupleDesc(), reorderqueue_push(), spg_range_quad_inner_consistent(), spg_text_inner_consistent(), spgist_name_inner_consistent(), spgMakeInnerItem(), spgNewHeapItem(), tuplesort_getdatum(), tuplesort_putdatum(), and union_tuples().

◆ datumEstimateSpace()

Size datumEstimateSpace ( Datum  value,
bool  isnull,
bool  typByVal,
int  typLen 
)

Definition at line 412 of file datum.c.

413 {
414  Size sz = sizeof(int);
415 
416  if (!isnull)
417  {
418  /* no need to use add_size, can't overflow */
419  if (typByVal)
420  sz += sizeof(Datum);
421  else if (typLen == -1 &&
423  {
424  /* Expanded objects need to be flattened, see comment below */
426  }
427  else
428  sz += datumGetSize(value, typByVal, typLen);
429  }
430 
431  return sz;
432 }

References DatumGetEOHP(), DatumGetPointer(), datumGetSize(), EOH_get_flat_size(), value, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by EstimateParamExecSpace(), and EstimateParamListSpace().

◆ datumGetSize()

Size datumGetSize ( Datum  value,
bool  typByVal,
int  typLen 
)

Definition at line 65 of file datum.c.

66 {
67  Size size;
68 
69  if (typByVal)
70  {
71  /* Pass-by-value types are always fixed-length */
72  Assert(typLen > 0 && typLen <= sizeof(Datum));
73  size = (Size) typLen;
74  }
75  else
76  {
77  if (typLen > 0)
78  {
79  /* Fixed-length pass-by-ref type */
80  size = (Size) typLen;
81  }
82  else if (typLen == -1)
83  {
84  /* It is a varlena datatype */
85  struct varlena *s = (struct varlena *) DatumGetPointer(value);
86 
87  if (!PointerIsValid(s))
88  ereport(ERROR,
89  (errcode(ERRCODE_DATA_EXCEPTION),
90  errmsg("invalid Datum pointer")));
91 
92  size = (Size) VARSIZE_ANY(s);
93  }
94  else if (typLen == -2)
95  {
96  /* It is a cstring datatype */
97  char *s = (char *) DatumGetPointer(value);
98 
99  if (!PointerIsValid(s))
100  ereport(ERROR,
101  (errcode(ERRCODE_DATA_EXCEPTION),
102  errmsg("invalid Datum pointer")));
103 
104  size = (Size) (strlen(s) + 1);
105  }
106  else
107  {
108  elog(ERROR, "invalid typLen: %d", typLen);
109  size = 0; /* keep compiler quiet */
110  }
111  }
112 
113  return size;
114 }
#define Assert(condition)
Definition: c.h:863
#define PointerIsValid(pointer)
Definition: c.h:768
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereport(elevel,...)
Definition: elog.h:149
static pg_noinline void Size size
Definition: slab.c:607

References Assert, DatumGetPointer(), elog, ereport, errcode(), errmsg(), ERROR, PointerIsValid, size, value, and VARSIZE_ANY.

Referenced by datumCopy(), datumEstimateSpace(), datumIsEqual(), datumSerialize(), outDatum(), and writetup_datum().

◆ datumIsEqual()

bool datumIsEqual ( Datum  value1,
Datum  value2,
bool  typByVal,
int  typLen 
)

Definition at line 223 of file datum.c.

224 {
225  bool res;
226 
227  if (typByVal)
228  {
229  /*
230  * just compare the two datums. NOTE: just comparing "len" bytes will
231  * not do the work, because we do not know how these bytes are aligned
232  * inside the "Datum". We assume instead that any given datatype is
233  * consistent about how it fills extraneous bits in the Datum.
234  */
235  res = (value1 == value2);
236  }
237  else
238  {
239  Size size1,
240  size2;
241  char *s1,
242  *s2;
243 
244  /*
245  * Compare the bytes pointed by the pointers stored in the datums.
246  */
247  size1 = datumGetSize(value1, typByVal, typLen);
248  size2 = datumGetSize(value2, typByVal, typLen);
249  if (size1 != size2)
250  return false;
251  s1 = (char *) DatumGetPointer(value1);
252  s2 = (char *) DatumGetPointer(value2);
253  res = (memcmp(s1, s2, size1) == 0);
254  }
255  return res;
256 }

References DatumGetPointer(), datumGetSize(), res, s1, and s2.

Referenced by _equalConst(), coerce_type(), equalTupleDescs(), find_compatible_trans(), heap_attr_equals(), and partition_bounds_equal().

◆ datumRestore()

Datum datumRestore ( char **  start_address,
bool isnull 
)

Definition at line 521 of file datum.c.

522 {
523  int header;
524  void *d;
525 
526  /* Read header word. */
527  memcpy(&header, *start_address, sizeof(int));
528  *start_address += sizeof(int);
529 
530  /* If this datum is NULL, we can stop here. */
531  if (header == -2)
532  {
533  *isnull = true;
534  return (Datum) 0;
535  }
536 
537  /* OK, datum is not null. */
538  *isnull = false;
539 
540  /* If this datum is pass-by-value, sizeof(Datum) bytes follow. */
541  if (header == -1)
542  {
543  Datum val;
544 
545  memcpy(&val, *start_address, sizeof(Datum));
546  *start_address += sizeof(Datum);
547  return val;
548  }
549 
550  /* Pass-by-reference case; copy indicated number of bytes. */
551  Assert(header > 0);
552  d = palloc(header);
553  memcpy(d, *start_address, header);
554  *start_address += header;
555  return PointerGetDatum(d);
556 }

References Assert, palloc(), PointerGetDatum(), and val.

Referenced by RestoreParamExecParams(), and RestoreParamList().

◆ datumSerialize()

void datumSerialize ( Datum  value,
bool  isnull,
bool  typByVal,
int  typLen,
char **  start_address 
)

Definition at line 459 of file datum.c.

461 {
462  ExpandedObjectHeader *eoh = NULL;
463  int header;
464 
465  /* Write header word. */
466  if (isnull)
467  header = -2;
468  else if (typByVal)
469  header = -1;
470  else if (typLen == -1 &&
472  {
473  eoh = DatumGetEOHP(value);
474  header = EOH_get_flat_size(eoh);
475  }
476  else
477  header = datumGetSize(value, typByVal, typLen);
478  memcpy(*start_address, &header, sizeof(int));
479  *start_address += sizeof(int);
480 
481  /* If not null, write payload bytes. */
482  if (!isnull)
483  {
484  if (typByVal)
485  {
486  memcpy(*start_address, &value, sizeof(Datum));
487  *start_address += sizeof(Datum);
488  }
489  else if (eoh)
490  {
491  char *tmp;
492 
493  /*
494  * EOH_flatten_into expects the target address to be maxaligned,
495  * so we can't store directly to *start_address.
496  */
497  tmp = (char *) palloc(header);
498  EOH_flatten_into(eoh, (void *) tmp, header);
499  memcpy(*start_address, tmp, header);
500  *start_address += header;
501 
502  /* be tidy. */
503  pfree(tmp);
504  }
505  else
506  {
507  memcpy(*start_address, DatumGetPointer(value), header);
508  *start_address += header;
509  }
510  }
511 }

References DatumGetEOHP(), DatumGetPointer(), datumGetSize(), EOH_flatten_into(), EOH_get_flat_size(), palloc(), pfree(), value, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by SerializeParamExecParams(), and SerializeParamList().

◆ datumTransfer()

Datum datumTransfer ( Datum  value,
bool  typByVal,
int  typLen 
)

Definition at line 194 of file datum.c.

195 {
196  if (!typByVal && typLen == -1 &&
199  else
200  value = datumCopy(value, typByVal, typLen);
201  return value;
202 }
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
Datum TransferExpandedObject(Datum d, MemoryContext new_parent)
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define VARATT_IS_EXTERNAL_EXPANDED_RW(PTR)
Definition: varatt.h:296

References CurrentMemoryContext, datumCopy(), DatumGetPointer(), TransferExpandedObject(), value, and VARATT_IS_EXTERNAL_EXPANDED_RW.

Referenced by exec_assign_value(), exec_stmt_block(), and SPI_datumTransfer().