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

Commit95ea57f

Browse files
author
Nikita Glukhov
committed
WIP: bytea append TOAST
1 parent98c5e45 commit95ea57f

File tree

7 files changed

+284
-82
lines changed

7 files changed

+284
-82
lines changed

‎src/backend/access/common/detoast.c

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,15 @@ detoast_attr_slice(struct varlena *attr,
223223
elseif (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 */
226+
//if (VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
227+
//elog(ERROR, "slicing of chunked attributes is not yet supported"); /* FIXME */
228228

229-
if (VARATT_IS_EXTERNAL_ONDISK(attr))
229+
if (VARATT_IS_EXTERNAL_ONDISK(attr)||
230+
VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
230231
{
231232
structvaratt_externaltoast_pointer;
232233

233-
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
234+
VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer,attr);
234235

235236
/* fast path for non-compressed external datums */
236237
if (!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
@@ -381,9 +382,18 @@ create_detoast_iterator(struct varlena *attr)
381382

382383
if (inlineSize>0)
383384
{
384-
memcpy((void*)fetch_iter->buf->limit,
385-
VARDATA_EXTERNAL_INLINE(attr),inlineSize);
386-
fetch_iter=->buf->limit+=inlineSize;
385+
if (VARATT_IS_EXTERNAL_ONDISK_INLINE_HEAD(attr))
386+
{
387+
memcpy((void*)fetch_iter->buf->limit,
388+
VARDATA_EXTERNAL_INLINE(attr),inlineSize);
389+
fetch_iter->buf->limit+=inlineSize;
390+
}
391+
else
392+
{
393+
memcpy(fetch_iter->buf->limit+fetch_iter->ressize,
394+
VARDATA_EXTERNAL_INLINE(attr),inlineSize);
395+
fetch_iter->tail_size=inlineSize;
396+
}
387397
}
388398

389399
returniter;
@@ -464,13 +474,14 @@ toast_fetch_datum(struct varlena *attr)
464474
structvarlena*result;
465475
structvaratt_externaltoast_pointer;
466476
int32attrsize;
467-
int32inlineSize;
477+
int32inline_size;
478+
char*detoast_ptr;
468479

469480
if (!VARATT_IS_EXTERNAL_ONDISK(attr)&& !VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
470481
elog(ERROR,"toast_fetch_datum shouldn't be called for non-ondisk datums");
471482

472483
/* Must copy to access aligned fields */
473-
inlineSize=VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer,attr);
484+
inline_size=VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer,attr);
474485
attrsize=VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer);
475486

476487
result= (structvarlena*)palloc(attrsize+VARHDRSZ);
@@ -484,8 +495,18 @@ toast_fetch_datum(struct varlena *attr)
484495
returnresult;/* Probably shouldn't happen, but just in
485496
* case. */
486497

487-
if (inlineSize)
488-
memcpy(VARDATA(result),VARDATA_EXTERNAL_INLINE(attr),inlineSize);
498+
detoast_ptr= (char*)result;
499+
500+
if (inline_size)
501+
{
502+
if (VARATT_IS_EXTERNAL_ONDISK_INLINE_TAIL(attr))
503+
memcpy(VARDATA(result)+attrsize-inline_size,VARDATA_EXTERNAL_INLINE(attr),inline_size);
504+
else
505+
{
506+
memcpy(VARDATA(result),VARDATA_EXTERNAL_INLINE(attr),inline_size);
507+
detoast_ptr+=inline_size;
508+
}
509+
}
489510

490511
/*
491512
* Open the toast relation and its indexes
@@ -494,8 +515,8 @@ toast_fetch_datum(struct varlena *attr)
494515

495516
/* Fetch all chunks */
496517
table_relation_fetch_toast_slice(toastrel,toast_pointer.va_valueid,
497-
attrsize-inlineSize,0,attrsize-inlineSize,
498-
(structvarlena*)((char*)result+inlineSize));
518+
attrsize-inline_size,0,attrsize-inline_size,
519+
(structvarlena*)detoast_ptr);
499520

500521
/* Close toast table */
501522
table_close(toastrel,AccessShareLock);
@@ -522,12 +543,14 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
522543
structvarlena*result;
523544
structvaratt_externaltoast_pointer;
524545
int32attrsize;
546+
int32inline_size;
525547

526-
if (!VARATT_IS_EXTERNAL_ONDISK(attr))/* FIXME */
548+
if (!VARATT_IS_EXTERNAL_ONDISK(attr)&&
549+
!VARATT_IS_EXTERNAL_ONDISK_INLINE(attr))
527550
elog(ERROR,"toast_fetch_datum_slice shouldn't be called for non-ondisk datums");
528551

529552
/* Must copy to access aligned fields */
530-
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
553+
inline_size=VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer,attr);
531554

532555
/*
533556
* It's nonsense to fetch slices of a compressed datum unless when it's a
@@ -567,15 +590,40 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset,
567590
else
568591
SET_VARSIZE(result,slicelength+VARHDRSZ);
569592

570-
if (slicelength==0)
593+
if (VARATT_IS_EXTERNAL_ONDISK_INLINE_HEAD(attr))
594+
{
595+
int32size=Min(slicelength,inline_size-sliceoffset);
596+
597+
if (size>0)
598+
memcpy(VARDATA(result),VARDATA_EXTERNAL_INLINE(attr)+sliceoffset,size);
599+
slicelength-=size;
600+
sliceoffset=size;
601+
}
602+
elseif (VARATT_IS_EXTERNAL_ONDISK_INLINE_TAIL(attr))
603+
{
604+
if (sliceoffset+slicelength>attrsize-inline_size)
605+
{
606+
int32size=Min(sliceoffset+slicelength- (attrsize-inline_size),inline_size);
607+
int32inline_offset=Max(0,sliceoffset- (attrsize-inline_size));
608+
609+
size=Min(size,slicelength);
610+
611+
memcpy(VARDATA(result)+slicelength-size,
612+
VARDATA_EXTERNAL_INLINE(attr)+inline_offset,size);
613+
614+
slicelength-=size;
615+
}
616+
}
617+
618+
if (slicelength <=0)
571619
returnresult;/* Can save a lot of work at this point! */
572620

573621
/* Open the toast relation */
574622
toastrel=table_open(toast_pointer.va_toastrelid,AccessShareLock);
575623

576624
/* Fetch all chunks */
577625
table_relation_fetch_toast_slice(toastrel,toast_pointer.va_valueid,
578-
attrsize,sliceoffset,slicelength,
626+
attrsize-inline_size,sliceoffset,slicelength,
579627
result);
580628

581629
/* Close toast table */
@@ -673,10 +721,9 @@ toast_raw_datum_size(Datum value)
673721
{
674722
/* va_rawsize is the size of the original datum -- including header */
675723
structvaratt_externaltoast_pointer;
676-
SizeinlineSize;
677724

678-
inlineSize=VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer,attr);
679-
result=toast_pointer.va_rawsize+inlineSize;
725+
VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer,attr);
726+
result=toast_pointer.va_rawsize;
680727
}
681728
elseif (VARATT_IS_EXTERNAL_INDIRECT(attr))
682729
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp