From 5d6168601419ff044f197dfe5c1a2479f97496d1 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 18 Aug 2018 08:15:52 -0700
Subject: [PATCH 3/4] Fix JIT calls to ExecEvalSysVar().

The previous attempt at this called the function without initializing
the slot argument. Which unsurprisingly leads to crashes.

Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
 src/backend/jit/llvm/llvmjit_expr.c | 58 ++++++++++++++++++++++++++---
 1 file changed, 52 insertions(+), 6 deletions(-)

diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index 432f81e0dfb..5c878e45285 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -64,6 +64,9 @@ static void build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod,
 				const char *funcname,
 				LLVMValueRef v_state, LLVMValueRef v_econtext,
 				ExprEvalStep *op);
+static void build_ExecEvalSysVar(LLVMBuilderRef b, LLVMModuleRef mod,
+				LLVMValueRef v_state, LLVMValueRef v_econtext,
+				ExprEvalStep *op, LLVMValueRef v_slot);
 static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod);
 
 
@@ -403,14 +406,22 @@ llvm_compile_expr(ExprState *state)
 				}
 
 			case EEOP_INNER_SYSVAR:
+				build_ExecEvalSysVar(b, mod, v_state,
+									 v_econtext, op, v_innerslot);
+				LLVMBuildBr(b, opblocks[i + 1]);
+				break;
+
 			case EEOP_OUTER_SYSVAR:
+				build_ExecEvalSysVar(b, mod, v_state,
+									 v_econtext, op, v_outerslot);
+				LLVMBuildBr(b, opblocks[i + 1]);
+				break;
+
 			case EEOP_SCAN_SYSVAR:
-				{
-					build_EvalXFunc(b, mod, "ExecEvalSysVar",
-									v_state, v_econtext, op);
-					LLVMBuildBr(b, opblocks[i + 1]);
-					break;
-				}
+				build_ExecEvalSysVar(b, mod, v_state,
+										 v_econtext, op, v_scanslot);
+				LLVMBuildBr(b, opblocks[i + 1]);
+				break;
 
 			case EEOP_WHOLEROW:
 				build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
@@ -2634,6 +2645,41 @@ build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
 				  params, lengthof(params), "");
 }
 
+static void
+build_ExecEvalSysVar(LLVMBuilderRef b, LLVMModuleRef mod,
+					 LLVMValueRef v_state, LLVMValueRef v_econtext,
+					 ExprEvalStep *op, LLVMValueRef v_slot)
+{
+	LLVMTypeRef sig;
+	LLVMValueRef v_fn;
+	LLVMTypeRef param_types[4];
+	LLVMValueRef params[4];
+	const char *funcname = "ExecEvalSysVar";
+
+	v_fn = LLVMGetNamedFunction(mod, funcname);
+	if (!v_fn)
+	{
+		param_types[0] = l_ptr(StructExprState);
+		param_types[1] = l_ptr(StructExprEvalStep);
+		param_types[2] = l_ptr(StructExprContext);
+		param_types[3] = l_ptr(StructTupleTableSlot);
+
+		sig = LLVMFunctionType(LLVMVoidType(),
+							   param_types, lengthof(param_types),
+							   false);
+		v_fn = LLVMAddFunction(mod, funcname, sig);
+	}
+
+	params[0] = v_state;
+	params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
+	params[2] = v_econtext;
+	params[3] = v_slot;
+
+	LLVMBuildCall(b,
+				  v_fn,
+				  params, lengthof(params), "");
+}
+
 static LLVMValueRef
 create_LifetimeEnd(LLVMModuleRef mod)
 {
-- 
2.18.0.rc2.dirty

