Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * detoast.h
4 : : * Access to compressed and external varlena values.
5 : : *
6 : : * Copyright (c) 2000-2026, PostgreSQL Global Development Group
7 : : *
8 : : * src/include/access/detoast.h
9 : : *
10 : : *-------------------------------------------------------------------------
11 : : */
12 : : #ifndef DETOAST_H
13 : : #define DETOAST_H
14 : :
15 : : #include "varatt.h"
16 : :
17 : : /*
18 : : * Macro to fetch the possibly-unaligned contents of an EXTERNAL datum
19 : : * into a local "varatt_external_oid" toast pointer. This should be
20 : : * just a memcpy, but some versions of gcc seem to produce broken code
21 : : * that assumes the datum contents are aligned. Introducing an explicit
22 : : * intermediate "varattrib_1b_e *" variable seems to fix it.
23 : : */
24 : : #define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \
25 : : do { \
26 : : varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \
27 : : Assert(VARATT_IS_EXTERNAL(attre)); \
28 : : Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \
29 : : memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \
30 : : } while (0)
31 : :
32 : : /* Size of an EXTERNAL datum that contains a standard TOAST pointer */
33 : : #define TOAST_OID_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external_oid))
34 : :
35 : : /* Size of an EXTERNAL datum that contains an Oid8 TOAST pointer */
36 : : #define TOAST_OID8_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external_oid8))
37 : :
38 : : /* Size of an EXTERNAL datum that contains an indirection pointer */
39 : : #define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_indirect))
40 : :
41 : : /*
42 : : * Decoded contents of an on-disk external TOAST pointer.
43 : : */
44 : : typedef struct toast_external_data
45 : : {
46 : : vartag_external tag; /* VARTAG_ONDISK_* */
47 : : int32 rawsize; /* original data size (includes header) */
48 : : uint32 extinfo; /* saved size + compression method */
49 : : Oid8 valueid; /* value ID (can be widened from Oid) */
50 : : Oid toastrelid; /* OID of the TOAST table containing it */
51 : : } toast_external_data;
52 : :
53 : : /*
54 : : * Decode an on-disk external TOAST pointer into a toast_external_data.
55 : : */
56 : : static inline void
5 michael@paquier.xyz 57 :GNC 58416 : toast_external_info_get(const struct varlena *attr, toast_external_data *toast_ext_data)
58 : : {
59 [ - + ]: 58416 : Assert(VARATT_IS_EXTERNAL_ONDISK(attr));
60 : :
61 : 58416 : toast_ext_data->tag = VARTAG_EXTERNAL(attr);
62 [ + + ]: 58416 : if (toast_ext_data->tag == VARTAG_ONDISK_OID8)
63 : : {
64 : : varatt_external_oid8 toast_pointer;
65 : :
66 [ - + - + ]: 232 : VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
67 : 232 : toast_ext_data->rawsize = toast_pointer.va_rawsize;
68 : 232 : toast_ext_data->extinfo = toast_pointer.va_extinfo;
69 : 232 : toast_ext_data->valueid = VARATT_EXTERNAL_OID8_GET_VALUEID(toast_pointer);
70 : 232 : toast_ext_data->toastrelid = toast_pointer.va_toastrelid;
71 : : }
72 : : else
73 : : {
74 : : varatt_external_oid toast_pointer;
75 : :
76 [ - + - + ]: 58184 : VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
77 : 58184 : toast_ext_data->rawsize = toast_pointer.va_rawsize;
78 : 58184 : toast_ext_data->extinfo = toast_pointer.va_extinfo;
79 : 58184 : toast_ext_data->valueid = toast_pointer.va_valueid;
80 : 58184 : toast_ext_data->toastrelid = toast_pointer.va_toastrelid;
81 : : }
82 : 58416 : }
83 : :
84 : : /* ----------
85 : : * detoast_external_attr() -
86 : : *
87 : : * Fetches an external stored attribute from the toast
88 : : * relation. Does NOT decompress it, if stored external
89 : : * in compressed format.
90 : : * ----------
91 : : */
92 : : extern varlena *detoast_external_attr(varlena *attr);
93 : :
94 : : /* ----------
95 : : * detoast_attr() -
96 : : *
97 : : * Fully detoasts one attribute, fetching and/or decompressing
98 : : * it as needed.
99 : : * ----------
100 : : */
101 : : extern varlena *detoast_attr(varlena *attr);
102 : :
103 : : /* ----------
104 : : * detoast_attr_slice() -
105 : : *
106 : : * Fetches only the specified portion of an attribute.
107 : : * (Handles all cases for attribute storage)
108 : : * ----------
109 : : */
110 : : extern varlena *detoast_attr_slice(varlena *attr,
111 : : int32 sliceoffset,
112 : : int32 slicelength);
113 : :
114 : : /* ----------
115 : : * toast_raw_datum_size -
116 : : *
117 : : * Return the raw (detoasted) size of a varlena datum
118 : : * ----------
119 : : */
120 : : extern Size toast_raw_datum_size(Datum value);
121 : :
122 : : /* ----------
123 : : * toast_datum_size -
124 : : *
125 : : * Return the storage size of a varlena datum
126 : : * ----------
127 : : */
128 : : extern Size toast_datum_size(Datum value);
129 : :
130 : : #endif /* DETOAST_H */
|