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