RoutineExpr represents sequential execution of multiple statements. For example, it is used to represent execution of statements in the body of a user-defined function. It is only created by execbuilder - it is never constructed during parsing.
| 59 | // user-defined function. It is only created by execbuilder - it is never |
| 60 | // constructed during parsing. |
| 61 | type RoutineExpr struct { |
| 62 | // Name is a string name that describes the RoutineExpr, e.g., the name of |
| 63 | // the UDF that the RoutineExpr is built from. |
| 64 | Name string |
| 65 | |
| 66 | // Args contains the argument expressions to the routine. |
| 67 | Args TypedExprs |
| 68 | |
| 69 | // ForEachPlan generates a plan for each statement in the routine. |
| 70 | ForEachPlan RoutinePlanGenerator |
| 71 | |
| 72 | // Typ is the type of the routine's result. |
| 73 | Typ *types.T |
| 74 | |
| 75 | // EnableStepping configures step-wise execution for the statements in the |
| 76 | // routine. When true, statements within the routine will see mutations made |
| 77 | // by the statement invoking the routine. They will also see changes made by |
| 78 | // previous statements in the routine. When false, statements within the |
| 79 | // routine will see a snapshot of the data as of the start of the statement |
| 80 | // invoking the routine. |
| 81 | EnableStepping bool |
| 82 | |
| 83 | // CachedResult stores the datum that the routine evaluates to, if the |
| 84 | // routine is nullary (i.e., it has zero arguments) and stepping is |
| 85 | // disabled. It is populated during the first execution of the routine. |
| 86 | // Subsequent invocations of the routine return Result directly, rather than |
| 87 | // being executed. |
| 88 | // |
| 89 | // The cache is never cleared - it lives for the entire lifetime of the |
| 90 | // routine. Therefore, to "invalidate" the cache, a new routine must be |
| 91 | // created. For example, consider: |
| 92 | // |
| 93 | // CREATE TABLE t (i INT); |
| 94 | // CREATE FUNCTION f() RETURNS INT VOLATILE LANGUAGE SQL AS $$ |
| 95 | // SELECT i FROM (VALUES (1), (2)) v(i) WHERE i = (SELECT max(i) FROM t) |
| 96 | // $$; |
| 97 | // SELECT f() FROM (VALUES (3), (4)); |
| 98 | // |
| 99 | // The optimizer query plan for the SELECT contains two expressions that are |
| 100 | // built as routines, the UDF and the subquery within it. Each invocation of |
| 101 | // the UDF's routine will re-plan the body of the function, creating a new |
| 102 | // routine for the subquery. This effectively "invalidates" the cached |
| 103 | // result in the subquery routines each time the UDF is invoked. Within a |
| 104 | // single invocation of the UDF, however, the subquery will only be executed |
| 105 | // once and the cached result will be returned if the subquery is evaluated |
| 106 | // multiple times (e.g., for each value of i in v). |
| 107 | CachedResult Datum |
| 108 | |
| 109 | // CalledOnNullInput is true if the function should be called when any of |
| 110 | // its inputs are NULL. If false, the function will not be evaluated in the |
| 111 | // presence of null inputs, and will instead evaluate directly to NULL. |
| 112 | // |
| 113 | // NOTE: This boolean only affects evaluation of Routines within project-set |
| 114 | // operators. This can apply to scalar routines if they are used as data |
| 115 | // source (e.g. SELECT * FROM scalar_udf()), and always applies to |
| 116 | // set-returning routines. |
| 117 | // Strict non-set-returning routines are not invoked when their arguments |
| 118 | // are NULL because optbuilder wraps them in a CASE expressions. |
nothing calls this directly
no outgoing calls
no test coverage detected