Eval implements the TypedExpr interface.
(ctx *EvalContext)
| 4080 | |
| 4081 | // Eval implements the TypedExpr interface. |
| 4082 | func (expr *FuncExpr) Eval(ctx *EvalContext) (Datum, error) { |
| 4083 | nullResult, args, err := expr.evalArgs(ctx) |
| 4084 | if err != nil { |
| 4085 | return nil, err |
| 4086 | } |
| 4087 | if nullResult { |
| 4088 | return DNull, err |
| 4089 | } |
| 4090 | |
| 4091 | res, err := expr.fn.Fn(ctx, args) |
| 4092 | if err != nil { |
| 4093 | // If we are facing an explicit error, propagate it unchanged. |
| 4094 | fName := expr.Func.String() |
| 4095 | if fName == `crdb_internal.force_error` { |
| 4096 | return nil, err |
| 4097 | } |
| 4098 | // Otherwise, wrap it with context. |
| 4099 | newErr := errors.Wrapf(err, "%s()", errors.Safe(fName)) |
| 4100 | // Count function errors as it flows out of the system. We need |
| 4101 | // to have this inside a if because if we are facing a retry |
| 4102 | // error, in particular those generated by |
| 4103 | // crdb_internal.force_retry(), Wrap() will propagate it as a |
| 4104 | // non-pgerror error (so that the executor can see it with the |
| 4105 | // right type). |
| 4106 | newErr = errors.WithTelemetry(newErr, fName+"()") |
| 4107 | return nil, newErr |
| 4108 | } |
| 4109 | if ctx.TestingKnobs.AssertFuncExprReturnTypes { |
| 4110 | if err := ensureExpectedType(expr.fn.FixedReturnType(), res); err != nil { |
| 4111 | return nil, errors.NewAssertionErrorWithWrappedErrf(err, "function %q", expr) |
| 4112 | } |
| 4113 | } |
| 4114 | return res, nil |
| 4115 | } |
| 4116 | |
| 4117 | // ensureExpectedType will return an error if a datum does not match the |
| 4118 | // provided type. If the expected type is Any or if the datum is a Null |
nothing calls this directly
no test coverage detected