MCPcopy Create free account
hub / github.com/apache/cloudberry / exec_stmt_foreach_a

Function exec_stmt_foreach_a

src/pl/plpgsql/src/pl_exec.c:2947–3094  ·  view source on GitHub ↗

---------- * exec_stmt_foreach_a Loop over elements or slices of an array * * When looping over elements, the loop variable is the same type that the * array stores (eg: integer), when looping through slices, the loop variable * is an array of size and dimensions to match the size of the slice. * ---------- */

Source from the content-addressed store, hash-verified

2945 * ----------
2946 */
2947static int
2948exec_stmt_foreach_a(PLpgSQL_execstate *estate, PLpgSQL_stmt_foreach_a *stmt)
2949{
2950 ArrayType *arr;
2951 Oid arrtype;
2952 int32 arrtypmod;
2953 PLpgSQL_datum *loop_var;
2954 Oid loop_var_elem_type;
2955 bool found = false;
2956 int rc = PLPGSQL_RC_OK;
2957 MemoryContext stmt_mcontext;
2958 MemoryContext oldcontext;
2959 ArrayIterator array_iterator;
2960 Oid iterator_result_type;
2961 int32 iterator_result_typmod;
2962 Datum value;
2963 bool isnull;
2964
2965 /* get the value of the array expression */
2966 value = exec_eval_expr(estate, stmt->expr, &isnull, &arrtype, &arrtypmod);
2967 if (isnull)
2968 ereport(ERROR,
2969 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2970 errmsg("FOREACH expression must not be null")));
2971
2972 /*
2973 * Do as much as possible of the code below in stmt_mcontext, to avoid any
2974 * leaks from called subroutines. We need a private stmt_mcontext since
2975 * we'll be calling arbitrary statement code.
2976 */
2977 stmt_mcontext = get_stmt_mcontext(estate);
2978 push_stmt_mcontext(estate);
2979 oldcontext = MemoryContextSwitchTo(stmt_mcontext);
2980
2981 /* check the type of the expression - must be an array */
2982 if (!OidIsValid(get_element_type(arrtype)))
2983 ereport(ERROR,
2984 (errcode(ERRCODE_DATATYPE_MISMATCH),
2985 errmsg("FOREACH expression must yield an array, not type %s",
2986 format_type_be(arrtype))));
2987
2988 /*
2989 * We must copy the array into stmt_mcontext, else it will disappear in
2990 * exec_eval_cleanup. This is annoying, but cleanup will certainly happen
2991 * while running the loop body, so we have little choice.
2992 */
2993 arr = DatumGetArrayTypePCopy(value);
2994
2995 /* Clean up any leftover temporary memory */
2996 exec_eval_cleanup(estate);
2997
2998 /* Slice dimension must be less than or equal to array dimension */
2999 if (stmt->slice < 0 || stmt->slice > ARR_NDIM(arr))
3000 ereport(ERROR,
3001 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3002 errmsg("slice dimension (%d) is out of the valid range 0..%d",
3003 stmt->slice, ARR_NDIM(arr))));
3004

Callers 1

exec_stmtsFunction · 0.85

Calls 15

exec_eval_exprFunction · 0.85
get_stmt_mcontextFunction · 0.85
push_stmt_mcontextFunction · 0.85
MemoryContextSwitchToFunction · 0.85
get_element_typeFunction · 0.85
format_type_beFunction · 0.85
exec_eval_cleanupFunction · 0.85
array_create_iteratorFunction · 0.85
array_iterateFunction · 0.85
exec_assign_valueFunction · 0.85
exec_stmtsFunction · 0.85

Tested by

no test coverage detected