-
+
User-Defined Types
and user-defined types
- If the values of your data type might exceed a few hundred bytes in
- size (in internal form), you should make the data type
- To do this, the internal
- representation must follow the standard layout for variable-length
- data: the first four bytes must be an int32 containing
- the total length in bytes of the datum (including itself). The C
- functions operating on the data type must be careful to unpack any
+ If the values of your data type vary in size (in internal form), you should
+ make the data type
TOAST>-able (see
+ linkend="storage-toast">). You should do this even if the data are always
+ too small to be compressed or stored externally because
+
Postgres> can save space on small data using
+
+
+ To do this, the internal representation must follow the standard layout for
+ variable-length data: the first four bytes must be an int32
+ which is never accessed directly (customarily named vl_len_>). You
+ must use SET_VARSIZE() to store the size of the datum
+ in this field and VARSIZE() 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 PG_DETOAST_DATUM>.
(This detail is customarily hidden by defining type-specific
- GETARG macros.) Then,
- when running the CREATE TYPE command, specify the
- internal length as variable> and select the appropriate
- storage option.
+ GETARG_DATATYPE_P macros.) Then, when running the
+ CREATE TYPE command, specify the internal length as
+ variable> and select the appropriate storage option.
+
+
+ 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 PG_DETOAST_DATUM>. You can use
+ PG_DETOAST_DATUM_PACKED> instead (customarily hidden by
+ defining a GETARG_DATATYPE_PP> macro) and using the macros
+ VARSIZE_ANY_EXHDR> and 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 PG_DETOAST_DATUM> interface.
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
* The resulting datum can be accessed using VARSIZE_ANY() and VARDATA_ANY()
* (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
* without evaluating the arguments multiple times, which is NOT acceptable.
*/
#define PG_DETOAST_DATUM_SLICE(datum,f,c) \
pg_detoast_datum_slice((struct varlena *) DatumGetPointer(datum), \
(int32) f, (int32) c)
+/* WARNING -- unaligned pointer */
#define PG_DETOAST_DATUM_PACKED(datum) \
pg_detoast_datum_packed((struct varlena *) DatumGetPointer(datum))
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
* use VARSIZE_ANY/VARSIZE_ANY_EXHDR/VARDATA_ANY. The other macros here
* should usually be used only by tuple assembly/disassembly code and
* 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 VARSIZE(PTR) VARSIZE_4B(PTR)
VARSIZE_4B(PTR)-4))
/* 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) \
(VARATT_IS_1B(PTR) ? VARDATA_1B(PTR) : VARDATA_4B(PTR))