PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
expandeddatum.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * expandeddatum.h
4  * Declarations for access to "expanded" value representations.
5  *
6  * Complex data types, particularly container types such as arrays and
7  * records, usually have on-disk representations that are compact but not
8  * especially convenient to modify. What's more, when we do modify them,
9  * having to recopy all the rest of the value can be extremely inefficient.
10  * Therefore, we provide a notion of an "expanded" representation that is used
11  * only in memory and is optimized more for computation than storage.
12  * The format appearing on disk is called the data type's "flattened"
13  * representation, since it is required to be a contiguous blob of bytes --
14  * but the type can have an expanded representation that is not. Data types
15  * must provide means to translate an expanded representation back to
16  * flattened form.
17  *
18  * An expanded object is meant to survive across multiple operations, but
19  * not to be enormously long-lived; for example it might be a local variable
20  * in a PL/pgSQL procedure. So its extra bulk compared to the on-disk format
21  * is a worthwhile trade-off.
22  *
23  * References to expanded objects are a type of TOAST pointer.
24  * Because of longstanding conventions in Postgres, this means that the
25  * flattened form of such an object must always be a varlena object.
26  * Fortunately that's no restriction in practice.
27  *
28  * There are actually two kinds of TOAST pointers for expanded objects:
29  * read-only and read-write pointers. Possession of one of the latter
30  * authorizes a function to modify the value in-place rather than copying it
31  * as would normally be required. Functions should always return a read-write
32  * pointer to any new expanded object they create. Functions that modify an
33  * argument value in-place must take care that they do not corrupt the old
34  * value if they fail partway through.
35  *
36  *
37  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
38  * Portions Copyright (c) 1994, Regents of the University of California
39  *
40  * src/include/utils/expandeddatum.h
41  *
42  *-------------------------------------------------------------------------
43  */
44 #ifndef EXPANDEDDATUM_H
45 #define EXPANDEDDATUM_H
46 
47 /* Size of an EXTERNAL datum that contains a pointer to an expanded object */
48 #define EXPANDED_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_expanded))
49 
50 /*
51  * "Methods" that must be provided for any expanded object.
52  *
53  * get_flat_size: compute space needed for flattened representation (total,
54  * including header).
55  *
56  * flatten_into: construct flattened representation in the caller-allocated
57  * space at *result, of size allocated_size (which will always be the result
58  * of a preceding get_flat_size call; it's passed for cross-checking).
59  *
60  * The flattened representation must be a valid in-line, non-compressed,
61  * 4-byte-header varlena object.
62  *
63  * Note: construction of a heap tuple from an expanded datum calls
64  * get_flat_size twice, so it's worthwhile to make sure that that doesn't
65  * incur too much overhead.
66  */
69  void *result, Size allocated_size);
70 
71 /* Struct of function pointers for an expanded object's methods */
72 typedef struct ExpandedObjectMethods
73 {
77 
78 /*
79  * Every expanded object must contain this header; typically the header
80  * is embedded in some larger struct that adds type-specific fields.
81  *
82  * It is presumed that the header object and all subsidiary data are stored
83  * in eoh_context, so that the object can be freed by deleting that context,
84  * or its storage lifespan can be altered by reparenting the context.
85  * (In principle the object could own additional resources, such as malloc'd
86  * storage, and use a memory context reset callback to free them upon reset or
87  * deletion of eoh_context.)
88  *
89  * We set up two TOAST pointers within the standard header, one read-write
90  * and one read-only. This allows functions to return either kind of pointer
91  * without making an additional allocation, and in particular without worrying
92  * whether a separately palloc'd object would have sufficient lifespan.
93  * But note that these pointers are just a convenience; a pointer object
94  * appearing somewhere else would still be legal.
95  *
96  * The typedef declaration for this appears in postgres.h.
97  */
99 {
100  /* Phony varlena header */
101  int32 vl_len_; /* always EOH_HEADER_MAGIC, see below */
102 
103  /* Pointer to methods required for object type */
105 
106  /* Memory context containing this header and subsidiary data */
108 
109  /* Standard R/W TOAST pointer for this object is kept here */
111 
112  /* Standard R/O TOAST pointer for this object is kept here */
114 };
115 
116 /*
117  * Particularly for read-only functions, it is handy to be able to work with
118  * either regular "flat" varlena inputs or expanded inputs of the same data
119  * type. To allow determining which case an argument-fetching function has
120  * returned, the first int32 of an ExpandedObjectHeader always contains -1
121  * (EOH_HEADER_MAGIC to the code). This works since no 4-byte-header varlena
122  * could have that as its first 4 bytes. Caution: we could not reliably tell
123  * the difference between an ExpandedObjectHeader and a short-header object
124  * with this trick. However, it works fine if the argument fetching code
125  * always returns either a 4-byte-header flat object or an expanded object.
126  */
127 #define EOH_HEADER_MAGIC (-1)
128 #define VARATT_IS_EXPANDED_HEADER(PTR) \
129  (((ExpandedObjectHeader *) (PTR))->vl_len_ == EOH_HEADER_MAGIC)
130 
131 /*
132  * Generic support functions for expanded objects.
133  * (More of these might be worth inlining later.)
134  */
135 
136 #define EOHPGetRWDatum(eohptr) PointerGetDatum((eohptr)->eoh_rw_ptr)
137 #define EOHPGetRODatum(eohptr) PointerGetDatum((eohptr)->eoh_ro_ptr)
138 
139 /* Does the Datum represent a writable expanded object? */
140 #define DatumIsReadWriteExpandedObject(d, isnull, typlen) \
141  (((isnull) || (typlen) != -1) ? false : \
142  VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)))
143 
144 #define MakeExpandedObjectReadOnly(d, isnull, typlen) \
145  (((isnull) || (typlen) != -1) ? (d) : \
146  MakeExpandedObjectReadOnlyInternal(d))
147 
149 extern void EOH_init_header(ExpandedObjectHeader *eohptr,
150  const ExpandedObjectMethods *methods,
151  MemoryContext obj_context);
153 extern void EOH_flatten_into(ExpandedObjectHeader *eohptr,
154  void *result, Size allocated_size);
156 extern Datum TransferExpandedObject(Datum d, MemoryContext new_parent);
157 extern void DeleteExpandedObject(Datum d);
158 
159 #endif /* EXPANDEDDATUM_H */
Datum MakeExpandedObjectReadOnlyInternal(Datum d)
Definition: expandeddatum.c:95
EOM_get_flat_size_method get_flat_size
Definition: expandeddatum.h:74
void(* EOM_flatten_into_method)(ExpandedObjectHeader *eohptr, void *result, Size allocated_size)
Definition: expandeddatum.h:68
char eoh_rw_ptr[EXPANDED_POINTER_SIZE]
Size(* EOM_get_flat_size_method)(ExpandedObjectHeader *eohptr)
Definition: expandeddatum.h:67
return result
Definition: formatting.c:1633
Size EOH_get_flat_size(ExpandedObjectHeader *eohptr)
Definition: expandeddatum.c:75
struct ExpandedObjectMethods ExpandedObjectMethods
Datum TransferExpandedObject(Datum d, MemoryContext new_parent)
signed int int32
Definition: c.h:246
void DeleteExpandedObject(Datum d)
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
EOM_flatten_into_method flatten_into
Definition: expandeddatum.h:75
const ExpandedObjectMethods * eoh_methods
void EOH_flatten_into(ExpandedObjectHeader *eohptr, void *result, Size allocated_size)
Definition: expandeddatum.c:81
char eoh_ro_ptr[EXPANDED_POINTER_SIZE]
uintptr_t Datum
Definition: postgres.h:372
#define EXPANDED_POINTER_SIZE
Definition: expandeddatum.h:48
size_t Size
Definition: c.h:350
void EOH_init_header(ExpandedObjectHeader *eohptr, const ExpandedObjectMethods *methods, MemoryContext obj_context)
Definition: expandeddatum.c:48
MemoryContext eoh_context