Currently, when a valid ErrorSaveContext is passed to state->escontext
(ExprState->escontext),
ExecInitExprRec is designed to compile the entire expression tree
using soft errors.
Consider the following example:
create table t1(a text, b text, c int, d int8);
create domain d2 as text check (value <> 'a');
insert into t1(a, d) values('a', 2147483648);
select cast (cast(d as int) as text default null on conversion
error) from t1; -- queryA
select cast (cast(a as d2) as text default null on conversion
error) from t1; -- queryB
select cast (cast(a as int) as text default null on conversion
error) from t1; -- queryC
With V24, for queryC, ExecInitExprRec will compile the inner ``cast(a as int)``
error-safe way. This is just a subexpression of the main outer
cast(... as text default ...) node,
we may want the inner cast to be evaluated not error-safe.
To resolve this, we need to differentiate whether the specific nodes produced by
coerce_to_target_type->build_coercion_expression/coerce_to_domain
should be error-safe.
This means the resulting nodes (FuncExpr, ArrayCoerceExpr,
CoerceViaIO, CoerceToDomain) need a boolean flag.
We have already solved this for FuncExpr in [1] by adding an errorsafe field. We
now need to add a similar errorsafe boolean to CoerceViaIO and CoerceToDomain.
Therefore, for safe error evaluation: 1. ExecInitExprRec, ExprState->escontext
must be a valid ErrorSaveContext 2. The expression node (need a booleaan) to
tell ExecInitExprRec that compile this in an error safe manner.
[1]:
https://postgr.es/m/cacjufxgbw9int8qvm4qd9cpfkndnvdbqp7agxkoqda-jjzv...@mail.gmail.com
Summary: Making the above queryA, queryB, and queryC return NULL is
straightforward; however, forcing all of them to throw an error is non-trivial
because it involves compiling/evaluating some subexpressions in an
error-safe manner while
others are not.
What do you think?
--
jian
https://www.enterprisedb.com/