Revert "Add soft error handling to some expression nodes"
authorAmit Langote <amitlan@postgresql.org>
Mon, 2 Oct 2023 04:48:15 +0000 (13:48 +0900)
committerAmit Langote <amitlan@postgresql.org>
Mon, 2 Oct 2023 04:48:15 +0000 (13:48 +0900)
This reverts commit 7fbc75b26ed8ec70c729c5e7f8233896c54c900f.

Looks like the LLVM additions may not be totally correct.

src/backend/executor/execExpr.c
src/backend/executor/execExprInterp.c
src/backend/jit/llvm/llvmjit.c
src/backend/jit/llvm/llvmjit_expr.c
src/backend/jit/llvm/llvmjit_types.c
src/include/executor/execExpr.h
src/include/jit/llvmjit.h
src/include/jit/llvmjit_emit.h
src/include/nodes/execnodes.h

index f6780bbf52c1a6d095e73694a3e54a2fa908e1a2..2c62b0c9c84635497dfbf1eed831b5aee6d28d48 100644 (file)
@@ -139,7 +139,6 @@ ExecInitExpr(Expr *node, PlanState *parent)
        state->expr = node;
        state->parent = parent;
        state->ext_params = NULL;
-       state->escontext = NULL;
 
        /* Insert setup steps as needed */
        ExecCreateExprSetupSteps(state, (Node *) node);
@@ -177,7 +176,6 @@ ExecInitExprWithParams(Expr *node, ParamListInfo ext_params)
        state->expr = node;
        state->parent = NULL;
        state->ext_params = ext_params;
-       state->escontext = NULL;
 
        /* Insert setup steps as needed */
        ExecCreateExprSetupSteps(state, (Node *) node);
@@ -230,7 +228,6 @@ ExecInitQual(List *qual, PlanState *parent)
        state->expr = (Expr *) qual;
        state->parent = parent;
        state->ext_params = NULL;
-       state->escontext = NULL;
 
        /* mark expression as to be used with ExecQual() */
        state->flags = EEO_FLAG_IS_QUAL;
@@ -376,7 +373,6 @@ ExecBuildProjectionInfo(List *targetList,
        state->expr = (Expr *) targetList;
        state->parent = parent;
        state->ext_params = NULL;
-       state->escontext = NULL;
 
        state->resultslot = slot;
 
@@ -548,7 +544,6 @@ ExecBuildUpdateProjection(List *targetList,
                state->expr = NULL;             /* not used */
        state->parent = parent;
        state->ext_params = NULL;
-       state->escontext = NULL;
 
        state->resultslot = slot;
 
@@ -1554,6 +1549,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
                                CoerceViaIO *iocoerce = (CoerceViaIO *) node;
                                Oid                     iofunc;
                                bool            typisvarlena;
+                               Oid                     typioparam;
+                               FunctionCallInfo fcinfo_in;
 
                                /* evaluate argument into step's result area */
                                ExecInitExprRec(iocoerce->arg, state, resv, resnull);
@@ -1582,13 +1579,25 @@ ExecInitExprRec(Expr *node, ExprState *state,
 
                                /* lookup the result type's input function */
                                scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo));
+                               scratch.d.iocoerce.fcinfo_data_in = palloc0(SizeForFunctionCallInfo(3));
+
                                getTypeInputInfo(iocoerce->resulttype,
-                                                                &iofunc, &scratch.d.iocoerce.typioparam);
+                                                                &iofunc, &typioparam);
                                fmgr_info(iofunc, scratch.d.iocoerce.finfo_in);
                                fmgr_info_set_expr((Node *) node, scratch.d.iocoerce.finfo_in);
+                               InitFunctionCallInfoData(*scratch.d.iocoerce.fcinfo_data_in,
+                                                                                scratch.d.iocoerce.finfo_in,
+                                                                                3, InvalidOid, NULL, NULL);
 
-                               /* Set ErrorSaveContext if passed by the caller. */
-                               scratch.d.iocoerce.escontext = state->escontext;
+                               /*
+                                * We can preload the second and third arguments for the input
+                                * function, since they're constants.
+                                */
+                               fcinfo_in = scratch.d.iocoerce.fcinfo_data_in;
+                               fcinfo_in->args[1].value = ObjectIdGetDatum(typioparam);
+                               fcinfo_in->args[1].isnull = false;
+                               fcinfo_in->args[2].value = Int32GetDatum(-1);
+                               fcinfo_in->args[2].isnull = false;
 
                                ExprEvalPushStep(state, &scratch);
                                break;
@@ -1619,7 +1628,6 @@ ExecInitExprRec(Expr *node, ExprState *state,
                                elemstate->expr = acoerce->elemexpr;
                                elemstate->parent = state->parent;
                                elemstate->ext_params = state->ext_params;
-                               state->escontext = NULL;
 
                                elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum));
                                elemstate->innermost_casenull = (bool *) palloc(sizeof(bool));
@@ -3298,8 +3306,6 @@ ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
        /* we'll allocate workspace only if needed */
        scratch->d.domaincheck.checkvalue = NULL;
        scratch->d.domaincheck.checknull = NULL;
-       /* Set ErrorSaveContext if passed by the caller. */
-       scratch->d.domaincheck.escontext = state->escontext;
 
        /*
         * Evaluate argument - it's fine to directly store it into resv/resnull,
index e55fd10e3b86064771158a253ccd48f7a32dca65..24c2b60c62a771bd1725a0c72d334722aef52307 100644 (file)
@@ -1177,27 +1177,29 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
                        /* call input function (similar to InputFunctionCall) */
                        if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL)
                        {
-                               bool            error;
+                               FunctionCallInfo fcinfo_in;
+                               Datum           d;
 
-                               /*
-                                * InputFunctionCallSafe() writes directly into *op->resvalue.
-                                * Return NULL if an error is reported.
-                                */
-                               error = !InputFunctionCallSafe(op->d.iocoerce.finfo_in, str,
-                                                                                          op->d.iocoerce.typioparam, -1,
-                                                                                          (Node *) op->d.iocoerce.escontext,
-                                                                                          op->resvalue);
-                               if (error)
-                                       *op->resnull = true;
+                               fcinfo_in = op->d.iocoerce.fcinfo_data_in;
+                               fcinfo_in->args[0].value = PointerGetDatum(str);
+                               fcinfo_in->args[0].isnull = *op->resnull;
+                               /* second and third arguments are already set up */
 
-                               /*
-                                * Should get null result if and only if str is NULL or if we
-                                * got an error above.
-                                */
-                               if (str == NULL || error)
+                               fcinfo_in->isnull = false;
+                               d = FunctionCallInvoke(fcinfo_in);
+                               *op->resvalue = d;
+
+                               /* Should get null result if and only if str is NULL */
+                               if (str == NULL)
+                               {
                                        Assert(*op->resnull);
+                                       Assert(fcinfo_in->isnull);
+                               }
                                else
+                               {
                                        Assert(!*op->resnull);
+                                       Assert(!fcinfo_in->isnull);
+                               }
                        }
 
                        EEO_NEXT();
@@ -3743,7 +3745,7 @@ ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op)
 {
        if (!*op->d.domaincheck.checknull &&
                !DatumGetBool(*op->d.domaincheck.checkvalue))
-               errsave((Node *) op->d.domaincheck.escontext,
+               ereport(ERROR,
                                (errcode(ERRCODE_CHECK_VIOLATION),
                                 errmsg("value for domain %s violates check constraint \"%s\"",
                                                format_type_be(op->d.domaincheck.resulttype),
index 125e1e73ae6c23c9ad84999e398a30cb05fa74bf..4dfaf797432155a20ae741ca145c3e52065d9647 100644 (file)
@@ -70,14 +70,12 @@ LLVMTypeRef StructHeapTupleTableSlot;
 LLVMTypeRef StructMinimalTupleTableSlot;
 LLVMTypeRef StructMemoryContextData;
 LLVMTypeRef StructFunctionCallInfoData;
-LLVMTypeRef StructFmgrInfo;
 LLVMTypeRef StructExprContext;
 LLVMTypeRef StructExprEvalStep;
 LLVMTypeRef StructExprState;
 LLVMTypeRef StructAggState;
 LLVMTypeRef StructAggStatePerGroupData;
 LLVMTypeRef StructAggStatePerTransData;
-LLVMTypeRef StructErrorSaveContext;
 
 LLVMValueRef AttributeTemplate;
 
@@ -1120,7 +1118,6 @@ llvm_create_types(void)
        StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep");
        StructExprState = llvm_pg_var_type("StructExprState");
        StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData");
-       StructFmgrInfo = llvm_pg_var_type("StructFmgrInfo");
        StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData");
        StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot");
        StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot");
@@ -1130,7 +1127,6 @@ llvm_create_types(void)
        StructAggState = llvm_pg_var_type("StructAggState");
        StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData");
        StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData");
-       StructErrorSaveContext = llvm_pg_var_type("StructErrorSaveContext");
 
        AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
 }
index 7d44a4c9f4e2426ffed67694d87b68eb6430e106..4b51aa1ce0773c4311e61437cee0df1fcde8791a 100644 (file)
@@ -1251,9 +1251,14 @@ llvm_compile_expr(ExprState *state)
 
                        case EEOP_IOCOERCE:
                                {
-                                       FunctionCallInfo fcinfo_out;
-                                       LLVMValueRef v_fn_out;
-                                       LLVMValueRef v_fcinfo_out;
+                                       FunctionCallInfo fcinfo_out,
+                                                               fcinfo_in;
+                                       LLVMValueRef v_fn_out,
+                                                               v_fn_in;
+                                       LLVMValueRef v_fcinfo_out,
+                                                               v_fcinfo_in;
+                                       LLVMValueRef v_fcinfo_in_isnullp;
+                                       LLVMValueRef v_retval;
                                        LLVMValueRef v_resvalue;
                                        LLVMValueRef v_resnull;
 
@@ -1266,6 +1271,7 @@ llvm_compile_expr(ExprState *state)
                                        LLVMBasicBlockRef b_inputcall;
 
                                        fcinfo_out = op->d.iocoerce.fcinfo_data_out;
+                                       fcinfo_in = op->d.iocoerce.fcinfo_data_in;
 
                                        b_skipoutput = l_bb_before_v(opblocks[opno + 1],
                                                                                                 "op.%d.skipoutputnull", opno);
@@ -1277,7 +1283,14 @@ llvm_compile_expr(ExprState *state)
                                                                                                "op.%d.inputcall", opno);
 
                                        v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out);
+                                       v_fn_in = llvm_function_reference(context, b, mod, fcinfo_in);
                                        v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData));
+                                       v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData));
+
+                                       v_fcinfo_in_isnullp =
+                                               LLVMBuildStructGEP(b, v_fcinfo_in,
+                                                                                  FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
+                                                                                  "v_fcinfo_in_isnull");
 
                                        /* output functions are not called on nulls */
                                        v_resnull = LLVMBuildLoad(b, v_resnullp, "");
@@ -1343,44 +1356,24 @@ llvm_compile_expr(ExprState *state)
                                                LLVMBuildBr(b, b_inputcall);
                                        }
 
-                                       /*
-                                        * Call the input function.
-                                        *
-                                        * If op->d.iocoerce.escontext references an
-                                        * ErrorSaveContext, InputFunctionCallSafe() would return
-                                        * false upon encountering an error.
-                                        */
                                        LLVMPositionBuilderAtEnd(b, b_inputcall);
-                                       {
-                                               Oid                     ioparam = op->d.iocoerce.typioparam;
-                                               LLVMValueRef v_params[6];
-                                               LLVMValueRef v_success;
-
-                                               v_params[0] = l_ptr_const(op->d.iocoerce.finfo_in,
-                                                                                                 l_ptr(StructFmgrInfo));
-                                               v_params[1] = v_output;
-                                               v_params[2] = l_oid_const(lc, ioparam);
-                                               v_params[3] = l_int32_const(lc, -1);
-                                               v_params[4] = l_ptr_const(op->d.iocoerce.escontext,
-                                                                                                 l_ptr(StructErrorSaveContext));
+                                       /* set arguments */
+                                       /* arg0: output */
+                                       LLVMBuildStore(b, v_output,
+                                                                  l_funcvaluep(b, v_fcinfo_in, 0));
+                                       LLVMBuildStore(b, v_resnull,
+                                                                  l_funcnullp(b, v_fcinfo_in, 0));
+
+                                       /* arg1: ioparam: preset in execExpr.c */
+                                       /* arg2: typmod: preset in execExpr.c  */
+
+                                       /* reset fcinfo_in->isnull */
+                                       LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp);
+                                       /* and call function */
+                                       v_retval = LLVMBuildCall(b, v_fn_in, &v_fcinfo_in, 1,
+                                                                                        "funccall_iocoerce_in");
 
-                                               /*
-                                                * InputFunctionCallSafe() will write directly into
-                                                * *op->resvalue.
-                                                */
-                                               v_params[5] = v_resvaluep;
-
-                                               v_success = LLVMBuildCall(b, llvm_pg_func(mod, "InputFunctionCallSafe"),
-                                                                                                 v_params, lengthof(v_params),
-                                                                                                 "funccall_iocoerce_in_safe");
-
-                                               /*
-                                                * Return null if InputFunctionCallSafe() encountered
-                                                * an error.
-                                                */
-                                               v_resnullp = LLVMBuildICmp(b, LLVMIntEQ, v_success,
-                                                                                                  l_sbool_const(0), "");
-                                       }
+                                       LLVMBuildStore(b, v_retval, v_resvaluep);
 
                                        LLVMBuildBr(b, opblocks[opno + 1]);
                                        break;
index e1e96250389063da12257870f8ba759e05bfae37..41ac4c6f45c682f24cc065b69e9741e1c13686b2 100644 (file)
@@ -59,7 +59,6 @@ AggStatePerTransData StructAggStatePerTransData;
 ExprContext StructExprContext;
 ExprEvalStep StructExprEvalStep;
 ExprState      StructExprState;
-FmgrInfo       StructFmgrInfo;
 FunctionCallInfoBaseData StructFunctionCallInfoData;
 HeapTupleData StructHeapTupleData;
 MemoryContextData StructMemoryContextData;
@@ -67,7 +66,6 @@ TupleTableSlot StructTupleTableSlot;
 HeapTupleTableSlot StructHeapTupleTableSlot;
 MinimalTupleTableSlot StructMinimalTupleTableSlot;
 TupleDescData StructTupleDescData;
-ErrorSaveContext StructErrorSaveContext;
 
 
 /*
@@ -138,7 +136,6 @@ void           *referenced_functions[] =
        ExecEvalJsonConstructor,
        ExecEvalJsonIsPredicate,
        MakeExpandedObjectReadOnlyInternal,
-       InputFunctionCallSafe,
        slot_getmissingattrs,
        slot_getsomeattrs_int,
        strlen,
index 59f3b043c6b83bfcdbba62a4a8030340e1ccef97..048573c2bcb5756a0dd537be3197a0e48f900ebe 100644 (file)
@@ -16,7 +16,6 @@
 
 #include "executor/nodeAgg.h"
 #include "nodes/execnodes.h"
-#include "nodes/miscnodes.h"
 
 /* forward references to avoid circularity */
 struct ExprEvalStep;
@@ -417,8 +416,7 @@ typedef struct ExprEvalStep
                        FunctionCallInfo fcinfo_data_out;
                        /* lookup and call info for result type's input function */
                        FmgrInfo   *finfo_in;
-                       Oid                     typioparam;
-                       ErrorSaveContext *escontext;
+                       FunctionCallInfo fcinfo_data_in;
                }                       iocoerce;
 
                /* for EEOP_SQLVALUEFUNCTION */
@@ -549,7 +547,6 @@ typedef struct ExprEvalStep
                        bool       *checknull;
                        /* OID of domain type */
                        Oid                     resulttype;
-                       ErrorSaveContext *escontext;
                }                       domaincheck;
 
                /* for EEOP_CONVERT_ROWTYPE */
index 5b7681eba904b908881a1ff107bf3e47864965ef..6d90a16f792b84e3e0a8ac91d51110af3e4cefa2 100644 (file)
@@ -75,7 +75,6 @@ extern PGDLLIMPORT LLVMTypeRef StructTupleTableSlot;
 extern PGDLLIMPORT LLVMTypeRef StructHeapTupleTableSlot;
 extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleTableSlot;
 extern PGDLLIMPORT LLVMTypeRef StructMemoryContextData;
-extern PGDLLIMPORT LLVMTypeRef StructFmgrInfo;
 extern PGDLLIMPORT LLVMTypeRef StructFunctionCallInfoData;
 extern PGDLLIMPORT LLVMTypeRef StructExprContext;
 extern PGDLLIMPORT LLVMTypeRef StructExprEvalStep;
@@ -83,7 +82,6 @@ extern PGDLLIMPORT LLVMTypeRef StructExprState;
 extern PGDLLIMPORT LLVMTypeRef StructAggState;
 extern PGDLLIMPORT LLVMTypeRef StructAggStatePerTransData;
 extern PGDLLIMPORT LLVMTypeRef StructAggStatePerGroupData;
-extern PGDLLIMPORT LLVMTypeRef StructErrorSaveContext;
 
 extern PGDLLIMPORT LLVMValueRef AttributeTemplate;
 
index ead46a64ae23ba0fcce4ff0bebd376d3021a6203..5e74543be4728ad4f49d32d42899de54dd97bade 100644 (file)
@@ -85,15 +85,6 @@ l_sizet_const(size_t i)
        return LLVMConstInt(TypeSizeT, i, false);
 }
 
-/*
- * Emit constant oid.
- */
-static inline LLVMValueRef
-l_oid_const(LLVMContextRef lc, Oid i)
-{
-       return LLVMConstInt(LLVMInt32TypeInContext(lc), i, false);
-}
-
 /*
  * Emit constant boolean, as used for storage (e.g. global vars, structs).
  */
index b9b08f0f62b2e46f830b56b1473cc1baacd0e583..869465d6f803a78417ffc325de4cc8c432362903 100644 (file)
@@ -34,7 +34,6 @@
 #include "fmgr.h"
 #include "lib/ilist.h"
 #include "lib/pairingheap.h"
-#include "nodes/miscnodes.h"
 #include "nodes/params.h"
 #include "nodes/plannodes.h"
 #include "nodes/tidbitmap.h"
@@ -130,12 +129,6 @@ typedef struct ExprState
 
        Datum      *innermost_domainval;
        bool       *innermost_domainnull;
-
-       /*
-        * For expression nodes that support soft errors.  Should be set to NULL
-        * before calling ExecInitExprRec() if the caller wants errors thrown.
-        */
-       ErrorSaveContext *escontext;
 } ExprState;