diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 4cf0883435..ba129948ef 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -3,26 +3,26 @@
  * execExpr.c
  *	  Expression evaluation infrastructure.
  *
- *	Expression evaluation now works by first converting expression trees
+ *	Expression evaluation works by first converting the expression tree
  *	(which went through planning first) into an ExprState using ExecInitExpr()
  *	et al. This converts the tree into a opcode based program (ExprEvalStep
- *	representing individual instructions); allocated as a flat array of
+ *	representing individual instructions), allocated as a flat array of
  *	steps.
  *
  *	This flat representation has the big advantage that it can be implemented
  *	non-recursively, within a single function.  This allows to interpret
  *	larger expressions from largely within a single function, keeping state
- *	between them.  In contrast to that, tree-walk based approaches in contrast
+ *	between them.  In contrast to that, tree-walk based approaches
  *	often run into performance issues due to function call / stack
  *	manipulation overhead.
  *
  *	The ExprEvalStep representation is designed to be usable for interpreting
- *	the expression, as well as compiling into native code. Thus, if possible,
- *	as much complexity as possible should be handed by ExecInitExpr() (and
- *	helpers), instead of handled at execution time where both interpreted and
+ *	the expression, as well as compiling into native code. As much complexity
+ *	as possible should be handled by ExecInitExpr() (and
+ *	helpers), instead of execution time where both interpreted and
  *	compiled versions would need to deal with the complexity. Additionally
  *	checks for initialization at run time have a small but noticeable cost at
- *	every execution.
+ *	every execution. (HEIKKI: What does this last sentence refer to?)
  *
  *	The next step is preparing the ExprState for execution, using
  *	ExecInstantiateExpr(). This is internally done by ExecInitExpr() and other
diff --git a/src/backend/executor/execInterpExpr.c b/src/backend/executor/execInterpExpr.c
index 21388f4086..2386fc898f 100644
--- a/src/backend/executor/execInterpExpr.c
+++ b/src/backend/executor/execInterpExpr.c
@@ -1,3 +1,7 @@
+/*
+ * HEIKKI: "Interp" is quite a mouthful. How about execExprInterpreter.c or
+ * just exprInterpreter.c?
+ */
 /*-------------------------------------------------------------------------
  *
  * execInterpExpr.c
@@ -5,19 +9,19 @@
  *
  * This file provides a "switch threaded" (all compilers) and "direct
  * threaded" (gcc, clang and compatible) implementation of expression
- * evaluation.  The former is among st the fastest known methods of
+ * evaluation.  The former is amongst the fastest known methods of
  * interpreting programs without resorting to assembly level work, or
  * just-in-time compilation, but requires support for computed gotos.  The
  * latter is amongst the fastest approaches doable in standard C.
  *
  * Both work by using ExprEvalStep->opcode to dispatch into code blocks
- * implementing the specific method.  Switch based uses a plain switch()
+ * implementing the specific method.  Switch-based uses a plain switch()
  * statement to perform the dispatch. This has the advantages of being plain C
  * and allowing to warn if implementation of a specific opcode has been
  * forgotten.  The disadvantage is that dispatches will, as commonly
  * implemented by compilers, happen from a single location, causing bad branch
  * prediction.  Direct dispatch uses the label-as-values gcc extension - also
- * adopted by some other compilers - to replace ExprEvalStep-> opcode with the
+ * adopted by some other compilers - to replace ExprEvalStep->opcode with the
  * address of the block implementing the instruction. This allows for better
  * branch prediction (the jumps are happening from different locations) and
  * fewer jumps (no jumps to common dispatch location needed).
@@ -84,26 +88,31 @@
  */
 #if defined(EEO_USE_COMPUTED_GOTO)
 static void **dispatch_table = NULL;
-#define EEO_SWITCH(d)
-#define EEO_DISPATCH_DIRECT(op) goto *((void *) op->opcode)
+#define EEO_DISPATCH() goto *((void *) op->opcode)
 #define EEO_CASE(name) CASE_##name:
 #else
-#define EEO_SWITCH(d) switch ((ExprEvalOp) d)
-#define EEO_DISPATCH_DIRECT(op) goto starteval
+#define EEO_DISPATCH() goto starteval
 #define EEO_CASE(name) case name:
 #endif   /* EEO_USE_COMPUTED_GOTO */
 
-#define EEO_DISPATCH(op) \
+#define EEO_JUMP(stepno) \
+	do \
+	{ \
+		op = &state->steps[stepno]; \
+		EEO_DISPATCH(); \
+	} while (0)
+
+#define EEO_NEXT() \
 	do \
 	{ \
 		op++; \
-		EEO_DISPATCH_DIRECT(op); \
+		EEO_DISPATCH(); \
 	} \
 	while (0)
 
 
 static Datum ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull);
-static void ExecPrepareInterp(void);
+static void ExecInitInterpreter(void);
 
 /* support functions */
 static void ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op, bool checkisnull);
@@ -127,10 +136,11 @@ static Datum ExecJustAssignScanVar(ExprState *state, ExprContext *econtext, bool
 void
 ExecInstantiateInterpretedExpr(ExprState *state)
 {
-	ExecPrepareInterp();
+	ExecInitInterpreter();
 
 	Assert(state->steps_len >= 1);
-	Assert(ExecEvalStepOp(state, &state->steps[state->steps_len - 1]) == EEO_DONE);
+	Assert(state->steps[state->steps_len - 1].opcode ==  EEO_DONE);
+	Assert(state->flags & EEO_FLAG_JUMP_THREADED == 0);
 
 	/*
 	 * Fast-path for very simple expressions. "starting up" the full
@@ -141,8 +151,8 @@ ExecInstantiateInterpretedExpr(ExprState *state)
 	 */
 	if (state->steps_len == 3)
 	{
-		ExprEvalOp	step0 = ExecEvalStepOp(state, &state->steps[0]);
-		ExprEvalOp	step1 = ExecEvalStepOp(state, &state->steps[1]);
+		ExprEvalOp	step0 = state->steps[0].opcode;
+		ExprEvalOp	step1 = state->steps[1].opcode;
 
 		if (step0 == EEO_INNER_FETCHSOME && step1 == EEO_INNER_VAR)
 		{
@@ -176,7 +186,7 @@ ExecInstantiateInterpretedExpr(ExprState *state)
 		}
 	}
 	else if (state->steps_len == 2 &&
-			 ExecEvalStepOp(state, &state->steps[0]) == EEO_CONST)
+			 state->steps[0].opcode == EEO_CONST)
 	{
 		state->evalfunc = ExecJustConst;
 		return;
@@ -319,11 +329,11 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
 	scanslot = econtext->ecxt_scantuple;
 
 #if defined(EEO_USE_COMPUTED_GOTO)
-	EEO_DISPATCH_DIRECT(op);
+	EEO_DISPATCH();
 #else
 starteval:
+	switch ((ExprEvalOp) op->opcode)
 #endif
-	EEO_SWITCH(op->opcode)
 	{
 		EEO_CASE(EEO_DONE)
 		{
@@ -335,21 +345,21 @@ starteval:
 			/* XXX: worthwhile to check tts_nvalid inline first? */
 			slot_getsomeattrs(innerslot, op->d.fetch.last_var);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_OUTER_FETCHSOME)
 		{
 			slot_getsomeattrs(outerslot, op->d.fetch.last_var);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_SCAN_FETCHSOME)
 		{
 			slot_getsomeattrs(scanslot, op->d.fetch.last_var);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_INNER_VAR)
@@ -365,7 +375,7 @@ starteval:
 			*op->resnull = innerslot->tts_isnull[attnum];
 			*op->resvalue = innerslot->tts_values[attnum];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_OUTER_VAR)
@@ -377,7 +387,7 @@ starteval:
 			*op->resnull = outerslot->tts_isnull[attnum];
 			*op->resvalue = outerslot->tts_values[attnum];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_SCAN_VAR)
@@ -389,7 +399,7 @@ starteval:
 			*op->resnull = scanslot->tts_isnull[attnum];
 			*op->resvalue = scanslot->tts_values[attnum];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ASSIGN_INNER_VAR)
@@ -400,7 +410,7 @@ starteval:
 			resultslot->tts_values[resultnum] = innerslot->tts_values[attnum];
 			resultslot->tts_isnull[resultnum] = innerslot->tts_isnull[attnum];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ASSIGN_OUTER_VAR)
@@ -411,7 +421,7 @@ starteval:
 			resultslot->tts_values[resultnum] = outerslot->tts_values[attnum];
 			resultslot->tts_isnull[resultnum] = outerslot->tts_isnull[attnum];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ASSIGN_SCAN_VAR)
@@ -422,7 +432,7 @@ starteval:
 			resultslot->tts_values[resultnum] = scanslot->tts_values[attnum];
 			resultslot->tts_isnull[resultnum] = scanslot->tts_isnull[attnum];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ASSIGN_TMP)
@@ -432,7 +442,7 @@ starteval:
 			resultslot->tts_values[resultnum] = state->resvalue;
 			resultslot->tts_isnull[resultnum] = state->resnull;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ASSIGN_TMP_UNEXPAND)
@@ -447,7 +457,7 @@ starteval:
 			else
 				resultslot->tts_values[resultnum] = state->resvalue;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_INNER_SYSVAR)
@@ -459,7 +469,7 @@ starteval:
 											innerslot->tts_tupleDescriptor,
 											op->resnull);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_OUTER_SYSVAR)
@@ -471,7 +481,7 @@ starteval:
 											scanslot->tts_tupleDescriptor,
 											op->resnull);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_SCAN_SYSVAR)
@@ -483,7 +493,7 @@ starteval:
 											scanslot->tts_tupleDescriptor,
 											op->resnull);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_CONST)
@@ -491,7 +501,7 @@ starteval:
 			*op->resnull = op->d.constval.isnull;
 			*op->resvalue = op->d.constval.value;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -510,7 +520,7 @@ starteval:
 			*op->resvalue = (op->d.func.fn_addr) (fcinfo);
 			*op->resnull = fcinfo->isnull;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_FUNCEXPR_STRICT)
@@ -533,7 +543,7 @@ starteval:
 			*op->resnull = fcinfo->isnull;
 
 	strictfail:
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_FUNCEXPR_FUSAGE)
@@ -549,7 +559,7 @@ starteval:
 
 			pgstat_end_function_usage(&fcusage, true);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_FUNCEXPR_STRICT_FUSAGE)
@@ -577,7 +587,7 @@ starteval:
 	strictfail_fusage:
 			pgstat_end_function_usage(&fcusage, true);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -608,12 +618,10 @@ starteval:
 				*op->resnull = false;
 				*op->resvalue = BoolGetDatum(false);
 				/* bail out early */
-				op = &state->steps[op->d.boolexpr.jumpdone];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.boolexpr.jumpdone);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_BOOL_AND_STEP_LAST)
@@ -645,7 +653,7 @@ starteval:
 				*op->resvalue = BoolGetDatum(true);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -683,12 +691,10 @@ starteval:
 				*op->resvalue = BoolGetDatum(true);
 
 				/* bail out early */
-				op = &state->steps[op->d.boolexpr.jumpdone];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.boolexpr.jumpdone);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_BOOL_OR_STEP_LAST)
@@ -720,7 +726,7 @@ starteval:
 				*op->resvalue = BoolGetDatum(false);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_BOOL_NOT_STEP)
@@ -737,7 +743,7 @@ starteval:
 			 */
 			*op->resvalue = BoolGetDatum(!DatumGetBool(*op->d.boolexpr.value));
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_QUAL)
@@ -750,12 +756,10 @@ starteval:
 				/* bail out early */
 				*op->resnull = false;
 				*op->resvalue = BoolGetDatum(false);
-				op = &state->steps[op->d.qualexpr.jumpdone];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.qualexpr.jumpdone);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_NULLTEST_ISNULL)
@@ -763,7 +767,7 @@ starteval:
 			*op->resvalue = BoolGetDatum(*op->resnull);
 			*op->resnull = false;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_NULLTEST_ISNOTNULL)
@@ -771,7 +775,7 @@ starteval:
 			*op->resvalue = BoolGetDatum(!*op->resnull);
 			*op->resnull = false;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_NULLTEST_ROWISNULL)
@@ -779,7 +783,7 @@ starteval:
 			/* out of line implementation: too large */
 			ExecEvalRowNull(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_NULLTEST_ROWISNOTNULL)
@@ -787,7 +791,7 @@ starteval:
 			/* out of line implementation: too large */
 			ExecEvalRowNotNull(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_PARAM_EXEC)
@@ -795,14 +799,14 @@ starteval:
 			/* out of line implementation: too large */
 			ExecEvalParamExec(state, op, econtext);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_PARAM_EXTERN)
 		{
 			/* out of line implementation: too large */
 			ExecEvalParamExtern(state, op, econtext);
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_CASE_WHEN_STEP)
@@ -810,22 +814,18 @@ starteval:
 			if (!*op->d.casewhen.isnull
 				&& DatumGetBool(*op->d.casewhen.value))
 			{
-				EEO_DISPATCH(op);
+				EEO_NEXT();
 			}
 			else
 			{
-				op = &state->steps[op->d.casewhen.jumpfalse];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.casewhen.jumpfalse);
 			}
 		}
 
 		EEO_CASE(EEO_CASE_THEN_STEP)
 		{
 			/* results already placed in correct place during preceding steps */
-			op = &state->steps[op->d.casethen.jumpdone];
-
-			EEO_DISPATCH_DIRECT(op);
+			EEO_JUMP(op->d.casethen.jumpdone);
 		}
 
 		EEO_CASE(EEO_CASE_TESTVAL)
@@ -850,7 +850,7 @@ starteval:
 				*op->resnull = econtext->caseValue_isNull;
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_CASE_TESTVAL_UNEXPAND)
@@ -876,7 +876,7 @@ starteval:
 					MakeExpandedObjectReadOnlyInternal(*op->resvalue);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_DOMAIN_TESTVAL)
@@ -895,7 +895,7 @@ starteval:
 				*op->resnull = econtext->domainValue_isNull;
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_DOMAIN_TESTVAL_UNEXPAND)
@@ -924,7 +924,7 @@ starteval:
 					MakeExpandedObjectReadOnlyInternal(*op->resvalue);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -935,12 +935,10 @@ starteval:
 		{
 			if (!*op->resnull)
 			{
-				op = &state->steps[op->d.coalesce.jumpdone];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.coalesce.jumpdone);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/* BooleanTest implementations for all booltesttypes */
@@ -952,7 +950,7 @@ starteval:
 				*op->resvalue = *op->resvalue;
 			*op->resnull = false;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_BOOLTEST_IS_NOT_FALSE)
@@ -963,7 +961,7 @@ starteval:
 				*op->resvalue = *op->resvalue;
 			*op->resnull = false;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_BOOLTEST_IS_FALSE)
@@ -974,7 +972,7 @@ starteval:
 				*op->resvalue = BoolGetDatum(!DatumGetBool(*op->resvalue));
 			*op->resnull = false;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_BOOLTEST_IS_NOT_TRUE)
@@ -985,7 +983,7 @@ starteval:
 				*op->resvalue = BoolGetDatum(!DatumGetBool(*op->resvalue));
 			*op->resnull = false;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_BOOLTEST_IS_UNKNOWN)
@@ -993,7 +991,7 @@ starteval:
 			*op->resvalue = BoolGetDatum(*op->resnull);
 			*op->resnull = false;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_BOOLTEST_IS_NOT_UNKNOWN)
@@ -1001,7 +999,7 @@ starteval:
 			*op->resvalue = BoolGetDatum(!*op->resnull);
 			*op->resnull = false;
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_WHOLEROW)
@@ -1009,7 +1007,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalWholeRowVar(state, op, econtext);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -1068,7 +1066,7 @@ starteval:
 
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -1106,7 +1104,7 @@ starteval:
 				*op->resnull = fcinfo->isnull;
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_NULLIF)
@@ -1127,13 +1125,13 @@ starteval:
 					*op->resnull = true;
 					*op->resvalue = true;
 
-					EEO_DISPATCH(op);
+					EEO_NEXT();
 				}
 			}
 			*op->resnull = fcinfo->argnull[0];
 			*op->resvalue = fcinfo->arg[0];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_SQLVALUEFUNCTION)
@@ -1144,7 +1142,7 @@ starteval:
 			 */
 			ExecEvalSQLValueFunction(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_CURRENTOFEXPR)
@@ -1152,7 +1150,7 @@ starteval:
 			/* error invocation uses space, and shouldn't ever occur */
 			ExecEvalCurrentOfExpr(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ARRAYEXPR)
@@ -1160,7 +1158,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalArrayExpr(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ARRAYCOERCE)
@@ -1168,7 +1166,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalArrayCoerce(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ROW)
@@ -1176,7 +1174,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalRow(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ROWCOMPARE_STEP)
@@ -1188,9 +1186,7 @@ starteval:
 				(fcinfo->argnull[0] || fcinfo->argnull[1]))
 			{
 				*op->resnull = true;
-				op = &state->steps[op->d.rowcompare_step.jumpnull];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.rowcompare_step.jumpnull);
 			}
 
 			fcinfo->isnull = false;
@@ -1200,20 +1196,16 @@ starteval:
 			if (fcinfo->isnull)
 			{
 				*op->resnull = true;
-				op = &state->steps[op->d.rowcompare_step.jumpnull];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.rowcompare_step.jumpnull);
 			}
 
 			/* no need to compare remaining columns */
 			if (DatumGetInt32(*op->resvalue) != 0)
 			{
-				op = &state->steps[op->d.rowcompare_step.jumpdone];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.rowcompare_step.jumpdone);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ROWCOMPARE_FINAL)
@@ -1242,7 +1234,7 @@ starteval:
 					break;
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_MINMAX)
@@ -1250,7 +1242,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalMinMax(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_FIELDSELECT)
@@ -1258,7 +1250,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalFieldSelect(state, op, econtext);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_FIELDSTORE_DEFORM)
@@ -1266,7 +1258,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalFieldStoreDeForm(state, op, econtext);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_FIELDSTORE_FORM)
@@ -1274,7 +1266,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalFieldStoreForm(state, op, econtext);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -1291,12 +1283,10 @@ starteval:
 			if (*op->resnull &&
 				!op->d.arrayref.state->isassignment)
 			{
-				op = &state->steps[op->d.arrayref.jumpdone];
-
-				EEO_DISPATCH_DIRECT(op);
+				EEO_JUMP(op->d.arrayref.jumpdone);
 			}
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -1307,14 +1297,12 @@ starteval:
 			/* too complex for an inline implementation */
 			if (ExecEvalArrayRefCheckSubscript(state, op))
 			{
-				op++;
+				EEO_NEXT();
 			}
 			else
 			{
-				op = &state->steps[op->d.arrayref_checksubscript.jumpdone];
+				EEO_JUMP(op->d.arrayref_checksubscript.jumpdone);
 			}
-
-			EEO_DISPATCH_DIRECT(op);
 		}
 
 		/*
@@ -1326,7 +1314,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalArrayRefOld(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -1337,7 +1325,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalArrayRefAssign(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -1348,7 +1336,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalArrayRefFetch(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_CONVERT_ROWTYPE)
@@ -1356,7 +1344,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalConvertRowtype(state, op, econtext);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_SCALARARRAYOP)
@@ -1364,14 +1352,14 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalScalarArrayOp(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_DOMAIN_NOTNULL)
 		{
 			/* too complex for an inline implementation */
 			ExecEvalConstraintNotNull(state, op);
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_DOMAIN_CHECK)
@@ -1379,7 +1367,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalConstraintCheck(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_XMLEXPR)
@@ -1387,7 +1375,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalXmlExpr(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		/*
@@ -1403,7 +1391,7 @@ starteval:
 			*op->resnull = econtext->ecxt_aggnulls[aggref->aggno];
 			*op->resvalue = econtext->ecxt_aggvalues[aggref->aggno];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_GROUPING_FUNC)
@@ -1411,7 +1399,7 @@ starteval:
 			/* too complex/uncommon for an inline implementation */
 			ExecEvalGroupingFunc(state, op);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_WINDOW_FUNC)
@@ -1423,7 +1411,7 @@ starteval:
 			*op->resnull = econtext->ecxt_aggnulls[wfunc->wfuncno];
 			*op->resvalue = econtext->ecxt_aggvalues[wfunc->wfuncno];
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_SUBPLAN)
@@ -1431,7 +1419,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalSubPlan(state, op, econtext);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_ALTERNATIVE_SUBPLAN)
@@ -1439,7 +1427,7 @@ starteval:
 			/* too complex for an inline implementation */
 			ExecEvalAlternativeSubPlan(state, op, econtext);
 
-			EEO_DISPATCH(op);
+			EEO_NEXT();
 		}
 
 		EEO_CASE(EEO_LAST)
@@ -1454,6 +1442,8 @@ out:
 	return state->resvalue;
 }
 
+/* Fast-path functions, for very simple expressions */
+
 static Datum
 ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull)
 {
@@ -1536,7 +1526,7 @@ ExecJustAssignScanVar(ExprState *state, ExprContext *econtext, bool *isnull)
 }
 
 static void
-ExecPrepareInterp(void)
+ExecInitInterpreter(void)
 {
 	static bool prepared = false;
 
@@ -1551,27 +1541,6 @@ ExecPrepareInterp(void)
 	prepared = true;
 }
 
-ExprEvalOp
-ExecEvalStepOp(ExprState *state, ExprEvalStep *op)
-{
-#if defined(EEO_USE_COMPUTED_GOTO)
-	if (state->flags & EEO_FLAG_JUMP_THREADED)
-	{
-		int			i;
-
-		for (i = 0; i < EEO_LAST; i++)
-		{
-			if ((void *) op->opcode == dispatch_table[i])
-			{
-				return (ExprEvalOp) i;
-			}
-		}
-		elog(ERROR, "unknown opcode");
-	}
-#endif
-	return (ExprEvalOp) op->opcode;
-}
-
 /*
  * Computes the value for a PARAM_EXEC parameter.
  */
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index 003f4faede..e28bb2a85e 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -22,6 +22,11 @@ struct ArrayRefState;
 
 typedef enum ExprEvalOp
 {
+	/*
+	 * HEIKKI: How about renaming these to EEOP_* ? I think it'd be a
+	 * good mnemonic to remember that these are opcodes, and just one
+	 * extra letter.
+	 */
 	EEO_DONE,
 	EEO_INNER_FETCHSOME,
 	EEO_OUTER_FETCHSOME,
@@ -110,6 +115,11 @@ typedef struct ExprEvalStep
 	 * ExprEvalOp, but during execution it can be swapped out to some other
 	 * type, e.g. a pointer for computed goto (that's why it's a size_t).
 	 */
+	/* HEIKKI: Is it safe to assume that sizeof(size_t) >= sizeof(void *) ? */
+	/* HEIKKI: How tight are we with space in this union? It'd be nice to keep
+	 * the original opcode, and have a separate field for the computed goto ptr.
+	 * For debugging purposes if nothing else.
+	 */
 	size_t		opcode;
 
 	/* target for the result of the current instruction */
@@ -419,8 +429,6 @@ typedef struct ArrayRefState
 
 extern void ExecInstantiateInterpretedExpr(ExprState *state);
 
-extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op);
-
 /*
  * Non fast-path execution functions. These are externs instead of static in
  * execInterpExpr.c, because that allows them to be used by other methods of
