1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-17 06:41:09 +03:00

Move EEOP_*_SYSVAR evaluation out of line.

This mainly de-duplicates code. As evaluating a system variable isn't
the hottest path and the current inline implementation ends up calling
out to an external function anyway, this is OK from a performance POV.

The main motivation for de-duplicating is the upcoming slot
abstraction work, after which there's not guaranteed to be a HeapTuple
backing the slot.

Author: Andres Freund, Amit Khandekar
Discussion: https://postgr.es/m/20181105210039.hh4vvi4vwoq5ba2q@alap3.anarazel.de
This commit is contained in:
Andres Freund
2018-11-07 11:08:45 -08:00
parent 517b0d0b5f
commit b84a6dafbf
6 changed files with 33 additions and 73 deletions

View File

@ -490,55 +490,19 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_CASE(EEOP_INNER_SYSVAR)
{
int attnum = op->d.var.attnum;
Datum d;
/* these asserts must match defenses in slot_getattr */
Assert(innerslot->tts_tuple != NULL);
Assert(innerslot->tts_tuple != &(innerslot->tts_minhdr));
/* heap_getsysattr has sufficient defenses against bad attnums */
d = heap_getsysattr(innerslot->tts_tuple, attnum,
innerslot->tts_tupleDescriptor,
op->resnull);
*op->resvalue = d;
ExecEvalSysVar(state, op, econtext, innerslot);
EEO_NEXT();
}
EEO_CASE(EEOP_OUTER_SYSVAR)
{
int attnum = op->d.var.attnum;
Datum d;
/* these asserts must match defenses in slot_getattr */
Assert(outerslot->tts_tuple != NULL);
Assert(outerslot->tts_tuple != &(outerslot->tts_minhdr));
/* heap_getsysattr has sufficient defenses against bad attnums */
d = heap_getsysattr(outerslot->tts_tuple, attnum,
outerslot->tts_tupleDescriptor,
op->resnull);
*op->resvalue = d;
ExecEvalSysVar(state, op, econtext, outerslot);
EEO_NEXT();
}
EEO_CASE(EEOP_SCAN_SYSVAR)
{
int attnum = op->d.var.attnum;
Datum d;
/* these asserts must match defenses in slot_getattr */
Assert(scanslot->tts_tuple != NULL);
Assert(scanslot->tts_tuple != &(scanslot->tts_minhdr));
/* heap_getsysattr has sufficient defenses against bad attnums */
d = heap_getsysattr(scanslot->tts_tuple, attnum,
scanslot->tts_tupleDescriptor,
op->resnull);
*op->resvalue = d;
ExecEvalSysVar(state, op, econtext, scanslot);
EEO_NEXT();
}
@ -4006,6 +3970,22 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
*op->resnull = false;
}
void
ExecEvalSysVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
TupleTableSlot *slot)
{
bool success;
/* slot_getsysattr has sufficient defenses against bad attnums */
success = slot_getsysattr(slot,
op->d.var.attnum,
op->resvalue,
op->resnull);
/* this ought to be unreachable, but it's cheap enough to check */
if (unlikely(!success))
elog(ERROR, "failed to fetch attribute from slot");
}
/*
* Transition value has not been initialized. This is the first non-NULL input
* value for a group. We use it as the initial value for transValue.