Commit 178214d2 authored by Bruce Momjian's avatar Bruce Momjian

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
parent 39712d11
<!-- $PostgreSQL: pgsql/doc/src/sgml/xtypes.sgml,v 1.28 2006/09/16 00:30:16 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/xtypes.sgml,v 1.29 2007/05/15 17:39:54 momjian Exp $ -->
<sect1 id="xtypes"> <sect1 id="xtypes">
<title>User-Defined Types</title> <title>User-Defined Types</title>
...@@ -237,20 +237,38 @@ CREATE TYPE complex ( ...@@ -237,20 +237,38 @@ CREATE TYPE complex (
<primary>TOAST</primary> <primary>TOAST</primary>
<secondary>and user-defined types</secondary> <secondary>and user-defined types</secondary>
</indexterm> </indexterm>
If the values of your data type might exceed a few hundred bytes in If the values of your data type vary in size (in internal form), you should
size (in internal form), you should make the data type make the data type <acronym>TOAST</>-able (see <xref
<acronym>TOAST</>-able (see <xref linkend="storage-toast">). linkend="storage-toast">). You should do this even if the data are always
To do this, the internal too small to be compressed or stored externally because
representation must follow the standard layout for variable-length <productname>Postgres</> can save space on small data using
data: the first four bytes must be an <type>int32</type> containing <acronym>TOAST</> as well.
the total length in bytes of the datum (including itself). The C </para>
functions operating on the data type must be careful to unpack any
<para>
To do this, the internal representation must follow the standard layout for
variable-length data: the first four bytes must be an <type>int32</type>
which is never accessed directly (customarily named <literal>vl_len_</>). You
must use <function>SET_VARSIZE()</function> to store the size of the datum
in this field and <function>VARSIZE()</function> to retrieve it. The C
functions operating on the data type must always be careful to unpack any
toasted values they are handed, by using <function>PG_DETOAST_DATUM</>. toasted values they are handed, by using <function>PG_DETOAST_DATUM</>.
(This detail is customarily hidden by defining type-specific (This detail is customarily hidden by defining type-specific
<function>GETARG</function> macros.) Then, <function>GETARG_DATATYPE_P</function> macros.) Then, when running the
when running the <command>CREATE TYPE</command> command, specify the <command>CREATE TYPE</command> command, specify the internal length as
internal length as <literal>variable</> and select the appropriate <literal>variable</> and select the appropriate storage option.
storage option. </para>
<para>
If the alignment is unimportant (either just for a specific function or
because the data type specifies byte alignment anyways) then it's possible
to avoid some of the overhead of <function>PG_DETOAST_DATUM</>. You can use
<function>PG_DETOAST_DATUM_PACKED</> instead (customarily hidden by
defining a <function>GETARG_DATATYPE_PP</> macro) and using the macros
<function>VARSIZE_ANY_EXHDR</> and <function>VARDATA_ANY</> macros.
Again, the data returned by these macros is not aligned even if the data
type definition specifies an alignment. If the alignment is important you
must go through the regular <function>PG_DETOAST_DATUM</> interface.
</para> </para>
<para> <para>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/fmgr.h,v 1.50 2007/04/06 04:21:44 tgl Exp $ * $PostgreSQL: pgsql/src/include/fmgr.h,v 1.51 2007/05/15 17:39:54 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -158,6 +158,12 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, ...@@ -158,6 +158,12 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
* The resulting datum can be accessed using VARSIZE_ANY() and VARDATA_ANY() * The resulting datum can be accessed using VARSIZE_ANY() and VARDATA_ANY()
* (beware of multiple evaluations in those macros!) * (beware of multiple evaluations in those macros!)
* *
* WARNING: It is only safe to use PG_DETOAST_DATUM_UNPACKED() and
* VARDATA_ANY() if you really don't care about the alignment. Either because
* you're working with something like text where the alignment doesn't matter
* or because you're not going to access its constituent parts and just use
* things like memcpy on it anyways.
*
* Note: it'd be nice if these could be macros, but I see no way to do that * Note: it'd be nice if these could be macros, but I see no way to do that
* without evaluating the arguments multiple times, which is NOT acceptable. * without evaluating the arguments multiple times, which is NOT acceptable.
*/ */
...@@ -174,6 +180,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum); ...@@ -174,6 +180,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum);
#define PG_DETOAST_DATUM_SLICE(datum,f,c) \ #define PG_DETOAST_DATUM_SLICE(datum,f,c) \
pg_detoast_datum_slice((struct varlena *) DatumGetPointer(datum), \ pg_detoast_datum_slice((struct varlena *) DatumGetPointer(datum), \
(int32) f, (int32) c) (int32) f, (int32) c)
/* WARNING -- unaligned pointer */
#define PG_DETOAST_DATUM_PACKED(datum) \ #define PG_DETOAST_DATUM_PACKED(datum) \
pg_detoast_datum_packed((struct varlena *) DatumGetPointer(datum)) pg_detoast_datum_packed((struct varlena *) DatumGetPointer(datum))
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1995, Regents of the University of California * Portions Copyright (c) 1995, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/postgres.h,v 1.80 2007/05/04 02:01:02 tgl Exp $ * $PostgreSQL: pgsql/src/include/postgres.h,v 1.81 2007/05/15 17:39:54 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -235,6 +235,12 @@ typedef struct ...@@ -235,6 +235,12 @@ typedef struct
* use VARSIZE_ANY/VARSIZE_ANY_EXHDR/VARDATA_ANY. The other macros here * use VARSIZE_ANY/VARSIZE_ANY_EXHDR/VARDATA_ANY. The other macros here
* should usually be used only by tuple assembly/disassembly code and * should usually be used only by tuple assembly/disassembly code and
* code that specifically wants to work with still-toasted Datums. * code that specifically wants to work with still-toasted Datums.
*
* WARNING: It is only safe to use VARDATA_ANY() -- typically with
* PG_DETOAST_DATUM_UNPACKED() -- if you really don't care about the alignment.
* Either because you're working with something like text where the alignment
* doesn't matter or because you're not going to access its constituent parts
* and just use things like memcpy on it anyways.
*/ */
#define VARDATA(PTR) VARDATA_4B(PTR) #define VARDATA(PTR) VARDATA_4B(PTR)
#define VARSIZE(PTR) VARSIZE_4B(PTR) #define VARSIZE(PTR) VARSIZE_4B(PTR)
...@@ -265,6 +271,7 @@ typedef struct ...@@ -265,6 +271,7 @@ typedef struct
VARSIZE_4B(PTR)-4)) VARSIZE_4B(PTR)-4))
/* caution: this will not work on an external or compressed-in-line Datum */ /* caution: this will not work on an external or compressed-in-line Datum */
/* caution: this will return a possibly unaligned pointer */
#define VARDATA_ANY(PTR) \ #define VARDATA_ANY(PTR) \
(VARATT_IS_1B(PTR) ? VARDATA_1B(PTR) : VARDATA_4B(PTR)) (VARATT_IS_1B(PTR) ? VARDATA_1B(PTR) : VARDATA_4B(PTR))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment