Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6cb2952

Browse files
author
Nikita Glukhov
committed
TOAST iterators
1 parent 9032dd5 commit 6cb2952

File tree

12 files changed

+802
-18
lines changed

12 files changed

+802
-18
lines changed

src/backend/access/common/detoast.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,113 @@ detoast_attr_slice(struct varlena *attr,
332332
return result;
333333
}
334334

335+
/* ----------
336+
* create_detoast_iterator -
337+
*
338+
* It only makes sense to initialize a de-TOAST iterator for external on-disk values.
339+
*
340+
* ----------
341+
*/
342+
DetoastIterator
343+
create_detoast_iterator(struct varlena *attr)
344+
{
345+
struct varatt_external toast_pointer;
346+
DetoastIterator iter;
347+
if (VARATT_IS_EXTERNAL_ONDISK(attr))
348+
{
349+
FetchDatumIterator fetch_iter;
350+
351+
iter = (DetoastIterator) palloc0(sizeof(DetoastIteratorData));
352+
iter->done = false;
353+
iter->nrefs = 1;
354+
355+
/* This is an externally stored datum --- initialize fetch datum iterator */
356+
iter->fetch_datum_iterator = fetch_iter = create_fetch_datum_iterator(attr);
357+
VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
358+
if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
359+
{
360+
iter->compressed = true;
361+
362+
/* prepare buffer to received decompressed data */
363+
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+
}
369+
else
370+
{
371+
iter->compressed = false;
372+
373+
/* point the buffer directly at the raw data */
374+
iter->buf = fetch_iter->buf;
375+
}
376+
return iter;
377+
}
378+
else if (VARATT_IS_EXTERNAL_INDIRECT(attr))
379+
{
380+
/* indirect pointer --- dereference it */
381+
struct varatt_indirect redirect;
382+
383+
VARATT_EXTERNAL_GET_POINTER(redirect, attr);
384+
attr = (struct varlena *) redirect.pointer;
385+
386+
/* nested indirect Datums aren't allowed */
387+
Assert(!VARATT_IS_EXTERNAL_INDIRECT(attr));
388+
389+
/* recurse in case value is still extended in some other way */
390+
return create_detoast_iterator(attr);
391+
392+
}
393+
else if (VARATT_IS_COMPRESSED(attr))
394+
{
395+
ToastBuffer *buf;
396+
397+
iter = (DetoastIterator) palloc0(sizeof(DetoastIteratorData));
398+
iter->done = false;
399+
iter->nrefs = 1;
400+
401+
iter->fetch_datum_iterator = palloc0(sizeof(*iter->fetch_datum_iterator));
402+
iter->fetch_datum_iterator->buf = buf = create_toast_buffer(VARSIZE_ANY(attr), true);
403+
iter->fetch_datum_iterator->done = true;
404+
iter->compressed = true;
405+
406+
memcpy((void *) buf->buf, attr, VARSIZE_ANY(attr));
407+
buf->limit = (char *) buf->capacity;
408+
409+
/* prepare buffer to received decompressed data */
410+
iter->buf = create_toast_buffer(TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ, false);
411+
412+
/* initialize state for pglz_decompress_iterate() */
413+
iter->ctrl = 0;
414+
iter->ctrlc = INVALID_CTRLC;
415+
return iter;
416+
}
417+
else
418+
/* in-line value -- no iteration used, even if it's compressed */
419+
return NULL;
420+
}
421+
422+
/* ----------
423+
* free_detoast_iterator -
424+
*
425+
* Free memory used by the de-TOAST iterator, including buffers and
426+
* fetch datum iterator.
427+
* ----------
428+
*/
429+
void
430+
free_detoast_iterator(DetoastIterator iter)
431+
{
432+
if (iter == NULL)
433+
return;
434+
if (--iter->nrefs > 0)
435+
return;
436+
if (iter->compressed)
437+
free_toast_buffer(iter->buf);
438+
free_fetch_datum_iterator(iter->fetch_datum_iterator);
439+
pfree(iter);
440+
}
441+
335442
/* ----------
336443
* toast_fetch_datum -
337444
*

0 commit comments

Comments
 (0)