mirror of
https://github.com/postgres/postgres.git
synced 2025-07-12 21:01:52 +03:00
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
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
<!-- $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 (
|
|||||||
<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 @@
|
|||||||
* 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,
|
|||||||
* 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);
|
|||||||
#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 @@
|
|||||||
* 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
|
|||||||
* 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
|
|||||||
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))
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user