postgres.git / summary / log / commit / refs

commit    07d5bffe75d05b9c84803ea1ffaf5ce729f0e717
Author:   David Rowley <drowley@postgresql.org>
Date:     Fri Mar 20 01:16:06 2026 +0000

    Fix new tuple deforming code so it can support cstrings again
    
    In c456e3911, I mistakenly thought that the deformer code would never
    see cstrings and that I could use pg_assume() to have the compiler omit
    producing code for attlen == -2 attributes.  That saves bloating the
    deforming code a bit with the extra check and strlen() call.  While this
    is ok to do for tuples from the heap, it's not ok to do for
    MinimalTuples as those *can* contain cstrings and
    tts_minimal_getsomeattrs() implements deforming by inlining the
    (slightly misleadingly named) slot_deform_heap_tuple() code.
    
    To fix, add a new parameter to the slot_deform_heap_tuple() and have the
    callers define which code to inline.  Because this new parameter is
    passed as a const, the compiler can choose to emit or not emit the
    cstring-related code based on the parameter's value.
    
    Author: David Rowley <dgrowleyml@gmail.com>
    Reported-by: Tender Wang <tndrwang@gmail.com>
    Discussion: https://postgr.es/m/CAHewXNmSK+gKziAt_WvQoMVWt3_LRVMmRYY9dAbMPMcpPV0QmA@mail.gmail.com


src/backend/executor/execTuples.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index b717b03b3d2..9d900147a55 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -73,7 +73,7 @@ static TupleDesc ExecTypeFromTLInternal(List *targetList, bool skipjunk); static pg_attribute_always_inline void slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, - int reqnatts); + int reqnatts, bool support_cstring); static inline void tts_buffer_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, Buffer buffer, @@ -349,7 +349,7 @@ tts_heap_getsomeattrs(TupleTableSlot *slot, int natts) Assert(!TTS_EMPTY(slot)); - slot_deform_heap_tuple(slot, hslot->tuple, &hslot->off, natts); + slot_deform_heap_tuple(slot, hslot->tuple, &hslot->off, natts, false); } static Datum @@ -547,7 +547,7 @@ tts_minimal_getsomeattrs(TupleTableSlot *slot, int natts) Assert(!TTS_EMPTY(slot)); - slot_deform_heap_tuple(slot, mslot->tuple, &mslot->off, natts); + slot_deform_heap_tuple(slot, mslot->tuple, &mslot->off, natts, true); } /* @@ -754,7 +754,7 @@ tts_buffer_heap_getsomeattrs(TupleTableSlot *slot, int natts) Assert(!TTS_EMPTY(slot)); - slot_deform_heap_tuple(slot, bslot->base.tuple, &bslot->base.off, natts); + slot_deform_heap_tuple(slot, bslot->base.tuple, &bslot->base.off, natts, false); } static Datum @@ -1008,10 +1008,14 @@ tts_buffer_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, * * This is marked as always inline, so the different offp for different types * of slots gets optimized away. + * + * support_cstring should be passed as a const to allow the compiler only + * emit code during inlining for cstring deforming when it's required. + * cstrings can exist in MinimalTuples, but not in HeapTuples. */ static pg_attribute_always_inline void slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, - int reqnatts) + int reqnatts, bool support_cstring) { CompactAttribute *cattrs; CompactAttribute *cattr; @@ -1190,11 +1194,12 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, attlen = cattr->attlen; /* - * cstrings don't exist in heap tuples. Use pg_assume to instruct the - * compiler not to emit the cstring-related code in - * align_fetch_then_add(). + * Only emit the cstring-related code in align_fetch_then_add() when + * cstring support is needed. We assume support_cstring will be + * passed as a const to allow the compiler to eliminate this branch. */ - pg_assume(attlen > 0 || attlen == -1); + if (!support_cstring) + pg_assume(attlen > 0 || attlen == -1); /* align 'off', fetch the datum, and increment off beyond the datum */ values[attnum] = align_fetch_then_add(tp, @@ -1222,8 +1227,9 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, cattr = &cattrs[attnum]; attlen = cattr->attlen; - /* As above, we don't expect cstrings */ - pg_assume(attlen > 0 || attlen == -1); + /* As above, only emit cstring code when needed. */ + if (!support_cstring) + pg_assume(attlen > 0 || attlen == -1); /* align 'off', fetch the datum, and increment off beyond the datum */ values[attnum] = align_fetch_then_add(tp, [parent: 703fee3b25c4]