Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)