PostgreSQL Source Code  git master
datum.c File Reference
#include "postgres.h"
#include "access/detoast.h"
#include "fmgr.h"
#include "utils/datum.h"
#include "utils/expandeddatum.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)
 
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

◆ datum_image_eq()

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

Definition at line 264 of file datum.c.

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(), record_image_eq(), and ri_KeysEqual().

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

◆ datumCopy()

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

Definition at line 130 of file datum.c.

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

Referenced by _copyConst(), accumArrayResult(), advance_transition_function(), advance_windowaggregate(), advance_windowaggregate_base(), array_set_element_expanded(), assign_simple_var(), brin_deform_tuple(), brin_inclusion_add_value(), brin_inclusion_union(), brin_minmax_add_value(), brin_minmax_union(), CatCacheCopyKeys(), collectMatchBitmap(), compute_array_stats(), compute_distinct_stats(), compute_index_stats(), compute_scalar_stats(), copyParamList(), create_list_bounds(), create_range_bounds(), CreateTupleDescCopyConstr(), datumTransfer(), eval_const_expressions_mutator(), eval_windowaggregates(), eval_windowfunction(), evaluate_expr(), exec_eval_using_params(), ExecAggInitGroup(), ExecAggTransReparent(), ExecComputeStoredGenerated(), ExecWindowAgg(), expanded_record_set_field_internal(), expanded_record_set_fields(), finalize_aggregate(), finalize_partialaggregate(), finalize_windowaggregate(), get_actual_variable_endpoint(), get_qual_for_list(), get_variable_range(), getDatumCopy(), initialize_aggregate(), initialize_windowaggregate(), partition_bounds_copy(), pattern_fixed_prefix(), postquel_get_single_result(), RelationBuildTupleDesc(), reorderqueue_push(), spg_range_quad_inner_consistent(), spg_text_inner_consistent(), spgMakeInnerItem(), spgNewHeapItem(), tuplesort_getdatum(), and tuplesort_putdatum().

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

◆ datumEstimateSpace()

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

Definition at line 334 of file datum.c.

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

Referenced by EstimateParamExecSpace(), and EstimateParamListSpace().

335 {
336  Size sz = sizeof(int);
337 
338  if (!isnull)
339  {
340  /* no need to use add_size, can't overflow */
341  if (typByVal)
342  sz += sizeof(Datum);
343  else if (typLen == -1 &&
345  {
346  /* Expanded objects need to be flattened, see comment below */
348  }
349  else
350  sz += datumGetSize(value, typByVal, typLen);
351  }
352 
353  return sz;
354 }
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:322
static struct @145 value
Size EOH_get_flat_size(ExpandedObjectHeader *eohptr)
Definition: expandeddatum.c:75
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
uintptr_t Datum
Definition: postgres.h:367
size_t Size
Definition: c.h:467
#define DatumGetPointer(X)
Definition: postgres.h:549
Size datumGetSize(Datum value, bool typByVal, int typLen)
Definition: datum.c:63

◆ datumGetSize()

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

Definition at line 63 of file datum.c.

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

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

64 {
65  Size size;
66 
67  if (typByVal)
68  {
69  /* Pass-by-value types are always fixed-length */
70  Assert(typLen > 0 && typLen <= sizeof(Datum));
71  size = (Size) typLen;
72  }
73  else
74  {
75  if (typLen > 0)
76  {
77  /* Fixed-length pass-by-ref type */
78  size = (Size) typLen;
79  }
80  else if (typLen == -1)
81  {
82  /* It is a varlena datatype */
83  struct varlena *s = (struct varlena *) DatumGetPointer(value);
84 
85  if (!PointerIsValid(s))
86  ereport(ERROR,
87  (errcode(ERRCODE_DATA_EXCEPTION),
88  errmsg("invalid Datum pointer")));
89 
90  size = (Size) VARSIZE_ANY(s);
91  }
92  else if (typLen == -2)
93  {
94  /* It is a cstring datatype */
95  char *s = (char *) DatumGetPointer(value);
96 
97  if (!PointerIsValid(s))
98  ereport(ERROR,
99  (errcode(ERRCODE_DATA_EXCEPTION),
100  errmsg("invalid Datum pointer")));
101 
102  size = (Size) (strlen(s) + 1);
103  }
104  else
105  {
106  elog(ERROR, "invalid typLen: %d", typLen);
107  size = 0; /* keep compiler quiet */
108  }
109  }
110 
111  return size;
112 }
static struct @145 value
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
uintptr_t Datum
Definition: postgres.h:367
#define VARSIZE_ANY(PTR)
Definition: postgres.h:335
#define Assert(condition)
Definition: c.h:739
size_t Size
Definition: c.h:467
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
Definition: c.h:556
#define PointerIsValid(pointer)
Definition: c.h:633

◆ datumIsEqual()

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

Definition at line 221 of file datum.c.

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

Referenced by _equalConst(), coerce_type(), equalTupleDescs(), find_compatible_pertrans(), heap_tuple_attr_equals(), and partition_bounds_equal().

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

◆ datumRestore()

Datum datumRestore ( char **  start_address,
bool isnull 
)

Definition at line 443 of file datum.c.

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

Referenced by RestoreParamExecParams(), and RestoreParamList().

444 {
445  int header;
446  void *d;
447 
448  /* Read header word. */
449  memcpy(&header, *start_address, sizeof(int));
450  *start_address += sizeof(int);
451 
452  /* If this datum is NULL, we can stop here. */
453  if (header == -2)
454  {
455  *isnull = true;
456  return (Datum) 0;
457  }
458 
459  /* OK, datum is not null. */
460  *isnull = false;
461 
462  /* If this datum is pass-by-value, sizeof(Datum) bytes follow. */
463  if (header == -1)
464  {
465  Datum val;
466 
467  memcpy(&val, *start_address, sizeof(Datum));
468  *start_address += sizeof(Datum);
469  return val;
470  }
471 
472  /* Pass-by-reference case; copy indicated number of bytes. */
473  Assert(header > 0);
474  d = palloc(header);
475  memcpy(d, *start_address, header);
476  *start_address += header;
477  return PointerGetDatum(d);
478 }
#define PointerGetDatum(X)
Definition: postgres.h:556
uintptr_t Datum
Definition: postgres.h:367
#define Assert(condition)
Definition: c.h:739
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:209
void * palloc(Size size)
Definition: mcxt.c:949
long val
Definition: informix.c:664

◆ datumSerialize()

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

Definition at line 381 of file datum.c.

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

Referenced by SerializeParamExecParams(), and SerializeParamList().

383 {
384  ExpandedObjectHeader *eoh = NULL;
385  int header;
386 
387  /* Write header word. */
388  if (isnull)
389  header = -2;
390  else if (typByVal)
391  header = -1;
392  else if (typLen == -1 &&
394  {
395  eoh = DatumGetEOHP(value);
396  header = EOH_get_flat_size(eoh);
397  }
398  else
399  header = datumGetSize(value, typByVal, typLen);
400  memcpy(*start_address, &header, sizeof(int));
401  *start_address += sizeof(int);
402 
403  /* If not null, write payload bytes. */
404  if (!isnull)
405  {
406  if (typByVal)
407  {
408  memcpy(*start_address, &value, sizeof(Datum));
409  *start_address += sizeof(Datum);
410  }
411  else if (eoh)
412  {
413  char *tmp;
414 
415  /*
416  * EOH_flatten_into expects the target address to be maxaligned,
417  * so we can't store directly to *start_address.
418  */
419  tmp = (char *) palloc(header);
420  EOH_flatten_into(eoh, (void *) tmp, header);
421  memcpy(*start_address, tmp, header);
422  *start_address += header;
423 
424  /* be tidy. */
425  pfree(tmp);
426  }
427  else
428  {
429  memcpy(*start_address, DatumGetPointer(value), header);
430  *start_address += header;
431  }
432  }
433 }
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:322
static struct @145 value
void pfree(void *pointer)
Definition: mcxt.c:1056
Size EOH_get_flat_size(ExpandedObjectHeader *eohptr)
Definition: expandeddatum.c:75
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
uintptr_t Datum
Definition: postgres.h:367
void EOH_flatten_into(ExpandedObjectHeader *eohptr, void *result, Size allocated_size)
Definition: expandeddatum.c:81
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:209
#define DatumGetPointer(X)
Definition: postgres.h:549
void * palloc(Size size)
Definition: mcxt.c:949
Size datumGetSize(Datum value, bool typByVal, int typLen)
Definition: datum.c:63

◆ datumTransfer()

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

Definition at line 192 of file datum.c.

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

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

193 {
194  if (!typByVal && typLen == -1 &&
197  else
198  value = datumCopy(value, typByVal, typLen);
199  return value;
200 }
static struct @145 value
Datum TransferExpandedObject(Datum d, MemoryContext new_parent)
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:130
#define DatumGetPointer(X)
Definition: postgres.h:549
#define VARATT_IS_EXTERNAL_EXPANDED_RW(PTR)
Definition: postgres.h:320