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,