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

References PG_RETURN_BOOL.

346 {
347  /* Oid opcintype = PG_GETARG_OID(0); */
348 
349  PG_RETURN_BOOL(true);
350 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:353

◆ datum_image_eq()

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

Definition at line 265 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().

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

◆ datumCopy()

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

Definition at line 131 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(), CopyIndexAttOptions(), 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_attoptions(), 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().

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

◆ datumEstimateSpace()

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

Definition at line 360 of file datum.c.

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

Referenced by EstimateParamExecSpace(), and EstimateParamListSpace().

361 {
362  Size sz = sizeof(int);
363 
364  if (!isnull)
365  {
366  /* no need to use add_size, can't overflow */
367  if (typByVal)
368  sz += sizeof(Datum);
369  else if (typLen == -1 &&
371  {
372  /* Expanded objects need to be flattened, see comment below */
374  }
375  else
376  sz += datumGetSize(value, typByVal, typLen);
377  }
378 
379  return sz;
380 }
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:322
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
static struct @143 value
size_t Size
Definition: c.h:466
#define DatumGetPointer(X)
Definition: postgres.h:549
Size datumGetSize(Datum value, bool typByVal, int typLen)
Definition: datum.c:64

◆ datumGetSize()

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

Definition at line 64 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().

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

◆ datumIsEqual()

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

Definition at line 222 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().

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

◆ datumRestore()

Datum datumRestore ( char **  start_address,
bool isnull 
)

Definition at line 469 of file datum.c.

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

Referenced by RestoreParamExecParams(), and RestoreParamList().

470 {
471  int header;
472  void *d;
473 
474  /* Read header word. */
475  memcpy(&header, *start_address, sizeof(int));
476  *start_address += sizeof(int);
477 
478  /* If this datum is NULL, we can stop here. */
479  if (header == -2)
480  {
481  *isnull = true;
482  return (Datum) 0;
483  }
484 
485  /* OK, datum is not null. */
486  *isnull = false;
487 
488  /* If this datum is pass-by-value, sizeof(Datum) bytes follow. */
489  if (header == -1)
490  {
491  Datum val;
492 
493  memcpy(&val, *start_address, sizeof(Datum));
494  *start_address += sizeof(Datum);
495  return val;
496  }
497 
498  /* Pass-by-reference case; copy indicated number of bytes. */
499  Assert(header > 0);
500  d = palloc(header);
501  memcpy(d, *start_address, header);
502  *start_address += header;
503  return PointerGetDatum(d);
504 }
#define PointerGetDatum(X)
Definition: postgres.h:556
uintptr_t Datum
Definition: postgres.h:367
#define Assert(condition)
Definition: c.h:738
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:208
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 407 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().

409 {
410  ExpandedObjectHeader *eoh = NULL;
411  int header;
412 
413  /* Write header word. */
414  if (isnull)
415  header = -2;
416  else if (typByVal)
417  header = -1;
418  else if (typLen == -1 &&
420  {
421  eoh = DatumGetEOHP(value);
422  header = EOH_get_flat_size(eoh);
423  }
424  else
425  header = datumGetSize(value, typByVal, typLen);
426  memcpy(*start_address, &header, sizeof(int));
427  *start_address += sizeof(int);
428 
429  /* If not null, write payload bytes. */
430  if (!isnull)
431  {
432  if (typByVal)
433  {
434  memcpy(*start_address, &value, sizeof(Datum));
435  *start_address += sizeof(Datum);
436  }
437  else if (eoh)
438  {
439  char *tmp;
440 
441  /*
442  * EOH_flatten_into expects the target address to be maxaligned,
443  * so we can't store directly to *start_address.
444  */
445  tmp = (char *) palloc(header);
446  EOH_flatten_into(eoh, (void *) tmp, header);
447  memcpy(*start_address, tmp, header);
448  *start_address += header;
449 
450  /* be tidy. */
451  pfree(tmp);
452  }
453  else
454  {
455  memcpy(*start_address, DatumGetPointer(value), header);
456  *start_address += header;
457  }
458  }
459 }
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:322
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 struct @143 value
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:208
#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:64

◆ datumTransfer()

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

Definition at line 193 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().

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