v4-0001-soft-error-variant-of-ExecPrepareExpr-ExecInitExp.patch
text/x-patch
Filename: v4-0001-soft-error-variant-of-ExecPrepareExpr-ExecInitExp.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch v4-0001
Subject: soft error variant of ExecPrepareExpr, ExecInitExpr
| File | + | − |
|---|---|---|
| src/backend/executor/execExpr.c | 63 | 0 |
| src/include/executor/executor.h | 2 | 0 |
From 09547bbc65f20846ac28efce035c016b21a75825 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Mon, 24 Mar 2025 16:07:46 +0800
Subject: [PATCH v4 1/3] soft error variant of ExecPrepareExpr, ExecInitExpr
ExecInitExprSafe: soft error of ExecInitExpr.
ExecPrepareExprSafe: soft error of ExecPrepareExpr.
ExecPrepareExprSafe initialize for expression execution with soft error support.
not all expression node support it. Like node CoerceToDomain support it.
XXX more comments.
discussion: https://postgr.es/m/CACJufxE_+iZBR1i49k_AHigppPwLTJi6km8NOsC7FWvKdEmmXg@mail.gmail.com
---
src/backend/executor/execExpr.c | 63 +++++++++++++++++++++++++++++++++
src/include/executor/executor.h | 2 ++
2 files changed, 65 insertions(+)
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index f1569879b52..9182ba446a0 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -170,6 +170,47 @@ ExecInitExpr(Expr *node, PlanState *parent)
return state;
}
+/*
+ * ExecInitExprSafe: soft error variant of ExecInitExpr.
+ *
+ * use it only for expression nodes support soft errors, not all expression
+ * nodes support it.
+*/
+ExprState *
+ExecInitExprSafe(Expr *node, PlanState *parent)
+{
+ ExprState *state;
+ ExprEvalStep scratch = {0};
+
+ /* Special case: NULL expression produces a NULL ExprState pointer */
+ if (node == NULL)
+ return NULL;
+
+ /* Initialize ExprState with empty step list */
+ state = makeNode(ExprState);
+ state->expr = node;
+ state->parent = parent;
+ state->ext_params = NULL;
+ state->escontext = makeNode(ErrorSaveContext);
+ state->escontext->type = T_ErrorSaveContext;
+ state->escontext->error_occurred = false;
+ state->escontext->details_wanted = true;
+
+ /* Insert setup steps as needed */
+ ExecCreateExprSetupSteps(state, (Node *) node);
+
+ /* Compile the expression proper */
+ ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
+
+ /* Finally, append a DONE step */
+ scratch.opcode = EEOP_DONE_RETURN;
+ ExprEvalPushStep(state, &scratch);
+
+ ExecReadyExpr(state);
+
+ return state;
+}
+
/*
* ExecInitExprWithParams: prepare a standalone expression tree for execution
*
@@ -778,6 +819,28 @@ ExecPrepareExpr(Expr *node, EState *estate)
return result;
}
+/*
+ * ExecPrepareExprSafe: soft error variant of ExecPrepareExpr.
+ *
+ * use it when expression node *support* soft error expression execution.
+ */
+ExprState *
+ExecPrepareExprSafe(Expr *node, EState *estate)
+{
+ ExprState *result;
+ MemoryContext oldcontext;
+
+ oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
+
+ node = expression_planner(node);
+
+ result = ExecInitExprSafe(node, NULL);
+
+ MemoryContextSwitchTo(oldcontext);
+
+ return result;
+}
+
/*
* ExecPrepareQual --- initialize for qual execution outside a normal
* Plan tree context.
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 0db5d18ba22..464c7318de1 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -305,6 +305,7 @@ ExecProcNode(PlanState *node)
* prototypes from functions in execExpr.c
*/
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
+extern ExprState *ExecInitExprSafe(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);
@@ -353,6 +354,7 @@ extern ProjectionInfo *ExecBuildUpdateProjection(List *targetList,
TupleTableSlot *slot,
PlanState *parent);
extern ExprState *ExecPrepareExpr(Expr *node, EState *estate);
+extern ExprState *ExecPrepareExprSafe(Expr *node, EState *estate);
extern ExprState *ExecPrepareQual(List *qual, EState *estate);
extern ExprState *ExecPrepareCheck(List *qual, EState *estate);
extern List *ExecPrepareExprList(List *nodes, EState *estate);
--
2.34.1