@@ -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)
114114struct varlena *
115115detoast_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 ;
0 commit comments