1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-26 01:22:12 +03:00

Revert "Add soft error handling to some expression nodes"

This reverts commit 7fbc75b26e.

Looks like the LLVM additions may not be totally correct.
This commit is contained in:
Amit Langote
2023-10-02 13:48:15 +09:00
parent 7fbc75b26e
commit c8ec5e0543
9 changed files with 67 additions and 94 deletions

View File

@ -139,7 +139,6 @@ ExecInitExpr(Expr *node, PlanState *parent)
state->expr = node; state->expr = node;
state->parent = parent; state->parent = parent;
state->ext_params = NULL; state->ext_params = NULL;
state->escontext = NULL;
/* Insert setup steps as needed */ /* Insert setup steps as needed */
ExecCreateExprSetupSteps(state, (Node *) node); ExecCreateExprSetupSteps(state, (Node *) node);
@ -177,7 +176,6 @@ ExecInitExprWithParams(Expr *node, ParamListInfo ext_params)
state->expr = node; state->expr = node;
state->parent = NULL; state->parent = NULL;
state->ext_params = ext_params; state->ext_params = ext_params;
state->escontext = NULL;
/* Insert setup steps as needed */ /* Insert setup steps as needed */
ExecCreateExprSetupSteps(state, (Node *) node); ExecCreateExprSetupSteps(state, (Node *) node);
@ -230,7 +228,6 @@ ExecInitQual(List *qual, PlanState *parent)
state->expr = (Expr *) qual; state->expr = (Expr *) qual;
state->parent = parent; state->parent = parent;
state->ext_params = NULL; state->ext_params = NULL;
state->escontext = NULL;
/* mark expression as to be used with ExecQual() */ /* mark expression as to be used with ExecQual() */
state->flags = EEO_FLAG_IS_QUAL; state->flags = EEO_FLAG_IS_QUAL;
@ -376,7 +373,6 @@ ExecBuildProjectionInfo(List *targetList,
state->expr = (Expr *) targetList; state->expr = (Expr *) targetList;
state->parent = parent; state->parent = parent;
state->ext_params = NULL; state->ext_params = NULL;
state->escontext = NULL;
state->resultslot = slot; state->resultslot = slot;
@ -548,7 +544,6 @@ ExecBuildUpdateProjection(List *targetList,
state->expr = NULL; /* not used */ state->expr = NULL; /* not used */
state->parent = parent; state->parent = parent;
state->ext_params = NULL; state->ext_params = NULL;
state->escontext = NULL;
state->resultslot = slot; state->resultslot = slot;
@ -1554,6 +1549,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
CoerceViaIO *iocoerce = (CoerceViaIO *) node; CoerceViaIO *iocoerce = (CoerceViaIO *) node;
Oid iofunc; Oid iofunc;
bool typisvarlena; bool typisvarlena;
Oid typioparam;
FunctionCallInfo fcinfo_in;
/* evaluate argument into step's result area */ /* evaluate argument into step's result area */
ExecInitExprRec(iocoerce->arg, state, resv, resnull); ExecInitExprRec(iocoerce->arg, state, resv, resnull);
@ -1582,13 +1579,25 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* lookup the result type's input function */ /* lookup the result type's input function */
scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo)); scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo));
scratch.d.iocoerce.fcinfo_data_in = palloc0(SizeForFunctionCallInfo(3));
getTypeInputInfo(iocoerce->resulttype, getTypeInputInfo(iocoerce->resulttype,
&iofunc, &scratch.d.iocoerce.typioparam); &iofunc, &typioparam);
fmgr_info(iofunc, scratch.d.iocoerce.finfo_in); fmgr_info(iofunc, scratch.d.iocoerce.finfo_in);
fmgr_info_set_expr((Node *) node, 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); ExprEvalPushStep(state, &scratch);
break; break;
@ -1619,7 +1628,6 @@ ExecInitExprRec(Expr *node, ExprState *state,
elemstate->expr = acoerce->elemexpr; elemstate->expr = acoerce->elemexpr;
elemstate->parent = state->parent; elemstate->parent = state->parent;
elemstate->ext_params = state->ext_params; elemstate->ext_params = state->ext_params;
state->escontext = NULL;
elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum)); elemstate->innermost_caseval = (Datum *) palloc(sizeof(Datum));
elemstate->innermost_casenull = (bool *) palloc(sizeof(bool)); elemstate->innermost_casenull = (bool *) palloc(sizeof(bool));
@ -3298,8 +3306,6 @@ ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
/* we'll allocate workspace only if needed */ /* we'll allocate workspace only if needed */
scratch->d.domaincheck.checkvalue = NULL; scratch->d.domaincheck.checkvalue = NULL;
scratch->d.domaincheck.checknull = 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, * Evaluate argument - it's fine to directly store it into resv/resnull,

View File

@ -1177,27 +1177,29 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* call input function (similar to InputFunctionCall) */ /* call input function (similar to InputFunctionCall) */
if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL) if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL)
{ {
bool error; FunctionCallInfo fcinfo_in;
Datum d;
/* fcinfo_in = op->d.iocoerce.fcinfo_data_in;
* InputFunctionCallSafe() writes directly into *op->resvalue. fcinfo_in->args[0].value = PointerGetDatum(str);
* Return NULL if an error is reported. fcinfo_in->args[0].isnull = *op->resnull;
*/ /* second and third arguments are already set up */
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->isnull = false;
* Should get null result if and only if str is NULL or if we d = FunctionCallInvoke(fcinfo_in);
* got an error above. *op->resvalue = d;
*/
if (str == NULL || error) /* Should get null result if and only if str is NULL */
if (str == NULL)
{
Assert(*op->resnull); Assert(*op->resnull);
Assert(fcinfo_in->isnull);
}
else else
{
Assert(!*op->resnull); Assert(!*op->resnull);
Assert(!fcinfo_in->isnull);
}
} }
EEO_NEXT(); EEO_NEXT();
@ -3743,7 +3745,7 @@ ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op)
{ {
if (!*op->d.domaincheck.checknull && if (!*op->d.domaincheck.checknull &&
!DatumGetBool(*op->d.domaincheck.checkvalue)) !DatumGetBool(*op->d.domaincheck.checkvalue))
errsave((Node *) op->d.domaincheck.escontext, ereport(ERROR,
(errcode(ERRCODE_CHECK_VIOLATION), (errcode(ERRCODE_CHECK_VIOLATION),
errmsg("value for domain %s violates check constraint \"%s\"", errmsg("value for domain %s violates check constraint \"%s\"",
format_type_be(op->d.domaincheck.resulttype), format_type_be(op->d.domaincheck.resulttype),

View File

@ -70,14 +70,12 @@ LLVMTypeRef StructHeapTupleTableSlot;
LLVMTypeRef StructMinimalTupleTableSlot; LLVMTypeRef StructMinimalTupleTableSlot;
LLVMTypeRef StructMemoryContextData; LLVMTypeRef StructMemoryContextData;
LLVMTypeRef StructFunctionCallInfoData; LLVMTypeRef StructFunctionCallInfoData;
LLVMTypeRef StructFmgrInfo;
LLVMTypeRef StructExprContext; LLVMTypeRef StructExprContext;
LLVMTypeRef StructExprEvalStep; LLVMTypeRef StructExprEvalStep;
LLVMTypeRef StructExprState; LLVMTypeRef StructExprState;
LLVMTypeRef StructAggState; LLVMTypeRef StructAggState;
LLVMTypeRef StructAggStatePerGroupData; LLVMTypeRef StructAggStatePerGroupData;
LLVMTypeRef StructAggStatePerTransData; LLVMTypeRef StructAggStatePerTransData;
LLVMTypeRef StructErrorSaveContext;
LLVMValueRef AttributeTemplate; LLVMValueRef AttributeTemplate;
@ -1120,7 +1118,6 @@ llvm_create_types(void)
StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep"); StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep");
StructExprState = llvm_pg_var_type("StructExprState"); StructExprState = llvm_pg_var_type("StructExprState");
StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData"); StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData");
StructFmgrInfo = llvm_pg_var_type("StructFmgrInfo");
StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData"); StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData");
StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot"); StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot");
StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot"); StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot");
@ -1130,7 +1127,6 @@ llvm_create_types(void)
StructAggState = llvm_pg_var_type("StructAggState"); StructAggState = llvm_pg_var_type("StructAggState");
StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData"); StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData");
StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData"); StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData");
StructErrorSaveContext = llvm_pg_var_type("StructErrorSaveContext");
AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate"); AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
} }

View File

@ -1251,9 +1251,14 @@ llvm_compile_expr(ExprState *state)
case EEOP_IOCOERCE: case EEOP_IOCOERCE:
{ {
FunctionCallInfo fcinfo_out; FunctionCallInfo fcinfo_out,
LLVMValueRef v_fn_out; fcinfo_in;
LLVMValueRef v_fcinfo_out; 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_resvalue;
LLVMValueRef v_resnull; LLVMValueRef v_resnull;
@ -1266,6 +1271,7 @@ llvm_compile_expr(ExprState *state)
LLVMBasicBlockRef b_inputcall; LLVMBasicBlockRef b_inputcall;
fcinfo_out = op->d.iocoerce.fcinfo_data_out; 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], b_skipoutput = l_bb_before_v(opblocks[opno + 1],
"op.%d.skipoutputnull", opno); "op.%d.skipoutputnull", opno);
@ -1277,7 +1283,14 @@ llvm_compile_expr(ExprState *state)
"op.%d.inputcall", opno); "op.%d.inputcall", opno);
v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out); 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_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 */ /* output functions are not called on nulls */
v_resnull = LLVMBuildLoad(b, v_resnullp, ""); v_resnull = LLVMBuildLoad(b, v_resnullp, "");
@ -1343,44 +1356,24 @@ llvm_compile_expr(ExprState *state)
LLVMBuildBr(b, b_inputcall); 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); LLVMPositionBuilderAtEnd(b, b_inputcall);
{ /* set arguments */
Oid ioparam = op->d.iocoerce.typioparam; /* arg0: output */
LLVMValueRef v_params[6]; LLVMBuildStore(b, v_output,
LLVMValueRef v_success; l_funcvaluep(b, v_fcinfo_in, 0));
LLVMBuildStore(b, v_resnull,
l_funcnullp(b, v_fcinfo_in, 0));
v_params[0] = l_ptr_const(op->d.iocoerce.finfo_in, /* arg1: ioparam: preset in execExpr.c */
l_ptr(StructFmgrInfo)); /* arg2: typmod: preset in execExpr.c */
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));
/* /* reset fcinfo_in->isnull */
* InputFunctionCallSafe() will write directly into LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp);
* *op->resvalue. /* and call function */
*/ v_retval = LLVMBuildCall(b, v_fn_in, &v_fcinfo_in, 1,
v_params[5] = v_resvaluep; "funccall_iocoerce_in");
v_success = LLVMBuildCall(b, llvm_pg_func(mod, "InputFunctionCallSafe"), LLVMBuildStore(b, v_retval, v_resvaluep);
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), "");
}
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;

View File

@ -59,7 +59,6 @@ AggStatePerTransData StructAggStatePerTransData;
ExprContext StructExprContext; ExprContext StructExprContext;
ExprEvalStep StructExprEvalStep; ExprEvalStep StructExprEvalStep;
ExprState StructExprState; ExprState StructExprState;
FmgrInfo StructFmgrInfo;
FunctionCallInfoBaseData StructFunctionCallInfoData; FunctionCallInfoBaseData StructFunctionCallInfoData;
HeapTupleData StructHeapTupleData; HeapTupleData StructHeapTupleData;
MemoryContextData StructMemoryContextData; MemoryContextData StructMemoryContextData;
@ -67,7 +66,6 @@ TupleTableSlot StructTupleTableSlot;
HeapTupleTableSlot StructHeapTupleTableSlot; HeapTupleTableSlot StructHeapTupleTableSlot;
MinimalTupleTableSlot StructMinimalTupleTableSlot; MinimalTupleTableSlot StructMinimalTupleTableSlot;
TupleDescData StructTupleDescData; TupleDescData StructTupleDescData;
ErrorSaveContext StructErrorSaveContext;
/* /*
@ -138,7 +136,6 @@ void *referenced_functions[] =
ExecEvalJsonConstructor, ExecEvalJsonConstructor,
ExecEvalJsonIsPredicate, ExecEvalJsonIsPredicate,
MakeExpandedObjectReadOnlyInternal, MakeExpandedObjectReadOnlyInternal,
InputFunctionCallSafe,
slot_getmissingattrs, slot_getmissingattrs,
slot_getsomeattrs_int, slot_getsomeattrs_int,
strlen, strlen,

View File

@ -16,7 +16,6 @@
#include "executor/nodeAgg.h" #include "executor/nodeAgg.h"
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
#include "nodes/miscnodes.h"
/* forward references to avoid circularity */ /* forward references to avoid circularity */
struct ExprEvalStep; struct ExprEvalStep;
@ -417,8 +416,7 @@ typedef struct ExprEvalStep
FunctionCallInfo fcinfo_data_out; FunctionCallInfo fcinfo_data_out;
/* lookup and call info for result type's input function */ /* lookup and call info for result type's input function */
FmgrInfo *finfo_in; FmgrInfo *finfo_in;
Oid typioparam; FunctionCallInfo fcinfo_data_in;
ErrorSaveContext *escontext;
} iocoerce; } iocoerce;
/* for EEOP_SQLVALUEFUNCTION */ /* for EEOP_SQLVALUEFUNCTION */
@ -549,7 +547,6 @@ typedef struct ExprEvalStep
bool *checknull; bool *checknull;
/* OID of domain type */ /* OID of domain type */
Oid resulttype; Oid resulttype;
ErrorSaveContext *escontext;
} domaincheck; } domaincheck;
/* for EEOP_CONVERT_ROWTYPE */ /* for EEOP_CONVERT_ROWTYPE */

View File

@ -75,7 +75,6 @@ extern PGDLLIMPORT LLVMTypeRef StructTupleTableSlot;
extern PGDLLIMPORT LLVMTypeRef StructHeapTupleTableSlot; extern PGDLLIMPORT LLVMTypeRef StructHeapTupleTableSlot;
extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleTableSlot; extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleTableSlot;
extern PGDLLIMPORT LLVMTypeRef StructMemoryContextData; extern PGDLLIMPORT LLVMTypeRef StructMemoryContextData;
extern PGDLLIMPORT LLVMTypeRef StructFmgrInfo;
extern PGDLLIMPORT LLVMTypeRef StructFunctionCallInfoData; extern PGDLLIMPORT LLVMTypeRef StructFunctionCallInfoData;
extern PGDLLIMPORT LLVMTypeRef StructExprContext; extern PGDLLIMPORT LLVMTypeRef StructExprContext;
extern PGDLLIMPORT LLVMTypeRef StructExprEvalStep; extern PGDLLIMPORT LLVMTypeRef StructExprEvalStep;
@ -83,7 +82,6 @@ extern PGDLLIMPORT LLVMTypeRef StructExprState;
extern PGDLLIMPORT LLVMTypeRef StructAggState; extern PGDLLIMPORT LLVMTypeRef StructAggState;
extern PGDLLIMPORT LLVMTypeRef StructAggStatePerTransData; extern PGDLLIMPORT LLVMTypeRef StructAggStatePerTransData;
extern PGDLLIMPORT LLVMTypeRef StructAggStatePerGroupData; extern PGDLLIMPORT LLVMTypeRef StructAggStatePerGroupData;
extern PGDLLIMPORT LLVMTypeRef StructErrorSaveContext;
extern PGDLLIMPORT LLVMValueRef AttributeTemplate; extern PGDLLIMPORT LLVMValueRef AttributeTemplate;

View File

@ -85,15 +85,6 @@ l_sizet_const(size_t i)
return LLVMConstInt(TypeSizeT, i, false); 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). * Emit constant boolean, as used for storage (e.g. global vars, structs).
*/ */

View File

@ -34,7 +34,6 @@
#include "fmgr.h" #include "fmgr.h"
#include "lib/ilist.h" #include "lib/ilist.h"
#include "lib/pairingheap.h" #include "lib/pairingheap.h"
#include "nodes/miscnodes.h"
#include "nodes/params.h" #include "nodes/params.h"
#include "nodes/plannodes.h" #include "nodes/plannodes.h"
#include "nodes/tidbitmap.h" #include "nodes/tidbitmap.h"
@ -130,12 +129,6 @@ typedef struct ExprState
Datum *innermost_domainval; Datum *innermost_domainval;
bool *innermost_domainnull; 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; } ExprState;