Inline hot path of slot_getsomeattrs().

This yields a minor speedup, which roughly balances the loss from the
upcoming introduction of callbacks to do some operations on slots.

Author: Andres Freund
Discussion: https://postgr.es/m/20181105210039.hh4vvi4vwoq5ba2q@alap3.anarazel.de
This commit is contained in:
Andres Freund 2018-11-16 10:25:34 -08:00
parent 3f2393edef
commit a7aa608e0f
7 changed files with 31 additions and 25 deletions

View File

@ -428,7 +428,6 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
{
CheckOpSlotCompatibility(op, innerslot);
/* XXX: worthwhile to check tts_nvalid inline first? */
slot_getsomeattrs(innerslot, op->d.fetch.last_var);
EEO_NEXT();

View File

@ -1183,22 +1183,19 @@ slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
}
/*
* slot_getsomeattrs
* This function forces the entries of the slot's Datum/isnull
* arrays to be valid at least up through the attnum'th entry.
* slot_getsomeattrs_int - workhorse for slot_getsomeattrs()
*/
void
slot_getsomeattrs(TupleTableSlot *slot, int attnum)
slot_getsomeattrs_int(TupleTableSlot *slot, int attnum)
{
HeapTuple tuple;
int attno;
/* Quick out if we have 'em all already */
if (slot->tts_nvalid >= attnum)
return;
/* Check for caller errors */
Assert(slot->tts_nvalid < attnum); /* slot_getsomeattr checked */
Assert(attnum > 0);
/* Check for caller error */
if (attnum <= 0 || attnum > slot->tts_tupleDescriptor->natts)
if (unlikely(attnum > slot->tts_tupleDescriptor->natts))
elog(ERROR, "invalid attribute number %d", attnum);
/*
@ -1209,9 +1206,7 @@ slot_getsomeattrs(TupleTableSlot *slot, int attnum)
if (tuple == NULL) /* internal error */
elog(ERROR, "cannot extract attribute from empty tuple slot");
/*
* load up any slots available from physical tuple
*/
/* Fetch as many attributes as possible from the underlying tuple. */
attno = HeapTupleHeaderGetNatts(tuple->t_data);
attno = Min(attno, attnum);
@ -1220,13 +1215,14 @@ slot_getsomeattrs(TupleTableSlot *slot, int attnum)
attno = slot->tts_nvalid;
/*
* If tuple doesn't have all the atts indicated by attnum, read the rest
* as NULLs or missing values
* If the underlying tuple doesn't have enough attributes, tuple descriptor
* must have the missing attributes.
*/
if (attno < attnum)
slot_getmissingattrs(slot, attno, attnum);
slot->tts_nvalid = attnum;
if (unlikely(slot->tts_nvalid < attnum))
{
slot_getmissingattrs(slot, slot->tts_nvalid, attnum);
slot->tts_nvalid = attnum;
}
}
/* ----------------------------------------------------------------

View File

@ -79,7 +79,7 @@ LLVMTypeRef StructAggStatePerTransData;
LLVMValueRef AttributeTemplate;
LLVMValueRef FuncStrlen;
LLVMValueRef FuncVarsizeAny;
LLVMValueRef FuncSlotGetsomeattrs;
LLVMValueRef FuncSlotGetsomeattrsInt;
LLVMValueRef FuncSlotGetmissingattrs;
LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
LLVMValueRef FuncExecEvalArrayRefSubscript;
@ -820,7 +820,7 @@ llvm_create_types(void)
AttributeTemplate = LLVMGetNamedFunction(mod, "AttributeTemplate");
FuncStrlen = LLVMGetNamedFunction(mod, "strlen");
FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any");
FuncSlotGetsomeattrs = LLVMGetNamedFunction(mod, "slot_getsomeattrs");
FuncSlotGetsomeattrsInt = LLVMGetNamedFunction(mod, "slot_getsomeattrs_int");
FuncSlotGetmissingattrs = LLVMGetNamedFunction(mod, "slot_getmissingattrs");
FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal");
FuncExecEvalArrayRefSubscript = LLVMGetNamedFunction(mod, "ExecEvalArrayRefSubscript");

View File

@ -345,7 +345,7 @@ llvm_compile_expr(ExprState *state)
params[1] = l_int32_const(op->d.fetch.last_var);
LLVMBuildCall(b,
llvm_get_decl(mod, FuncSlotGetsomeattrs),
llvm_get_decl(mod, FuncSlotGetsomeattrsInt),
params, lengthof(params), "");
}

View File

@ -97,7 +97,7 @@ void *referenced_functions[] =
{
strlen,
varsize_any,
slot_getsomeattrs,
slot_getsomeattrs_int,
slot_getmissingattrs,
MakeExpandedObjectReadOnlyInternal,
ExecEvalArrayRefSubscript,

View File

@ -219,7 +219,6 @@ extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum,
int lastAttNum);
extern Datum slot_getattr(TupleTableSlot *slot, int attnum,
bool *isnull);
extern void slot_getsomeattrs(TupleTableSlot *slot, int attnum);
/* in access/common/heaptuple.c */
extern bool slot_attisnull(TupleTableSlot *slot, int attnum);
@ -227,9 +226,21 @@ extern bool slot_getsysattr(TupleTableSlot *slot, int attnum,
Datum *value, bool *isnull);
extern Datum getmissingattr(TupleDesc tupleDesc,
int attnum, bool *isnull);
extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attnum);
#ifndef FRONTEND
/*
* This function forces the entries of the slot's Datum/isnull arrays to be
* valid at least up through the attnum'th entry.
*/
static inline void
slot_getsomeattrs(TupleTableSlot *slot, int attnum)
{
if (slot->tts_nvalid < attnum)
slot_getsomeattrs_int(slot, attnum);
}
/*
* slot_getallattrs
* This function forces all the entries of the slot's Datum/isnull

View File

@ -77,8 +77,8 @@ extern LLVMTypeRef StructAggStatePerGroupData;
extern LLVMValueRef AttributeTemplate;
extern LLVMValueRef FuncStrlen;
extern LLVMValueRef FuncVarsizeAny;
extern LLVMValueRef FuncSlotGetsomeattrs;
extern LLVMValueRef FuncSlotGetmissingattrs;
extern LLVMValueRef FuncSlotGetsomeattrsInt;
extern LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
extern LLVMValueRef FuncExecEvalArrayRefSubscript;
extern LLVMValueRef FuncExecEvalSysVar;