Skip to content

Commit 43a24b8

Browse files
author
Nikita Glukhov
committed
WIP: TOAST with first chunk stored inline
1 parent 332a0f6 commit 43a24b8

File tree

20 files changed

+384
-72
lines changed

20 files changed

+384
-72
lines changed

src/backend/access/brin/brin_tuple.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple,
211211
if (!VARATT_IS_EXTENDED(DatumGetPointer(value)) &&
212212
VARSIZE(DatumGetPointer(value)) > TOAST_INDEX_TARGET &&
213213
(atttype->typstorage == TYPSTORAGE_EXTENDED ||
214+
atttype->typstorage == TYPSTORAGE_TAPAS ||
214215
atttype->typstorage == TYPSTORAGE_MAIN))
215216
{
216217
Datum cvalue = toast_compress_datum(value);

src/backend/access/common/detoast.c

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ detoast_external_attr(struct varlena *attr)
4545
{
4646
struct varlena *result;
4747

48-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
48+
if (VARATT_IS_EXTERNAL_ONDISK(attr) || VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
4949
{
5050
/*
5151
* This is an external stored plain value
@@ -114,7 +114,7 @@ detoast_external_attr(struct varlena *attr)
114114
struct varlena *
115115
detoast_attr(struct varlena *attr)
116116
{
117-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
117+
if (VARATT_IS_EXTERNAL_ONDISK(attr) || VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
118118
{
119119
/*
120120
* This is an externally stored datum --- fetch it back from there
@@ -208,6 +208,9 @@ detoast_attr_slice(struct varlena *attr,
208208
char *attrdata;
209209
int32 attrsize;
210210

211+
if (VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
212+
elog(ERROR, "slicing of chunked attributes is not yet supported"); /* FIXME */
213+
211214
if (VARATT_IS_EXTERNAL_ONDISK(attr))
212215
{
213216
struct varatt_external toast_pointer;
@@ -324,15 +327,33 @@ create_detoast_iterator(struct varlena *attr)
324327
{
325328
struct varatt_external toast_pointer;
326329
DetoastIterator iter;
327-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
330+
if (VARATT_IS_EXTERNAL_ONDISK(attr) || VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
328331
{
332+
int32 inlineSize;
333+
329334
iter = (DetoastIterator) palloc0(sizeof(DetoastIteratorData));
330335
iter->done = false;
331336
iter->nrefs = 1;
332337

333338
/* This is an externally stored datum --- initialize fetch datum iterator */
334339
iter->fetch_datum_iterator = create_fetch_datum_iterator(attr);
335-
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
340+
341+
/* Must copy to access aligned fields */
342+
if (VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
343+
{
344+
//VARATT_EXTERNAL_GET_POINTER(toast_pointer_inline, attr);
345+
struct varatt_external_inline toast_pointer_inline;
346+
347+
memcpy(&toast_pointer_inline, VARDATA_EXTERNAL(attr), sizeof(toast_pointer_inline));
348+
toast_pointer = toast_pointer_inline.va_external;
349+
inlineSize = toast_pointer_inline.va_inline_size;
350+
}
351+
else
352+
{
353+
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
354+
inlineSize = 0;
355+
}
356+
336357
if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
337358
{
338359
iter->compressed = true;
@@ -353,6 +374,14 @@ create_detoast_iterator(struct varlena *attr)
353374
/* point the buffer directly at the raw data */
354375
iter->buf = iter->fetch_datum_iterator->buf;
355376
}
377+
378+
if (inlineSize > 0)
379+
{
380+
memcpy((void *) iter->fetch_datum_iterator->buf->limit,
381+
VARDATA_EXTERNAL_INLINE(attr), inlineSize);
382+
iter->fetch_datum_iterator->buf->limit += inlineSize;
383+
}
384+
356385
return iter;
357386
}
358387
else if (VARATT_IS_EXTERNAL_INDIRECT(attr))
@@ -431,14 +460,27 @@ toast_fetch_datum(struct varlena *attr)
431460
{
432461
Relation toastrel;
433462
struct varlena *result;
463+
struct varatt_external_inline toast_pointer_inline;
434464
struct varatt_external toast_pointer;
435465
int32 attrsize;
466+
int32 inlineSize;
436467

437-
if (!VARATT_IS_EXTERNAL_ONDISK(attr))
468+
if (!VARATT_IS_EXTERNAL_ONDISK(attr) && !VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
438469
elog(ERROR, "toast_fetch_datum shouldn't be called for non-ondisk datums");
439470

440471
/* Must copy to access aligned fields */
441-
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
472+
if (VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
473+
{
474+
//VARATT_EXTERNAL_GET_POINTER(toast_pointer_inline, attr);
475+
memcpy(&toast_pointer_inline, VARDATA_EXTERNAL(attr), sizeof(toast_pointer_inline));
476+
toast_pointer = toast_pointer_inline.va_external;
477+
inlineSize = toast_pointer_inline.va_inline_size;
478+
}
479+
else
480+
{
481+
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
482+
inlineSize = 0;
483+
}
442484

443485
attrsize = toast_pointer.va_extsize;
444486

@@ -453,14 +495,18 @@ toast_fetch_datum(struct varlena *attr)
453495
return result; /* Probably shouldn't happen, but just in
454496
* case. */
455497

498+
if (inlineSize)
499+
memcpy(VARDATA(result), VARDATA_EXTERNAL_INLINE(attr), inlineSize);
500+
456501
/*
457502
* Open the toast relation and its indexes
458503
*/
459504
toastrel = table_open(toast_pointer.va_toastrelid, AccessShareLock);
460505

461506
/* Fetch all chunks */
462507
table_relation_fetch_toast_slice(toastrel, toast_pointer.va_valueid,
463-
attrsize, 0, attrsize, result);
508+
attrsize - inlineSize, 0, attrsize - inlineSize,
509+
(struct varlena *)((char *) result + inlineSize));
464510

465511
/* Close toast table */
466512
table_close(toastrel, AccessShareLock);
@@ -488,7 +534,7 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
488534
struct varatt_external toast_pointer;
489535
int32 attrsize;
490536

491-
if (!VARATT_IS_EXTERNAL_ONDISK(attr))
537+
if (!VARATT_IS_EXTERNAL_ONDISK(attr)) /* FIXME */
492538
elog(ERROR, "toast_fetch_datum_slice shouldn't be called for non-ondisk datums");
493539

494540
/* Must copy to access aligned fields */
@@ -611,7 +657,7 @@ toast_raw_datum_size(Datum value)
611657
struct varlena *attr = (struct varlena *) DatumGetPointer(value);
612658
Size result;
613659

614-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
660+
if (VARATT_IS_EXTERNAL_ONDISK(attr) || VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
615661
{
616662
/* va_rawsize is the size of the original datum -- including header */
617663
struct varatt_external toast_pointer;
@@ -679,6 +725,13 @@ toast_datum_size(Datum value)
679725
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
680726
result = toast_pointer.va_extsize;
681727
}
728+
else if (VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
729+
{
730+
struct varatt_external toast_pointer;
731+
732+
memcpy(&toast_pointer, VARDATA_EXTERNAL(attr), sizeof(toast_pointer));
733+
result = toast_pointer.va_extsize;
734+
}
682735
else if (VARATT_IS_EXTERNAL_INDIRECT(attr))
683736
{
684737
struct varatt_indirect toast_pointer;

src/backend/access/common/indextuple.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ index_form_tuple(TupleDesc tupleDescriptor,
101101
if (!VARATT_IS_EXTENDED(DatumGetPointer(untoasted_values[i])) &&
102102
VARSIZE(DatumGetPointer(untoasted_values[i])) > TOAST_INDEX_TARGET &&
103103
(att->attstorage == TYPSTORAGE_EXTENDED ||
104+
att->attstorage == TYPSTORAGE_TAPAS ||
104105
att->attstorage == TYPSTORAGE_MAIN))
105106
{
106107
Datum cvalue = toast_compress_datum(untoasted_values[i]);

0 commit comments

Comments
 (0)