Skip to content

Commit b84a6da

Browse files
committed
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
1 parent 517b0d0 commit b84a6da

File tree

6 files changed

+33
-73
lines changed

6 files changed

+33
-73
lines changed

src/backend/executor/execExprInterp.c

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -490,55 +490,19 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
490490

491491
EEO_CASE(EEOP_INNER_SYSVAR)
492492
{
493-
int attnum = op->d.var.attnum;
494-
Datum d;
495-
496-
/* these asserts must match defenses in slot_getattr */
497-
Assert(innerslot->tts_tuple != NULL);
498-
Assert(innerslot->tts_tuple != &(innerslot->tts_minhdr));
499-
500-
/* heap_getsysattr has sufficient defenses against bad attnums */
501-
d = heap_getsysattr(innerslot->tts_tuple, attnum,
502-
innerslot->tts_tupleDescriptor,
503-
op->resnull);
504-
*op->resvalue = d;
505-
493+
ExecEvalSysVar(state, op, econtext, innerslot);
506494
EEO_NEXT();
507495
}
508496

509497
EEO_CASE(EEOP_OUTER_SYSVAR)
510498
{
511-
int attnum = op->d.var.attnum;
512-
Datum d;
513-
514-
/* these asserts must match defenses in slot_getattr */
515-
Assert(outerslot->tts_tuple != NULL);
516-
Assert(outerslot->tts_tuple != &(outerslot->tts_minhdr));
517-
518-
/* heap_getsysattr has sufficient defenses against bad attnums */
519-
d = heap_getsysattr(outerslot->tts_tuple, attnum,
520-
outerslot->tts_tupleDescriptor,
521-
op->resnull);
522-
*op->resvalue = d;
523-
499+
ExecEvalSysVar(state, op, econtext, outerslot);
524500
EEO_NEXT();
525501
}
526502

527503
EEO_CASE(EEOP_SCAN_SYSVAR)
528504
{
529-
int attnum = op->d.var.attnum;
530-
Datum d;
531-
532-
/* these asserts must match defenses in slot_getattr */
533-
Assert(scanslot->tts_tuple != NULL);
534-
Assert(scanslot->tts_tuple != &(scanslot->tts_minhdr));
535-
536-
/* heap_getsysattr has sufficient defenses against bad attnums */
537-
d = heap_getsysattr(scanslot->tts_tuple, attnum,
538-
scanslot->tts_tupleDescriptor,
539-
op->resnull);
540-
*op->resvalue = d;
541-
505+
ExecEvalSysVar(state, op, econtext, scanslot);
542506
EEO_NEXT();
543507
}
544508

@@ -4006,6 +3970,22 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
40063970
*op->resnull = false;
40073971
}
40083972

3973+
void
3974+
ExecEvalSysVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
3975+
TupleTableSlot *slot)
3976+
{
3977+
bool success;
3978+
3979+
/* slot_getsysattr has sufficient defenses against bad attnums */
3980+
success = slot_getsysattr(slot,
3981+
op->d.var.attnum,
3982+
op->resvalue,
3983+
op->resnull);
3984+
/* this ought to be unreachable, but it's cheap enough to check */
3985+
if (unlikely(!success))
3986+
elog(ERROR, "failed to fetch attribute from slot");
3987+
}
3988+
40093989
/*
40103990
* Transition value has not been initialized. This is the first non-NULL input
40113991
* value for a group. We use it as the initial value for transValue.

src/backend/jit/llvm/llvmjit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ LLVMValueRef FuncStrlen;
8181
LLVMValueRef FuncVarsizeAny;
8282
LLVMValueRef FuncSlotGetsomeattrs;
8383
LLVMValueRef FuncSlotGetmissingattrs;
84-
LLVMValueRef FuncHeapGetsysattr;
8584
LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
8685
LLVMValueRef FuncExecEvalArrayRefSubscript;
86+
LLVMValueRef FuncExecEvalSysVar;
8787
LLVMValueRef FuncExecAggTransReparent;
8888
LLVMValueRef FuncExecAggInitGroup;
8989

@@ -822,9 +822,9 @@ llvm_create_types(void)
822822
FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any");
823823
FuncSlotGetsomeattrs = LLVMGetNamedFunction(mod, "slot_getsomeattrs");
824824
FuncSlotGetmissingattrs = LLVMGetNamedFunction(mod, "slot_getmissingattrs");
825-
FuncHeapGetsysattr = LLVMGetNamedFunction(mod, "heap_getsysattr");
826825
FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal");
827826
FuncExecEvalArrayRefSubscript = LLVMGetNamedFunction(mod, "ExecEvalArrayRefSubscript");
827+
FuncExecEvalSysVar = LLVMGetNamedFunction(mod, "ExecEvalSysVar");
828828
FuncExecAggTransReparent = LLVMGetNamedFunction(mod, "ExecAggTransReparent");
829829
FuncExecAggInitGroup = LLVMGetNamedFunction(mod, "ExecAggInitGroup");
830830

src/backend/jit/llvm/llvmjit_expr.c

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,8 @@ llvm_compile_expr(ExprState *state)
406406
case EEOP_OUTER_SYSVAR:
407407
case EEOP_SCAN_SYSVAR:
408408
{
409-
int attnum = op->d.var.attnum;
410-
LLVMValueRef v_attnum;
411-
LLVMValueRef v_tuple;
412-
LLVMValueRef v_tupleDescriptor;
413-
LLVMValueRef v_params[4];
414-
LLVMValueRef v_syscol;
415409
LLVMValueRef v_slot;
410+
LLVMValueRef v_params[4];
416411

417412
if (opcode == EEOP_INNER_SYSVAR)
418413
v_slot = v_innerslot;
@@ -421,31 +416,14 @@ llvm_compile_expr(ExprState *state)
421416
else
422417
v_slot = v_scanslot;
423418

424-
Assert(op->d.var.attnum < 0);
425-
426-
v_tuple = l_load_struct_gep(b, v_slot,
427-
FIELDNO_TUPLETABLESLOT_TUPLE,
428-
"v.tuple");
419+
v_params[0] = v_state;
420+
v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
421+
v_params[2] = v_econtext;
422+
v_params[3] = v_slot;
429423

430-
/*
431-
* Could optimize this a bit for fixed descriptors, but
432-
* this shouldn't be that critical a path.
433-
*/
434-
v_tupleDescriptor =
435-
l_load_struct_gep(b, v_slot,
436-
FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR,
437-
"v.tupledesc");
438-
v_attnum = l_int32_const(attnum);
439-
440-
v_params[0] = v_tuple;
441-
v_params[1] = v_attnum;
442-
v_params[2] = v_tupleDescriptor;
443-
v_params[3] = v_resnullp;
444-
v_syscol = LLVMBuildCall(b,
445-
llvm_get_decl(mod, FuncHeapGetsysattr),
446-
v_params, lengthof(v_params),
447-
"");
448-
LLVMBuildStore(b, v_syscol, v_resvaluep);
424+
LLVMBuildCall(b,
425+
FuncExecEvalSysVar,
426+
v_params, lengthof(v_params), "");
449427

450428
LLVMBuildBr(b, opblocks[i + 1]);
451429
break;

src/backend/jit/llvm/llvmjit_types.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ void *referenced_functions[] =
9999
varsize_any,
100100
slot_getsomeattrs,
101101
slot_getmissingattrs,
102-
heap_getsysattr,
103102
MakeExpandedObjectReadOnlyInternal,
104103
ExecEvalArrayRefSubscript,
104+
ExecEvalSysVar,
105105
ExecAggTransReparent,
106106
ExecAggInitGroup
107107
};

src/include/executor/execExpr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ extern void ExecEvalAlternativeSubPlan(ExprState *state, ExprEvalStep *op,
734734
ExprContext *econtext);
735735
extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op,
736736
ExprContext *econtext);
737+
extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op,
738+
ExprContext *econtext, TupleTableSlot *slot);
737739

738740
extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup);
739741
extern Datum ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans,

src/include/jit/llvmjit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ extern LLVMValueRef FuncStrlen;
7979
extern LLVMValueRef FuncVarsizeAny;
8080
extern LLVMValueRef FuncSlotGetsomeattrs;
8181
extern LLVMValueRef FuncSlotGetmissingattrs;
82-
extern LLVMValueRef FuncHeapGetsysattr;
8382
extern LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
8483
extern LLVMValueRef FuncExecEvalArrayRefSubscript;
84+
extern LLVMValueRef FuncExecEvalSysVar;
8585
extern LLVMValueRef FuncExecAggTransReparent;
8686
extern LLVMValueRef FuncExecAggInitGroup;
8787

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy