aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/executor/execExpr.h23
-rw-r--r--src/include/executor/executor.h1
-rw-r--r--src/include/nodes/execnodes.h21
-rw-r--r--src/include/nodes/params.h84
4 files changed, 100 insertions, 29 deletions
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index 5bbb63a9d80..080252fad60 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -16,7 +16,8 @@
#include "nodes/execnodes.h"
-/* forward reference to avoid circularity */
+/* forward references to avoid circularity */
+struct ExprEvalStep;
struct ArrayRefState;
/* Bits in ExprState->flags (see also execnodes.h for public flag bits): */
@@ -25,6 +26,11 @@ struct ArrayRefState;
/* jump-threading is in use */
#define EEO_FLAG_DIRECT_THREADED (1 << 2)
+/* Typical API for out-of-line evaluation subroutines */
+typedef void (*ExecEvalSubroutine) (ExprState *state,
+ struct ExprEvalStep *op,
+ ExprContext *econtext);
+
/*
* Discriminator for ExprEvalSteps.
*
@@ -131,6 +137,7 @@ typedef enum ExprEvalOp
/* evaluate PARAM_EXEC/EXTERN parameters */
EEOP_PARAM_EXEC,
EEOP_PARAM_EXTERN,
+ EEOP_PARAM_CALLBACK,
/* return CaseTestExpr value */
EEOP_CASE_TESTVAL,
@@ -331,6 +338,15 @@ typedef struct ExprEvalStep
Oid paramtype; /* OID of parameter's datatype */
} param;
+ /* for EEOP_PARAM_CALLBACK */
+ struct
+ {
+ ExecEvalSubroutine paramfunc; /* add-on evaluation subroutine */
+ void *paramarg; /* private data for same */
+ int paramid; /* numeric ID for parameter */
+ Oid paramtype; /* OID of parameter's datatype */
+ } cparam;
+
/* for EEOP_CASE_TESTVAL/DOMAIN_TESTVAL */
struct
{
@@ -598,8 +614,11 @@ typedef struct ArrayRefState
} ArrayRefState;
-extern void ExecReadyInterpretedExpr(ExprState *state);
+/* functions in execExpr.c */
+extern void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s);
+/* functions in execExprInterp.c */
+extern void ExecReadyInterpretedExpr(ExprState *state);
extern ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op);
/*
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index dea9216fd62..2cc74da0ba3 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -247,6 +247,7 @@ ExecProcNode(PlanState *node)
* prototypes from functions in execExpr.c
*/
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
+extern ExprState *ExecInitExprWithParams(Expr *node, ParamListInfo ext_params);
extern ExprState *ExecInitQual(List *qual, PlanState *parent);
extern ExprState *ExecInitCheck(List *qual, PlanState *parent);
extern List *ExecInitExprList(List *nodes, PlanState *parent);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 44d8c47d2c2..c9a5279dc58 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -33,6 +33,13 @@
#include "storage/condition_variable.h"
+struct PlanState; /* forward references in this file */
+struct ParallelHashJoinState;
+struct ExprState;
+struct ExprContext;
+struct ExprEvalStep; /* avoid including execExpr.h everywhere */
+
+
/* ----------------
* ExprState node
*
@@ -40,12 +47,6 @@
* It contains instructions (in ->steps) to evaluate the expression.
* ----------------
*/
-struct ExprState; /* forward references in this file */
-struct ExprContext;
-struct ExprEvalStep; /* avoid including execExpr.h everywhere */
-
-struct ParallelHashJoinState;
-
typedef Datum (*ExprStateEvalFunc) (struct ExprState *expression,
struct ExprContext *econtext,
bool *isNull);
@@ -87,12 +88,16 @@ typedef struct ExprState
Expr *expr;
/*
- * XXX: following only needed during "compilation", could be thrown away.
+ * XXX: following fields only needed during "compilation" (ExecInitExpr);
+ * could be thrown away afterwards.
*/
int steps_len; /* number of steps currently */
int steps_alloc; /* allocated length of steps array */
+ struct PlanState *parent; /* parent PlanState node, if any */
+ ParamListInfo ext_params; /* for compiling PARAM_EXTERN nodes */
+
Datum *innermost_caseval;
bool *innermost_casenull;
@@ -827,8 +832,6 @@ typedef struct DomainConstraintState
* ----------------------------------------------------------------
*/
-struct PlanState;
-
/* ----------------
* ExecProcNodeMtd
*
diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h
index 55219dab6e7..b198db5ee49 100644
--- a/src/include/nodes/params.h
+++ b/src/include/nodes/params.h
@@ -16,16 +16,23 @@
/* Forward declarations, to avoid including other headers */
struct Bitmapset;
+struct ExprState;
+struct Param;
struct ParseState;
-/* ----------------
+/*
* ParamListInfo
*
- * ParamListInfo arrays are used to pass parameters into the executor
- * for parameterized plans. Each entry in the array defines the value
- * to be substituted for a PARAM_EXTERN parameter. The "paramid"
- * of a PARAM_EXTERN Param can range from 1 to numParams.
+ * ParamListInfo structures are used to pass parameters into the executor
+ * for parameterized plans. We support two basic approaches to supplying
+ * parameter values, the "static" way and the "dynamic" way.
+ *
+ * In the static approach, per-parameter data is stored in an array of
+ * ParamExternData structs appended to the ParamListInfo struct.
+ * Each entry in the array defines the value to be substituted for a
+ * PARAM_EXTERN parameter. The "paramid" of a PARAM_EXTERN Param
+ * can range from 1 to numParams.
*
* Although parameter numbers are normally consecutive, we allow
* ptype == InvalidOid to signal an unused array entry.
@@ -35,18 +42,47 @@ struct ParseState;
* as a constant (i.e., generate a plan that works only for this value
* of the parameter).
*
- * There are two hook functions that can be associated with a ParamListInfo
- * array to support dynamic parameter handling. First, if paramFetch
- * isn't null and the executor requires a value for an invalid parameter
- * (one with ptype == InvalidOid), the paramFetch hook is called to give
- * it a chance to fill in the parameter value. Second, a parserSetup
- * hook can be supplied to re-instantiate the original parsing hooks if
- * a query needs to be re-parsed/planned (as a substitute for supposing
- * that the current ptype values represent a fixed set of parameter types).
-
+ * In the dynamic approach, all access to parameter values is done through
+ * hook functions found in the ParamListInfo struct. In this case,
+ * the ParamExternData array is typically unused and not allocated;
+ * but the legal range of paramid is still 1 to numParams.
+ *
* Although the data structure is really an array, not a list, we keep
* the old typedef name to avoid unnecessary code changes.
- * ----------------
+ *
+ * There are 3 hook functions that can be associated with a ParamListInfo
+ * structure:
+ *
+ * If paramFetch isn't null, it is called to fetch the ParamExternData
+ * for a particular param ID, rather than accessing the relevant element
+ * of the ParamExternData array. This supports the case where the array
+ * isn't there at all, as well as cases where the data in the array
+ * might be obsolete or lazily evaluated. paramFetch must return the
+ * address of a ParamExternData struct describing the specified param ID;
+ * the convention above about ptype == InvalidOid signaling an invalid
+ * param ID still applies. The returned struct can either be placed in
+ * the "workspace" supplied by the caller, or it can be in storage
+ * controlled by the paramFetch hook if that's more convenient.
+ * (In either case, the struct is not expected to be long-lived.)
+ * If "speculative" is true, the paramFetch hook should not risk errors
+ * in trying to fetch the parameter value, and should report an invalid
+ * parameter instead.
+ *
+ * If paramCompile isn't null, then it controls what execExpr.c compiles
+ * for PARAM_EXTERN Param nodes --- typically, this hook would emit a
+ * EEOP_PARAM_CALLBACK step. This allows unnecessary work to be
+ * optimized away in compiled expressions.
+ *
+ * If parserSetup isn't null, then it is called to re-instantiate the
+ * original parsing hooks when a query needs to be re-parsed/planned.
+ * This is especially useful if the types of parameters might change
+ * from time to time, since it can replace the need to supply a fixed
+ * list of parameter types to the parser.
+ *
+ * Notice that the paramFetch and paramCompile hooks are actually passed
+ * the ParamListInfo struct's address; they can therefore access all
+ * three of the "arg" fields, and the distinction between paramFetchArg
+ * and paramCompileArg is rather arbitrary.
*/
#define PARAM_FLAG_CONST 0x0001 /* parameter is constant */
@@ -61,7 +97,13 @@ typedef struct ParamExternData
typedef struct ParamListInfoData *ParamListInfo;
-typedef void (*ParamFetchHook) (ParamListInfo params, int paramid);
+typedef ParamExternData *(*ParamFetchHook) (ParamListInfo params,
+ int paramid, bool speculative,
+ ParamExternData *workspace);
+
+typedef void (*ParamCompileHook) (ParamListInfo params, struct Param *param,
+ struct ExprState *state,
+ Datum *resv, bool *resnull);
typedef void (*ParserSetupHook) (struct ParseState *pstate, void *arg);
@@ -69,10 +111,16 @@ typedef struct ParamListInfoData
{
ParamFetchHook paramFetch; /* parameter fetch hook */
void *paramFetchArg;
+ ParamCompileHook paramCompile; /* parameter compile hook */
+ void *paramCompileArg;
ParserSetupHook parserSetup; /* parser setup hook */
void *parserSetupArg;
- int numParams; /* number of ParamExternDatas following */
- struct Bitmapset *paramMask; /* if non-NULL, can ignore omitted params */
+ int numParams; /* nominal/maximum # of Params represented */
+
+ /*
+ * params[] may be of length zero if paramFetch is supplied; otherwise it
+ * must be of length numParams.
+ */
ParamExternData params[FLEXIBLE_ARRAY_MEMBER];
} ParamListInfoData;