Skip to content

Commit 178214d

Browse files
committed
Update comments for PG_DETOAST_PACKED and VARDATA_ANY on a structures
that require alignment. Add a paragraph to the "User-Defined Types" chapter on using these macros since it seems like they're a hit. Gregory Stark
1 parent 39712d1 commit 178214d

File tree

3 files changed

+47
-15
lines changed

3 files changed

+47
-15
lines changed

doc/src/sgml/xtypes.sgml

+31-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/xtypes.sgml,v 1.28 2006/09/16 00:30:16 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/xtypes.sgml,v 1.29 2007/05/15 17:39:54 momjian Exp $ -->
22

33
<sect1 id="xtypes">
44
<title>User-Defined Types</title>
@@ -237,20 +237,38 @@ CREATE TYPE complex (
237237
<primary>TOAST</primary>
238238
<secondary>and user-defined types</secondary>
239239
</indexterm>
240-
If the values of your data type might exceed a few hundred bytes in
241-
size (in internal form), you should make the data type
242-
<acronym>TOAST</>-able (see <xref linkend="storage-toast">).
243-
To do this, the internal
244-
representation must follow the standard layout for variable-length
245-
data: the first four bytes must be an <type>int32</type> containing
246-
the total length in bytes of the datum (including itself). The C
247-
functions operating on the data type must be careful to unpack any
240+
If the values of your data type vary in size (in internal form), you should
241+
make the data type <acronym>TOAST</>-able (see <xref
242+
linkend="storage-toast">). You should do this even if the data are always
243+
too small to be compressed or stored externally because
244+
<productname>Postgres</> can save space on small data using
245+
<acronym>TOAST</> as well.
246+
</para>
247+
248+
<para>
249+
To do this, the internal representation must follow the standard layout for
250+
variable-length data: the first four bytes must be an <type>int32</type>
251+
which is never accessed directly (customarily named <literal>vl_len_</>). You
252+
must use <function>SET_VARSIZE()</function> to store the size of the datum
253+
in this field and <function>VARSIZE()</function> to retrieve it. The C
254+
functions operating on the data type must always be careful to unpack any
248255
toasted values they are handed, by using <function>PG_DETOAST_DATUM</>.
249256
(This detail is customarily hidden by defining type-specific
250-
<function>GETARG</function> macros.) Then,
251-
when running the <command>CREATE TYPE</command> command, specify the
252-
internal length as <literal>variable</> and select the appropriate
253-
storage option.
257+
<function>GETARG_DATATYPE_P</function> macros.) Then, when running the
258+
<command>CREATE TYPE</command> command, specify the internal length as
259+
<literal>variable</> and select the appropriate storage option.
260+
</para>
261+
262+
<para>
263+
If the alignment is unimportant (either just for a specific function or
264+
because the data type specifies byte alignment anyways) then it's possible
265+
to avoid some of the overhead of <function>PG_DETOAST_DATUM</>. You can use
266+
<function>PG_DETOAST_DATUM_PACKED</> instead (customarily hidden by
267+
defining a <function>GETARG_DATATYPE_PP</> macro) and using the macros
268+
<function>VARSIZE_ANY_EXHDR</> and <function>VARDATA_ANY</> macros.
269+
Again, the data returned by these macros is not aligned even if the data
270+
type definition specifies an alignment. If the alignment is important you
271+
must go through the regular <function>PG_DETOAST_DATUM</> interface.
254272
</para>
255273

256274
<para>

src/include/fmgr.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
14-
* $PostgreSQL: pgsql/src/include/fmgr.h,v 1.50 2007/04/06 04:21:44 tgl Exp $
14+
* $PostgreSQL: pgsql/src/include/fmgr.h,v 1.51 2007/05/15 17:39:54 momjian Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -158,6 +158,12 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
158158
* The resulting datum can be accessed using VARSIZE_ANY() and VARDATA_ANY()
159159
* (beware of multiple evaluations in those macros!)
160160
*
161+
* WARNING: It is only safe to use PG_DETOAST_DATUM_UNPACKED() and
162+
* VARDATA_ANY() if you really don't care about the alignment. Either because
163+
* you're working with something like text where the alignment doesn't matter
164+
* or because you're not going to access its constituent parts and just use
165+
* things like memcpy on it anyways.
166+
*
161167
* Note: it'd be nice if these could be macros, but I see no way to do that
162168
* without evaluating the arguments multiple times, which is NOT acceptable.
163169
*/
@@ -174,6 +180,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum);
174180
#define PG_DETOAST_DATUM_SLICE(datum,f,c) \
175181
pg_detoast_datum_slice((struct varlena *) DatumGetPointer(datum), \
176182
(int32) f, (int32) c)
183+
/* WARNING -- unaligned pointer */
177184
#define PG_DETOAST_DATUM_PACKED(datum) \
178185
pg_detoast_datum_packed((struct varlena *) DatumGetPointer(datum))
179186

src/include/postgres.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
1111
* Portions Copyright (c) 1995, Regents of the University of California
1212
*
13-
* $PostgreSQL: pgsql/src/include/postgres.h,v 1.80 2007/05/04 02:01:02 tgl Exp $
13+
* $PostgreSQL: pgsql/src/include/postgres.h,v 1.81 2007/05/15 17:39:54 momjian Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -235,6 +235,12 @@ typedef struct
235235
* use VARSIZE_ANY/VARSIZE_ANY_EXHDR/VARDATA_ANY. The other macros here
236236
* should usually be used only by tuple assembly/disassembly code and
237237
* code that specifically wants to work with still-toasted Datums.
238+
*
239+
* WARNING: It is only safe to use VARDATA_ANY() -- typically with
240+
* PG_DETOAST_DATUM_UNPACKED() -- if you really don't care about the alignment.
241+
* Either because you're working with something like text where the alignment
242+
* doesn't matter or because you're not going to access its constituent parts
243+
* and just use things like memcpy on it anyways.
238244
*/
239245
#define VARDATA(PTR) VARDATA_4B(PTR)
240246
#define VARSIZE(PTR) VARSIZE_4B(PTR)
@@ -265,6 +271,7 @@ typedef struct
265271
VARSIZE_4B(PTR)-4))
266272

267273
/* caution: this will not work on an external or compressed-in-line Datum */
274+
/* caution: this will return a possibly unaligned pointer */
268275
#define VARDATA_ANY(PTR) \
269276
(VARATT_IS_1B(PTR) ? VARDATA_1B(PTR) : VARDATA_4B(PTR))
270277

0 commit comments

Comments
 (0)