Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit27b8922

Browse files
committed
Add an extra header byte to TOAST-pointer datums to represent their size
explicitly. This means a TOAST pointer takes 18 bytes instead of 17 --- stillsmaller than in 8.2 --- which seems a good tradeoff to ensure we won't havepainted ourselves into a corner if we want to support multiple types of TOASTpointer later on. Per discussion with Greg Stark.
1 parent3ff0018 commit27b8922

File tree

4 files changed

+58
-37
lines changed

4 files changed

+58
-37
lines changed

‎doc/src/sgml/storage.sgml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/storage.sgml,v 1.19 2007/09/21 21:25:42 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/storage.sgml,v 1.20 2007/09/30 19:54:57 tgl Exp $ -->
22

33
<chapter id="storage">
44

@@ -233,8 +233,8 @@ header, and the remaining bits give the total datum size (including length
233233
byte) in bytes. As a special case, if the remaining bits are all zero
234234
(which would be impossible for a self-inclusive length), the value is a
235235
pointer to out-of-line data stored in a separate TOAST table. (The size of
236-
a TOAST pointer isknown a priori, so it doesn't need to be represented in
237-
the header.)Values with single-byte headers aren't aligned on any particular
236+
a TOAST pointer isgiven in the second byte of the datum.)
237+
Values with single-byte headers aren't aligned on any particular
238238
boundary, either. Lastly, when the highest-order or lowest-order bit is
239239
clear but the adjacent bit is set, the content of the datum has been
240240
compressed and must be decompressed before use. In this case the remaining
@@ -274,8 +274,8 @@ retrieval of the values. A pointer datum representing an out-of-line
274274
<acronym>TOAST</> table in which to look and the OID of the specific value
275275
(its <structfield>chunk_id</>). For convenience, pointer datums also store the
276276
logical datum size (original uncompressed data length) and actual stored size
277-
(different if compression was applied). Allowing for the varlena headerbyte,
278-
the total size of a <acronym>TOAST</> pointer datum is therefore17 bytes
277+
(different if compression was applied). Allowing for the varlena headerbytes,
278+
the total size of a <acronym>TOAST</> pointer datum is therefore18 bytes
279279
regardless of the actual size of the represented value.
280280
</para>
281281

‎src/backend/access/heap/tuptoaster.c

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.75 2007/09/26 23:29:10 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.76 2007/09/30 19:54:58 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -52,6 +52,21 @@
5252
#defineVARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) \
5353
((toast_pointer).va_extsize < (toast_pointer).va_rawsize - VARHDRSZ)
5454

55+
/*
56+
* Macro to fetch the possibly-unaligned contents of an EXTERNAL datum
57+
* into a local "struct varatt_external" toast pointer. This should be
58+
* just a memcpy, but some versions of gcc seem to produce broken code
59+
* that assumes the datum contents are aligned. Introducing an explicit
60+
* intermediate "varattrib_1b_e *" variable seems to fix it.
61+
*/
62+
#defineVARATT_EXTERNAL_GET_POINTER(toast_pointer,attr) \
63+
do { \
64+
varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \
65+
Assert(VARSIZE_ANY_EXHDR(attre) == sizeof(toast_pointer)); \
66+
memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \
67+
} while (0)
68+
69+
5570
staticvoidtoast_delete_datum(Relationrel,Datumvalue);
5671
staticDatumtoast_save_datum(Relationrel,Datumvalue,
5772
booluse_wal,booluse_fsm);
@@ -172,7 +187,7 @@ heap_tuple_untoast_attr_slice(struct varlena *attr,
172187
{
173188
structvaratt_externaltoast_pointer;
174189

175-
memcpy(&toast_pointer,VARDATA_SHORT(attr),sizeof(toast_pointer));
190+
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
176191

177192
/* fast path for non-compressed external datums */
178193
if (!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
@@ -249,7 +264,7 @@ toast_raw_datum_size(Datum value)
249264
/* va_rawsize is the size of the original datum -- including header */
250265
structvaratt_externaltoast_pointer;
251266

252-
memcpy(&toast_pointer,VARDATA_SHORT(attr),sizeof(toast_pointer));
267+
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
253268
result=toast_pointer.va_rawsize;
254269
}
255270
elseif (VARATT_IS_COMPRESSED(attr))
@@ -294,7 +309,7 @@ toast_datum_size(Datum value)
294309
*/
295310
structvaratt_externaltoast_pointer;
296311

297-
memcpy(&toast_pointer,VARDATA_SHORT(attr),sizeof(toast_pointer));
312+
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
298313
result=toast_pointer.va_extsize;
299314
}
300315
elseif (VARATT_IS_SHORT(attr))
@@ -470,9 +485,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
470485
VARATT_IS_EXTERNAL(old_value))
471486
{
472487
if (toast_isnull[i]|| !VARATT_IS_EXTERNAL(new_value)||
473-
memcmp(VARDATA_SHORT(old_value),
474-
VARDATA_SHORT(new_value),
475-
sizeof(structvaratt_external))!=0)
488+
memcmp((char*)old_value, (char*)new_value,
489+
VARSIZE_EXTERNAL(old_value))!=0)
476490
{
477491
/*
478492
* The old external stored value isn't needed any more
@@ -1071,7 +1085,7 @@ toast_save_datum(Relation rel, Datum value,
10711085
Datumt_values[3];
10721086
boolt_isnull[3];
10731087
CommandIdmycid=GetCurrentCommandId();
1074-
structvarlena*result;
1088+
varattrib_pointer*result;
10751089
structvaratt_externaltoast_pointer;
10761090
struct
10771091
{
@@ -1192,9 +1206,9 @@ toast_save_datum(Relation rel, Datum value,
11921206
/*
11931207
* Create the TOAST pointer value that we'll return
11941208
*/
1195-
result= (structvarlena*)palloc(sizeof(varattrib_pointer));
1196-
SET_VARSIZE_EXTERNAL(result);
1197-
memcpy(VARDATA_SHORT(result),&toast_pointer,sizeof(toast_pointer));
1209+
result= (varattrib_pointer*)palloc(sizeof(varattrib_pointer));
1210+
SET_VARSIZE_EXTERNAL(result,sizeof(varattrib_pointer));
1211+
memcpy(VARDATA_EXTERNAL(result),&toast_pointer,sizeof(toast_pointer));
11981212

11991213
returnPointerGetDatum(result);
12001214
}
@@ -1221,8 +1235,7 @@ toast_delete_datum(Relation rel, Datum value)
12211235
return;
12221236

12231237
/* Must copy to access aligned fields */
1224-
memcpy(&toast_pointer,VARDATA_SHORT(attr),
1225-
sizeof(structvaratt_external));
1238+
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
12261239

12271240
/*
12281241
* Open the toast relation and its index
@@ -1289,8 +1302,7 @@ toast_fetch_datum(struct varlena *attr)
12891302
int32chunksize;
12901303

12911304
/* Must copy to access aligned fields */
1292-
memcpy(&toast_pointer,VARDATA_SHORT(attr),
1293-
sizeof(structvaratt_external));
1305+
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
12941306

12951307
ressize=toast_pointer.va_extsize;
12961308
numchunks= ((ressize-1) /TOAST_MAX_CHUNK_SIZE)+1;
@@ -1452,8 +1464,7 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset, int32 length)
14521464
Assert(VARATT_IS_EXTERNAL(attr));
14531465

14541466
/* Must copy to access aligned fields */
1455-
memcpy(&toast_pointer,VARDATA_SHORT(attr),
1456-
sizeof(structvaratt_external));
1467+
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
14571468

14581469
/*
14591470
* It's nonsense to fetch slices of a compressed datum -- this isn't lo_*

‎src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.429 2007/09/25 22:21:55 tgl Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.430 2007/09/30 19:54:58 tgl Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO200709251
56+
#defineCATALOG_VERSION_NO200709301
5757

5858
#endif

‎src/include/postgres.h

Lines changed: 23 additions & 13 deletions
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.83 2007/09/27 21:01:59 tgl Exp $
13+
* $PostgreSQL: pgsql/src/include/postgres.h,v 1.84 2007/09/30 19:54:58 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -100,12 +100,20 @@ typedef union
100100
typedefstruct
101101
{
102102
uint8va_header;
103-
charva_data[1];/* Dataor TOAST pointer */
103+
charva_data[1];/* Databegins here */
104104
}varattrib_1b;
105105

106106
typedefstruct
107107
{
108-
uint8va_header;
108+
uint8va_header;/* Always 0x80 or 0x01 */
109+
uint8va_len_1be;/* Physical length of datum */
110+
charva_data[1];/* Data (for now always a TOAST pointer) */
111+
}varattrib_1b_e;
112+
113+
typedefstruct
114+
{
115+
uint8va_header;/* Always 0x80 or 0x01 */
116+
uint8va_len_1be;/* Physical length of datum */
109117
charva_data[sizeof(structvaratt_external)];
110118
}varattrib_pointer;
111119

@@ -161,18 +169,18 @@ typedef struct
161169
(((varattrib_4b *) (PTR))->va_4byte.va_header & 0x3FFFFFFF)
162170
#defineVARSIZE_1B(PTR) \
163171
(((varattrib_1b *) (PTR))->va_header & 0x7F)
164-
/* Currently there is only one size of toast pointer, but someday maybe not */
165172
#defineVARSIZE_1B_E(PTR) \
166-
(sizeof(varattrib_pointer))
173+
(((varattrib_1b_e *) (PTR))->va_len_1be)
167174

168175
#defineSET_VARSIZE_4B(PTR,len) \
169176
(((varattrib_4b *) (PTR))->va_4byte.va_header = (len) & 0x3FFFFFFF)
170177
#defineSET_VARSIZE_4B_C(PTR,len) \
171178
(((varattrib_4b *) (PTR))->va_4byte.va_header = ((len) & 0x3FFFFFFF) | 0x40000000)
172179
#defineSET_VARSIZE_1B(PTR,len) \
173180
(((varattrib_1b *) (PTR))->va_header = (len) | 0x80)
174-
#defineSET_VARSIZE_1B_E(PTR) \
175-
(((varattrib_1b *) (PTR))->va_header = 0x80)
181+
#defineSET_VARSIZE_1B_E(PTR,len) \
182+
(((varattrib_1b_e *) (PTR))->va_header = 0x80, \
183+
((varattrib_1b_e *) (PTR))->va_len_1be = (len))
176184

177185
#else/* !WORDS_BIGENDIAN */
178186

@@ -194,18 +202,18 @@ typedef struct
194202
((((varattrib_4b *) (PTR))->va_4byte.va_header >> 2) & 0x3FFFFFFF)
195203
#defineVARSIZE_1B(PTR) \
196204
((((varattrib_1b *) (PTR))->va_header >> 1) & 0x7F)
197-
/* Currently there is only one size of toast pointer, but someday maybe not */
198205
#defineVARSIZE_1B_E(PTR) \
199-
(sizeof(varattrib_pointer))
206+
(((varattrib_1b_e *) (PTR))->va_len_1be)
200207

201208
#defineSET_VARSIZE_4B(PTR,len) \
202209
(((varattrib_4b *) (PTR))->va_4byte.va_header = (((uint32) (len)) << 2))
203210
#defineSET_VARSIZE_4B_C(PTR,len) \
204211
(((varattrib_4b *) (PTR))->va_4byte.va_header = (((uint32) (len)) << 2) | 0x02)
205212
#defineSET_VARSIZE_1B(PTR,len) \
206213
(((varattrib_1b *) (PTR))->va_header = (((uint8) (len)) << 1) | 0x01)
207-
#defineSET_VARSIZE_1B_E(PTR) \
208-
(((varattrib_1b *) (PTR))->va_header = 0x01)
214+
#defineSET_VARSIZE_1B_E(PTR,len) \
215+
(((varattrib_1b_e *) (PTR))->va_header = 0x01, \
216+
((varattrib_1b_e *) (PTR))->va_len_1be = (len))
209217

210218
#endif/* WORDS_BIGENDIAN */
211219

@@ -220,6 +228,7 @@ typedef struct
220228
#defineVARDATA_4B(PTR)(((varattrib_4b *) (PTR))->va_4byte.va_data)
221229
#defineVARDATA_4B_C(PTR)(((varattrib_4b *) (PTR))->va_compressed.va_data)
222230
#defineVARDATA_1B(PTR)(((varattrib_1b *) (PTR))->va_data)
231+
#defineVARDATA_1B_E(PTR)(((varattrib_1b_e *) (PTR))->va_data)
223232

224233
#defineVARRAWSIZE_4B_C(PTR) \
225234
(((varattrib_4b *) (PTR))->va_compressed.va_rawsize)
@@ -249,6 +258,7 @@ typedef struct
249258
#defineVARDATA_SHORT(PTR)VARDATA_1B(PTR)
250259

251260
#defineVARSIZE_EXTERNAL(PTR)VARSIZE_1B_E(PTR)
261+
#defineVARDATA_EXTERNAL(PTR)VARDATA_1B_E(PTR)
252262

253263
#defineVARATT_IS_COMPRESSED(PTR)VARATT_IS_4B_C(PTR)
254264
#defineVARATT_IS_EXTERNAL(PTR)VARATT_IS_1B_E(PTR)
@@ -258,15 +268,15 @@ typedef struct
258268
#defineSET_VARSIZE(PTR,len)SET_VARSIZE_4B(PTR, len)
259269
#defineSET_VARSIZE_SHORT(PTR,len)SET_VARSIZE_1B(PTR, len)
260270
#defineSET_VARSIZE_COMPRESSED(PTR,len)SET_VARSIZE_4B_C(PTR, len)
261-
#defineSET_VARSIZE_EXTERNAL(PTR)SET_VARSIZE_1B_E(PTR)
271+
#defineSET_VARSIZE_EXTERNAL(PTR,len)SET_VARSIZE_1B_E(PTR, len)
262272

263273
#defineVARSIZE_ANY(PTR) \
264274
(VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR) : \
265275
(VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR) : \
266276
VARSIZE_4B(PTR)))
267277

268278
#defineVARSIZE_ANY_EXHDR(PTR) \
269-
(VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR)-1 : \
279+
(VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR)-2 : \
270280
(VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR)-1 : \
271281
VARSIZE_4B(PTR)-4))
272282

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp