Skip to content

Commit 30683da

Browse files
author
Nikita Glukhov
committed
Inline TOAST
1 parent eb5d44a commit 30683da

File tree

12 files changed

+404
-122
lines changed

12 files changed

+404
-122
lines changed

src/backend/access/common/detoast.c

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ detoast_external_attr(struct varlena *attr)
4646
{
4747
struct varlena *result;
4848

49-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
49+
if (VARATT_IS_EXTERNAL_ONDISK(attr) || VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
5050
{
5151
/*
5252
* This is an external stored plain value
@@ -115,7 +115,7 @@ detoast_external_attr(struct varlena *attr)
115115
struct varlena *
116116
detoast_attr(struct varlena *attr)
117117
{
118-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
118+
if (VARATT_IS_EXTERNAL_ONDISK(attr) || VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
119119
{
120120
/*
121121
* This is an externally stored datum --- fetch it back from there
@@ -223,6 +223,9 @@ detoast_attr_slice(struct varlena *attr,
223223
else if (pg_add_s32_overflow(sliceoffset, slicelength, &slicelimit))
224224
slicelength = slicelimit = -1;
225225

226+
if (VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
227+
elog(ERROR, "slicing of chunked attributes is not yet supported"); /* FIXME */
228+
226229
if (VARATT_IS_EXTERNAL_ONDISK(attr))
227230
{
228231
struct varatt_external toast_pointer;
@@ -344,37 +347,45 @@ create_detoast_iterator(struct varlena *attr)
344347
{
345348
struct varatt_external toast_pointer;
346349
DetoastIterator iter;
347-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
350+
if (VARATT_IS_EXTERNAL_ONDISK(attr) || VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
348351
{
349352
FetchDatumIterator fetch_iter;
353+
int32 inlineSize;
350354

351355
iter = (DetoastIterator) palloc0(sizeof(DetoastIteratorData));
352356
iter->done = false;
353357
iter->nrefs = 1;
354358

355359
/* This is an externally stored datum --- initialize fetch datum iterator */
356360
iter->fetch_datum_iterator = fetch_iter = create_fetch_datum_iterator(attr);
357-
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
361+
362+
/* Must copy to access aligned fields */
363+
inlineSize = VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer, attr);
364+
358365
if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
359366
{
360367
iter->compressed = true;
368+
iter->compression_method = VARATT_EXTERNAL_GET_COMPRESS_METHOD(toast_pointer);
361369

362370
/* prepare buffer to received decompressed data */
363371
iter->buf = create_toast_buffer(toast_pointer.va_rawsize, false);
364-
365-
/* initialize state for pglz_decompress_iterate() */
366-
iter->ctrl = 0;
367-
iter->ctrlc = INVALID_CTRLC;
368-
iter->len = 0;
369-
iter->off = 0;
370372
}
371373
else
372374
{
373375
iter->compressed = false;
376+
iter->compression_method = TOAST_INVALID_COMPRESSION_ID;
374377

375378
/* point the buffer directly at the raw data */
376379
iter->buf = fetch_iter->buf;
377380
}
381+
382+
if (inlineSize > 0)
383+
{
384+
memcpy((void *) fetch_iter->buf->limit,
385+
VARDATA_EXTERNAL_INLINE(attr), inlineSize);
386+
fetch_iter =->buf->limit += inlineSize;
387+
}
388+
378389
return iter;
379390
}
380391
else if (VARATT_IS_EXTERNAL_INDIRECT(attr))
@@ -404,16 +415,14 @@ create_detoast_iterator(struct varlena *attr)
404415
iter->fetch_datum_iterator->buf = buf = create_toast_buffer(VARSIZE_ANY(attr), true);
405416
iter->fetch_datum_iterator->done = true;
406417
iter->compressed = true;
418+
iter->compression_method = VARDATA_COMPRESSED_GET_COMPRESS_METHOD(attr);
407419

408420
memcpy((void *) buf->buf, attr, VARSIZE_ANY(attr));
409421
buf->limit = (char *) buf->capacity;
410422

411423
/* prepare buffer to received decompressed data */
412-
iter->buf = create_toast_buffer(TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ, false);
424+
iter->buf = create_toast_buffer(TOAST_COMPRESS_EXTSIZE(attr) + VARHDRSZ, false);
413425

414-
/* initialize state for pglz_decompress_iterate() */
415-
iter->ctrl = 0;
416-
iter->ctrlc = INVALID_CTRLC;
417426
return iter;
418427
}
419428
else
@@ -455,13 +464,13 @@ toast_fetch_datum(struct varlena *attr)
455464
struct varlena *result;
456465
struct varatt_external toast_pointer;
457466
int32 attrsize;
467+
int32 inlineSize;
458468

459-
if (!VARATT_IS_EXTERNAL_ONDISK(attr))
469+
if (!VARATT_IS_EXTERNAL_ONDISK(attr) && !VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
460470
elog(ERROR, "toast_fetch_datum shouldn't be called for non-ondisk datums");
461471

462472
/* Must copy to access aligned fields */
463-
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
464-
473+
inlineSize = VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer, attr);
465474
attrsize = VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer);
466475

467476
result = (struct varlena *) palloc(attrsize + VARHDRSZ);
@@ -475,14 +484,18 @@ toast_fetch_datum(struct varlena *attr)
475484
return result; /* Probably shouldn't happen, but just in
476485
* case. */
477486

487+
if (inlineSize)
488+
memcpy(VARDATA(result), VARDATA_EXTERNAL_INLINE(attr), inlineSize);
489+
478490
/*
479491
* Open the toast relation and its indexes
480492
*/
481493
toastrel = table_open(toast_pointer.va_toastrelid, AccessShareLock);
482494

483495
/* Fetch all chunks */
484496
table_relation_fetch_toast_slice(toastrel, toast_pointer.va_valueid,
485-
attrsize, 0, attrsize, result);
497+
attrsize - inlineSize, 0, attrsize - inlineSize,
498+
(struct varlena *)((char *) result + inlineSize));
486499

487500
/* Close toast table */
488501
table_close(toastrel, AccessShareLock);
@@ -510,7 +523,7 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
510523
struct varatt_external toast_pointer;
511524
int32 attrsize;
512525

513-
if (!VARATT_IS_EXTERNAL_ONDISK(attr))
526+
if (!VARATT_IS_EXTERNAL_ONDISK(attr)) /* FIXME */
514527
elog(ERROR, "toast_fetch_datum_slice shouldn't be called for non-ondisk datums");
515528

516529
/* Must copy to access aligned fields */
@@ -656,13 +669,14 @@ toast_raw_datum_size(Datum value)
656669
struct varlena *attr = (struct varlena *) DatumGetPointer(value);
657670
Size result;
658671

659-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
672+
if (VARATT_IS_EXTERNAL_ONDISK(attr) || VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
660673
{
661674
/* va_rawsize is the size of the original datum -- including header */
662675
struct varatt_external toast_pointer;
676+
Size inlineSize;
663677

664-
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
665-
result = toast_pointer.va_rawsize;
678+
inlineSize = VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer, attr);
679+
result = toast_pointer.va_rawsize + inlineSize;
666680
}
667681
else if (VARATT_IS_EXTERNAL_INDIRECT(attr))
668682
{
@@ -712,7 +726,8 @@ toast_datum_size(Datum value)
712726
struct varlena *attr = (struct varlena *) DatumGetPointer(value);
713727
Size result;
714728

715-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
729+
if (VARATT_IS_EXTERNAL_ONDISK(attr) ||
730+
VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
716731
{
717732
/*
718733
* Attribute is stored externally - return the extsize whether
@@ -721,8 +736,8 @@ toast_datum_size(Datum value)
721736
*/
722737
struct varatt_external toast_pointer;
723738

724-
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
725-
result = VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer);
739+
VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer, attr);
740+
result = VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer); /* FIXME inlineSize */
726741
}
727742
else if (VARATT_IS_EXTERNAL_INDIRECT(attr))
728743
{

src/backend/access/common/toast_compression.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ pglz_compress_datum(const struct varlena *value)
6565
len = pglz_compress(VARDATA_ANY(value),
6666
valsize,
6767
(char *) tmp + VARHDRSZ_COMPRESSED,
68+
NULL,
6869
NULL);
6970
if (len < 0)
7071
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy