From d50183c5786a21910bac566d2987f955c7bc1d62 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 3 Jun 2016 18:34:05 -0400 Subject: [PATCH] Inline the easy cases in MakeExpandedObjectReadOnly(). This attempts to buy back some of whatever performance we lost from fixing bug #14174 by inlining the initial checks in MakeExpandedObjectReadOnly() into the callers. We can do that in a macro without creating multiple- evaluation hazards, so it's pretty much free notationally; and the amount of code added to callers should be minimal as well. (Testing a value can't take many more instructions than passing it to a subroutine.) Might as well inline DatumIsReadWriteExpandedObject() while we're at it. This is an ABI break for callers, so it doesn't seem safe to put into 9.5, but I see no reason not to do it in HEAD. --- src/backend/utils/adt/expandeddatum.c | 26 ++++---------------------- src/include/utils/expandeddatum.h | 12 ++++++++++-- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/backend/utils/adt/expandeddatum.c b/src/backend/utils/adt/expandeddatum.c index 6bb5675e08..bc30150dde 100644 --- a/src/backend/utils/adt/expandeddatum.c +++ b/src/backend/utils/adt/expandeddatum.c @@ -84,36 +84,18 @@ EOH_flatten_into(ExpandedObjectHeader *eohptr, (*eohptr->eoh_methods->flatten_into) (eohptr, result, allocated_size); } -/* - * Does the Datum represent a writable expanded object? - */ -bool -DatumIsReadWriteExpandedObject(Datum d, bool isnull, int16 typlen) -{ - /* Reject if it's NULL or not a varlena type */ - if (isnull || typlen != -1) - return false; - - /* Reject if not a read-write expanded-object pointer */ - if (!VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d))) - return false; - - return true; -} - /* * If the Datum represents a R/W expanded object, change it to R/O. * Otherwise return the original Datum. + * + * Caller must ensure that the datum is a non-null varlena value. Typically + * this is invoked via MakeExpandedObjectReadOnly(), which checks that. */ Datum -MakeExpandedObjectReadOnly(Datum d, bool isnull, int16 typlen) +MakeExpandedObjectReadOnlyInternal(Datum d) { ExpandedObjectHeader *eohptr; - /* Nothing to do if it's NULL or not a varlena type */ - if (isnull || typlen != -1) - return d; - /* Nothing to do if not a read-write expanded-object pointer */ if (!VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d))) return d; diff --git a/src/include/utils/expandeddatum.h b/src/include/utils/expandeddatum.h index 9c3b466731..47989a8cf2 100644 --- a/src/include/utils/expandeddatum.h +++ b/src/include/utils/expandeddatum.h @@ -136,6 +136,15 @@ struct ExpandedObjectHeader #define EOHPGetRWDatum(eohptr) PointerGetDatum((eohptr)->eoh_rw_ptr) #define EOHPGetRODatum(eohptr) PointerGetDatum((eohptr)->eoh_ro_ptr) +/* Does the Datum represent a writable expanded object? */ +#define DatumIsReadWriteExpandedObject(d, isnull, typlen) \ + (((isnull) || (typlen) != -1) ? false : \ + VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d))) + +#define MakeExpandedObjectReadOnly(d, isnull, typlen) \ + (((isnull) || (typlen) != -1) ? (d) : \ + MakeExpandedObjectReadOnlyInternal(d)) + extern ExpandedObjectHeader *DatumGetEOHP(Datum d); extern void EOH_init_header(ExpandedObjectHeader *eohptr, const ExpandedObjectMethods *methods, @@ -143,8 +152,7 @@ extern void EOH_init_header(ExpandedObjectHeader *eohptr, extern Size EOH_get_flat_size(ExpandedObjectHeader *eohptr); extern void EOH_flatten_into(ExpandedObjectHeader *eohptr, void *result, Size allocated_size); -extern bool DatumIsReadWriteExpandedObject(Datum d, bool isnull, int16 typlen); -extern Datum MakeExpandedObjectReadOnly(Datum d, bool isnull, int16 typlen); +extern Datum MakeExpandedObjectReadOnlyInternal(Datum d); extern Datum TransferExpandedObject(Datum d, MemoryContext new_parent); extern void DeleteExpandedObject(Datum d);