Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * pl_exec.c - Executor for the PL/pgSQL
4 : * procedural language
5 : *
6 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/pl/plpgsql/src/pl_exec.c
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 :
16 : #include "postgres.h"
17 :
18 : #include <ctype.h>
19 :
20 : #include "access/detoast.h"
21 : #include "access/htup_details.h"
22 : #include "access/tupconvert.h"
23 : #include "catalog/pg_proc.h"
24 : #include "catalog/pg_type.h"
25 : #include "executor/execExpr.h"
26 : #include "executor/spi.h"
27 : #include "executor/tstoreReceiver.h"
28 : #include "funcapi.h"
29 : #include "mb/stringinfo_mb.h"
30 : #include "miscadmin.h"
31 : #include "nodes/nodeFuncs.h"
32 : #include "nodes/supportnodes.h"
33 : #include "optimizer/optimizer.h"
34 : #include "parser/parse_coerce.h"
35 : #include "parser/parse_type.h"
36 : #include "plpgsql.h"
37 : #include "storage/proc.h"
38 : #include "tcop/cmdtag.h"
39 : #include "tcop/pquery.h"
40 : #include "utils/array.h"
41 : #include "utils/builtins.h"
42 : #include "utils/datum.h"
43 : #include "utils/fmgroids.h"
44 : #include "utils/lsyscache.h"
45 : #include "utils/memutils.h"
46 : #include "utils/rel.h"
47 : #include "utils/snapmgr.h"
48 : #include "utils/syscache.h"
49 : #include "utils/typcache.h"
50 :
51 : /*
52 : * All plpgsql function executions within a single transaction share the same
53 : * executor EState for evaluating "simple" expressions. Each function call
54 : * creates its own "eval_econtext" ExprContext within this estate for
55 : * per-evaluation workspace. eval_econtext is freed at normal function exit,
56 : * and the EState is freed at transaction end (in case of error, we assume
57 : * that the abort mechanisms clean it all up). Furthermore, any exception
58 : * block within a function has to have its own eval_econtext separate from
59 : * the containing function's, so that we can clean up ExprContext callbacks
60 : * properly at subtransaction exit. We maintain a stack that tracks the
61 : * individual econtexts so that we can clean up correctly at subxact exit.
62 : *
63 : * This arrangement is a bit tedious to maintain, but it's worth the trouble
64 : * so that we don't have to re-prepare simple expressions on each trip through
65 : * a function. (We assume the case to optimize is many repetitions of a
66 : * function within a transaction.)
67 : *
68 : * However, there's no value in trying to amortize simple expression setup
69 : * across multiple executions of a DO block (inline code block), since there
70 : * can never be any. If we use the shared EState for a DO block, the expr
71 : * state trees are effectively leaked till end of transaction, and that can
72 : * add up if the user keeps on submitting DO blocks. Therefore, each DO block
73 : * has its own simple-expression EState, which is cleaned up at exit from
74 : * plpgsql_inline_handler(). DO blocks still use the simple_econtext_stack,
75 : * though, so that subxact abort cleanup does the right thing.
76 : *
77 : * (However, if a DO block executes COMMIT or ROLLBACK, then exec_stmt_commit
78 : * or exec_stmt_rollback will unlink it from the DO's simple-expression EState
79 : * and create a new shared EState that will be used thenceforth. The original
80 : * EState will be cleaned up when we get back to plpgsql_inline_handler. This
81 : * is a bit ugly, but it isn't worth doing better, since scenarios like this
82 : * can't result in indefinite accumulation of state trees.)
83 : */
84 : typedef struct SimpleEcontextStackEntry
85 : {
86 : ExprContext *stack_econtext; /* a stacked econtext */
87 : SubTransactionId xact_subxid; /* ID for current subxact */
88 : struct SimpleEcontextStackEntry *next; /* next stack entry up */
89 : } SimpleEcontextStackEntry;
90 :
91 : static EState *shared_simple_eval_estate = NULL;
92 : static SimpleEcontextStackEntry *simple_econtext_stack = NULL;
93 :
94 : /*
95 : * In addition to the shared simple-eval EState, we have a shared resource
96 : * owner that holds refcounts on the CachedPlans for any "simple" expressions
97 : * we have evaluated in the current transaction. This allows us to avoid
98 : * continually grabbing and releasing a plan refcount when a simple expression
99 : * is used over and over. (DO blocks use their own resowner, in exactly the
100 : * same way described above for shared_simple_eval_estate.)
101 : */
102 : static ResourceOwner shared_simple_eval_resowner = NULL;
103 :
104 : /*
105 : * Memory management within a plpgsql function generally works with three
106 : * contexts:
107 : *
108 : * 1. Function-call-lifespan data, such as variable values, is kept in the
109 : * "main" context, a/k/a the "SPI Proc" context established by SPI_connect().
110 : * This is usually the CurrentMemoryContext while running code in this module
111 : * (which is not good, because careless coding can easily cause
112 : * function-lifespan memory leaks, but we live with it for now).
113 : *
114 : * 2. Some statement-execution routines need statement-lifespan workspace.
115 : * A suitable context is created on-demand by get_stmt_mcontext(), and must
116 : * be reset at the end of the requesting routine. Error recovery will clean
117 : * it up automatically. Nested statements requiring statement-lifespan
118 : * workspace will result in a stack of such contexts, see push_stmt_mcontext().
119 : *
120 : * 3. We use the eval_econtext's per-tuple memory context for expression
121 : * evaluation, and as a general-purpose workspace for short-lived allocations.
122 : * Such allocations usually aren't explicitly freed, but are left to be
123 : * cleaned up by a context reset, typically done by exec_eval_cleanup().
124 : *
125 : * These macros are for use in making short-lived allocations:
126 : */
127 : #define get_eval_mcontext(estate) \
128 : ((estate)->eval_econtext->ecxt_per_tuple_memory)
129 : #define eval_mcontext_alloc(estate, sz) \
130 : MemoryContextAlloc(get_eval_mcontext(estate), sz)
131 : #define eval_mcontext_alloc0(estate, sz) \
132 : MemoryContextAllocZero(get_eval_mcontext(estate), sz)
133 :
134 : /*
135 : * We use two session-wide hash tables for caching cast information.
136 : *
137 : * cast_expr_hash entries (of type plpgsql_CastExprHashEntry) hold compiled
138 : * expression trees for casts. These survive for the life of the session and
139 : * are shared across all PL/pgSQL functions and DO blocks. At some point it
140 : * might be worth invalidating them after pg_cast changes, but for the moment
141 : * we don't bother.
142 : *
143 : * There is a separate hash table shared_cast_hash (with entries of type
144 : * plpgsql_CastHashEntry) containing evaluation state trees for these
145 : * expressions, which are managed in the same way as simple expressions
146 : * (i.e., we assume cast expressions are always simple).
147 : *
148 : * As with simple expressions, DO blocks don't use the shared_cast_hash table
149 : * but must have their own evaluation state trees. This isn't ideal, but we
150 : * don't want to deal with multiple simple_eval_estates within a DO block.
151 : */
152 : typedef struct /* lookup key for cast info */
153 : {
154 : /* NB: we assume this struct contains no padding bytes */
155 : Oid srctype; /* source type for cast */
156 : Oid dsttype; /* destination type for cast */
157 : int32 srctypmod; /* source typmod for cast */
158 : int32 dsttypmod; /* destination typmod for cast */
159 : } plpgsql_CastHashKey;
160 :
161 : typedef struct /* cast_expr_hash table entry */
162 : {
163 : plpgsql_CastHashKey key; /* hash key --- MUST BE FIRST */
164 : Expr *cast_expr; /* cast expression, or NULL if no-op cast */
165 : CachedExpression *cast_cexpr; /* cached expression backing the above */
166 : } plpgsql_CastExprHashEntry;
167 :
168 : typedef struct /* cast_hash table entry */
169 : {
170 : plpgsql_CastHashKey key; /* hash key --- MUST BE FIRST */
171 : plpgsql_CastExprHashEntry *cast_centry; /* link to matching expr entry */
172 : /* ExprState is valid only when cast_lxid matches current LXID */
173 : ExprState *cast_exprstate; /* expression's eval tree */
174 : bool cast_in_use; /* true while we're executing eval tree */
175 : LocalTransactionId cast_lxid;
176 : } plpgsql_CastHashEntry;
177 :
178 : static HTAB *cast_expr_hash = NULL;
179 : static HTAB *shared_cast_hash = NULL;
180 :
181 : /*
182 : * LOOP_RC_PROCESSING encapsulates common logic for looping statements to
183 : * handle return/exit/continue result codes from the loop body statement(s).
184 : * It's meant to be used like this:
185 : *
186 : * int rc = PLPGSQL_RC_OK;
187 : * for (...)
188 : * {
189 : * ...
190 : * rc = exec_stmts(estate, stmt->body);
191 : * LOOP_RC_PROCESSING(stmt->label, break);
192 : * ...
193 : * }
194 : * return rc;
195 : *
196 : * If execution of the loop should terminate, LOOP_RC_PROCESSING will execute
197 : * "exit_action" (typically a "break" or "goto"), after updating "rc" to the
198 : * value the current statement should return. If execution should continue,
199 : * LOOP_RC_PROCESSING will do nothing except reset "rc" to PLPGSQL_RC_OK.
200 : *
201 : * estate and rc are implicit arguments to the macro.
202 : * estate->exitlabel is examined and possibly updated.
203 : */
204 : #define LOOP_RC_PROCESSING(looplabel, exit_action) \
205 : if (rc == PLPGSQL_RC_RETURN) \
206 : { \
207 : /* RETURN, so propagate RC_RETURN out */ \
208 : exit_action; \
209 : } \
210 : else if (rc == PLPGSQL_RC_EXIT) \
211 : { \
212 : if (estate->exitlabel == NULL) \
213 : { \
214 : /* unlabeled EXIT terminates this loop */ \
215 : rc = PLPGSQL_RC_OK; \
216 : exit_action; \
217 : } \
218 : else if ((looplabel) != NULL && \
219 : strcmp(looplabel, estate->exitlabel) == 0) \
220 : { \
221 : /* labeled EXIT matching this loop, so terminate loop */ \
222 : estate->exitlabel = NULL; \
223 : rc = PLPGSQL_RC_OK; \
224 : exit_action; \
225 : } \
226 : else \
227 : { \
228 : /* non-matching labeled EXIT, propagate RC_EXIT out */ \
229 : exit_action; \
230 : } \
231 : } \
232 : else if (rc == PLPGSQL_RC_CONTINUE) \
233 : { \
234 : if (estate->exitlabel == NULL) \
235 : { \
236 : /* unlabeled CONTINUE matches this loop, so continue in loop */ \
237 : rc = PLPGSQL_RC_OK; \
238 : } \
239 : else if ((looplabel) != NULL && \
240 : strcmp(looplabel, estate->exitlabel) == 0) \
241 : { \
242 : /* labeled CONTINUE matching this loop, so continue in loop */ \
243 : estate->exitlabel = NULL; \
244 : rc = PLPGSQL_RC_OK; \
245 : } \
246 : else \
247 : { \
248 : /* non-matching labeled CONTINUE, propagate RC_CONTINUE out */ \
249 : exit_action; \
250 : } \
251 : } \
252 : else \
253 : Assert(rc == PLPGSQL_RC_OK)
254 :
255 : /* State struct for count_param_references */
256 : typedef struct count_param_references_context
257 : {
258 : int paramid;
259 : int count;
260 : Param *last_param;
261 : } count_param_references_context;
262 :
263 :
264 : /************************************************************
265 : * Local function forward declarations
266 : ************************************************************/
267 : static void coerce_function_result_tuple(PLpgSQL_execstate *estate,
268 : TupleDesc tupdesc);
269 : static void plpgsql_exec_error_callback(void *arg);
270 : static void plpgsql_execsql_error_callback(void *arg);
271 : static void copy_plpgsql_datums(PLpgSQL_execstate *estate,
272 : PLpgSQL_function *func);
273 : static void plpgsql_fulfill_promise(PLpgSQL_execstate *estate,
274 : PLpgSQL_var *var);
275 : static MemoryContext get_stmt_mcontext(PLpgSQL_execstate *estate);
276 : static void push_stmt_mcontext(PLpgSQL_execstate *estate);
277 : static void pop_stmt_mcontext(PLpgSQL_execstate *estate);
278 :
279 : static int exec_toplevel_block(PLpgSQL_execstate *estate,
280 : PLpgSQL_stmt_block *block);
281 : static int exec_stmt_block(PLpgSQL_execstate *estate,
282 : PLpgSQL_stmt_block *block);
283 : static int exec_stmts(PLpgSQL_execstate *estate,
284 : List *stmts);
285 : static int exec_stmt_assign(PLpgSQL_execstate *estate,
286 : PLpgSQL_stmt_assign *stmt);
287 : static int exec_stmt_perform(PLpgSQL_execstate *estate,
288 : PLpgSQL_stmt_perform *stmt);
289 : static int exec_stmt_call(PLpgSQL_execstate *estate,
290 : PLpgSQL_stmt_call *stmt);
291 : static int exec_stmt_getdiag(PLpgSQL_execstate *estate,
292 : PLpgSQL_stmt_getdiag *stmt);
293 : static int exec_stmt_if(PLpgSQL_execstate *estate,
294 : PLpgSQL_stmt_if *stmt);
295 : static int exec_stmt_case(PLpgSQL_execstate *estate,
296 : PLpgSQL_stmt_case *stmt);
297 : static int exec_stmt_loop(PLpgSQL_execstate *estate,
298 : PLpgSQL_stmt_loop *stmt);
299 : static int exec_stmt_while(PLpgSQL_execstate *estate,
300 : PLpgSQL_stmt_while *stmt);
301 : static int exec_stmt_fori(PLpgSQL_execstate *estate,
302 : PLpgSQL_stmt_fori *stmt);
303 : static int exec_stmt_fors(PLpgSQL_execstate *estate,
304 : PLpgSQL_stmt_fors *stmt);
305 : static int exec_stmt_forc(PLpgSQL_execstate *estate,
306 : PLpgSQL_stmt_forc *stmt);
307 : static int exec_stmt_foreach_a(PLpgSQL_execstate *estate,
308 : PLpgSQL_stmt_foreach_a *stmt);
309 : static int exec_stmt_open(PLpgSQL_execstate *estate,
310 : PLpgSQL_stmt_open *stmt);
311 : static int exec_stmt_fetch(PLpgSQL_execstate *estate,
312 : PLpgSQL_stmt_fetch *stmt);
313 : static int exec_stmt_close(PLpgSQL_execstate *estate,
314 : PLpgSQL_stmt_close *stmt);
315 : static int exec_stmt_exit(PLpgSQL_execstate *estate,
316 : PLpgSQL_stmt_exit *stmt);
317 : static int exec_stmt_return(PLpgSQL_execstate *estate,
318 : PLpgSQL_stmt_return *stmt);
319 : static int exec_stmt_return_next(PLpgSQL_execstate *estate,
320 : PLpgSQL_stmt_return_next *stmt);
321 : static int exec_stmt_return_query(PLpgSQL_execstate *estate,
322 : PLpgSQL_stmt_return_query *stmt);
323 : static int exec_stmt_raise(PLpgSQL_execstate *estate,
324 : PLpgSQL_stmt_raise *stmt);
325 : static int exec_stmt_assert(PLpgSQL_execstate *estate,
326 : PLpgSQL_stmt_assert *stmt);
327 : static int exec_stmt_execsql(PLpgSQL_execstate *estate,
328 : PLpgSQL_stmt_execsql *stmt);
329 : static int exec_stmt_dynexecute(PLpgSQL_execstate *estate,
330 : PLpgSQL_stmt_dynexecute *stmt);
331 : static int exec_stmt_dynfors(PLpgSQL_execstate *estate,
332 : PLpgSQL_stmt_dynfors *stmt);
333 : static int exec_stmt_commit(PLpgSQL_execstate *estate,
334 : PLpgSQL_stmt_commit *stmt);
335 : static int exec_stmt_rollback(PLpgSQL_execstate *estate,
336 : PLpgSQL_stmt_rollback *stmt);
337 :
338 : static void plpgsql_estate_setup(PLpgSQL_execstate *estate,
339 : PLpgSQL_function *func,
340 : ReturnSetInfo *rsi,
341 : EState *simple_eval_estate,
342 : ResourceOwner simple_eval_resowner);
343 : static void exec_eval_cleanup(PLpgSQL_execstate *estate);
344 :
345 : static void exec_prepare_plan(PLpgSQL_execstate *estate,
346 : PLpgSQL_expr *expr, int cursorOptions);
347 : static void exec_simple_check_plan(PLpgSQL_execstate *estate, PLpgSQL_expr *expr);
348 : static bool exec_is_simple_query(PLpgSQL_expr *expr);
349 : static void exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan);
350 : static void exec_check_rw_parameter(PLpgSQL_expr *expr, int paramid);
351 : static bool count_param_references(Node *node,
352 : count_param_references_context *context);
353 : static void exec_check_assignable(PLpgSQL_execstate *estate, int dno);
354 : static bool exec_eval_simple_expr(PLpgSQL_execstate *estate,
355 : PLpgSQL_expr *expr,
356 : Datum *result,
357 : bool *isNull,
358 : Oid *rettype,
359 : int32 *rettypmod);
360 :
361 : static void exec_assign_expr(PLpgSQL_execstate *estate,
362 : PLpgSQL_datum *target,
363 : PLpgSQL_expr *expr);
364 : static void exec_assign_c_string(PLpgSQL_execstate *estate,
365 : PLpgSQL_datum *target,
366 : const char *str);
367 : static void exec_assign_value(PLpgSQL_execstate *estate,
368 : PLpgSQL_datum *target,
369 : Datum value, bool isNull,
370 : Oid valtype, int32 valtypmod);
371 : static void exec_eval_datum(PLpgSQL_execstate *estate,
372 : PLpgSQL_datum *datum,
373 : Oid *typeid,
374 : int32 *typetypmod,
375 : Datum *value,
376 : bool *isnull);
377 : static int exec_eval_integer(PLpgSQL_execstate *estate,
378 : PLpgSQL_expr *expr,
379 : bool *isNull);
380 : static bool exec_eval_boolean(PLpgSQL_execstate *estate,
381 : PLpgSQL_expr *expr,
382 : bool *isNull);
383 : static Datum exec_eval_expr(PLpgSQL_execstate *estate,
384 : PLpgSQL_expr *expr,
385 : bool *isNull,
386 : Oid *rettype,
387 : int32 *rettypmod);
388 : static int exec_run_select(PLpgSQL_execstate *estate,
389 : PLpgSQL_expr *expr, long maxtuples, Portal *portalP);
390 : static int exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
391 : Portal portal, bool prefetch_ok);
392 : static ParamListInfo setup_param_list(PLpgSQL_execstate *estate,
393 : PLpgSQL_expr *expr);
394 : static ParamExternData *plpgsql_param_fetch(ParamListInfo params,
395 : int paramid, bool speculative,
396 : ParamExternData *prm);
397 : static void plpgsql_param_compile(ParamListInfo params, Param *param,
398 : ExprState *state,
399 : Datum *resv, bool *resnull);
400 : static void plpgsql_param_eval_var_check(ExprState *state, ExprEvalStep *op,
401 : ExprContext *econtext);
402 : static void plpgsql_param_eval_var_transfer(ExprState *state, ExprEvalStep *op,
403 : ExprContext *econtext);
404 : static void plpgsql_param_eval_var(ExprState *state, ExprEvalStep *op,
405 : ExprContext *econtext);
406 : static void plpgsql_param_eval_var_ro(ExprState *state, ExprEvalStep *op,
407 : ExprContext *econtext);
408 : static void plpgsql_param_eval_recfield(ExprState *state, ExprEvalStep *op,
409 : ExprContext *econtext);
410 : static void plpgsql_param_eval_generic(ExprState *state, ExprEvalStep *op,
411 : ExprContext *econtext);
412 : static void plpgsql_param_eval_generic_ro(ExprState *state, ExprEvalStep *op,
413 : ExprContext *econtext);
414 : static void exec_move_row(PLpgSQL_execstate *estate,
415 : PLpgSQL_variable *target,
416 : HeapTuple tup, TupleDesc tupdesc);
417 : static void revalidate_rectypeid(PLpgSQL_rec *rec);
418 : static ExpandedRecordHeader *make_expanded_record_for_rec(PLpgSQL_execstate *estate,
419 : PLpgSQL_rec *rec,
420 : TupleDesc srctupdesc,
421 : ExpandedRecordHeader *srcerh);
422 : static void exec_move_row_from_fields(PLpgSQL_execstate *estate,
423 : PLpgSQL_variable *target,
424 : ExpandedRecordHeader *newerh,
425 : Datum *values, bool *nulls,
426 : TupleDesc tupdesc);
427 : static bool compatible_tupdescs(TupleDesc src_tupdesc, TupleDesc dst_tupdesc);
428 : static HeapTuple make_tuple_from_row(PLpgSQL_execstate *estate,
429 : PLpgSQL_row *row,
430 : TupleDesc tupdesc);
431 : static TupleDesc deconstruct_composite_datum(Datum value,
432 : HeapTupleData *tmptup);
433 : static void exec_move_row_from_datum(PLpgSQL_execstate *estate,
434 : PLpgSQL_variable *target,
435 : Datum value);
436 : static void instantiate_empty_record_variable(PLpgSQL_execstate *estate,
437 : PLpgSQL_rec *rec);
438 : static char *convert_value_to_string(PLpgSQL_execstate *estate,
439 : Datum value, Oid valtype);
440 : static inline Datum exec_cast_value(PLpgSQL_execstate *estate,
441 : Datum value, bool *isnull,
442 : Oid valtype, int32 valtypmod,
443 : Oid reqtype, int32 reqtypmod);
444 : static Datum do_cast_value(PLpgSQL_execstate *estate,
445 : Datum value, bool *isnull,
446 : Oid valtype, int32 valtypmod,
447 : Oid reqtype, int32 reqtypmod);
448 : static plpgsql_CastHashEntry *get_cast_hashentry(PLpgSQL_execstate *estate,
449 : Oid srctype, int32 srctypmod,
450 : Oid dsttype, int32 dsttypmod);
451 : static void exec_init_tuple_store(PLpgSQL_execstate *estate);
452 : static void exec_set_found(PLpgSQL_execstate *estate, bool state);
453 : static void plpgsql_create_econtext(PLpgSQL_execstate *estate);
454 : static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate);
455 : static void assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var,
456 : Datum newvalue, bool isnull, bool freeable);
457 : static void assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var,
458 : const char *str);
459 : static void assign_record_var(PLpgSQL_execstate *estate, PLpgSQL_rec *rec,
460 : ExpandedRecordHeader *erh);
461 : static ParamListInfo exec_eval_using_params(PLpgSQL_execstate *estate,
462 : List *params);
463 : static Portal exec_dynquery_with_params(PLpgSQL_execstate *estate,
464 : PLpgSQL_expr *dynquery, List *params,
465 : const char *portalname, int cursorOptions);
466 : static char *format_expr_params(PLpgSQL_execstate *estate,
467 : const PLpgSQL_expr *expr);
468 : static char *format_preparedparamsdata(PLpgSQL_execstate *estate,
469 : ParamListInfo paramLI);
470 : static PLpgSQL_variable *make_callstmt_target(PLpgSQL_execstate *estate,
471 : PLpgSQL_expr *expr);
472 :
473 :
474 : /* ----------
475 : * plpgsql_exec_function Called by the call handler for
476 : * function execution.
477 : *
478 : * This is also used to execute inline code blocks (DO blocks). The only
479 : * difference that this code is aware of is that for a DO block, we want
480 : * to use a private simple_eval_estate and a private simple_eval_resowner,
481 : * which are created and passed in by the caller. For regular functions,
482 : * pass NULL, which implies using shared_simple_eval_estate and
483 : * shared_simple_eval_resowner. (When using a private simple_eval_estate,
484 : * we must also use a private cast hashtable, but that's taken care of
485 : * within plpgsql_estate_setup.)
486 : * procedure_resowner is a resowner that will survive for the duration
487 : * of execution of this function/procedure. It is needed only if we
488 : * are doing non-atomic execution and there are CALL or DO statements
489 : * in the function; otherwise it can be NULL. We use it to hold refcounts
490 : * on the CALL/DO statements' plans.
491 : * ----------
492 : */
493 : Datum
494 43196 : plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
495 : EState *simple_eval_estate,
496 : ResourceOwner simple_eval_resowner,
497 : ResourceOwner procedure_resowner,
498 : bool atomic)
499 : {
500 : PLpgSQL_execstate estate;
501 : ErrorContextCallback plerrcontext;
502 : int i;
503 : int rc;
504 :
505 : /*
506 : * Setup the execution state
507 : */
508 43196 : plpgsql_estate_setup(&estate, func, (ReturnSetInfo *) fcinfo->resultinfo,
509 : simple_eval_estate, simple_eval_resowner);
510 43196 : estate.procedure_resowner = procedure_resowner;
511 43196 : estate.atomic = atomic;
512 :
513 : /*
514 : * Setup error traceback support for ereport()
515 : */
516 43196 : plerrcontext.callback = plpgsql_exec_error_callback;
517 43196 : plerrcontext.arg = &estate;
518 43196 : plerrcontext.previous = error_context_stack;
519 43196 : error_context_stack = &plerrcontext;
520 :
521 : /*
522 : * Make local execution copies of all the datums
523 : */
524 43196 : estate.err_text = gettext_noop("during initialization of execution state");
525 43196 : copy_plpgsql_datums(&estate, func);
526 :
527 : /*
528 : * Store the actual call argument values into the appropriate variables
529 : */
530 43196 : estate.err_text = gettext_noop("while storing call arguments into local variables");
531 97555 : for (i = 0; i < func->fn_nargs; i++)
532 : {
533 54359 : int n = func->fn_argvarnos[i];
534 :
535 54359 : switch (estate.datums[n]->dtype)
536 : {
537 53840 : case PLPGSQL_DTYPE_VAR:
538 : {
539 53840 : PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
540 :
541 53840 : assign_simple_var(&estate, var,
542 : fcinfo->args[i].value,
543 53840 : fcinfo->args[i].isnull,
544 : false);
545 :
546 : /*
547 : * If it's a varlena type, check to see if we received a
548 : * R/W expanded-object pointer. If so, we can commandeer
549 : * the object rather than having to copy it. If passed a
550 : * R/O expanded pointer, just keep it as the value of the
551 : * variable for the moment. (We can change it to R/W if
552 : * the variable gets modified, but that may very well
553 : * never happen.)
554 : *
555 : * Also, force any flat array value to be stored in
556 : * expanded form in our local variable, in hopes of
557 : * improving efficiency of uses of the variable. (This is
558 : * a hack, really: why only arrays? Need more thought
559 : * about which cases are likely to win. See also
560 : * typisarray-specific heuristic in exec_assign_value.)
561 : */
562 53840 : if (!var->isnull && var->datatype->typlen == -1)
563 : {
564 23371 : if (VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(var->value)))
565 : {
566 : /* take ownership of R/W object */
567 4 : assign_simple_var(&estate, var,
568 : TransferExpandedObject(var->value,
569 : estate.datum_context),
570 : false,
571 : true);
572 : }
573 23367 : else if (VARATT_IS_EXTERNAL_EXPANDED_RO(DatumGetPointer(var->value)))
574 : {
575 : /* R/O pointer, keep it as-is until assigned to */
576 : }
577 23323 : else if (var->datatype->typisarray)
578 : {
579 : /* flat array, so force to expanded form */
580 1881 : assign_simple_var(&estate, var,
581 : expand_array(var->value,
582 : estate.datum_context,
583 : NULL),
584 : false,
585 : true);
586 : }
587 : }
588 : }
589 53840 : break;
590 :
591 519 : case PLPGSQL_DTYPE_REC:
592 : {
593 519 : PLpgSQL_rec *rec = (PLpgSQL_rec *) estate.datums[n];
594 :
595 519 : if (!fcinfo->args[i].isnull)
596 : {
597 : /* Assign row value from composite datum */
598 480 : exec_move_row_from_datum(&estate,
599 : (PLpgSQL_variable *) rec,
600 : fcinfo->args[i].value);
601 : }
602 : else
603 : {
604 : /* If arg is null, set variable to null */
605 39 : exec_move_row(&estate, (PLpgSQL_variable *) rec,
606 : NULL, NULL);
607 : }
608 : /* clean up after exec_move_row() */
609 519 : exec_eval_cleanup(&estate);
610 : }
611 519 : break;
612 :
613 0 : default:
614 : /* Anything else should not be an argument variable */
615 0 : elog(ERROR, "unrecognized dtype: %d", func->datums[i]->dtype);
616 : }
617 : }
618 :
619 43196 : estate.err_text = gettext_noop("during function entry");
620 :
621 : /*
622 : * Set the magic variable FOUND to false
623 : */
624 43196 : exec_set_found(&estate, false);
625 :
626 : /*
627 : * Let the instrumentation plugin peek at this function
628 : */
629 43196 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
630 0 : ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
631 :
632 : /*
633 : * Now call the toplevel block of statements
634 : */
635 43196 : estate.err_text = NULL;
636 43196 : rc = exec_toplevel_block(&estate, func->action);
637 42653 : if (rc != PLPGSQL_RC_RETURN)
638 : {
639 4 : estate.err_text = NULL;
640 4 : ereport(ERROR,
641 : (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
642 : errmsg("control reached end of function without RETURN")));
643 : }
644 :
645 : /*
646 : * We got a return value - process it
647 : */
648 42649 : estate.err_text = gettext_noop("while casting return value to function's return type");
649 :
650 42649 : fcinfo->isnull = estate.retisnull;
651 :
652 42649 : if (estate.retisset)
653 : {
654 2426 : ReturnSetInfo *rsi = estate.rsi;
655 :
656 : /* Check caller can handle a set result */
657 2426 : if (!rsi || !IsA(rsi, ReturnSetInfo))
658 0 : ereport(ERROR,
659 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
660 : errmsg("set-valued function called in context that cannot accept a set")));
661 :
662 2426 : if (!(rsi->allowedModes & SFRM_Materialize))
663 0 : ereport(ERROR,
664 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
665 : errmsg("materialize mode required, but it is not allowed in this context")));
666 :
667 2426 : rsi->returnMode = SFRM_Materialize;
668 :
669 : /* If we produced any tuples, send back the result */
670 2426 : if (estate.tuple_store)
671 : {
672 : MemoryContext oldcxt;
673 :
674 2414 : rsi->setResult = estate.tuple_store;
675 2414 : oldcxt = MemoryContextSwitchTo(estate.tuple_store_cxt);
676 2414 : rsi->setDesc = CreateTupleDescCopy(estate.tuple_store_desc);
677 2414 : MemoryContextSwitchTo(oldcxt);
678 : }
679 2426 : estate.retval = (Datum) 0;
680 2426 : fcinfo->isnull = true;
681 : }
682 40223 : else if (!estate.retisnull)
683 : {
684 : /*
685 : * Cast result value to function's declared result type, and copy it
686 : * out to the upper executor memory context. We must treat tuple
687 : * results specially in order to deal with cases like rowtypes
688 : * involving dropped columns.
689 : */
690 39924 : if (estate.retistuple)
691 : {
692 : /* Don't need coercion if rowtype is known to match */
693 4321 : if (func->fn_rettype == estate.rettype &&
694 4282 : func->fn_rettype != RECORDOID)
695 : {
696 : /*
697 : * Copy the tuple result into upper executor memory context.
698 : * However, if we have a R/W expanded datum, we can just
699 : * transfer its ownership out to the upper context.
700 : */
701 142 : estate.retval = SPI_datumTransfer(estate.retval,
702 : false,
703 : -1);
704 : }
705 : else
706 : {
707 : /*
708 : * Need to look up the expected result type. XXX would be
709 : * better to cache the tupdesc instead of repeating
710 : * get_call_result_type(), but the only easy place to save it
711 : * is in the PLpgSQL_function struct, and that's too
712 : * long-lived: composite types could change during the
713 : * existence of a PLpgSQL_function.
714 : */
715 : Oid resultTypeId;
716 : TupleDesc tupdesc;
717 :
718 4179 : switch (get_call_result_type(fcinfo, &resultTypeId, &tupdesc))
719 : {
720 4135 : case TYPEFUNC_COMPOSITE:
721 : /* got the expected result rowtype, now coerce it */
722 4135 : coerce_function_result_tuple(&estate, tupdesc);
723 4119 : break;
724 8 : case TYPEFUNC_COMPOSITE_DOMAIN:
725 : /* got the expected result rowtype, now coerce it */
726 8 : coerce_function_result_tuple(&estate, tupdesc);
727 : /* and check domain constraints */
728 : /* XXX allowing caching here would be good, too */
729 8 : domain_check(estate.retval, false, resultTypeId,
730 : NULL, NULL);
731 4 : break;
732 36 : case TYPEFUNC_RECORD:
733 :
734 : /*
735 : * Failed to determine actual type of RECORD. We
736 : * could raise an error here, but what this means in
737 : * practice is that the caller is expecting any old
738 : * generic rowtype, so we don't really need to be
739 : * restrictive. Pass back the generated result as-is.
740 : */
741 36 : estate.retval = SPI_datumTransfer(estate.retval,
742 : false,
743 : -1);
744 36 : break;
745 0 : default:
746 : /* shouldn't get here if retistuple is true ... */
747 0 : elog(ERROR, "return type must be a row type");
748 : break;
749 : }
750 : }
751 : }
752 : else
753 : {
754 : /* Scalar case: use exec_cast_value */
755 35603 : estate.retval = exec_cast_value(&estate,
756 : estate.retval,
757 : &fcinfo->isnull,
758 : estate.rettype,
759 : -1,
760 : func->fn_rettype,
761 : -1);
762 :
763 : /*
764 : * If the function's return type isn't by value, copy the value
765 : * into upper executor memory context. However, if we have a R/W
766 : * expanded datum, we can just transfer its ownership out to the
767 : * upper executor context.
768 : */
769 35581 : if (!fcinfo->isnull && !func->fn_retbyval)
770 3536 : estate.retval = SPI_datumTransfer(estate.retval,
771 : false,
772 : func->fn_rettyplen);
773 : }
774 : }
775 : else
776 : {
777 : /*
778 : * We're returning a NULL, which normally requires no conversion work
779 : * regardless of datatypes. But, if we are casting it to a domain
780 : * return type, we'd better check that the domain's constraints pass.
781 : */
782 299 : if (func->fn_retisdomain)
783 3 : estate.retval = exec_cast_value(&estate,
784 : estate.retval,
785 : &fcinfo->isnull,
786 : estate.rettype,
787 : -1,
788 : func->fn_rettype,
789 : -1);
790 : }
791 :
792 42606 : estate.err_text = gettext_noop("during function exit");
793 :
794 : /*
795 : * Let the instrumentation plugin peek at this function
796 : */
797 42606 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
798 0 : ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
799 :
800 : /* Clean up any leftover temporary memory */
801 42606 : plpgsql_destroy_econtext(&estate);
802 42606 : exec_eval_cleanup(&estate);
803 : /* stmt_mcontext will be destroyed when function's main context is */
804 :
805 : /*
806 : * Pop the error context stack
807 : */
808 42606 : error_context_stack = plerrcontext.previous;
809 :
810 : /*
811 : * Return the function's result
812 : */
813 42606 : return estate.retval;
814 : }
815 :
816 : /*
817 : * Helper for plpgsql_exec_function: coerce composite result to the specified
818 : * tuple descriptor, and copy it out to upper executor memory. This is split
819 : * out mostly for cosmetic reasons --- the logic would be very deeply nested
820 : * otherwise.
821 : *
822 : * estate->retval is updated in-place.
823 : */
824 : static void
825 4143 : coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc)
826 : {
827 : HeapTuple rettup;
828 : TupleDesc retdesc;
829 : TupleConversionMap *tupmap;
830 :
831 : /* We assume exec_stmt_return verified that result is composite */
832 : Assert(type_is_rowtype(estate->rettype));
833 :
834 : /* We can special-case expanded records for speed */
835 4143 : if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(estate->retval)))
836 : {
837 26 : ExpandedRecordHeader *erh = (ExpandedRecordHeader *) DatumGetEOHP(estate->retval);
838 :
839 : Assert(erh->er_magic == ER_MAGIC);
840 :
841 : /* Extract record's TupleDesc */
842 26 : retdesc = expanded_record_get_tupdesc(erh);
843 :
844 : /* check rowtype compatibility */
845 26 : tupmap = convert_tuples_by_position(retdesc,
846 : tupdesc,
847 : gettext_noop("returned record type does not match expected record type"));
848 :
849 : /* it might need conversion */
850 20 : if (tupmap)
851 : {
852 1 : rettup = expanded_record_get_tuple(erh);
853 : Assert(rettup);
854 1 : rettup = execute_attr_map_tuple(rettup, tupmap);
855 :
856 : /*
857 : * Copy tuple to upper executor memory, as a tuple Datum. Make
858 : * sure it is labeled with the caller-supplied tuple type.
859 : */
860 1 : estate->retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc));
861 : /* no need to free map, we're about to return anyway */
862 : }
863 19 : else if (!(tupdesc->tdtypeid == erh->er_decltypeid ||
864 8 : (tupdesc->tdtypeid == RECORDOID &&
865 0 : !ExpandedRecordIsDomain(erh))))
866 8 : {
867 : /*
868 : * The expanded record has the right physical tupdesc, but the
869 : * wrong type ID. (Typically, the expanded record is RECORDOID
870 : * but the function is declared to return a named composite type.
871 : * As in exec_move_row_from_datum, we don't allow returning a
872 : * composite-domain record from a function declared to return
873 : * RECORD.) So we must flatten the record to a tuple datum and
874 : * overwrite its type fields with the right thing. spi.c doesn't
875 : * provide any easy way to deal with this case, so we end up
876 : * duplicating the guts of datumCopy() :-(
877 : */
878 : Size resultsize;
879 : HeapTupleHeader tuphdr;
880 :
881 8 : resultsize = EOH_get_flat_size(&erh->hdr);
882 8 : tuphdr = (HeapTupleHeader) SPI_palloc(resultsize);
883 8 : EOH_flatten_into(&erh->hdr, tuphdr, resultsize);
884 8 : HeapTupleHeaderSetTypeId(tuphdr, tupdesc->tdtypeid);
885 8 : HeapTupleHeaderSetTypMod(tuphdr, tupdesc->tdtypmod);
886 8 : estate->retval = PointerGetDatum(tuphdr);
887 : }
888 : else
889 : {
890 : /*
891 : * We need only copy result into upper executor memory context.
892 : * However, if we have a R/W expanded datum, we can just transfer
893 : * its ownership out to the upper executor context.
894 : */
895 11 : estate->retval = SPI_datumTransfer(estate->retval,
896 : false,
897 : -1);
898 : }
899 : }
900 : else
901 : {
902 : /* Convert composite datum to a HeapTuple and TupleDesc */
903 : HeapTupleData tmptup;
904 :
905 4117 : retdesc = deconstruct_composite_datum(estate->retval, &tmptup);
906 4117 : rettup = &tmptup;
907 :
908 : /* check rowtype compatibility */
909 4117 : tupmap = convert_tuples_by_position(retdesc,
910 : tupdesc,
911 : gettext_noop("returned record type does not match expected record type"));
912 :
913 : /* it might need conversion */
914 4107 : if (tupmap)
915 1 : rettup = execute_attr_map_tuple(rettup, tupmap);
916 :
917 : /*
918 : * Copy tuple to upper executor memory, as a tuple Datum. Make sure
919 : * it is labeled with the caller-supplied tuple type.
920 : */
921 4107 : estate->retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc));
922 :
923 : /* no need to free map, we're about to return anyway */
924 :
925 4107 : ReleaseTupleDesc(retdesc);
926 : }
927 4127 : }
928 :
929 :
930 : /* ----------
931 : * plpgsql_exec_trigger Called by the call handler for
932 : * trigger execution.
933 : * ----------
934 : */
935 : HeapTuple
936 10006 : plpgsql_exec_trigger(PLpgSQL_function *func,
937 : TriggerData *trigdata)
938 : {
939 : PLpgSQL_execstate estate;
940 : ErrorContextCallback plerrcontext;
941 : int rc;
942 : TupleDesc tupdesc;
943 : PLpgSQL_rec *rec_new,
944 : *rec_old;
945 : HeapTuple rettup;
946 :
947 : /*
948 : * Setup the execution state
949 : */
950 10006 : plpgsql_estate_setup(&estate, func, NULL, NULL, NULL);
951 10006 : estate.trigdata = trigdata;
952 :
953 : /*
954 : * Setup error traceback support for ereport()
955 : */
956 10006 : plerrcontext.callback = plpgsql_exec_error_callback;
957 10006 : plerrcontext.arg = &estate;
958 10006 : plerrcontext.previous = error_context_stack;
959 10006 : error_context_stack = &plerrcontext;
960 :
961 : /*
962 : * Make local execution copies of all the datums
963 : */
964 10006 : estate.err_text = gettext_noop("during initialization of execution state");
965 10006 : copy_plpgsql_datums(&estate, func);
966 :
967 : /*
968 : * Put the OLD and NEW tuples into record variables
969 : *
970 : * We set up expanded records for both variables even though only one may
971 : * have a value. This allows record references to succeed in functions
972 : * that are used for multiple trigger types. For example, we might have a
973 : * test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')", which should
974 : * work regardless of the current trigger type. If a value is actually
975 : * fetched from an unsupplied tuple, it will read as NULL.
976 : */
977 10006 : tupdesc = RelationGetDescr(trigdata->tg_relation);
978 :
979 10006 : rec_new = (PLpgSQL_rec *) (estate.datums[func->new_varno]);
980 10006 : rec_old = (PLpgSQL_rec *) (estate.datums[func->old_varno]);
981 :
982 10006 : rec_new->erh = make_expanded_record_from_tupdesc(tupdesc,
983 : estate.datum_context);
984 10006 : rec_old->erh = make_expanded_record_from_exprecord(rec_new->erh,
985 : estate.datum_context);
986 :
987 10006 : if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
988 : {
989 : /*
990 : * Per-statement triggers don't use OLD/NEW variables
991 : */
992 : }
993 9026 : else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
994 : {
995 4651 : expanded_record_set_tuple(rec_new->erh, trigdata->tg_trigtuple,
996 : false, false);
997 : }
998 4375 : else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
999 : {
1000 4066 : expanded_record_set_tuple(rec_new->erh, trigdata->tg_newtuple,
1001 : false, false);
1002 4066 : expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
1003 : false, false);
1004 :
1005 : /*
1006 : * In BEFORE trigger, stored generated columns are not computed yet,
1007 : * so make them null in the NEW row. (Only needed in UPDATE branch;
1008 : * in the INSERT case, they are already null, but in UPDATE, the field
1009 : * still contains the old value.) Alternatively, we could construct a
1010 : * whole new row structure without the generated columns, but this way
1011 : * seems more efficient and potentially less confusing.
1012 : */
1013 4066 : if (tupdesc->constr && tupdesc->constr->has_generated_stored &&
1014 29 : TRIGGER_FIRED_BEFORE(trigdata->tg_event))
1015 : {
1016 65 : for (int i = 0; i < tupdesc->natts; i++)
1017 44 : if (TupleDescAttr(tupdesc, i)->attgenerated == ATTRIBUTE_GENERATED_STORED)
1018 21 : expanded_record_set_field_internal(rec_new->erh,
1019 : i + 1,
1020 : (Datum) 0,
1021 : true, /* isnull */
1022 : false, false);
1023 : }
1024 : }
1025 309 : else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
1026 : {
1027 309 : expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple,
1028 : false, false);
1029 : }
1030 : else
1031 0 : elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE");
1032 :
1033 : /* Make transition tables visible to this SPI connection */
1034 10006 : rc = SPI_register_trigger_data(trigdata);
1035 : Assert(rc >= 0);
1036 :
1037 10006 : estate.err_text = gettext_noop("during function entry");
1038 :
1039 : /*
1040 : * Set the magic variable FOUND to false
1041 : */
1042 10006 : exec_set_found(&estate, false);
1043 :
1044 : /*
1045 : * Let the instrumentation plugin peek at this function
1046 : */
1047 10006 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
1048 0 : ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
1049 :
1050 : /*
1051 : * Now call the toplevel block of statements
1052 : */
1053 10006 : estate.err_text = NULL;
1054 10006 : rc = exec_toplevel_block(&estate, func->action);
1055 9868 : if (rc != PLPGSQL_RC_RETURN)
1056 : {
1057 0 : estate.err_text = NULL;
1058 0 : ereport(ERROR,
1059 : (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
1060 : errmsg("control reached end of trigger procedure without RETURN")));
1061 : }
1062 :
1063 9868 : estate.err_text = gettext_noop("during function exit");
1064 :
1065 9868 : if (estate.retisset)
1066 0 : ereport(ERROR,
1067 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1068 : errmsg("trigger procedure cannot return a set")));
1069 :
1070 : /*
1071 : * Check that the returned tuple structure has the same attributes, the
1072 : * relation that fired the trigger has. A per-statement trigger always
1073 : * needs to return NULL, so we ignore any return value the function itself
1074 : * produces (XXX: is this a good idea?)
1075 : *
1076 : * XXX This way it is possible, that the trigger returns a tuple where
1077 : * attributes don't have the correct atttypmod's length. It's up to the
1078 : * trigger's programmer to ensure that this doesn't happen. Jan
1079 : */
1080 9868 : if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
1081 1810 : rettup = NULL;
1082 : else
1083 : {
1084 : TupleDesc retdesc;
1085 : TupleConversionMap *tupmap;
1086 :
1087 : /* We assume exec_stmt_return verified that result is composite */
1088 : Assert(type_is_rowtype(estate.rettype));
1089 :
1090 : /* We can special-case expanded records for speed */
1091 8058 : if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(estate.retval)))
1092 : {
1093 8056 : ExpandedRecordHeader *erh = (ExpandedRecordHeader *) DatumGetEOHP(estate.retval);
1094 :
1095 : Assert(erh->er_magic == ER_MAGIC);
1096 :
1097 : /* Extract HeapTuple and TupleDesc */
1098 8056 : rettup = expanded_record_get_tuple(erh);
1099 : Assert(rettup);
1100 8056 : retdesc = expanded_record_get_tupdesc(erh);
1101 :
1102 8056 : if (retdesc != RelationGetDescr(trigdata->tg_relation))
1103 : {
1104 : /* check rowtype compatibility */
1105 2 : tupmap = convert_tuples_by_position(retdesc,
1106 2 : RelationGetDescr(trigdata->tg_relation),
1107 : gettext_noop("returned row structure does not match the structure of the triggering table"));
1108 : /* it might need conversion */
1109 2 : if (tupmap)
1110 2 : rettup = execute_attr_map_tuple(rettup, tupmap);
1111 : /* no need to free map, we're about to return anyway */
1112 : }
1113 :
1114 : /*
1115 : * Copy tuple to upper executor memory. But if user just did
1116 : * "return new" or "return old" without changing anything, there's
1117 : * no need to copy; we can return the original tuple (which will
1118 : * save a few cycles in trigger.c as well as here).
1119 : */
1120 8056 : if (rettup != trigdata->tg_newtuple &&
1121 5105 : rettup != trigdata->tg_trigtuple)
1122 1354 : rettup = SPI_copytuple(rettup);
1123 : }
1124 : else
1125 : {
1126 : /* Convert composite datum to a HeapTuple and TupleDesc */
1127 : HeapTupleData tmptup;
1128 :
1129 2 : retdesc = deconstruct_composite_datum(estate.retval, &tmptup);
1130 2 : rettup = &tmptup;
1131 :
1132 : /* check rowtype compatibility */
1133 2 : tupmap = convert_tuples_by_position(retdesc,
1134 2 : RelationGetDescr(trigdata->tg_relation),
1135 : gettext_noop("returned row structure does not match the structure of the triggering table"));
1136 : /* it might need conversion */
1137 2 : if (tupmap)
1138 2 : rettup = execute_attr_map_tuple(rettup, tupmap);
1139 :
1140 2 : ReleaseTupleDesc(retdesc);
1141 : /* no need to free map, we're about to return anyway */
1142 :
1143 : /* Copy tuple to upper executor memory */
1144 2 : rettup = SPI_copytuple(rettup);
1145 : }
1146 : }
1147 :
1148 : /*
1149 : * Let the instrumentation plugin peek at this function
1150 : */
1151 9868 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1152 0 : ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1153 :
1154 : /* Clean up any leftover temporary memory */
1155 9868 : plpgsql_destroy_econtext(&estate);
1156 9868 : exec_eval_cleanup(&estate);
1157 : /* stmt_mcontext will be destroyed when function's main context is */
1158 :
1159 : /*
1160 : * Pop the error context stack
1161 : */
1162 9868 : error_context_stack = plerrcontext.previous;
1163 :
1164 : /*
1165 : * Return the trigger's result
1166 : */
1167 9868 : return rettup;
1168 : }
1169 :
1170 : /* ----------
1171 : * plpgsql_exec_event_trigger Called by the call handler for
1172 : * event trigger execution.
1173 : * ----------
1174 : */
1175 : void
1176 1170 : plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
1177 : {
1178 : PLpgSQL_execstate estate;
1179 : ErrorContextCallback plerrcontext;
1180 : int rc;
1181 :
1182 : /*
1183 : * Setup the execution state
1184 : */
1185 1170 : plpgsql_estate_setup(&estate, func, NULL, NULL, NULL);
1186 1170 : estate.evtrigdata = trigdata;
1187 :
1188 : /*
1189 : * Setup error traceback support for ereport()
1190 : */
1191 1170 : plerrcontext.callback = plpgsql_exec_error_callback;
1192 1170 : plerrcontext.arg = &estate;
1193 1170 : plerrcontext.previous = error_context_stack;
1194 1170 : error_context_stack = &plerrcontext;
1195 :
1196 : /*
1197 : * Make local execution copies of all the datums
1198 : */
1199 1170 : estate.err_text = gettext_noop("during initialization of execution state");
1200 1170 : copy_plpgsql_datums(&estate, func);
1201 :
1202 : /*
1203 : * Let the instrumentation plugin peek at this function
1204 : */
1205 1170 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_beg)
1206 0 : ((*plpgsql_plugin_ptr)->func_beg) (&estate, func);
1207 :
1208 : /*
1209 : * Now call the toplevel block of statements
1210 : */
1211 1170 : estate.err_text = NULL;
1212 1170 : rc = exec_toplevel_block(&estate, func->action);
1213 1154 : if (rc != PLPGSQL_RC_RETURN)
1214 : {
1215 0 : estate.err_text = NULL;
1216 0 : ereport(ERROR,
1217 : (errcode(ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT),
1218 : errmsg("control reached end of trigger procedure without RETURN")));
1219 : }
1220 :
1221 1154 : estate.err_text = gettext_noop("during function exit");
1222 :
1223 : /*
1224 : * Let the instrumentation plugin peek at this function
1225 : */
1226 1154 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->func_end)
1227 0 : ((*plpgsql_plugin_ptr)->func_end) (&estate, func);
1228 :
1229 : /* Clean up any leftover temporary memory */
1230 1154 : plpgsql_destroy_econtext(&estate);
1231 1154 : exec_eval_cleanup(&estate);
1232 : /* stmt_mcontext will be destroyed when function's main context is */
1233 :
1234 : /*
1235 : * Pop the error context stack
1236 : */
1237 1154 : error_context_stack = plerrcontext.previous;
1238 1154 : }
1239 :
1240 : /*
1241 : * error context callback to let us supply a call-stack traceback
1242 : */
1243 : static void
1244 15711 : plpgsql_exec_error_callback(void *arg)
1245 : {
1246 15711 : PLpgSQL_execstate *estate = (PLpgSQL_execstate *) arg;
1247 : int err_lineno;
1248 :
1249 : /*
1250 : * If err_var is set, report the variable's declaration line number.
1251 : * Otherwise, if err_stmt is set, report the err_stmt's line number. When
1252 : * err_stmt is not set, we're in function entry/exit, or some such place
1253 : * not attached to a specific line number.
1254 : */
1255 15711 : if (estate->err_var != NULL)
1256 34 : err_lineno = estate->err_var->lineno;
1257 15677 : else if (estate->err_stmt != NULL)
1258 15630 : err_lineno = estate->err_stmt->lineno;
1259 : else
1260 47 : err_lineno = 0;
1261 :
1262 15711 : if (estate->err_text != NULL)
1263 : {
1264 : /*
1265 : * We don't expend the cycles to run gettext() on err_text unless we
1266 : * actually need it. Therefore, places that set up err_text should
1267 : * use gettext_noop() to ensure the strings get recorded in the
1268 : * message dictionary.
1269 : */
1270 78 : if (err_lineno > 0)
1271 : {
1272 : /*
1273 : * translator: last %s is a phrase such as "during statement block
1274 : * local variable initialization"
1275 : */
1276 35 : errcontext("PL/pgSQL function %s line %d %s",
1277 35 : estate->func->fn_signature,
1278 : err_lineno,
1279 : _(estate->err_text));
1280 : }
1281 : else
1282 : {
1283 : /*
1284 : * translator: last %s is a phrase such as "while storing call
1285 : * arguments into local variables"
1286 : */
1287 43 : errcontext("PL/pgSQL function %s %s",
1288 43 : estate->func->fn_signature,
1289 : _(estate->err_text));
1290 : }
1291 : }
1292 15633 : else if (estate->err_stmt != NULL && err_lineno > 0)
1293 : {
1294 : /* translator: last %s is a plpgsql statement type name */
1295 15629 : errcontext("PL/pgSQL function %s line %d at %s",
1296 15629 : estate->func->fn_signature,
1297 : err_lineno,
1298 : plpgsql_stmt_typename(estate->err_stmt));
1299 : }
1300 : else
1301 4 : errcontext("PL/pgSQL function %s",
1302 4 : estate->func->fn_signature);
1303 15711 : }
1304 :
1305 : /*
1306 : * error context callback used for "SELECT simple-expr INTO var"
1307 : *
1308 : * This should match the behavior of spi.c's _SPI_error_callback(),
1309 : * so that the construct still reports errors the same as it did
1310 : * before we optimized it with the simple-expression code path.
1311 : */
1312 : static void
1313 4 : plpgsql_execsql_error_callback(void *arg)
1314 : {
1315 4 : PLpgSQL_expr *expr = (PLpgSQL_expr *) arg;
1316 4 : const char *query = expr->query;
1317 : int syntaxerrposition;
1318 :
1319 : /*
1320 : * If there is a syntax error position, convert to internal syntax error;
1321 : * otherwise treat the query as an item of context stack
1322 : */
1323 4 : syntaxerrposition = geterrposition();
1324 4 : if (syntaxerrposition > 0)
1325 : {
1326 0 : errposition(0);
1327 0 : internalerrposition(syntaxerrposition);
1328 0 : internalerrquery(query);
1329 : }
1330 : else
1331 : {
1332 4 : errcontext("SQL statement \"%s\"", query);
1333 : }
1334 4 : }
1335 :
1336 :
1337 : /* ----------
1338 : * Support function for initializing local execution variables
1339 : * ----------
1340 : */
1341 : static void
1342 54372 : copy_plpgsql_datums(PLpgSQL_execstate *estate,
1343 : PLpgSQL_function *func)
1344 : {
1345 54372 : int ndatums = estate->ndatums;
1346 : PLpgSQL_datum **indatums;
1347 : PLpgSQL_datum **outdatums;
1348 : char *workspace;
1349 : char *ws_next;
1350 : int i;
1351 :
1352 : /* Allocate local datum-pointer array */
1353 54372 : estate->datums = palloc_array(PLpgSQL_datum *, ndatums);
1354 :
1355 : /*
1356 : * To reduce palloc overhead, we make a single palloc request for all the
1357 : * space needed for locally-instantiated datums.
1358 : */
1359 54372 : workspace = palloc(func->copiable_size);
1360 54372 : ws_next = workspace;
1361 :
1362 : /* Fill datum-pointer array, copying datums into workspace as needed */
1363 54372 : indatums = func->datums;
1364 54372 : outdatums = estate->datums;
1365 376024 : for (i = 0; i < ndatums; i++)
1366 : {
1367 321652 : PLpgSQL_datum *indatum = indatums[i];
1368 : PLpgSQL_datum *outdatum;
1369 :
1370 : /* This must agree with plpgsql_finish_datums on what is copiable */
1371 321652 : switch (indatum->dtype)
1372 : {
1373 257572 : case PLPGSQL_DTYPE_VAR:
1374 : case PLPGSQL_DTYPE_PROMISE:
1375 257572 : outdatum = (PLpgSQL_datum *) ws_next;
1376 257572 : memcpy(outdatum, indatum, sizeof(PLpgSQL_var));
1377 257572 : ws_next += MAXALIGN(sizeof(PLpgSQL_var));
1378 257572 : break;
1379 :
1380 23941 : case PLPGSQL_DTYPE_REC:
1381 23941 : outdatum = (PLpgSQL_datum *) ws_next;
1382 23941 : memcpy(outdatum, indatum, sizeof(PLpgSQL_rec));
1383 23941 : ws_next += MAXALIGN(sizeof(PLpgSQL_rec));
1384 23941 : break;
1385 :
1386 40139 : case PLPGSQL_DTYPE_ROW:
1387 : case PLPGSQL_DTYPE_RECFIELD:
1388 :
1389 : /*
1390 : * These datum records are read-only at runtime, so no need to
1391 : * copy them (well, RECFIELD contains cached data, but we'd
1392 : * just as soon centralize the caching anyway).
1393 : */
1394 40139 : outdatum = indatum;
1395 40139 : break;
1396 :
1397 0 : default:
1398 0 : elog(ERROR, "unrecognized dtype: %d", indatum->dtype);
1399 : outdatum = NULL; /* keep compiler quiet */
1400 : break;
1401 : }
1402 :
1403 321652 : outdatums[i] = outdatum;
1404 : }
1405 :
1406 : Assert(ws_next == workspace + func->copiable_size);
1407 54372 : }
1408 :
1409 : /*
1410 : * If the variable has an armed "promise", compute the promised value
1411 : * and assign it to the variable.
1412 : * The assignment automatically disarms the promise.
1413 : */
1414 : static void
1415 14891 : plpgsql_fulfill_promise(PLpgSQL_execstate *estate,
1416 : PLpgSQL_var *var)
1417 : {
1418 : MemoryContext oldcontext;
1419 :
1420 14891 : if (var->promise == PLPGSQL_PROMISE_NONE)
1421 4470 : return; /* nothing to do */
1422 :
1423 : /*
1424 : * This will typically be invoked in a short-lived context such as the
1425 : * mcontext. We must create variable values in the estate's datum
1426 : * context. This quick-and-dirty solution risks leaking some additional
1427 : * cruft there, but since any one promise is honored at most once per
1428 : * function call, it's probably not worth being more careful.
1429 : */
1430 10421 : oldcontext = MemoryContextSwitchTo(estate->datum_context);
1431 :
1432 10421 : switch (var->promise)
1433 : {
1434 983 : case PLPGSQL_PROMISE_TG_NAME:
1435 983 : if (estate->trigdata == NULL)
1436 0 : elog(ERROR, "trigger promise is not in a trigger function");
1437 983 : assign_simple_var(estate, var,
1438 983 : DirectFunctionCall1(namein,
1439 : CStringGetDatum(estate->trigdata->tg_trigger->tgname)),
1440 : false, true);
1441 983 : break;
1442 :
1443 1611 : case PLPGSQL_PROMISE_TG_WHEN:
1444 1611 : if (estate->trigdata == NULL)
1445 0 : elog(ERROR, "trigger promise is not in a trigger function");
1446 1611 : if (TRIGGER_FIRED_BEFORE(estate->trigdata->tg_event))
1447 658 : assign_text_var(estate, var, "BEFORE");
1448 953 : else if (TRIGGER_FIRED_AFTER(estate->trigdata->tg_event))
1449 913 : assign_text_var(estate, var, "AFTER");
1450 40 : else if (TRIGGER_FIRED_INSTEAD(estate->trigdata->tg_event))
1451 40 : assign_text_var(estate, var, "INSTEAD OF");
1452 : else
1453 0 : elog(ERROR, "unrecognized trigger execution time: not BEFORE, AFTER, or INSTEAD OF");
1454 1611 : break;
1455 :
1456 1495 : case PLPGSQL_PROMISE_TG_LEVEL:
1457 1495 : if (estate->trigdata == NULL)
1458 0 : elog(ERROR, "trigger promise is not in a trigger function");
1459 1495 : if (TRIGGER_FIRED_FOR_ROW(estate->trigdata->tg_event))
1460 939 : assign_text_var(estate, var, "ROW");
1461 556 : else if (TRIGGER_FIRED_FOR_STATEMENT(estate->trigdata->tg_event))
1462 556 : assign_text_var(estate, var, "STATEMENT");
1463 : else
1464 0 : elog(ERROR, "unrecognized trigger event type: not ROW or STATEMENT");
1465 1495 : break;
1466 :
1467 4013 : case PLPGSQL_PROMISE_TG_OP:
1468 4013 : if (estate->trigdata == NULL)
1469 0 : elog(ERROR, "trigger promise is not in a trigger function");
1470 4013 : if (TRIGGER_FIRED_BY_INSERT(estate->trigdata->tg_event))
1471 1945 : assign_text_var(estate, var, "INSERT");
1472 2068 : else if (TRIGGER_FIRED_BY_UPDATE(estate->trigdata->tg_event))
1473 1790 : assign_text_var(estate, var, "UPDATE");
1474 278 : else if (TRIGGER_FIRED_BY_DELETE(estate->trigdata->tg_event))
1475 268 : assign_text_var(estate, var, "DELETE");
1476 10 : else if (TRIGGER_FIRED_BY_TRUNCATE(estate->trigdata->tg_event))
1477 10 : assign_text_var(estate, var, "TRUNCATE");
1478 : else
1479 0 : elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, UPDATE, or TRUNCATE");
1480 4013 : break;
1481 :
1482 64 : case PLPGSQL_PROMISE_TG_RELID:
1483 64 : if (estate->trigdata == NULL)
1484 0 : elog(ERROR, "trigger promise is not in a trigger function");
1485 64 : assign_simple_var(estate, var,
1486 64 : ObjectIdGetDatum(estate->trigdata->tg_relation->rd_id),
1487 : false, false);
1488 64 : break;
1489 :
1490 583 : case PLPGSQL_PROMISE_TG_TABLE_NAME:
1491 583 : if (estate->trigdata == NULL)
1492 0 : elog(ERROR, "trigger promise is not in a trigger function");
1493 583 : assign_simple_var(estate, var,
1494 583 : DirectFunctionCall1(namein,
1495 : CStringGetDatum(RelationGetRelationName(estate->trigdata->tg_relation))),
1496 : false, true);
1497 583 : break;
1498 :
1499 12 : case PLPGSQL_PROMISE_TG_TABLE_SCHEMA:
1500 12 : if (estate->trigdata == NULL)
1501 0 : elog(ERROR, "trigger promise is not in a trigger function");
1502 12 : assign_simple_var(estate, var,
1503 12 : DirectFunctionCall1(namein,
1504 : CStringGetDatum(get_namespace_name(RelationGetNamespace(estate->trigdata->tg_relation)))),
1505 : false, true);
1506 12 : break;
1507 :
1508 176 : case PLPGSQL_PROMISE_TG_NARGS:
1509 176 : if (estate->trigdata == NULL)
1510 0 : elog(ERROR, "trigger promise is not in a trigger function");
1511 176 : assign_simple_var(estate, var,
1512 176 : Int16GetDatum(estate->trigdata->tg_trigger->tgnargs),
1513 : false, false);
1514 176 : break;
1515 :
1516 1184 : case PLPGSQL_PROMISE_TG_ARGV:
1517 1184 : if (estate->trigdata == NULL)
1518 0 : elog(ERROR, "trigger promise is not in a trigger function");
1519 1184 : if (estate->trigdata->tg_trigger->tgnargs > 0)
1520 : {
1521 : /*
1522 : * For historical reasons, tg_argv[] subscripts start at zero
1523 : * not one. So we can't use construct_array().
1524 : */
1525 1172 : int nelems = estate->trigdata->tg_trigger->tgnargs;
1526 : Datum *elems;
1527 : int dims[1];
1528 : int lbs[1];
1529 : int i;
1530 :
1531 1172 : elems = palloc_array(Datum, nelems);
1532 2420 : for (i = 0; i < nelems; i++)
1533 1248 : elems[i] = CStringGetTextDatum(estate->trigdata->tg_trigger->tgargs[i]);
1534 1172 : dims[0] = nelems;
1535 1172 : lbs[0] = 0;
1536 :
1537 1172 : assign_simple_var(estate, var,
1538 1172 : PointerGetDatum(construct_md_array(elems, NULL,
1539 : 1, dims, lbs,
1540 : TEXTOID,
1541 : -1, false, TYPALIGN_INT)),
1542 : false, true);
1543 : }
1544 : else
1545 : {
1546 12 : assign_simple_var(estate, var, (Datum) 0, true, false);
1547 : }
1548 1184 : break;
1549 :
1550 130 : case PLPGSQL_PROMISE_TG_EVENT:
1551 130 : if (estate->evtrigdata == NULL)
1552 0 : elog(ERROR, "event trigger promise is not in an event trigger function");
1553 130 : assign_text_var(estate, var, estate->evtrigdata->event);
1554 130 : break;
1555 :
1556 170 : case PLPGSQL_PROMISE_TG_TAG:
1557 170 : if (estate->evtrigdata == NULL)
1558 0 : elog(ERROR, "event trigger promise is not in an event trigger function");
1559 170 : assign_text_var(estate, var, GetCommandTagName(estate->evtrigdata->tag));
1560 170 : break;
1561 :
1562 0 : default:
1563 0 : elog(ERROR, "unrecognized promise type: %d", var->promise);
1564 : }
1565 :
1566 10421 : MemoryContextSwitchTo(oldcontext);
1567 : }
1568 :
1569 : /*
1570 : * Create a memory context for statement-lifespan variables, if we don't
1571 : * have one already. It will be a child of stmt_mcontext_parent, which is
1572 : * either the function's main context or a pushed-down outer stmt_mcontext.
1573 : */
1574 : static MemoryContext
1575 40622 : get_stmt_mcontext(PLpgSQL_execstate *estate)
1576 : {
1577 40622 : if (estate->stmt_mcontext == NULL)
1578 : {
1579 16021 : estate->stmt_mcontext =
1580 16021 : AllocSetContextCreate(estate->stmt_mcontext_parent,
1581 : "PLpgSQL per-statement data",
1582 : ALLOCSET_DEFAULT_SIZES);
1583 : }
1584 40622 : return estate->stmt_mcontext;
1585 : }
1586 :
1587 : /*
1588 : * Push down the current stmt_mcontext so that called statements won't use it.
1589 : * This is needed by statements that have statement-lifespan data and need to
1590 : * preserve it across some inner statements. The caller should eventually do
1591 : * pop_stmt_mcontext().
1592 : */
1593 : static void
1594 121 : push_stmt_mcontext(PLpgSQL_execstate *estate)
1595 : {
1596 : /* Should have done get_stmt_mcontext() first */
1597 : Assert(estate->stmt_mcontext != NULL);
1598 : /* Assert we've not messed up the stack linkage */
1599 : Assert(MemoryContextGetParent(estate->stmt_mcontext) == estate->stmt_mcontext_parent);
1600 : /* Push it down to become the parent of any nested stmt mcontext */
1601 121 : estate->stmt_mcontext_parent = estate->stmt_mcontext;
1602 : /* And make it not available for use directly */
1603 121 : estate->stmt_mcontext = NULL;
1604 121 : }
1605 :
1606 : /*
1607 : * Undo push_stmt_mcontext(). We assume this is done just before or after
1608 : * resetting the caller's stmt_mcontext; since that action will also delete
1609 : * any child contexts, there's no need to explicitly delete whatever context
1610 : * might currently be estate->stmt_mcontext.
1611 : */
1612 : static void
1613 4265 : pop_stmt_mcontext(PLpgSQL_execstate *estate)
1614 : {
1615 : /* We need only pop the stack */
1616 4265 : estate->stmt_mcontext = estate->stmt_mcontext_parent;
1617 4265 : estate->stmt_mcontext_parent = MemoryContextGetParent(estate->stmt_mcontext);
1618 4265 : }
1619 :
1620 :
1621 : /*
1622 : * Subroutine for exec_stmt_block: does any condition in the condition list
1623 : * match the current exception?
1624 : */
1625 : static bool
1626 4194 : exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond)
1627 : {
1628 4612 : for (; cond != NULL; cond = cond->next)
1629 : {
1630 4595 : int sqlerrstate = cond->sqlerrstate;
1631 :
1632 : /*
1633 : * OTHERS matches everything *except* query-canceled and
1634 : * assert-failure. If you're foolish enough, you can match those
1635 : * explicitly.
1636 : */
1637 4595 : if (sqlerrstate == PLPGSQL_OTHERS)
1638 : {
1639 3618 : if (edata->sqlerrcode != ERRCODE_QUERY_CANCELED &&
1640 3617 : edata->sqlerrcode != ERRCODE_ASSERT_FAILURE)
1641 3613 : return true;
1642 : }
1643 : /* Exact match? */
1644 977 : else if (edata->sqlerrcode == sqlerrstate)
1645 562 : return true;
1646 : /* Category match? */
1647 415 : else if (ERRCODE_IS_CATEGORY(sqlerrstate) &&
1648 3 : ERRCODE_TO_CATEGORY(edata->sqlerrcode) == sqlerrstate)
1649 2 : return true;
1650 : }
1651 17 : return false;
1652 : }
1653 :
1654 :
1655 : /* ----------
1656 : * exec_toplevel_block Execute the toplevel block
1657 : *
1658 : * This is intentionally equivalent to executing exec_stmts() with a
1659 : * list consisting of the one statement. One tiny difference is that
1660 : * we do not bother to save the entry value of estate->err_stmt;
1661 : * that's assumed to be NULL.
1662 : * ----------
1663 : */
1664 : static int
1665 54372 : exec_toplevel_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
1666 : {
1667 : int rc;
1668 :
1669 54372 : estate->err_stmt = (PLpgSQL_stmt *) block;
1670 :
1671 : /* Let the plugin know that we are about to execute this statement */
1672 54372 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->stmt_beg)
1673 0 : ((*plpgsql_plugin_ptr)->stmt_beg) (estate, (PLpgSQL_stmt *) block);
1674 :
1675 54372 : CHECK_FOR_INTERRUPTS();
1676 :
1677 54372 : rc = exec_stmt_block(estate, block);
1678 :
1679 : /* Let the plugin know that we have finished executing this statement */
1680 53675 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->stmt_end)
1681 0 : ((*plpgsql_plugin_ptr)->stmt_end) (estate, (PLpgSQL_stmt *) block);
1682 :
1683 53675 : estate->err_stmt = NULL;
1684 :
1685 53675 : return rc;
1686 : }
1687 :
1688 :
1689 : /* ----------
1690 : * exec_stmt_block Execute a block of statements
1691 : * ----------
1692 : */
1693 : static int
1694 62926 : exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
1695 : {
1696 62926 : volatile int rc = -1;
1697 : int i;
1698 :
1699 : /*
1700 : * First initialize all variables declared in this block
1701 : */
1702 62926 : estate->err_text = gettext_noop("during statement block local variable initialization");
1703 :
1704 85849 : for (i = 0; i < block->n_initvars; i++)
1705 : {
1706 22957 : int n = block->initvarnos[i];
1707 22957 : PLpgSQL_datum *datum = estate->datums[n];
1708 :
1709 : /*
1710 : * The set of dtypes handled here must match plpgsql_add_initdatums().
1711 : *
1712 : * Note that we currently don't support promise datums within blocks,
1713 : * only at a function's outermost scope, so we needn't handle those
1714 : * here.
1715 : *
1716 : * Since RECFIELD isn't a supported case either, it's okay to cast the
1717 : * PLpgSQL_datum to PLpgSQL_variable.
1718 : */
1719 22957 : estate->err_var = (PLpgSQL_variable *) datum;
1720 :
1721 22957 : switch (datum->dtype)
1722 : {
1723 19840 : case PLPGSQL_DTYPE_VAR:
1724 : {
1725 19840 : PLpgSQL_var *var = (PLpgSQL_var *) datum;
1726 :
1727 : /*
1728 : * Free any old value, in case re-entering block, and
1729 : * initialize to NULL
1730 : */
1731 19840 : assign_simple_var(estate, var, (Datum) 0, true, false);
1732 :
1733 19840 : if (var->default_val == NULL)
1734 : {
1735 : /*
1736 : * If needed, give the datatype a chance to reject
1737 : * NULLs, by assigning a NULL to the variable. We
1738 : * claim the value is of type UNKNOWN, not the var's
1739 : * datatype, else coercion will be skipped.
1740 : */
1741 17464 : if (var->datatype->typtype == TYPTYPE_DOMAIN)
1742 81 : exec_assign_value(estate,
1743 : (PLpgSQL_datum *) var,
1744 : (Datum) 0,
1745 : true,
1746 : UNKNOWNOID,
1747 : -1);
1748 :
1749 : /* parser should have rejected NOT NULL */
1750 : Assert(!var->notnull);
1751 : }
1752 : else
1753 : {
1754 2376 : exec_assign_expr(estate, (PLpgSQL_datum *) var,
1755 : var->default_val);
1756 : }
1757 : }
1758 19815 : break;
1759 :
1760 3117 : case PLPGSQL_DTYPE_REC:
1761 : {
1762 3117 : PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
1763 :
1764 : /*
1765 : * Deletion of any existing object will be handled during
1766 : * the assignments below, and in some cases it's more
1767 : * efficient for us not to get rid of it beforehand.
1768 : */
1769 3117 : if (rec->default_val == NULL)
1770 : {
1771 : /*
1772 : * If needed, give the datatype a chance to reject
1773 : * NULLs, by assigning a NULL to the variable.
1774 : */
1775 3098 : exec_move_row(estate, (PLpgSQL_variable *) rec,
1776 : NULL, NULL);
1777 :
1778 : /* parser should have rejected NOT NULL */
1779 : Assert(!rec->notnull);
1780 : }
1781 : else
1782 : {
1783 19 : exec_assign_expr(estate, (PLpgSQL_datum *) rec,
1784 : rec->default_val);
1785 : }
1786 : }
1787 3108 : break;
1788 :
1789 0 : default:
1790 0 : elog(ERROR, "unrecognized dtype: %d", datum->dtype);
1791 : }
1792 : }
1793 :
1794 62892 : estate->err_var = NULL;
1795 :
1796 62892 : if (block->exceptions)
1797 : {
1798 : /*
1799 : * Execute the statements in the block's body inside a sub-transaction
1800 : */
1801 8703 : MemoryContext oldcontext = CurrentMemoryContext;
1802 8703 : ResourceOwner oldowner = CurrentResourceOwner;
1803 8703 : ExprContext *old_eval_econtext = estate->eval_econtext;
1804 8703 : ErrorData *save_cur_error = estate->cur_error;
1805 : MemoryContext stmt_mcontext;
1806 :
1807 8703 : estate->err_text = gettext_noop("during statement block entry");
1808 :
1809 : /*
1810 : * We will need a stmt_mcontext to hold the error data if an error
1811 : * occurs. It seems best to force it to exist before entering the
1812 : * subtransaction, so that we reduce the risk of out-of-memory during
1813 : * error recovery, and because this greatly simplifies restoring the
1814 : * stmt_mcontext stack to the correct state after an error. We can
1815 : * ameliorate the cost of this by allowing the called statements to
1816 : * use this mcontext too; so we don't push it down here.
1817 : */
1818 8703 : stmt_mcontext = get_stmt_mcontext(estate);
1819 :
1820 8703 : BeginInternalSubTransaction(NULL);
1821 : /* Want to run statements inside function's memory context */
1822 8703 : MemoryContextSwitchTo(oldcontext);
1823 :
1824 8703 : PG_TRY();
1825 : {
1826 : /*
1827 : * We need to run the block's statements with a new eval_econtext
1828 : * that belongs to the current subtransaction; if we try to use
1829 : * the outer econtext then ExprContext shutdown callbacks will be
1830 : * called at the wrong times.
1831 : */
1832 8703 : plpgsql_create_econtext(estate);
1833 :
1834 8703 : estate->err_text = NULL;
1835 :
1836 : /* Run the block's statements */
1837 8703 : rc = exec_stmts(estate, block->body);
1838 :
1839 4518 : estate->err_text = gettext_noop("during statement block exit");
1840 :
1841 : /*
1842 : * If the block ended with RETURN, we may need to copy the return
1843 : * value out of the subtransaction eval_context. We can avoid a
1844 : * physical copy if the value happens to be a R/W expanded object.
1845 : */
1846 4518 : if (rc == PLPGSQL_RC_RETURN &&
1847 1038 : !estate->retisset &&
1848 1038 : !estate->retisnull)
1849 : {
1850 : int16 resTypLen;
1851 : bool resTypByVal;
1852 :
1853 1038 : get_typlenbyval(estate->rettype, &resTypLen, &resTypByVal);
1854 1038 : estate->retval = datumTransfer(estate->retval,
1855 : resTypByVal, resTypLen);
1856 : }
1857 :
1858 : /* Commit the inner transaction, return to outer xact context */
1859 4518 : ReleaseCurrentSubTransaction();
1860 4518 : MemoryContextSwitchTo(oldcontext);
1861 4518 : CurrentResourceOwner = oldowner;
1862 :
1863 : /* Assert that the stmt_mcontext stack is unchanged */
1864 : Assert(stmt_mcontext == estate->stmt_mcontext);
1865 :
1866 : /*
1867 : * Revert to outer eval_econtext. (The inner one was
1868 : * automatically cleaned up during subxact exit.)
1869 : */
1870 4518 : estate->eval_econtext = old_eval_econtext;
1871 : }
1872 4185 : PG_CATCH();
1873 : {
1874 : ErrorData *edata;
1875 : ListCell *e;
1876 :
1877 4185 : estate->err_text = gettext_noop("during exception cleanup");
1878 :
1879 : /* Save error info in our stmt_mcontext */
1880 4185 : MemoryContextSwitchTo(stmt_mcontext);
1881 4185 : edata = CopyErrorData();
1882 4185 : FlushErrorState();
1883 :
1884 : /* Abort the inner transaction */
1885 4185 : RollbackAndReleaseCurrentSubTransaction();
1886 4185 : MemoryContextSwitchTo(oldcontext);
1887 4185 : CurrentResourceOwner = oldowner;
1888 :
1889 : /*
1890 : * Set up the stmt_mcontext stack as though we had restored our
1891 : * previous state and then done push_stmt_mcontext(). The push is
1892 : * needed so that statements in the exception handler won't
1893 : * clobber the error data that's in our stmt_mcontext.
1894 : */
1895 4185 : estate->stmt_mcontext_parent = stmt_mcontext;
1896 4185 : estate->stmt_mcontext = NULL;
1897 :
1898 : /*
1899 : * Now we can delete any nested stmt_mcontexts that might have
1900 : * been created as children of ours. (Note: we do not immediately
1901 : * release any statement-lifespan data that might have been left
1902 : * behind in stmt_mcontext itself. We could attempt that by doing
1903 : * a MemoryContextReset on it before collecting the error data
1904 : * above, but it seems too risky to do any significant amount of
1905 : * work before collecting the error.)
1906 : */
1907 4185 : MemoryContextDeleteChildren(stmt_mcontext);
1908 :
1909 : /* Revert to outer eval_econtext */
1910 4185 : estate->eval_econtext = old_eval_econtext;
1911 :
1912 : /*
1913 : * Must clean up the econtext too. However, any tuple table made
1914 : * in the subxact will have been thrown away by SPI during subxact
1915 : * abort, so we don't need to (and mustn't try to) free the
1916 : * eval_tuptable.
1917 : */
1918 4185 : estate->eval_tuptable = NULL;
1919 4185 : exec_eval_cleanup(estate);
1920 :
1921 : /* Look for a matching exception handler */
1922 4202 : foreach(e, block->exceptions->exc_list)
1923 : {
1924 4194 : PLpgSQL_exception *exception = (PLpgSQL_exception *) lfirst(e);
1925 :
1926 4194 : if (exception_matches_conditions(edata, exception->conditions))
1927 : {
1928 : /*
1929 : * Initialize the magic SQLSTATE and SQLERRM variables for
1930 : * the exception block; this also frees values from any
1931 : * prior use of the same exception. We needn't do this
1932 : * until we have found a matching exception.
1933 : */
1934 : PLpgSQL_var *state_var;
1935 : PLpgSQL_var *errm_var;
1936 :
1937 4177 : state_var = (PLpgSQL_var *)
1938 4177 : estate->datums[block->exceptions->sqlstate_varno];
1939 4177 : errm_var = (PLpgSQL_var *)
1940 4177 : estate->datums[block->exceptions->sqlerrm_varno];
1941 :
1942 4177 : assign_text_var(estate, state_var,
1943 4177 : unpack_sql_state(edata->sqlerrcode));
1944 4177 : assign_text_var(estate, errm_var, edata->message);
1945 :
1946 : /*
1947 : * Also set up cur_error so the error data is accessible
1948 : * inside the handler.
1949 : */
1950 4177 : estate->cur_error = edata;
1951 :
1952 4177 : estate->err_text = NULL;
1953 :
1954 4177 : rc = exec_stmts(estate, exception->action);
1955 :
1956 4156 : break;
1957 : }
1958 : }
1959 :
1960 : /*
1961 : * Restore previous state of cur_error, whether or not we executed
1962 : * a handler. This is needed in case an error got thrown from
1963 : * some inner block's exception handler.
1964 : */
1965 4164 : estate->cur_error = save_cur_error;
1966 :
1967 : /* If no match found, re-throw the error */
1968 4164 : if (e == NULL)
1969 8 : ReThrowError(edata);
1970 :
1971 : /* Restore stmt_mcontext stack and release the error data */
1972 4156 : pop_stmt_mcontext(estate);
1973 4156 : MemoryContextReset(stmt_mcontext);
1974 : }
1975 8674 : PG_END_TRY();
1976 :
1977 : Assert(save_cur_error == estate->cur_error);
1978 : }
1979 : else
1980 : {
1981 : /*
1982 : * Just execute the statements in the block's body
1983 : */
1984 54189 : estate->err_text = NULL;
1985 :
1986 54189 : rc = exec_stmts(estate, block->body);
1987 : }
1988 :
1989 62188 : estate->err_text = NULL;
1990 :
1991 : /*
1992 : * Handle the return code. This is intentionally different from
1993 : * LOOP_RC_PROCESSING(): CONTINUE never matches a block, and EXIT matches
1994 : * a block only if there is a label match.
1995 : */
1996 62188 : switch (rc)
1997 : {
1998 62178 : case PLPGSQL_RC_OK:
1999 : case PLPGSQL_RC_RETURN:
2000 : case PLPGSQL_RC_CONTINUE:
2001 62178 : return rc;
2002 :
2003 10 : case PLPGSQL_RC_EXIT:
2004 10 : if (estate->exitlabel == NULL)
2005 4 : return PLPGSQL_RC_EXIT;
2006 6 : if (block->label == NULL)
2007 1 : return PLPGSQL_RC_EXIT;
2008 5 : if (strcmp(block->label, estate->exitlabel) != 0)
2009 2 : return PLPGSQL_RC_EXIT;
2010 3 : estate->exitlabel = NULL;
2011 3 : return PLPGSQL_RC_OK;
2012 :
2013 0 : default:
2014 0 : elog(ERROR, "unrecognized rc: %d", rc);
2015 : }
2016 :
2017 : return PLPGSQL_RC_OK;
2018 : }
2019 :
2020 :
2021 : /* ----------
2022 : * exec_stmts Iterate over a list of statements
2023 : * as long as their return code is OK
2024 : * ----------
2025 : */
2026 : static int
2027 201820 : exec_stmts(PLpgSQL_execstate *estate, List *stmts)
2028 : {
2029 201820 : PLpgSQL_stmt *save_estmt = estate->err_stmt;
2030 : ListCell *s;
2031 :
2032 201820 : if (stmts == NIL)
2033 : {
2034 : /*
2035 : * Ensure we do a CHECK_FOR_INTERRUPTS() even though there is no
2036 : * statement. This prevents hangup in a tight loop if, for instance,
2037 : * there is a LOOP construct with an empty body.
2038 : */
2039 52739 : CHECK_FOR_INTERRUPTS();
2040 52739 : return PLPGSQL_RC_OK;
2041 : }
2042 :
2043 374927 : foreach(s, stmts)
2044 : {
2045 292354 : PLpgSQL_stmt *stmt = (PLpgSQL_stmt *) lfirst(s);
2046 : int rc;
2047 :
2048 292354 : estate->err_stmt = stmt;
2049 :
2050 : /* Let the plugin know that we are about to execute this statement */
2051 292354 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->stmt_beg)
2052 0 : ((*plpgsql_plugin_ptr)->stmt_beg) (estate, stmt);
2053 :
2054 292354 : CHECK_FOR_INTERRUPTS();
2055 :
2056 292354 : switch (stmt->cmd_type)
2057 : {
2058 8554 : case PLPGSQL_STMT_BLOCK:
2059 8554 : rc = exec_stmt_block(estate, (PLpgSQL_stmt_block *) stmt);
2060 8513 : break;
2061 :
2062 63908 : case PLPGSQL_STMT_ASSIGN:
2063 63908 : rc = exec_stmt_assign(estate, (PLpgSQL_stmt_assign *) stmt);
2064 63756 : break;
2065 :
2066 3906 : case PLPGSQL_STMT_PERFORM:
2067 3906 : rc = exec_stmt_perform(estate, (PLpgSQL_stmt_perform *) stmt);
2068 2927 : break;
2069 :
2070 65 : case PLPGSQL_STMT_CALL:
2071 65 : rc = exec_stmt_call(estate, (PLpgSQL_stmt_call *) stmt);
2072 58 : break;
2073 :
2074 101 : case PLPGSQL_STMT_GETDIAG:
2075 101 : rc = exec_stmt_getdiag(estate, (PLpgSQL_stmt_getdiag *) stmt);
2076 97 : break;
2077 :
2078 71850 : case PLPGSQL_STMT_IF:
2079 71850 : rc = exec_stmt_if(estate, (PLpgSQL_stmt_if *) stmt);
2080 71721 : break;
2081 :
2082 144 : case PLPGSQL_STMT_CASE:
2083 144 : rc = exec_stmt_case(estate, (PLpgSQL_stmt_case *) stmt);
2084 141 : break;
2085 :
2086 56 : case PLPGSQL_STMT_LOOP:
2087 56 : rc = exec_stmt_loop(estate, (PLpgSQL_stmt_loop *) stmt);
2088 56 : break;
2089 :
2090 284 : case PLPGSQL_STMT_WHILE:
2091 284 : rc = exec_stmt_while(estate, (PLpgSQL_stmt_while *) stmt);
2092 284 : break;
2093 :
2094 3046 : case PLPGSQL_STMT_FORI:
2095 3046 : rc = exec_stmt_fori(estate, (PLpgSQL_stmt_fori *) stmt);
2096 3031 : break;
2097 :
2098 1636 : case PLPGSQL_STMT_FORS:
2099 1636 : rc = exec_stmt_fors(estate, (PLpgSQL_stmt_fors *) stmt);
2100 1608 : break;
2101 :
2102 69 : case PLPGSQL_STMT_FORC:
2103 69 : rc = exec_stmt_forc(estate, (PLpgSQL_stmt_forc *) stmt);
2104 69 : break;
2105 :
2106 121 : case PLPGSQL_STMT_FOREACH_A:
2107 121 : rc = exec_stmt_foreach_a(estate, (PLpgSQL_stmt_foreach_a *) stmt);
2108 109 : break;
2109 :
2110 2097 : case PLPGSQL_STMT_EXIT:
2111 2097 : rc = exec_stmt_exit(estate, (PLpgSQL_stmt_exit *) stmt);
2112 2097 : break;
2113 :
2114 53735 : case PLPGSQL_STMT_RETURN:
2115 53735 : rc = exec_stmt_return(estate, (PLpgSQL_stmt_return *) stmt);
2116 53671 : break;
2117 :
2118 3895 : case PLPGSQL_STMT_RETURN_NEXT:
2119 3895 : rc = exec_stmt_return_next(estate, (PLpgSQL_stmt_return_next *) stmt);
2120 3893 : break;
2121 :
2122 1795 : case PLPGSQL_STMT_RETURN_QUERY:
2123 1795 : rc = exec_stmt_return_query(estate, (PLpgSQL_stmt_return_query *) stmt);
2124 1786 : break;
2125 :
2126 12732 : case PLPGSQL_STMT_RAISE:
2127 12732 : rc = exec_stmt_raise(estate, (PLpgSQL_stmt_raise *) stmt);
2128 12082 : break;
2129 :
2130 4476 : case PLPGSQL_STMT_ASSERT:
2131 4476 : rc = exec_stmt_assert(estate, (PLpgSQL_stmt_assert *) stmt);
2132 4460 : break;
2133 :
2134 40424 : case PLPGSQL_STMT_EXECSQL:
2135 40424 : rc = exec_stmt_execsql(estate, (PLpgSQL_stmt_execsql *) stmt);
2136 37701 : break;
2137 :
2138 10599 : case PLPGSQL_STMT_DYNEXECUTE:
2139 10599 : rc = exec_stmt_dynexecute(estate, (PLpgSQL_stmt_dynexecute *) stmt);
2140 10423 : break;
2141 :
2142 6355 : case PLPGSQL_STMT_DYNFORS:
2143 6355 : rc = exec_stmt_dynfors(estate, (PLpgSQL_stmt_dynfors *) stmt);
2144 6351 : break;
2145 :
2146 93 : case PLPGSQL_STMT_OPEN:
2147 93 : rc = exec_stmt_open(estate, (PLpgSQL_stmt_open *) stmt);
2148 85 : break;
2149 :
2150 229 : case PLPGSQL_STMT_FETCH:
2151 229 : rc = exec_stmt_fetch(estate, (PLpgSQL_stmt_fetch *) stmt);
2152 225 : break;
2153 :
2154 48 : case PLPGSQL_STMT_CLOSE:
2155 48 : rc = exec_stmt_close(estate, (PLpgSQL_stmt_close *) stmt);
2156 48 : break;
2157 :
2158 2083 : case PLPGSQL_STMT_COMMIT:
2159 2083 : rc = exec_stmt_commit(estate, (PLpgSQL_stmt_commit *) stmt);
2160 2072 : break;
2161 :
2162 53 : case PLPGSQL_STMT_ROLLBACK:
2163 53 : rc = exec_stmt_rollback(estate, (PLpgSQL_stmt_rollback *) stmt);
2164 50 : break;
2165 :
2166 0 : default:
2167 : /* point err_stmt to parent, since this one seems corrupt */
2168 0 : estate->err_stmt = save_estmt;
2169 0 : elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
2170 : rc = -1; /* keep compiler quiet */
2171 : }
2172 :
2173 : /* Let the plugin know that we have finished executing this statement */
2174 287314 : if (*plpgsql_plugin_ptr && (*plpgsql_plugin_ptr)->stmt_end)
2175 0 : ((*plpgsql_plugin_ptr)->stmt_end) (estate, stmt);
2176 :
2177 287314 : if (rc != PLPGSQL_RC_OK)
2178 : {
2179 61468 : estate->err_stmt = save_estmt;
2180 61468 : return rc;
2181 : }
2182 : } /* end of loop over statements */
2183 :
2184 82573 : estate->err_stmt = save_estmt;
2185 82573 : return PLPGSQL_RC_OK;
2186 : }
2187 :
2188 :
2189 : /* ----------
2190 : * exec_stmt_assign Evaluate an expression and
2191 : * put the result into a variable.
2192 : * ----------
2193 : */
2194 : static int
2195 63908 : exec_stmt_assign(PLpgSQL_execstate *estate, PLpgSQL_stmt_assign *stmt)
2196 : {
2197 : Assert(stmt->varno >= 0);
2198 :
2199 63908 : exec_assign_expr(estate, estate->datums[stmt->varno], stmt->expr);
2200 :
2201 63756 : return PLPGSQL_RC_OK;
2202 : }
2203 :
2204 : /* ----------
2205 : * exec_stmt_perform Evaluate query and discard result (but set
2206 : * FOUND depending on whether at least one row
2207 : * was returned).
2208 : * ----------
2209 : */
2210 : static int
2211 3906 : exec_stmt_perform(PLpgSQL_execstate *estate, PLpgSQL_stmt_perform *stmt)
2212 : {
2213 3906 : PLpgSQL_expr *expr = stmt->expr;
2214 :
2215 3906 : (void) exec_run_select(estate, expr, 0, NULL);
2216 2927 : exec_set_found(estate, (estate->eval_processed != 0));
2217 2927 : exec_eval_cleanup(estate);
2218 :
2219 2927 : return PLPGSQL_RC_OK;
2220 : }
2221 :
2222 : /*
2223 : * exec_stmt_call
2224 : *
2225 : * NOTE: this is used for both CALL and DO statements.
2226 : */
2227 : static int
2228 65 : exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt)
2229 : {
2230 65 : PLpgSQL_expr *expr = stmt->expr;
2231 : LocalTransactionId before_lxid;
2232 : LocalTransactionId after_lxid;
2233 : ParamListInfo paramLI;
2234 : SPIExecuteOptions options;
2235 : int rc;
2236 :
2237 : /*
2238 : * Make a plan if we don't have one already.
2239 : */
2240 65 : if (expr->plan == NULL)
2241 52 : exec_prepare_plan(estate, expr, 0);
2242 :
2243 : /*
2244 : * A CALL or DO can never be a simple expression.
2245 : */
2246 : Assert(!expr->expr_simple_expr);
2247 :
2248 : /*
2249 : * Also construct a DTYPE_ROW datum representing the plpgsql variables
2250 : * associated with the procedure's output arguments. Then we can use
2251 : * exec_move_row() to do the assignments.
2252 : */
2253 64 : if (stmt->is_call && stmt->target == NULL)
2254 50 : stmt->target = make_callstmt_target(estate, expr);
2255 :
2256 59 : paramLI = setup_param_list(estate, expr);
2257 :
2258 59 : before_lxid = MyProc->vxid.lxid;
2259 :
2260 : /*
2261 : * If we have a procedure-lifespan resowner, use that to hold the refcount
2262 : * for the plan. This avoids refcount leakage complaints if the called
2263 : * procedure ends the current transaction.
2264 : *
2265 : * Also, tell SPI to allow non-atomic execution.
2266 : */
2267 59 : memset(&options, 0, sizeof(options));
2268 59 : options.params = paramLI;
2269 59 : options.read_only = estate->readonly_func;
2270 59 : options.allow_nonatomic = true;
2271 59 : options.owner = estate->procedure_resowner;
2272 :
2273 59 : rc = SPI_execute_plan_extended(expr->plan, &options);
2274 :
2275 58 : if (rc < 0)
2276 0 : elog(ERROR, "SPI_execute_plan_extended failed executing query \"%s\": %s",
2277 : expr->query, SPI_result_code_string(rc));
2278 :
2279 58 : after_lxid = MyProc->vxid.lxid;
2280 :
2281 58 : if (before_lxid != after_lxid)
2282 : {
2283 : /*
2284 : * If we are in a new transaction after the call, we need to build new
2285 : * simple-expression infrastructure.
2286 : */
2287 4 : estate->simple_eval_estate = NULL;
2288 4 : estate->simple_eval_resowner = NULL;
2289 4 : plpgsql_create_econtext(estate);
2290 : }
2291 :
2292 : /*
2293 : * Check result rowcount; if there's one row, assign procedure's output
2294 : * values back to the appropriate variables.
2295 : */
2296 58 : if (SPI_processed == 1)
2297 : {
2298 38 : SPITupleTable *tuptab = SPI_tuptable;
2299 :
2300 38 : if (!stmt->is_call)
2301 0 : elog(ERROR, "DO statement returned a row");
2302 :
2303 38 : exec_move_row(estate, stmt->target, tuptab->vals[0], tuptab->tupdesc);
2304 : }
2305 20 : else if (SPI_processed > 1)
2306 0 : elog(ERROR, "procedure call returned more than one row");
2307 :
2308 58 : exec_eval_cleanup(estate);
2309 58 : SPI_freetuptable(SPI_tuptable);
2310 :
2311 58 : return PLPGSQL_RC_OK;
2312 : }
2313 :
2314 : /*
2315 : * We construct a DTYPE_ROW datum representing the plpgsql variables
2316 : * associated with the procedure's output arguments. Then we can use
2317 : * exec_move_row() to do the assignments.
2318 : */
2319 : static PLpgSQL_variable *
2320 50 : make_callstmt_target(PLpgSQL_execstate *estate, PLpgSQL_expr *expr)
2321 : {
2322 : CachedPlan *cplan;
2323 : PlannedStmt *pstmt;
2324 : CallStmt *stmt;
2325 : FuncExpr *funcexpr;
2326 : HeapTuple func_tuple;
2327 : Oid *argtypes;
2328 : char **argnames;
2329 : char *argmodes;
2330 : int numargs;
2331 : MemoryContext oldcontext;
2332 : PLpgSQL_row *row;
2333 : int nfields;
2334 : int i;
2335 :
2336 : /* Use eval_mcontext for any cruft accumulated here */
2337 50 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
2338 :
2339 : /*
2340 : * Get the parsed CallStmt, and look up the called procedure. We use
2341 : * SPI_plan_get_cached_plan to cover the edge case where expr->plan is
2342 : * already stale and needs to be updated.
2343 : */
2344 50 : cplan = SPI_plan_get_cached_plan(expr->plan);
2345 50 : if (cplan == NULL || list_length(cplan->stmt_list) != 1)
2346 0 : elog(ERROR, "query for CALL statement is not a CallStmt");
2347 50 : pstmt = linitial_node(PlannedStmt, cplan->stmt_list);
2348 50 : stmt = (CallStmt *) pstmt->utilityStmt;
2349 50 : if (stmt == NULL || !IsA(stmt, CallStmt))
2350 0 : elog(ERROR, "query for CALL statement is not a CallStmt");
2351 :
2352 50 : funcexpr = stmt->funcexpr;
2353 :
2354 50 : func_tuple = SearchSysCache1(PROCOID,
2355 : ObjectIdGetDatum(funcexpr->funcid));
2356 50 : if (!HeapTupleIsValid(func_tuple))
2357 0 : elog(ERROR, "cache lookup failed for function %u",
2358 : funcexpr->funcid);
2359 :
2360 : /*
2361 : * Get the argument names and modes, so that we can deliver on-point error
2362 : * messages when something is wrong.
2363 : */
2364 50 : numargs = get_func_arg_info(func_tuple, &argtypes, &argnames, &argmodes);
2365 :
2366 50 : ReleaseSysCache(func_tuple);
2367 :
2368 : /*
2369 : * Begin constructing row Datum; keep it in fn_cxt so it's adequately
2370 : * long-lived.
2371 : */
2372 50 : MemoryContextSwitchTo(estate->func->fn_cxt);
2373 :
2374 50 : row = palloc0_object(PLpgSQL_row);
2375 50 : row->dtype = PLPGSQL_DTYPE_ROW;
2376 50 : row->refname = "(unnamed row)";
2377 50 : row->lineno = -1;
2378 50 : row->varnos = palloc_array(int, numargs);
2379 :
2380 50 : MemoryContextSwitchTo(get_eval_mcontext(estate));
2381 :
2382 : /*
2383 : * Examine procedure's argument list. Each output arg position should be
2384 : * an unadorned plpgsql variable (Datum), which we can insert into the row
2385 : * Datum.
2386 : */
2387 50 : nfields = 0;
2388 152 : for (i = 0; i < numargs; i++)
2389 : {
2390 107 : if (argmodes &&
2391 89 : (argmodes[i] == PROARGMODE_INOUT ||
2392 46 : argmodes[i] == PROARGMODE_OUT))
2393 : {
2394 57 : Node *n = list_nth(stmt->outargs, nfields);
2395 :
2396 57 : if (IsA(n, Param))
2397 : {
2398 53 : Param *param = (Param *) n;
2399 : int dno;
2400 :
2401 : /* paramid is offset by 1 (see make_datum_param()) */
2402 53 : dno = param->paramid - 1;
2403 : /* must check assignability now, because grammar can't */
2404 53 : exec_check_assignable(estate, dno);
2405 52 : row->varnos[nfields++] = dno;
2406 : }
2407 : else
2408 : {
2409 : /* report error using parameter name, if available */
2410 4 : if (argnames && argnames[i] && argnames[i][0])
2411 4 : ereport(ERROR,
2412 : (errcode(ERRCODE_SYNTAX_ERROR),
2413 : errmsg("procedure parameter \"%s\" is an output parameter but corresponding argument is not writable",
2414 : argnames[i])));
2415 : else
2416 0 : ereport(ERROR,
2417 : (errcode(ERRCODE_SYNTAX_ERROR),
2418 : errmsg("procedure parameter %d is an output parameter but corresponding argument is not writable",
2419 : i + 1)));
2420 : }
2421 : }
2422 : }
2423 :
2424 : Assert(nfields == list_length(stmt->outargs));
2425 :
2426 45 : row->nfields = nfields;
2427 :
2428 45 : ReleaseCachedPlan(cplan, CurrentResourceOwner);
2429 :
2430 45 : MemoryContextSwitchTo(oldcontext);
2431 :
2432 45 : return (PLpgSQL_variable *) row;
2433 : }
2434 :
2435 : /* ----------
2436 : * exec_stmt_getdiag Put internal PG information into
2437 : * specified variables.
2438 : * ----------
2439 : */
2440 : static int
2441 101 : exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt)
2442 : {
2443 : ListCell *lc;
2444 :
2445 : /*
2446 : * GET STACKED DIAGNOSTICS is only valid inside an exception handler.
2447 : *
2448 : * Note: we trust the grammar to have disallowed the relevant item kinds
2449 : * if not is_stacked, otherwise we'd dump core below.
2450 : */
2451 101 : if (stmt->is_stacked && estate->cur_error == NULL)
2452 4 : ereport(ERROR,
2453 : (errcode(ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER),
2454 : errmsg("GET STACKED DIAGNOSTICS cannot be used outside an exception handler")));
2455 :
2456 234 : foreach(lc, stmt->diag_items)
2457 : {
2458 137 : PLpgSQL_diag_item *diag_item = (PLpgSQL_diag_item *) lfirst(lc);
2459 137 : PLpgSQL_datum *var = estate->datums[diag_item->target];
2460 :
2461 137 : switch (diag_item->kind)
2462 : {
2463 44 : case PLPGSQL_GETDIAG_ROW_COUNT:
2464 44 : exec_assign_value(estate, var,
2465 : UInt64GetDatum(estate->eval_processed),
2466 : false, INT8OID, -1);
2467 44 : break;
2468 :
2469 8 : case PLPGSQL_GETDIAG_ROUTINE_OID:
2470 8 : exec_assign_value(estate, var,
2471 8 : ObjectIdGetDatum(estate->func->fn_oid),
2472 : false, OIDOID, -1);
2473 8 : break;
2474 :
2475 4 : case PLPGSQL_GETDIAG_ERROR_CONTEXT:
2476 4 : exec_assign_c_string(estate, var,
2477 4 : estate->cur_error->context);
2478 4 : break;
2479 :
2480 5 : case PLPGSQL_GETDIAG_ERROR_DETAIL:
2481 5 : exec_assign_c_string(estate, var,
2482 5 : estate->cur_error->detail);
2483 5 : break;
2484 :
2485 5 : case PLPGSQL_GETDIAG_ERROR_HINT:
2486 5 : exec_assign_c_string(estate, var,
2487 5 : estate->cur_error->hint);
2488 5 : break;
2489 :
2490 5 : case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
2491 5 : exec_assign_c_string(estate, var,
2492 5 : unpack_sql_state(estate->cur_error->sqlerrcode));
2493 5 : break;
2494 :
2495 5 : case PLPGSQL_GETDIAG_COLUMN_NAME:
2496 5 : exec_assign_c_string(estate, var,
2497 5 : estate->cur_error->column_name);
2498 5 : break;
2499 :
2500 5 : case PLPGSQL_GETDIAG_CONSTRAINT_NAME:
2501 5 : exec_assign_c_string(estate, var,
2502 5 : estate->cur_error->constraint_name);
2503 5 : break;
2504 :
2505 5 : case PLPGSQL_GETDIAG_DATATYPE_NAME:
2506 5 : exec_assign_c_string(estate, var,
2507 5 : estate->cur_error->datatype_name);
2508 5 : break;
2509 :
2510 9 : case PLPGSQL_GETDIAG_MESSAGE_TEXT:
2511 9 : exec_assign_c_string(estate, var,
2512 9 : estate->cur_error->message);
2513 9 : break;
2514 :
2515 5 : case PLPGSQL_GETDIAG_TABLE_NAME:
2516 5 : exec_assign_c_string(estate, var,
2517 5 : estate->cur_error->table_name);
2518 5 : break;
2519 :
2520 5 : case PLPGSQL_GETDIAG_SCHEMA_NAME:
2521 5 : exec_assign_c_string(estate, var,
2522 5 : estate->cur_error->schema_name);
2523 5 : break;
2524 :
2525 32 : case PLPGSQL_GETDIAG_CONTEXT:
2526 : {
2527 : char *contextstackstr;
2528 : MemoryContext oldcontext;
2529 :
2530 : /* Use eval_mcontext for short-lived string */
2531 32 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
2532 32 : contextstackstr = GetErrorContextStack();
2533 32 : MemoryContextSwitchTo(oldcontext);
2534 :
2535 32 : exec_assign_c_string(estate, var, contextstackstr);
2536 : }
2537 32 : break;
2538 :
2539 0 : default:
2540 0 : elog(ERROR, "unrecognized diagnostic item kind: %d",
2541 : diag_item->kind);
2542 : }
2543 : }
2544 :
2545 97 : exec_eval_cleanup(estate);
2546 :
2547 97 : return PLPGSQL_RC_OK;
2548 : }
2549 :
2550 : /* ----------
2551 : * exec_stmt_if Evaluate a bool expression and
2552 : * execute the true or false body
2553 : * conditionally.
2554 : * ----------
2555 : */
2556 : static int
2557 71850 : exec_stmt_if(PLpgSQL_execstate *estate, PLpgSQL_stmt_if *stmt)
2558 : {
2559 : bool value;
2560 : bool isnull;
2561 : ListCell *lc;
2562 :
2563 71850 : value = exec_eval_boolean(estate, stmt->cond, &isnull);
2564 71850 : exec_eval_cleanup(estate);
2565 71850 : if (!isnull && value)
2566 14297 : return exec_stmts(estate, stmt->then_body);
2567 :
2568 57742 : foreach(lc, stmt->elsif_list)
2569 : {
2570 667 : PLpgSQL_if_elsif *elif = (PLpgSQL_if_elsif *) lfirst(lc);
2571 :
2572 667 : value = exec_eval_boolean(estate, elif->cond, &isnull);
2573 667 : exec_eval_cleanup(estate);
2574 667 : if (!isnull && value)
2575 478 : return exec_stmts(estate, elif->stmts);
2576 : }
2577 :
2578 57075 : return exec_stmts(estate, stmt->else_body);
2579 : }
2580 :
2581 :
2582 : /*-----------
2583 : * exec_stmt_case
2584 : *-----------
2585 : */
2586 : static int
2587 144 : exec_stmt_case(PLpgSQL_execstate *estate, PLpgSQL_stmt_case *stmt)
2588 : {
2589 144 : PLpgSQL_var *t_var = NULL;
2590 : bool isnull;
2591 : ListCell *l;
2592 :
2593 144 : if (stmt->t_expr != NULL)
2594 : {
2595 : /* simple case */
2596 : Datum t_val;
2597 : Oid t_typoid;
2598 : int32 t_typmod;
2599 :
2600 140 : t_val = exec_eval_expr(estate, stmt->t_expr,
2601 : &isnull, &t_typoid, &t_typmod);
2602 :
2603 140 : t_var = (PLpgSQL_var *) estate->datums[stmt->t_varno];
2604 :
2605 : /*
2606 : * When expected datatype is different from real, change it. Note that
2607 : * what we're modifying here is an execution copy of the datum, so
2608 : * this doesn't affect the originally stored function parse tree. (In
2609 : * theory, if the expression datatype keeps changing during execution,
2610 : * this could cause a function-lifespan memory leak. Doesn't seem
2611 : * worth worrying about though.)
2612 : */
2613 140 : if (t_var->datatype->typoid != t_typoid ||
2614 113 : t_var->datatype->atttypmod != t_typmod)
2615 27 : t_var->datatype = plpgsql_build_datatype(t_typoid,
2616 : t_typmod,
2617 27 : estate->func->fn_input_collation,
2618 : NULL);
2619 :
2620 : /* now we can assign to the variable */
2621 140 : exec_assign_value(estate,
2622 : (PLpgSQL_datum *) t_var,
2623 : t_val,
2624 : isnull,
2625 : t_typoid,
2626 : t_typmod);
2627 :
2628 140 : exec_eval_cleanup(estate);
2629 : }
2630 :
2631 : /* Now search for a successful WHEN clause */
2632 262 : foreach(l, stmt->case_when_list)
2633 : {
2634 257 : PLpgSQL_case_when *cwt = (PLpgSQL_case_when *) lfirst(l);
2635 : bool value;
2636 :
2637 257 : value = exec_eval_boolean(estate, cwt->expr, &isnull);
2638 257 : exec_eval_cleanup(estate);
2639 257 : if (!isnull && value)
2640 : {
2641 : /* Found it */
2642 :
2643 : /* We can now discard any value we had for the temp variable */
2644 139 : if (t_var != NULL)
2645 137 : assign_simple_var(estate, t_var, (Datum) 0, true, false);
2646 :
2647 : /* Evaluate the statement(s), and we're done */
2648 139 : return exec_stmts(estate, cwt->stmts);
2649 : }
2650 : }
2651 :
2652 : /* We can now discard any value we had for the temp variable */
2653 5 : if (t_var != NULL)
2654 3 : assign_simple_var(estate, t_var, (Datum) 0, true, false);
2655 :
2656 : /* SQL2003 mandates this error if there was no ELSE clause */
2657 5 : if (!stmt->have_else)
2658 3 : ereport(ERROR,
2659 : (errcode(ERRCODE_CASE_NOT_FOUND),
2660 : errmsg("case not found"),
2661 : errhint("CASE statement is missing ELSE part.")));
2662 :
2663 : /* Evaluate the ELSE statements, and we're done */
2664 2 : return exec_stmts(estate, stmt->else_stmts);
2665 : }
2666 :
2667 :
2668 : /* ----------
2669 : * exec_stmt_loop Loop over statements until
2670 : * an exit occurs.
2671 : * ----------
2672 : */
2673 : static int
2674 56 : exec_stmt_loop(PLpgSQL_execstate *estate, PLpgSQL_stmt_loop *stmt)
2675 : {
2676 56 : int rc = PLPGSQL_RC_OK;
2677 :
2678 : for (;;)
2679 : {
2680 3190 : rc = exec_stmts(estate, stmt->body);
2681 :
2682 3190 : LOOP_RC_PROCESSING(stmt->label, break);
2683 : }
2684 :
2685 56 : return rc;
2686 : }
2687 :
2688 :
2689 : /* ----------
2690 : * exec_stmt_while Loop over statements as long
2691 : * as an expression evaluates to
2692 : * true or an exit occurs.
2693 : * ----------
2694 : */
2695 : static int
2696 284 : exec_stmt_while(PLpgSQL_execstate *estate, PLpgSQL_stmt_while *stmt)
2697 : {
2698 284 : int rc = PLPGSQL_RC_OK;
2699 :
2700 : for (;;)
2701 2098 : {
2702 : bool value;
2703 : bool isnull;
2704 :
2705 2382 : value = exec_eval_boolean(estate, stmt->cond, &isnull);
2706 2382 : exec_eval_cleanup(estate);
2707 :
2708 2382 : if (isnull || !value)
2709 : break;
2710 :
2711 2108 : rc = exec_stmts(estate, stmt->body);
2712 :
2713 2108 : LOOP_RC_PROCESSING(stmt->label, break);
2714 : }
2715 :
2716 284 : return rc;
2717 : }
2718 :
2719 :
2720 : /* ----------
2721 : * exec_stmt_fori Iterate an integer variable
2722 : * from a lower to an upper value
2723 : * incrementing or decrementing by the BY value
2724 : * ----------
2725 : */
2726 : static int
2727 3046 : exec_stmt_fori(PLpgSQL_execstate *estate, PLpgSQL_stmt_fori *stmt)
2728 : {
2729 : PLpgSQL_var *var;
2730 : Datum value;
2731 : bool isnull;
2732 : Oid valtype;
2733 : int32 valtypmod;
2734 : int32 loop_value;
2735 : int32 end_value;
2736 : int32 step_value;
2737 3046 : bool found = false;
2738 3046 : int rc = PLPGSQL_RC_OK;
2739 :
2740 3046 : var = (PLpgSQL_var *) (estate->datums[stmt->var->dno]);
2741 :
2742 : /*
2743 : * Get the value of the lower bound
2744 : */
2745 3046 : value = exec_eval_expr(estate, stmt->lower,
2746 : &isnull, &valtype, &valtypmod);
2747 3046 : value = exec_cast_value(estate, value, &isnull,
2748 : valtype, valtypmod,
2749 3046 : var->datatype->typoid,
2750 3046 : var->datatype->atttypmod);
2751 3046 : if (isnull)
2752 0 : ereport(ERROR,
2753 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2754 : errmsg("lower bound of FOR loop cannot be null")));
2755 3046 : loop_value = DatumGetInt32(value);
2756 3046 : exec_eval_cleanup(estate);
2757 :
2758 : /*
2759 : * Get the value of the upper bound
2760 : */
2761 3046 : value = exec_eval_expr(estate, stmt->upper,
2762 : &isnull, &valtype, &valtypmod);
2763 3046 : value = exec_cast_value(estate, value, &isnull,
2764 : valtype, valtypmod,
2765 3046 : var->datatype->typoid,
2766 3046 : var->datatype->atttypmod);
2767 3046 : if (isnull)
2768 0 : ereport(ERROR,
2769 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2770 : errmsg("upper bound of FOR loop cannot be null")));
2771 3046 : end_value = DatumGetInt32(value);
2772 3046 : exec_eval_cleanup(estate);
2773 :
2774 : /*
2775 : * Get the step value
2776 : */
2777 3046 : if (stmt->step)
2778 : {
2779 9 : value = exec_eval_expr(estate, stmt->step,
2780 : &isnull, &valtype, &valtypmod);
2781 9 : value = exec_cast_value(estate, value, &isnull,
2782 : valtype, valtypmod,
2783 9 : var->datatype->typoid,
2784 9 : var->datatype->atttypmod);
2785 9 : if (isnull)
2786 0 : ereport(ERROR,
2787 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2788 : errmsg("BY value of FOR loop cannot be null")));
2789 9 : step_value = DatumGetInt32(value);
2790 9 : exec_eval_cleanup(estate);
2791 9 : if (step_value <= 0)
2792 3 : ereport(ERROR,
2793 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2794 : errmsg("BY value of FOR loop must be greater than zero")));
2795 : }
2796 : else
2797 3037 : step_value = 1;
2798 :
2799 : /*
2800 : * Now do the loop
2801 : */
2802 : for (;;)
2803 : {
2804 : /*
2805 : * Check against upper bound
2806 : */
2807 21425 : if (stmt->reverse)
2808 : {
2809 8 : if (loop_value < end_value)
2810 1 : break;
2811 : }
2812 : else
2813 : {
2814 21417 : if (loop_value > end_value)
2815 3017 : break;
2816 : }
2817 :
2818 18407 : found = true; /* looped at least once */
2819 :
2820 : /*
2821 : * Assign current value to loop var
2822 : */
2823 18407 : assign_simple_var(estate, var, Int32GetDatum(loop_value), false, false);
2824 :
2825 : /*
2826 : * Execute the statements
2827 : */
2828 18407 : rc = exec_stmts(estate, stmt->body);
2829 :
2830 18395 : LOOP_RC_PROCESSING(stmt->label, break);
2831 :
2832 : /*
2833 : * Increase/decrease loop value, unless it would overflow, in which
2834 : * case exit the loop.
2835 : */
2836 18384 : if (stmt->reverse)
2837 : {
2838 7 : if (loop_value < (PG_INT32_MIN + step_value))
2839 1 : break;
2840 6 : loop_value -= step_value;
2841 : }
2842 : else
2843 : {
2844 18377 : if (loop_value > (PG_INT32_MAX - step_value))
2845 1 : break;
2846 18376 : loop_value += step_value;
2847 : }
2848 : }
2849 :
2850 : /*
2851 : * Set the FOUND variable to indicate the result of executing the loop
2852 : * (namely, whether we looped one or more times). This must be set here so
2853 : * that it does not interfere with the value of the FOUND variable inside
2854 : * the loop processing itself.
2855 : */
2856 3031 : exec_set_found(estate, found);
2857 :
2858 3031 : return rc;
2859 : }
2860 :
2861 :
2862 : /* ----------
2863 : * exec_stmt_fors Execute a query, assign each
2864 : * tuple to a record or row and
2865 : * execute a group of statements
2866 : * for it.
2867 : * ----------
2868 : */
2869 : static int
2870 1636 : exec_stmt_fors(PLpgSQL_execstate *estate, PLpgSQL_stmt_fors *stmt)
2871 : {
2872 : Portal portal;
2873 : int rc;
2874 :
2875 : /*
2876 : * Open the implicit cursor for the statement using exec_run_select
2877 : */
2878 1636 : exec_run_select(estate, stmt->query, 0, &portal);
2879 :
2880 : /*
2881 : * Execute the loop
2882 : */
2883 1628 : rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, true);
2884 :
2885 : /*
2886 : * Close the implicit cursor
2887 : */
2888 1608 : SPI_cursor_close(portal);
2889 :
2890 1608 : return rc;
2891 : }
2892 :
2893 :
2894 : /* ----------
2895 : * exec_stmt_forc Execute a loop for each row from a cursor.
2896 : * ----------
2897 : */
2898 : static int
2899 69 : exec_stmt_forc(PLpgSQL_execstate *estate, PLpgSQL_stmt_forc *stmt)
2900 : {
2901 : PLpgSQL_var *curvar;
2902 69 : MemoryContext stmt_mcontext = NULL;
2903 69 : char *curname = NULL;
2904 : PLpgSQL_expr *query;
2905 : ParamListInfo paramLI;
2906 : Portal portal;
2907 : int rc;
2908 :
2909 : /* ----------
2910 : * Get the cursor variable and if it has an assigned name, check
2911 : * that it's not in use currently.
2912 : * ----------
2913 : */
2914 69 : curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
2915 69 : if (!curvar->isnull)
2916 : {
2917 : MemoryContext oldcontext;
2918 :
2919 : /* We only need stmt_mcontext to hold the cursor name string */
2920 16 : stmt_mcontext = get_stmt_mcontext(estate);
2921 16 : oldcontext = MemoryContextSwitchTo(stmt_mcontext);
2922 16 : curname = TextDatumGetCString(curvar->value);
2923 16 : MemoryContextSwitchTo(oldcontext);
2924 :
2925 16 : if (SPI_cursor_find(curname) != NULL)
2926 0 : ereport(ERROR,
2927 : (errcode(ERRCODE_DUPLICATE_CURSOR),
2928 : errmsg("cursor \"%s\" already in use", curname)));
2929 : }
2930 :
2931 : /* ----------
2932 : * Open the cursor just like an OPEN command
2933 : *
2934 : * Note: parser should already have checked that statement supplies
2935 : * args iff cursor needs them, but we check again to be safe.
2936 : * ----------
2937 : */
2938 69 : if (stmt->argquery != NULL)
2939 : {
2940 : /* ----------
2941 : * OPEN CURSOR with args. We fake a SELECT ... INTO ...
2942 : * statement to evaluate the args and put 'em into the
2943 : * internal row.
2944 : * ----------
2945 : */
2946 : PLpgSQL_stmt_execsql set_args;
2947 :
2948 8 : if (curvar->cursor_explicit_argrow < 0)
2949 0 : ereport(ERROR,
2950 : (errcode(ERRCODE_SYNTAX_ERROR),
2951 : errmsg("arguments given for cursor without arguments")));
2952 :
2953 8 : memset(&set_args, 0, sizeof(set_args));
2954 8 : set_args.cmd_type = PLPGSQL_STMT_EXECSQL;
2955 8 : set_args.lineno = stmt->lineno;
2956 8 : set_args.sqlstmt = stmt->argquery;
2957 8 : set_args.into = true;
2958 : /* XXX historically this has not been STRICT */
2959 8 : set_args.target = (PLpgSQL_variable *)
2960 8 : (estate->datums[curvar->cursor_explicit_argrow]);
2961 :
2962 8 : if (exec_stmt_execsql(estate, &set_args) != PLPGSQL_RC_OK)
2963 0 : elog(ERROR, "open cursor failed during argument processing");
2964 : }
2965 : else
2966 : {
2967 61 : if (curvar->cursor_explicit_argrow >= 0)
2968 0 : ereport(ERROR,
2969 : (errcode(ERRCODE_SYNTAX_ERROR),
2970 : errmsg("arguments required for cursor")));
2971 : }
2972 :
2973 69 : query = curvar->cursor_explicit_expr;
2974 : Assert(query);
2975 :
2976 69 : if (query->plan == NULL)
2977 21 : exec_prepare_plan(estate, query, curvar->cursor_options);
2978 :
2979 : /*
2980 : * Set up ParamListInfo for this query
2981 : */
2982 69 : paramLI = setup_param_list(estate, query);
2983 :
2984 : /*
2985 : * Open the cursor (the paramlist will get copied into the portal)
2986 : */
2987 69 : portal = SPI_cursor_open_with_paramlist(curname, query->plan,
2988 : paramLI,
2989 69 : estate->readonly_func);
2990 69 : if (portal == NULL)
2991 0 : elog(ERROR, "could not open cursor: %s",
2992 : SPI_result_code_string(SPI_result));
2993 :
2994 : /*
2995 : * If cursor variable was NULL, store the generated portal name in it,
2996 : * after verifying it's okay to assign to.
2997 : */
2998 69 : if (curname == NULL)
2999 : {
3000 53 : exec_check_assignable(estate, stmt->curvar);
3001 53 : assign_text_var(estate, curvar, portal->name);
3002 : }
3003 :
3004 : /*
3005 : * Clean up before entering exec_for_query
3006 : */
3007 69 : exec_eval_cleanup(estate);
3008 69 : if (stmt_mcontext)
3009 16 : MemoryContextReset(stmt_mcontext);
3010 :
3011 : /*
3012 : * Execute the loop. We can't prefetch because the cursor is accessible
3013 : * to the user, for instance via UPDATE WHERE CURRENT OF within the loop.
3014 : */
3015 69 : rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, false);
3016 :
3017 : /* ----------
3018 : * Close portal, and restore cursor variable if it was initially NULL.
3019 : * ----------
3020 : */
3021 69 : SPI_cursor_close(portal);
3022 :
3023 69 : if (curname == NULL)
3024 53 : assign_simple_var(estate, curvar, (Datum) 0, true, false);
3025 :
3026 69 : return rc;
3027 : }
3028 :
3029 :
3030 : /* ----------
3031 : * exec_stmt_foreach_a Loop over elements or slices of an array
3032 : *
3033 : * When looping over elements, the loop variable is the same type that the
3034 : * array stores (eg: integer), when looping through slices, the loop variable
3035 : * is an array of size and dimensions to match the size of the slice.
3036 : * ----------
3037 : */
3038 : static int
3039 121 : exec_stmt_foreach_a(PLpgSQL_execstate *estate, PLpgSQL_stmt_foreach_a *stmt)
3040 : {
3041 : ArrayType *arr;
3042 : Oid arrtype;
3043 : int32 arrtypmod;
3044 : PLpgSQL_datum *loop_var;
3045 : Oid loop_var_elem_type;
3046 121 : bool found = false;
3047 121 : int rc = PLPGSQL_RC_OK;
3048 : MemoryContext stmt_mcontext;
3049 : MemoryContext oldcontext;
3050 : ArrayIterator array_iterator;
3051 : Oid iterator_result_type;
3052 : int32 iterator_result_typmod;
3053 : Datum value;
3054 : bool isnull;
3055 :
3056 : /* get the value of the array expression */
3057 121 : value = exec_eval_expr(estate, stmt->expr, &isnull, &arrtype, &arrtypmod);
3058 121 : if (isnull)
3059 0 : ereport(ERROR,
3060 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
3061 : errmsg("FOREACH expression must not be null")));
3062 :
3063 : /*
3064 : * Do as much as possible of the code below in stmt_mcontext, to avoid any
3065 : * leaks from called subroutines. We need a private stmt_mcontext since
3066 : * we'll be calling arbitrary statement code.
3067 : */
3068 121 : stmt_mcontext = get_stmt_mcontext(estate);
3069 121 : push_stmt_mcontext(estate);
3070 121 : oldcontext = MemoryContextSwitchTo(stmt_mcontext);
3071 :
3072 : /* check the type of the expression - must be an array */
3073 121 : if (!OidIsValid(get_element_type(arrtype)))
3074 0 : ereport(ERROR,
3075 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3076 : errmsg("FOREACH expression must yield an array, not type %s",
3077 : format_type_be(arrtype))));
3078 :
3079 : /*
3080 : * We must copy the array into stmt_mcontext, else it will disappear in
3081 : * exec_eval_cleanup. This is annoying, but cleanup will certainly happen
3082 : * while running the loop body, so we have little choice.
3083 : */
3084 121 : arr = DatumGetArrayTypePCopy(value);
3085 :
3086 : /* Clean up any leftover temporary memory */
3087 121 : exec_eval_cleanup(estate);
3088 :
3089 : /* Slice dimension must be less than or equal to array dimension */
3090 121 : if (stmt->slice < 0 || stmt->slice > ARR_NDIM(arr))
3091 4 : ereport(ERROR,
3092 : (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3093 : errmsg("slice dimension (%d) is out of the valid range 0..%d",
3094 : stmt->slice, ARR_NDIM(arr))));
3095 :
3096 : /* Set up the loop variable and see if it is of an array type */
3097 117 : loop_var = estate->datums[stmt->varno];
3098 117 : if (loop_var->dtype == PLPGSQL_DTYPE_REC ||
3099 109 : loop_var->dtype == PLPGSQL_DTYPE_ROW)
3100 : {
3101 : /*
3102 : * Record/row variable is certainly not of array type, and might not
3103 : * be initialized at all yet, so don't try to get its type
3104 : */
3105 16 : loop_var_elem_type = InvalidOid;
3106 : }
3107 : else
3108 101 : loop_var_elem_type = get_element_type(plpgsql_exec_get_datum_type(estate,
3109 : loop_var));
3110 :
3111 : /*
3112 : * Sanity-check the loop variable type. We don't try very hard here, and
3113 : * should not be too picky since it's possible that exec_assign_value can
3114 : * coerce values of different types. But it seems worthwhile to complain
3115 : * if the array-ness of the loop variable is not right.
3116 : */
3117 117 : if (stmt->slice > 0 && loop_var_elem_type == InvalidOid)
3118 8 : ereport(ERROR,
3119 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3120 : errmsg("FOREACH ... SLICE loop variable must be of an array type")));
3121 109 : if (stmt->slice == 0 && loop_var_elem_type != InvalidOid)
3122 0 : ereport(ERROR,
3123 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3124 : errmsg("FOREACH loop variable must not be of an array type")));
3125 :
3126 : /* Create an iterator to step through the array */
3127 109 : array_iterator = array_create_iterator(arr, stmt->slice, NULL);
3128 :
3129 : /* Identify iterator result type */
3130 109 : if (stmt->slice > 0)
3131 : {
3132 : /* When slicing, nominal type of result is same as array type */
3133 24 : iterator_result_type = arrtype;
3134 24 : iterator_result_typmod = arrtypmod;
3135 : }
3136 : else
3137 : {
3138 : /* Without slicing, results are individual array elements */
3139 85 : iterator_result_type = ARR_ELEMTYPE(arr);
3140 85 : iterator_result_typmod = arrtypmod;
3141 : }
3142 :
3143 : /* Iterate over the array elements or slices */
3144 3705 : while (array_iterate(array_iterator, &value, &isnull))
3145 : {
3146 3596 : found = true; /* looped at least once */
3147 :
3148 : /* exec_assign_value and exec_stmts must run in the main context */
3149 3596 : MemoryContextSwitchTo(oldcontext);
3150 :
3151 : /* Assign current element/slice to the loop variable */
3152 3596 : exec_assign_value(estate, loop_var, value, isnull,
3153 : iterator_result_type, iterator_result_typmod);
3154 :
3155 : /* In slice case, value is temporary; must free it to avoid leakage */
3156 3596 : if (stmt->slice > 0)
3157 36 : pfree(DatumGetPointer(value));
3158 :
3159 : /*
3160 : * Execute the statements
3161 : */
3162 3596 : rc = exec_stmts(estate, stmt->body);
3163 :
3164 3596 : LOOP_RC_PROCESSING(stmt->label, break);
3165 :
3166 3596 : MemoryContextSwitchTo(stmt_mcontext);
3167 : }
3168 :
3169 : /* Restore memory context state */
3170 109 : MemoryContextSwitchTo(oldcontext);
3171 109 : pop_stmt_mcontext(estate);
3172 :
3173 : /* Release temporary memory, including the array value */
3174 109 : MemoryContextReset(stmt_mcontext);
3175 :
3176 : /*
3177 : * Set the FOUND variable to indicate the result of executing the loop
3178 : * (namely, whether we looped one or more times). This must be set here so
3179 : * that it does not interfere with the value of the FOUND variable inside
3180 : * the loop processing itself.
3181 : */
3182 109 : exec_set_found(estate, found);
3183 :
3184 109 : return rc;
3185 : }
3186 :
3187 :
3188 : /* ----------
3189 : * exec_stmt_exit Implements EXIT and CONTINUE
3190 : *
3191 : * This begins the process of exiting / restarting a loop.
3192 : * ----------
3193 : */
3194 : static int
3195 2097 : exec_stmt_exit(PLpgSQL_execstate *estate, PLpgSQL_stmt_exit *stmt)
3196 : {
3197 : /*
3198 : * If the exit / continue has a condition, evaluate it
3199 : */
3200 2097 : if (stmt->cond != NULL)
3201 : {
3202 : bool value;
3203 : bool isnull;
3204 :
3205 1694 : value = exec_eval_boolean(estate, stmt->cond, &isnull);
3206 1694 : exec_eval_cleanup(estate);
3207 1694 : if (isnull || value == false)
3208 1597 : return PLPGSQL_RC_OK;
3209 : }
3210 :
3211 500 : estate->exitlabel = stmt->label;
3212 500 : if (stmt->is_exit)
3213 58 : return PLPGSQL_RC_EXIT;
3214 : else
3215 442 : return PLPGSQL_RC_CONTINUE;
3216 : }
3217 :
3218 :
3219 : /* ----------
3220 : * exec_stmt_return Evaluate an expression and start
3221 : * returning from the function.
3222 : *
3223 : * Note: The result may be in the eval_mcontext. Therefore, we must not
3224 : * do exec_eval_cleanup while unwinding the control stack.
3225 : * ----------
3226 : */
3227 : static int
3228 53735 : exec_stmt_return(PLpgSQL_execstate *estate, PLpgSQL_stmt_return *stmt)
3229 : {
3230 : /*
3231 : * If processing a set-returning PL/pgSQL function, the final RETURN
3232 : * indicates that the function is finished producing tuples. The rest of
3233 : * the work will be done at the top level.
3234 : */
3235 53735 : if (estate->retisset)
3236 2426 : return PLPGSQL_RC_RETURN;
3237 :
3238 : /* initialize for null result */
3239 51309 : estate->retval = (Datum) 0;
3240 51309 : estate->retisnull = true;
3241 51309 : estate->rettype = InvalidOid;
3242 :
3243 : /*
3244 : * Special case path when the RETURN expression is a simple variable
3245 : * reference; in particular, this path is always taken in functions with
3246 : * one or more OUT parameters.
3247 : *
3248 : * This special case is especially efficient for returning variables that
3249 : * have R/W expanded values: we can put the R/W pointer directly into
3250 : * estate->retval, leading to transferring the value to the caller's
3251 : * context cheaply. If we went through exec_eval_expr we'd end up with a
3252 : * R/O pointer. It's okay to skip MakeExpandedObjectReadOnly here since
3253 : * we know we won't need the variable's value within the function anymore.
3254 : */
3255 51309 : if (stmt->retvarno >= 0)
3256 : {
3257 36640 : PLpgSQL_datum *retvar = estate->datums[stmt->retvarno];
3258 :
3259 36640 : switch (retvar->dtype)
3260 : {
3261 0 : case PLPGSQL_DTYPE_PROMISE:
3262 : /* fulfill promise if needed, then handle like regular var */
3263 0 : plpgsql_fulfill_promise(estate, (PLpgSQL_var *) retvar);
3264 :
3265 : pg_fallthrough;
3266 :
3267 24168 : case PLPGSQL_DTYPE_VAR:
3268 : {
3269 24168 : PLpgSQL_var *var = (PLpgSQL_var *) retvar;
3270 :
3271 24168 : estate->retval = var->value;
3272 24168 : estate->retisnull = var->isnull;
3273 24168 : estate->rettype = var->datatype->typoid;
3274 :
3275 : /*
3276 : * A PLpgSQL_var could not be of composite type, so
3277 : * conversion must fail if retistuple. We throw a custom
3278 : * error mainly for consistency with historical behavior.
3279 : * For the same reason, we don't throw error if the result
3280 : * is NULL. (Note that plpgsql_exec_trigger assumes that
3281 : * any non-null result has been verified to be composite.)
3282 : */
3283 24168 : if (estate->retistuple && !estate->retisnull)
3284 4 : ereport(ERROR,
3285 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3286 : errmsg("cannot return non-composite value from function returning composite type")));
3287 : }
3288 24164 : break;
3289 :
3290 12472 : case PLPGSQL_DTYPE_ROW:
3291 : case PLPGSQL_DTYPE_REC:
3292 : {
3293 : /* exec_eval_datum can handle these cases */
3294 : int32 rettypmod;
3295 :
3296 12472 : exec_eval_datum(estate,
3297 : retvar,
3298 : &estate->rettype,
3299 : &rettypmod,
3300 : &estate->retval,
3301 : &estate->retisnull);
3302 : }
3303 12472 : break;
3304 :
3305 0 : default:
3306 0 : elog(ERROR, "unrecognized dtype: %d", retvar->dtype);
3307 : }
3308 :
3309 36636 : return PLPGSQL_RC_RETURN;
3310 : }
3311 :
3312 14669 : if (stmt->expr != NULL)
3313 : {
3314 : int32 rettypmod;
3315 :
3316 11335 : estate->retval = exec_eval_expr(estate, stmt->expr,
3317 : &(estate->retisnull),
3318 : &(estate->rettype),
3319 : &rettypmod);
3320 :
3321 : /*
3322 : * As in the DTYPE_VAR case above, throw a custom error if a non-null,
3323 : * non-composite value is returned in a function returning tuple.
3324 : */
3325 11279 : if (estate->retistuple && !estate->retisnull &&
3326 59 : !type_is_rowtype(estate->rettype))
3327 4 : ereport(ERROR,
3328 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3329 : errmsg("cannot return non-composite value from function returning composite type")));
3330 :
3331 11275 : return PLPGSQL_RC_RETURN;
3332 : }
3333 :
3334 : /*
3335 : * Special hack for function returning VOID: instead of NULL, return a
3336 : * non-null VOID value. This is of dubious importance but is kept for
3337 : * backwards compatibility. We don't do it for procedures, though.
3338 : */
3339 3334 : if (estate->fn_rettype == VOIDOID &&
3340 3334 : estate->func->fn_prokind != PROKIND_PROCEDURE)
3341 : {
3342 3279 : estate->retval = (Datum) 0;
3343 3279 : estate->retisnull = false;
3344 3279 : estate->rettype = VOIDOID;
3345 : }
3346 :
3347 3334 : return PLPGSQL_RC_RETURN;
3348 : }
3349 :
3350 : /* ----------
3351 : * exec_stmt_return_next Evaluate an expression and add it to the
3352 : * list of tuples returned by the current
3353 : * SRF.
3354 : * ----------
3355 : */
3356 : static int
3357 3895 : exec_stmt_return_next(PLpgSQL_execstate *estate,
3358 : PLpgSQL_stmt_return_next *stmt)
3359 : {
3360 : TupleDesc tupdesc;
3361 : int natts;
3362 : HeapTuple tuple;
3363 : MemoryContext oldcontext;
3364 :
3365 3895 : if (!estate->retisset)
3366 0 : ereport(ERROR,
3367 : (errcode(ERRCODE_SYNTAX_ERROR),
3368 : errmsg("cannot use RETURN NEXT in a non-SETOF function")));
3369 :
3370 3895 : if (estate->tuple_store == NULL)
3371 667 : exec_init_tuple_store(estate);
3372 :
3373 : /* tuple_store_desc will be filled by exec_init_tuple_store */
3374 3895 : tupdesc = estate->tuple_store_desc;
3375 3895 : natts = tupdesc->natts;
3376 :
3377 : /*
3378 : * Special case path when the RETURN NEXT expression is a simple variable
3379 : * reference; in particular, this path is always taken in functions with
3380 : * one or more OUT parameters.
3381 : *
3382 : * Unlike exec_stmt_return, there's no special win here for R/W expanded
3383 : * values, since they'll have to get flattened to go into the tuplestore.
3384 : * Indeed, we'd better make them R/O to avoid any risk of the casting step
3385 : * changing them in-place.
3386 : */
3387 3895 : if (stmt->retvarno >= 0)
3388 : {
3389 3532 : PLpgSQL_datum *retvar = estate->datums[stmt->retvarno];
3390 :
3391 3532 : switch (retvar->dtype)
3392 : {
3393 0 : case PLPGSQL_DTYPE_PROMISE:
3394 : /* fulfill promise if needed, then handle like regular var */
3395 0 : plpgsql_fulfill_promise(estate, (PLpgSQL_var *) retvar);
3396 :
3397 : pg_fallthrough;
3398 :
3399 3300 : case PLPGSQL_DTYPE_VAR:
3400 : {
3401 3300 : PLpgSQL_var *var = (PLpgSQL_var *) retvar;
3402 3300 : Datum retval = var->value;
3403 3300 : bool isNull = var->isnull;
3404 3300 : Form_pg_attribute attr = TupleDescAttr(tupdesc, 0);
3405 :
3406 3300 : if (natts != 1)
3407 0 : ereport(ERROR,
3408 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3409 : errmsg("wrong result type supplied in RETURN NEXT")));
3410 :
3411 : /* let's be very paranoid about the cast step */
3412 3300 : retval = MakeExpandedObjectReadOnly(retval,
3413 : isNull,
3414 : var->datatype->typlen);
3415 :
3416 : /* coerce type if needed */
3417 6600 : retval = exec_cast_value(estate,
3418 : retval,
3419 : &isNull,
3420 3300 : var->datatype->typoid,
3421 3300 : var->datatype->atttypmod,
3422 : attr->atttypid,
3423 : attr->atttypmod);
3424 :
3425 3300 : tuplestore_putvalues(estate->tuple_store, tupdesc,
3426 : &retval, &isNull);
3427 : }
3428 3300 : break;
3429 :
3430 136 : case PLPGSQL_DTYPE_REC:
3431 : {
3432 136 : PLpgSQL_rec *rec = (PLpgSQL_rec *) retvar;
3433 : TupleDesc rec_tupdesc;
3434 : TupleConversionMap *tupmap;
3435 :
3436 : /* If rec is null, try to convert it to a row of nulls */
3437 136 : if (rec->erh == NULL)
3438 2 : instantiate_empty_record_variable(estate, rec);
3439 135 : if (ExpandedRecordIsEmpty(rec->erh))
3440 1 : deconstruct_expanded_record(rec->erh);
3441 :
3442 : /* Use eval_mcontext for tuple conversion work */
3443 135 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
3444 135 : rec_tupdesc = expanded_record_get_tupdesc(rec->erh);
3445 135 : tupmap = convert_tuples_by_position(rec_tupdesc,
3446 : tupdesc,
3447 : gettext_noop("wrong record type supplied in RETURN NEXT"));
3448 135 : tuple = expanded_record_get_tuple(rec->erh);
3449 135 : if (tupmap)
3450 29 : tuple = execute_attr_map_tuple(tuple, tupmap);
3451 135 : tuplestore_puttuple(estate->tuple_store, tuple);
3452 135 : MemoryContextSwitchTo(oldcontext);
3453 : }
3454 135 : break;
3455 :
3456 96 : case PLPGSQL_DTYPE_ROW:
3457 : {
3458 96 : PLpgSQL_row *row = (PLpgSQL_row *) retvar;
3459 :
3460 : /* We get here if there are multiple OUT parameters */
3461 :
3462 : /* Use eval_mcontext for tuple conversion work */
3463 96 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
3464 96 : tuple = make_tuple_from_row(estate, row, tupdesc);
3465 96 : if (tuple == NULL) /* should not happen */
3466 0 : ereport(ERROR,
3467 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3468 : errmsg("wrong record type supplied in RETURN NEXT")));
3469 96 : tuplestore_puttuple(estate->tuple_store, tuple);
3470 96 : MemoryContextSwitchTo(oldcontext);
3471 : }
3472 96 : break;
3473 :
3474 0 : default:
3475 0 : elog(ERROR, "unrecognized dtype: %d", retvar->dtype);
3476 : break;
3477 : }
3478 : }
3479 363 : else if (stmt->expr)
3480 : {
3481 : Datum retval;
3482 : bool isNull;
3483 : Oid rettype;
3484 : int32 rettypmod;
3485 :
3486 363 : retval = exec_eval_expr(estate,
3487 : stmt->expr,
3488 : &isNull,
3489 : &rettype,
3490 : &rettypmod);
3491 :
3492 363 : if (estate->retistuple)
3493 : {
3494 : /* Expression should be of RECORD or composite type */
3495 323 : if (!isNull)
3496 : {
3497 : HeapTupleData tmptup;
3498 : TupleDesc retvaldesc;
3499 : TupleConversionMap *tupmap;
3500 :
3501 319 : if (!type_is_rowtype(rettype))
3502 0 : ereport(ERROR,
3503 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3504 : errmsg("cannot return non-composite value from function returning composite type")));
3505 :
3506 : /* Use eval_mcontext for tuple conversion work */
3507 319 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
3508 319 : retvaldesc = deconstruct_composite_datum(retval, &tmptup);
3509 319 : tuple = &tmptup;
3510 319 : tupmap = convert_tuples_by_position(retvaldesc, tupdesc,
3511 : gettext_noop("returned record type does not match expected record type"));
3512 318 : if (tupmap)
3513 1 : tuple = execute_attr_map_tuple(tuple, tupmap);
3514 318 : tuplestore_puttuple(estate->tuple_store, tuple);
3515 318 : ReleaseTupleDesc(retvaldesc);
3516 318 : MemoryContextSwitchTo(oldcontext);
3517 : }
3518 : else
3519 : {
3520 : /* Composite NULL --- store a row of nulls */
3521 : Datum *nulldatums;
3522 : bool *nullflags;
3523 :
3524 : nulldatums = (Datum *)
3525 4 : eval_mcontext_alloc0(estate, natts * sizeof(Datum));
3526 : nullflags = (bool *)
3527 4 : eval_mcontext_alloc(estate, natts * sizeof(bool));
3528 4 : memset(nullflags, true, natts * sizeof(bool));
3529 4 : tuplestore_putvalues(estate->tuple_store, tupdesc,
3530 : nulldatums, nullflags);
3531 : }
3532 : }
3533 : else
3534 : {
3535 40 : Form_pg_attribute attr = TupleDescAttr(tupdesc, 0);
3536 :
3537 : /* Simple scalar result */
3538 40 : if (natts != 1)
3539 0 : ereport(ERROR,
3540 : (errcode(ERRCODE_DATATYPE_MISMATCH),
3541 : errmsg("wrong result type supplied in RETURN NEXT")));
3542 :
3543 : /* coerce type if needed */
3544 40 : retval = exec_cast_value(estate,
3545 : retval,
3546 : &isNull,
3547 : rettype,
3548 : rettypmod,
3549 : attr->atttypid,
3550 : attr->atttypmod);
3551 :
3552 40 : tuplestore_putvalues(estate->tuple_store, tupdesc,
3553 : &retval, &isNull);
3554 : }
3555 : }
3556 : else
3557 : {
3558 0 : ereport(ERROR,
3559 : (errcode(ERRCODE_SYNTAX_ERROR),
3560 : errmsg("RETURN NEXT must have a parameter")));
3561 : }
3562 :
3563 3893 : exec_eval_cleanup(estate);
3564 :
3565 3893 : return PLPGSQL_RC_OK;
3566 : }
3567 :
3568 : /* ----------
3569 : * exec_stmt_return_query Evaluate a query and add it to the
3570 : * list of tuples returned by the current
3571 : * SRF.
3572 : * ----------
3573 : */
3574 : static int
3575 1795 : exec_stmt_return_query(PLpgSQL_execstate *estate,
3576 : PLpgSQL_stmt_return_query *stmt)
3577 : {
3578 : int64 tcount;
3579 : DestReceiver *treceiver;
3580 : int rc;
3581 : uint64 processed;
3582 1795 : MemoryContext stmt_mcontext = get_stmt_mcontext(estate);
3583 : MemoryContext oldcontext;
3584 :
3585 1795 : if (!estate->retisset)
3586 0 : ereport(ERROR,
3587 : (errcode(ERRCODE_SYNTAX_ERROR),
3588 : errmsg("cannot use RETURN QUERY in a non-SETOF function")));
3589 :
3590 1795 : if (estate->tuple_store == NULL)
3591 1758 : exec_init_tuple_store(estate);
3592 : /* There might be some tuples in the tuplestore already */
3593 1795 : tcount = tuplestore_tuple_count(estate->tuple_store);
3594 :
3595 : /*
3596 : * Set up DestReceiver to transfer results directly to tuplestore,
3597 : * converting rowtype if necessary. DestReceiver lives in mcontext.
3598 : */
3599 1795 : oldcontext = MemoryContextSwitchTo(stmt_mcontext);
3600 1795 : treceiver = CreateDestReceiver(DestTuplestore);
3601 1795 : SetTuplestoreDestReceiverParams(treceiver,
3602 : estate->tuple_store,
3603 : estate->tuple_store_cxt,
3604 : false,
3605 : estate->tuple_store_desc,
3606 : gettext_noop("structure of query does not match function result type"));
3607 1795 : MemoryContextSwitchTo(oldcontext);
3608 :
3609 1795 : if (stmt->query != NULL)
3610 : {
3611 : /* static query */
3612 1623 : PLpgSQL_expr *expr = stmt->query;
3613 : ParamListInfo paramLI;
3614 : SPIExecuteOptions options;
3615 :
3616 : /*
3617 : * On the first call for this expression generate the plan.
3618 : */
3619 1623 : if (expr->plan == NULL)
3620 47 : exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
3621 :
3622 : /*
3623 : * Set up ParamListInfo to pass to executor
3624 : */
3625 1623 : paramLI = setup_param_list(estate, expr);
3626 :
3627 : /*
3628 : * Execute the query
3629 : */
3630 1623 : memset(&options, 0, sizeof(options));
3631 1623 : options.params = paramLI;
3632 1623 : options.read_only = estate->readonly_func;
3633 1623 : options.must_return_tuples = true;
3634 1623 : options.dest = treceiver;
3635 :
3636 1623 : rc = SPI_execute_plan_extended(expr->plan, &options);
3637 1618 : if (rc < 0)
3638 0 : elog(ERROR, "SPI_execute_plan_extended failed executing query \"%s\": %s",
3639 : expr->query, SPI_result_code_string(rc));
3640 : }
3641 : else
3642 : {
3643 : /* RETURN QUERY EXECUTE */
3644 : Datum query;
3645 : bool isnull;
3646 : Oid restype;
3647 : int32 restypmod;
3648 : char *querystr;
3649 : SPIExecuteOptions options;
3650 :
3651 : /*
3652 : * Evaluate the string expression after the EXECUTE keyword. Its
3653 : * result is the querystring we have to execute.
3654 : */
3655 : Assert(stmt->dynquery != NULL);
3656 172 : query = exec_eval_expr(estate, stmt->dynquery,
3657 : &isnull, &restype, &restypmod);
3658 172 : if (isnull)
3659 0 : ereport(ERROR,
3660 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
3661 : errmsg("query string argument of EXECUTE is null")));
3662 :
3663 : /* Get the C-String representation */
3664 172 : querystr = convert_value_to_string(estate, query, restype);
3665 :
3666 : /* copy it into the stmt_mcontext before we clean up */
3667 172 : querystr = MemoryContextStrdup(stmt_mcontext, querystr);
3668 :
3669 172 : exec_eval_cleanup(estate);
3670 :
3671 : /* Execute query, passing params if necessary */
3672 172 : memset(&options, 0, sizeof(options));
3673 172 : options.params = exec_eval_using_params(estate,
3674 : stmt->params);
3675 172 : options.read_only = estate->readonly_func;
3676 172 : options.must_return_tuples = true;
3677 172 : options.dest = treceiver;
3678 :
3679 172 : rc = SPI_execute_extended(querystr, &options);
3680 168 : if (rc < 0)
3681 0 : elog(ERROR, "SPI_execute_extended failed executing query \"%s\": %s",
3682 : querystr, SPI_result_code_string(rc));
3683 : }
3684 :
3685 : /* Clean up */
3686 1786 : treceiver->rDestroy(treceiver);
3687 1786 : exec_eval_cleanup(estate);
3688 1786 : MemoryContextReset(stmt_mcontext);
3689 :
3690 : /* Count how many tuples we got */
3691 1786 : processed = tuplestore_tuple_count(estate->tuple_store) - tcount;
3692 :
3693 1786 : estate->eval_processed = processed;
3694 1786 : exec_set_found(estate, processed != 0);
3695 :
3696 1786 : return PLPGSQL_RC_OK;
3697 : }
3698 :
3699 : static void
3700 2425 : exec_init_tuple_store(PLpgSQL_execstate *estate)
3701 : {
3702 2425 : ReturnSetInfo *rsi = estate->rsi;
3703 : MemoryContext oldcxt;
3704 : ResourceOwner oldowner;
3705 :
3706 : /*
3707 : * Check caller can handle a set result in the way we want
3708 : */
3709 2425 : if (!rsi || !IsA(rsi, ReturnSetInfo))
3710 0 : ereport(ERROR,
3711 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3712 : errmsg("set-valued function called in context that cannot accept a set")));
3713 :
3714 2425 : if (!(rsi->allowedModes & SFRM_Materialize) ||
3715 2425 : rsi->expectedDesc == NULL)
3716 0 : ereport(ERROR,
3717 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3718 : errmsg("materialize mode required, but it is not allowed in this context")));
3719 :
3720 : /*
3721 : * Switch to the right memory context and resource owner for storing the
3722 : * tuplestore for return set. If we're within a subtransaction opened for
3723 : * an exception-block, for example, we must still create the tuplestore in
3724 : * the resource owner that was active when this function was entered, and
3725 : * not in the subtransaction resource owner.
3726 : */
3727 2425 : oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
3728 2425 : oldowner = CurrentResourceOwner;
3729 2425 : CurrentResourceOwner = estate->tuple_store_owner;
3730 :
3731 2425 : estate->tuple_store =
3732 2425 : tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
3733 : false, work_mem);
3734 :
3735 2425 : CurrentResourceOwner = oldowner;
3736 2425 : MemoryContextSwitchTo(oldcxt);
3737 :
3738 2425 : estate->tuple_store_desc = rsi->expectedDesc;
3739 2425 : }
3740 :
3741 : #define SET_RAISE_OPTION_TEXT(opt, name) \
3742 : do { \
3743 : if (opt) \
3744 : ereport(ERROR, \
3745 : (errcode(ERRCODE_SYNTAX_ERROR), \
3746 : errmsg("RAISE option already specified: %s", \
3747 : name))); \
3748 : opt = MemoryContextStrdup(stmt_mcontext, extval); \
3749 : } while (0)
3750 :
3751 : /* ----------
3752 : * exec_stmt_raise Build a message and throw it with elog()
3753 : * ----------
3754 : */
3755 : static int
3756 12732 : exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
3757 : {
3758 12732 : int err_code = 0;
3759 12732 : char *condname = NULL;
3760 12732 : char *err_message = NULL;
3761 12732 : char *err_detail = NULL;
3762 12732 : char *err_hint = NULL;
3763 12732 : char *err_column = NULL;
3764 12732 : char *err_constraint = NULL;
3765 12732 : char *err_datatype = NULL;
3766 12732 : char *err_table = NULL;
3767 12732 : char *err_schema = NULL;
3768 : MemoryContext stmt_mcontext;
3769 : ListCell *lc;
3770 :
3771 : /* RAISE with no parameters: re-throw current exception */
3772 12732 : if (stmt->condname == NULL && stmt->message == NULL &&
3773 36 : stmt->options == NIL)
3774 : {
3775 24 : if (estate->cur_error != NULL)
3776 20 : ReThrowError(estate->cur_error);
3777 : /* oops, we're not inside a handler */
3778 4 : ereport(ERROR,
3779 : (errcode(ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER),
3780 : errmsg("RAISE without parameters cannot be used outside an exception handler")));
3781 : }
3782 :
3783 : /* We'll need to accumulate the various strings in stmt_mcontext */
3784 12708 : stmt_mcontext = get_stmt_mcontext(estate);
3785 :
3786 12708 : if (stmt->condname)
3787 : {
3788 438 : err_code = plpgsql_recognize_err_condition(stmt->condname, true);
3789 438 : condname = MemoryContextStrdup(stmt_mcontext, stmt->condname);
3790 : }
3791 :
3792 12708 : if (stmt->message)
3793 : {
3794 : StringInfoData ds;
3795 : ListCell *current_param;
3796 : char *cp;
3797 : MemoryContext oldcontext;
3798 :
3799 : /* build string in stmt_mcontext */
3800 12258 : oldcontext = MemoryContextSwitchTo(stmt_mcontext);
3801 12258 : initStringInfo(&ds);
3802 12258 : MemoryContextSwitchTo(oldcontext);
3803 :
3804 12258 : current_param = list_head(stmt->params);
3805 :
3806 215535 : for (cp = stmt->message; *cp; cp++)
3807 : {
3808 : /*
3809 : * Occurrences of a single % are replaced by the next parameter's
3810 : * external representation. Double %'s are converted to one %.
3811 : */
3812 203294 : if (cp[0] == '%')
3813 : {
3814 : Oid paramtypeid;
3815 : int32 paramtypmod;
3816 : Datum paramvalue;
3817 : bool paramisnull;
3818 : char *extval;
3819 :
3820 30174 : if (cp[1] == '%')
3821 : {
3822 4 : appendStringInfoChar(&ds, '%');
3823 4 : cp++;
3824 4 : continue;
3825 : }
3826 :
3827 : /* should have been checked at compile time */
3828 30170 : if (current_param == NULL)
3829 0 : elog(ERROR, "unexpected RAISE parameter list length");
3830 :
3831 30170 : paramvalue = exec_eval_expr(estate,
3832 30170 : (PLpgSQL_expr *) lfirst(current_param),
3833 : ¶misnull,
3834 : ¶mtypeid,
3835 : ¶mtypmod);
3836 :
3837 30153 : if (paramisnull)
3838 260 : extval = "<NULL>";
3839 : else
3840 29893 : extval = convert_value_to_string(estate,
3841 : paramvalue,
3842 : paramtypeid);
3843 30153 : appendStringInfoString(&ds, extval);
3844 30153 : current_param = lnext(stmt->params, current_param);
3845 30153 : exec_eval_cleanup(estate);
3846 : }
3847 : else
3848 173120 : appendStringInfoChar(&ds, cp[0]);
3849 : }
3850 :
3851 : /* should have been checked at compile time */
3852 12241 : if (current_param != NULL)
3853 0 : elog(ERROR, "unexpected RAISE parameter list length");
3854 :
3855 12241 : err_message = ds.data;
3856 : }
3857 :
3858 13201 : foreach(lc, stmt->options)
3859 : {
3860 518 : PLpgSQL_raise_option *opt = (PLpgSQL_raise_option *) lfirst(lc);
3861 : Datum optionvalue;
3862 : bool optionisnull;
3863 : Oid optiontypeid;
3864 : int32 optiontypmod;
3865 : char *extval;
3866 :
3867 518 : optionvalue = exec_eval_expr(estate, opt->expr,
3868 : &optionisnull,
3869 : &optiontypeid,
3870 : &optiontypmod);
3871 518 : if (optionisnull)
3872 0 : ereport(ERROR,
3873 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
3874 : errmsg("RAISE statement option cannot be null")));
3875 :
3876 518 : extval = convert_value_to_string(estate, optionvalue, optiontypeid);
3877 :
3878 518 : switch (opt->opt_type)
3879 : {
3880 28 : case PLPGSQL_RAISEOPTION_ERRCODE:
3881 28 : if (err_code)
3882 4 : ereport(ERROR,
3883 : (errcode(ERRCODE_SYNTAX_ERROR),
3884 : errmsg("RAISE option already specified: %s",
3885 : "ERRCODE")));
3886 24 : err_code = plpgsql_recognize_err_condition(extval, true);
3887 24 : condname = MemoryContextStrdup(stmt_mcontext, extval);
3888 24 : break;
3889 426 : case PLPGSQL_RAISEOPTION_MESSAGE:
3890 426 : SET_RAISE_OPTION_TEXT(err_message, "MESSAGE");
3891 422 : break;
3892 30 : case PLPGSQL_RAISEOPTION_DETAIL:
3893 30 : SET_RAISE_OPTION_TEXT(err_detail, "DETAIL");
3894 30 : break;
3895 9 : case PLPGSQL_RAISEOPTION_HINT:
3896 9 : SET_RAISE_OPTION_TEXT(err_hint, "HINT");
3897 9 : break;
3898 5 : case PLPGSQL_RAISEOPTION_COLUMN:
3899 5 : SET_RAISE_OPTION_TEXT(err_column, "COLUMN");
3900 5 : break;
3901 5 : case PLPGSQL_RAISEOPTION_CONSTRAINT:
3902 5 : SET_RAISE_OPTION_TEXT(err_constraint, "CONSTRAINT");
3903 5 : break;
3904 5 : case PLPGSQL_RAISEOPTION_DATATYPE:
3905 5 : SET_RAISE_OPTION_TEXT(err_datatype, "DATATYPE");
3906 5 : break;
3907 5 : case PLPGSQL_RAISEOPTION_TABLE:
3908 5 : SET_RAISE_OPTION_TEXT(err_table, "TABLE");
3909 5 : break;
3910 5 : case PLPGSQL_RAISEOPTION_SCHEMA:
3911 5 : SET_RAISE_OPTION_TEXT(err_schema, "SCHEMA");
3912 5 : break;
3913 0 : default:
3914 0 : elog(ERROR, "unrecognized raise option: %d", opt->opt_type);
3915 : }
3916 :
3917 510 : exec_eval_cleanup(estate);
3918 : }
3919 :
3920 : /* Default code if nothing specified */
3921 12683 : if (err_code == 0 && stmt->elog_level >= ERROR)
3922 147 : err_code = ERRCODE_RAISE_EXCEPTION;
3923 :
3924 : /* Default error message if nothing specified */
3925 12683 : if (err_message == NULL)
3926 : {
3927 28 : if (condname)
3928 : {
3929 24 : err_message = condname;
3930 24 : condname = NULL;
3931 : }
3932 : else
3933 4 : err_message = MemoryContextStrdup(stmt_mcontext,
3934 4 : unpack_sql_state(err_code));
3935 : }
3936 :
3937 : /*
3938 : * Throw the error (may or may not come back)
3939 : */
3940 12683 : ereport(stmt->elog_level,
3941 : (err_code ? errcode(err_code) : 0,
3942 : errmsg_internal("%s", err_message),
3943 : (err_detail != NULL) ? errdetail_internal("%s", err_detail) : 0,
3944 : (err_hint != NULL) ? errhint("%s", err_hint) : 0,
3945 : (err_column != NULL) ?
3946 : err_generic_string(PG_DIAG_COLUMN_NAME, err_column) : 0,
3947 : (err_constraint != NULL) ?
3948 : err_generic_string(PG_DIAG_CONSTRAINT_NAME, err_constraint) : 0,
3949 : (err_datatype != NULL) ?
3950 : err_generic_string(PG_DIAG_DATATYPE_NAME, err_datatype) : 0,
3951 : (err_table != NULL) ?
3952 : err_generic_string(PG_DIAG_TABLE_NAME, err_table) : 0,
3953 : (err_schema != NULL) ?
3954 : err_generic_string(PG_DIAG_SCHEMA_NAME, err_schema) : 0));
3955 :
3956 : /* Clean up transient strings */
3957 12082 : MemoryContextReset(stmt_mcontext);
3958 :
3959 12082 : return PLPGSQL_RC_OK;
3960 : }
3961 :
3962 : /* ----------
3963 : * exec_stmt_assert Assert statement
3964 : * ----------
3965 : */
3966 : static int
3967 4476 : exec_stmt_assert(PLpgSQL_execstate *estate, PLpgSQL_stmt_assert *stmt)
3968 : {
3969 : bool value;
3970 : bool isnull;
3971 :
3972 : /* do nothing when asserts are not enabled */
3973 4476 : if (!plpgsql_check_asserts)
3974 4 : return PLPGSQL_RC_OK;
3975 :
3976 4472 : value = exec_eval_boolean(estate, stmt->cond, &isnull);
3977 4472 : exec_eval_cleanup(estate);
3978 :
3979 4472 : if (isnull || !value)
3980 : {
3981 16 : char *message = NULL;
3982 :
3983 16 : if (stmt->message != NULL)
3984 : {
3985 : Datum val;
3986 : Oid typeid;
3987 : int32 typmod;
3988 :
3989 8 : val = exec_eval_expr(estate, stmt->message,
3990 : &isnull, &typeid, &typmod);
3991 8 : if (!isnull)
3992 8 : message = convert_value_to_string(estate, val, typeid);
3993 : /* we mustn't do exec_eval_cleanup here */
3994 : }
3995 :
3996 16 : ereport(ERROR,
3997 : (errcode(ERRCODE_ASSERT_FAILURE),
3998 : message ? errmsg_internal("%s", message) :
3999 : errmsg("assertion failed")));
4000 : }
4001 :
4002 4456 : return PLPGSQL_RC_OK;
4003 : }
4004 :
4005 : /* ----------
4006 : * Initialize a mostly empty execution state
4007 : * ----------
4008 : */
4009 : static void
4010 54372 : plpgsql_estate_setup(PLpgSQL_execstate *estate,
4011 : PLpgSQL_function *func,
4012 : ReturnSetInfo *rsi,
4013 : EState *simple_eval_estate,
4014 : ResourceOwner simple_eval_resowner)
4015 : {
4016 : HASHCTL ctl;
4017 :
4018 : /* this link will be restored at exit from plpgsql_call_handler */
4019 54372 : func->cur_estate = estate;
4020 :
4021 54372 : estate->func = func;
4022 54372 : estate->trigdata = NULL;
4023 54372 : estate->evtrigdata = NULL;
4024 :
4025 54372 : estate->retval = (Datum) 0;
4026 54372 : estate->retisnull = true;
4027 54372 : estate->rettype = InvalidOid;
4028 :
4029 54372 : estate->fn_rettype = func->fn_rettype;
4030 54372 : estate->retistuple = func->fn_retistuple;
4031 54372 : estate->retisset = func->fn_retset;
4032 :
4033 54372 : estate->readonly_func = func->fn_readonly;
4034 54372 : estate->atomic = true;
4035 :
4036 54372 : estate->exitlabel = NULL;
4037 54372 : estate->cur_error = NULL;
4038 :
4039 54372 : estate->tuple_store = NULL;
4040 54372 : estate->tuple_store_desc = NULL;
4041 54372 : if (rsi)
4042 : {
4043 2640 : estate->tuple_store_cxt = rsi->econtext->ecxt_per_query_memory;
4044 2640 : estate->tuple_store_owner = CurrentResourceOwner;
4045 : }
4046 : else
4047 : {
4048 51732 : estate->tuple_store_cxt = NULL;
4049 51732 : estate->tuple_store_owner = NULL;
4050 : }
4051 54372 : estate->rsi = rsi;
4052 :
4053 54372 : estate->found_varno = func->found_varno;
4054 54372 : estate->ndatums = func->ndatums;
4055 54372 : estate->datums = NULL;
4056 : /* the datums array will be filled by copy_plpgsql_datums() */
4057 54372 : estate->datum_context = CurrentMemoryContext;
4058 :
4059 : /* initialize our ParamListInfo with appropriate hook functions */
4060 54372 : estate->paramLI = makeParamList(0);
4061 54372 : estate->paramLI->paramFetch = plpgsql_param_fetch;
4062 54372 : estate->paramLI->paramFetchArg = estate;
4063 54372 : estate->paramLI->paramCompile = plpgsql_param_compile;
4064 54372 : estate->paramLI->paramCompileArg = NULL; /* not needed */
4065 54372 : estate->paramLI->parserSetup = (ParserSetupHook) plpgsql_parser_setup;
4066 54372 : estate->paramLI->parserSetupArg = NULL; /* filled during use */
4067 54372 : estate->paramLI->numParams = estate->ndatums;
4068 :
4069 : /* Create the session-wide cast-expression hash if we didn't already */
4070 54372 : if (cast_expr_hash == NULL)
4071 : {
4072 694 : ctl.keysize = sizeof(plpgsql_CastHashKey);
4073 694 : ctl.entrysize = sizeof(plpgsql_CastExprHashEntry);
4074 694 : cast_expr_hash = hash_create("PLpgSQL cast expressions",
4075 : 16, /* start small and extend */
4076 : &ctl,
4077 : HASH_ELEM | HASH_BLOBS);
4078 : }
4079 :
4080 : /* set up for use of appropriate simple-expression EState and cast hash */
4081 54372 : if (simple_eval_estate)
4082 : {
4083 810 : estate->simple_eval_estate = simple_eval_estate;
4084 : /* Private cast hash just lives in function's main context */
4085 810 : ctl.keysize = sizeof(plpgsql_CastHashKey);
4086 810 : ctl.entrysize = sizeof(plpgsql_CastHashEntry);
4087 810 : ctl.hcxt = CurrentMemoryContext;
4088 810 : estate->cast_hash = hash_create("PLpgSQL private cast cache",
4089 : 16, /* start small and extend */
4090 : &ctl,
4091 : HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
4092 : }
4093 : else
4094 : {
4095 53562 : estate->simple_eval_estate = shared_simple_eval_estate;
4096 : /* Create the session-wide cast-info hash table if we didn't already */
4097 53562 : if (shared_cast_hash == NULL)
4098 : {
4099 587 : ctl.keysize = sizeof(plpgsql_CastHashKey);
4100 587 : ctl.entrysize = sizeof(plpgsql_CastHashEntry);
4101 587 : shared_cast_hash = hash_create("PLpgSQL cast cache",
4102 : 16, /* start small and extend */
4103 : &ctl,
4104 : HASH_ELEM | HASH_BLOBS);
4105 : }
4106 53562 : estate->cast_hash = shared_cast_hash;
4107 : }
4108 : /* likewise for the simple-expression resource owner */
4109 54372 : if (simple_eval_resowner)
4110 810 : estate->simple_eval_resowner = simple_eval_resowner;
4111 : else
4112 53562 : estate->simple_eval_resowner = shared_simple_eval_resowner;
4113 :
4114 : /* if there's a procedure resowner, it'll be filled in later */
4115 54372 : estate->procedure_resowner = NULL;
4116 :
4117 : /*
4118 : * We start with no stmt_mcontext; one will be created only if needed.
4119 : * That context will be a direct child of the function's main execution
4120 : * context. Additional stmt_mcontexts might be created as children of it.
4121 : */
4122 54372 : estate->stmt_mcontext = NULL;
4123 54372 : estate->stmt_mcontext_parent = CurrentMemoryContext;
4124 :
4125 54372 : estate->eval_tuptable = NULL;
4126 54372 : estate->eval_processed = 0;
4127 54372 : estate->eval_econtext = NULL;
4128 :
4129 54372 : estate->err_stmt = NULL;
4130 54372 : estate->err_var = NULL;
4131 54372 : estate->err_text = NULL;
4132 :
4133 54372 : estate->plugin_info = NULL;
4134 :
4135 : /*
4136 : * Create an EState and ExprContext for evaluation of simple expressions.
4137 : */
4138 54372 : plpgsql_create_econtext(estate);
4139 :
4140 : /*
4141 : * Let the plugin, if any, see this function before we initialize local
4142 : * PL/pgSQL variables. Note that we also give the plugin a few function
4143 : * pointers, so it can call back into PL/pgSQL for doing things like
4144 : * variable assignments and stack traces.
4145 : */
4146 54372 : if (*plpgsql_plugin_ptr)
4147 : {
4148 0 : (*plpgsql_plugin_ptr)->error_callback = plpgsql_exec_error_callback;
4149 0 : (*plpgsql_plugin_ptr)->assign_expr = exec_assign_expr;
4150 0 : (*plpgsql_plugin_ptr)->assign_value = exec_assign_value;
4151 0 : (*plpgsql_plugin_ptr)->eval_datum = exec_eval_datum;
4152 0 : (*plpgsql_plugin_ptr)->cast_value = exec_cast_value;
4153 :
4154 0 : if ((*plpgsql_plugin_ptr)->func_setup)
4155 0 : ((*plpgsql_plugin_ptr)->func_setup) (estate, func);
4156 : }
4157 54372 : }
4158 :
4159 : /* ----------
4160 : * Release temporary memory used by expression/subselect evaluation
4161 : *
4162 : * NB: the result of the evaluation is no longer valid after this is done,
4163 : * unless it is a pass-by-value datatype.
4164 : * ----------
4165 : */
4166 : static void
4167 320450 : exec_eval_cleanup(PLpgSQL_execstate *estate)
4168 : {
4169 : /* Clear result of a full SPI_execute */
4170 320450 : if (estate->eval_tuptable != NULL)
4171 8142 : SPI_freetuptable(estate->eval_tuptable);
4172 320450 : estate->eval_tuptable = NULL;
4173 :
4174 : /*
4175 : * Clear result of exec_eval_simple_expr (but keep the econtext). This
4176 : * also clears any short-lived allocations done via get_eval_mcontext.
4177 : */
4178 320450 : if (estate->eval_econtext != NULL)
4179 266822 : ResetExprContext(estate->eval_econtext);
4180 320450 : }
4181 :
4182 :
4183 : /* ----------
4184 : * Generate a prepared plan
4185 : *
4186 : * CAUTION: it is possible for this function to throw an error after it has
4187 : * built a SPIPlan and saved it in expr->plan. Therefore, be wary of doing
4188 : * additional things contingent on expr->plan being NULL. That is, given
4189 : * code like
4190 : *
4191 : * if (query->plan == NULL)
4192 : * {
4193 : * // okay to put setup code here
4194 : * exec_prepare_plan(estate, query, ...);
4195 : * // NOT okay to put more logic here
4196 : * }
4197 : *
4198 : * extra steps at the end are unsafe because they will not be executed when
4199 : * re-executing the calling statement, if exec_prepare_plan failed the first
4200 : * time. This is annoyingly error-prone, but the alternatives are worse.
4201 : * ----------
4202 : */
4203 : static void
4204 17077 : exec_prepare_plan(PLpgSQL_execstate *estate,
4205 : PLpgSQL_expr *expr, int cursorOptions)
4206 : {
4207 : SPIPlanPtr plan;
4208 : SPIPrepareOptions options;
4209 :
4210 : /*
4211 : * Generate and save the plan
4212 : */
4213 17077 : memset(&options, 0, sizeof(options));
4214 17077 : options.parserSetup = (ParserSetupHook) plpgsql_parser_setup;
4215 17077 : options.parserSetupArg = expr;
4216 17077 : options.parseMode = expr->parseMode;
4217 17077 : options.cursorOptions = cursorOptions;
4218 17077 : plan = SPI_prepare_extended(expr->query, &options);
4219 17016 : if (plan == NULL)
4220 0 : elog(ERROR, "SPI_prepare_extended failed for \"%s\": %s",
4221 : expr->query, SPI_result_code_string(SPI_result));
4222 :
4223 17016 : SPI_keepplan(plan);
4224 17016 : expr->plan = plan;
4225 :
4226 : /* Check to see if it's a simple expression */
4227 17016 : exec_simple_check_plan(estate, expr);
4228 16991 : }
4229 :
4230 :
4231 : /* ----------
4232 : * exec_stmt_execsql Execute an SQL statement (possibly with INTO).
4233 : *
4234 : * Note: some callers rely on this not touching stmt_mcontext. If it ever
4235 : * needs to use that, fix those callers to push/pop stmt_mcontext.
4236 : * ----------
4237 : */
4238 : static int
4239 40464 : exec_stmt_execsql(PLpgSQL_execstate *estate,
4240 : PLpgSQL_stmt_execsql *stmt)
4241 : {
4242 : ParamListInfo paramLI;
4243 : long tcount;
4244 : int rc;
4245 40464 : PLpgSQL_expr *expr = stmt->sqlstmt;
4246 40464 : int too_many_rows_level = 0;
4247 :
4248 40464 : if (plpgsql_extra_errors & PLPGSQL_XCHECK_TOOMANYROWS)
4249 4 : too_many_rows_level = ERROR;
4250 40460 : else if (plpgsql_extra_warnings & PLPGSQL_XCHECK_TOOMANYROWS)
4251 4 : too_many_rows_level = WARNING;
4252 :
4253 : /*
4254 : * On the first call for this statement generate the plan, and detect
4255 : * whether the statement is INSERT/UPDATE/DELETE/MERGE
4256 : */
4257 40464 : if (expr->plan == NULL)
4258 1667 : exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
4259 :
4260 40450 : if (!stmt->mod_stmt_set)
4261 : {
4262 : ListCell *l;
4263 :
4264 1663 : stmt->mod_stmt = false;
4265 2813 : foreach(l, SPI_plan_get_plan_sources(expr->plan))
4266 : {
4267 1663 : CachedPlanSource *plansource = (CachedPlanSource *) lfirst(l);
4268 :
4269 : /*
4270 : * We could look at the raw_parse_tree, but it seems simpler to
4271 : * check the command tag. Note we should *not* look at the Query
4272 : * tree(s), since those are the result of rewriting and could be
4273 : * stale, or could have been transmogrified into something else
4274 : * entirely.
4275 : */
4276 1663 : if (plansource->commandTag == CMDTAG_INSERT ||
4277 1358 : plansource->commandTag == CMDTAG_UPDATE ||
4278 1232 : plansource->commandTag == CMDTAG_DELETE ||
4279 1186 : plansource->commandTag == CMDTAG_MERGE)
4280 : {
4281 513 : stmt->mod_stmt = true;
4282 513 : break;
4283 : }
4284 : }
4285 1663 : stmt->mod_stmt_set = true;
4286 : }
4287 :
4288 : /*
4289 : * Some users write "SELECT expr INTO var" instead of "var := expr". If
4290 : * the expression is simple and the INTO target is a single variable, we
4291 : * can bypass SPI and call ExecEvalExpr() directly. (exec_eval_expr would
4292 : * actually work for non-simple expressions too, but such an expression
4293 : * might return more or less than one row, complicating matters greatly.
4294 : * The potential performance win is small if it's non-simple, and any
4295 : * errors we might issue would likely look different, so avoid using this
4296 : * code path for non-simple cases.)
4297 : */
4298 40450 : if (expr->expr_simple_expr && stmt->into)
4299 : {
4300 1304 : PLpgSQL_datum *target = estate->datums[stmt->target->dno];
4301 :
4302 1304 : if (target->dtype == PLPGSQL_DTYPE_ROW)
4303 : {
4304 1299 : PLpgSQL_row *row = (PLpgSQL_row *) target;
4305 :
4306 1299 : if (row->nfields == 1)
4307 : {
4308 : ErrorContextCallback plerrcontext;
4309 : Datum value;
4310 : bool isnull;
4311 : Oid valtype;
4312 : int32 valtypmod;
4313 :
4314 : /*
4315 : * Setup error traceback support for ereport(). This is so
4316 : * that error reports for the expression will look similar
4317 : * whether or not we take this code path.
4318 : */
4319 1291 : plerrcontext.callback = plpgsql_execsql_error_callback;
4320 1291 : plerrcontext.arg = expr;
4321 1291 : plerrcontext.previous = error_context_stack;
4322 1291 : error_context_stack = &plerrcontext;
4323 :
4324 : /* If first time through, create a plan for this expression */
4325 1291 : if (expr->plan == NULL)
4326 0 : exec_prepare_plan(estate, expr, 0);
4327 :
4328 : /* And evaluate the expression */
4329 1291 : value = exec_eval_expr(estate, expr,
4330 : &isnull, &valtype, &valtypmod);
4331 :
4332 : /*
4333 : * Pop the error context stack: the code below would not use
4334 : * SPI's error handling during the assignment step.
4335 : */
4336 1287 : error_context_stack = plerrcontext.previous;
4337 :
4338 : /* Assign the result to the INTO target */
4339 1287 : exec_assign_value(estate, estate->datums[row->varnos[0]],
4340 : value, isnull, valtype, valtypmod);
4341 1286 : exec_eval_cleanup(estate);
4342 :
4343 : /*
4344 : * We must duplicate the other effects of the code below, as
4345 : * well. We know that exactly one row was returned, so it
4346 : * doesn't matter whether the INTO was STRICT or not.
4347 : */
4348 1286 : exec_set_found(estate, true);
4349 1286 : estate->eval_processed = 1;
4350 :
4351 1286 : return PLPGSQL_RC_OK;
4352 : }
4353 : }
4354 : }
4355 :
4356 : /*
4357 : * Set up ParamListInfo to pass to executor
4358 : */
4359 39159 : paramLI = setup_param_list(estate, expr);
4360 :
4361 : /*
4362 : * If we have INTO, then we only need one row back ... but if we have INTO
4363 : * STRICT or extra check too_many_rows, ask for two rows, so that we can
4364 : * verify the statement returns only one. INSERT/UPDATE/DELETE/MERGE are
4365 : * always treated strictly. Without INTO, just run the statement to
4366 : * completion (tcount = 0).
4367 : *
4368 : * We could just ask for two rows always when using INTO, but there are
4369 : * some cases where demanding the extra row costs significant time, eg by
4370 : * forcing completion of a sequential scan. So don't do it unless we need
4371 : * to enforce strictness.
4372 : */
4373 39159 : if (stmt->into)
4374 : {
4375 10005 : if (stmt->strict || stmt->mod_stmt || too_many_rows_level)
4376 1132 : tcount = 2;
4377 : else
4378 8873 : tcount = 1;
4379 : }
4380 : else
4381 29154 : tcount = 0;
4382 :
4383 : /*
4384 : * Execute the plan
4385 : */
4386 39159 : rc = SPI_execute_plan_with_paramlist(expr->plan, paramLI,
4387 39159 : estate->readonly_func, tcount);
4388 :
4389 : /*
4390 : * Check for error, and set FOUND if appropriate (for historical reasons
4391 : * we set FOUND only for certain query types). Also Assert that we
4392 : * identified the statement type the same as SPI did.
4393 : */
4394 36510 : switch (rc)
4395 : {
4396 6317 : case SPI_OK_SELECT:
4397 : Assert(!stmt->mod_stmt);
4398 6317 : exec_set_found(estate, (SPI_processed != 0));
4399 6317 : break;
4400 :
4401 18050 : case SPI_OK_INSERT:
4402 : case SPI_OK_UPDATE:
4403 : case SPI_OK_DELETE:
4404 : case SPI_OK_MERGE:
4405 : case SPI_OK_INSERT_RETURNING:
4406 : case SPI_OK_UPDATE_RETURNING:
4407 : case SPI_OK_DELETE_RETURNING:
4408 : case SPI_OK_MERGE_RETURNING:
4409 : Assert(stmt->mod_stmt);
4410 18050 : exec_set_found(estate, (SPI_processed != 0));
4411 18050 : break;
4412 :
4413 12140 : case SPI_OK_SELINTO:
4414 : case SPI_OK_UTILITY:
4415 : Assert(!stmt->mod_stmt);
4416 12140 : break;
4417 :
4418 0 : case SPI_OK_REWRITTEN:
4419 :
4420 : /*
4421 : * The command was rewritten into another kind of command. It's
4422 : * not clear what FOUND would mean in that case (and SPI doesn't
4423 : * return the row count either), so just set it to false. Note
4424 : * that we can't assert anything about mod_stmt here.
4425 : */
4426 0 : exec_set_found(estate, false);
4427 0 : break;
4428 :
4429 : /* Some SPI errors deserve specific error messages */
4430 2 : case SPI_ERROR_COPY:
4431 2 : ereport(ERROR,
4432 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4433 : errmsg("cannot COPY to/from client in PL/pgSQL")));
4434 : break;
4435 :
4436 1 : case SPI_ERROR_TRANSACTION:
4437 1 : ereport(ERROR,
4438 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4439 : errmsg("unsupported transaction command in PL/pgSQL")));
4440 : break;
4441 :
4442 0 : default:
4443 0 : elog(ERROR, "SPI_execute_plan_with_paramlist failed executing query \"%s\": %s",
4444 : expr->query, SPI_result_code_string(rc));
4445 : break;
4446 : }
4447 :
4448 : /* All variants should save result info for GET DIAGNOSTICS */
4449 36507 : estate->eval_processed = SPI_processed;
4450 :
4451 : /* Process INTO if present */
4452 36507 : if (stmt->into)
4453 : {
4454 7395 : SPITupleTable *tuptab = SPI_tuptable;
4455 7395 : uint64 n = SPI_processed;
4456 : PLpgSQL_variable *target;
4457 :
4458 : /* If the statement did not return a tuple table, complain */
4459 7395 : if (tuptab == NULL)
4460 0 : ereport(ERROR,
4461 : (errcode(ERRCODE_SYNTAX_ERROR),
4462 : errmsg("INTO used with a command that cannot return data")));
4463 :
4464 : /* Fetch target's datum entry */
4465 7395 : target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
4466 :
4467 : /*
4468 : * If SELECT ... INTO specified STRICT, and the query didn't find
4469 : * exactly one row, throw an error. If STRICT was not specified, then
4470 : * allow the query to find any number of rows.
4471 : */
4472 7395 : if (n == 0)
4473 : {
4474 41 : if (stmt->strict)
4475 : {
4476 : char *errdetail;
4477 :
4478 12 : if (estate->func->print_strict_params)
4479 8 : errdetail = format_expr_params(estate, expr);
4480 : else
4481 4 : errdetail = NULL;
4482 :
4483 12 : ereport(ERROR,
4484 : (errcode(ERRCODE_NO_DATA_FOUND),
4485 : errmsg("query returned no rows"),
4486 : errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
4487 : }
4488 : /* set the target to NULL(s) */
4489 29 : exec_move_row(estate, target, NULL, tuptab->tupdesc);
4490 : }
4491 : else
4492 : {
4493 7354 : if (n > 1 && (stmt->strict || stmt->mod_stmt || too_many_rows_level))
4494 : {
4495 : char *errdetail;
4496 : int errlevel;
4497 :
4498 32 : if (estate->func->print_strict_params)
4499 12 : errdetail = format_expr_params(estate, expr);
4500 : else
4501 20 : errdetail = NULL;
4502 :
4503 32 : errlevel = (stmt->strict || stmt->mod_stmt) ? ERROR : too_many_rows_level;
4504 :
4505 32 : ereport(errlevel,
4506 : (errcode(ERRCODE_TOO_MANY_ROWS),
4507 : errmsg("query returned more than one row"),
4508 : errdetail ? errdetail_internal("parameters: %s", errdetail) : 0,
4509 : errhint("Make sure the query returns a single row, or use LIMIT 1.")));
4510 : }
4511 : /* Put the first result row into the target */
4512 7326 : exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
4513 : }
4514 :
4515 : /* Clean up */
4516 7339 : exec_eval_cleanup(estate);
4517 7339 : SPI_freetuptable(SPI_tuptable);
4518 : }
4519 : else
4520 : {
4521 : /* If the statement returned a tuple table, complain */
4522 29112 : if (SPI_tuptable != NULL)
4523 0 : ereport(ERROR,
4524 : (errcode(ERRCODE_SYNTAX_ERROR),
4525 : errmsg("query has no destination for result data"),
4526 : (rc == SPI_OK_SELECT) ? errhint("If you want to discard the results of a SELECT, use PERFORM instead.") : 0));
4527 : }
4528 :
4529 36451 : return PLPGSQL_RC_OK;
4530 : }
4531 :
4532 :
4533 : /* ----------
4534 : * exec_stmt_dynexecute Execute a dynamic SQL query
4535 : * (possibly with INTO).
4536 : * ----------
4537 : */
4538 : static int
4539 10599 : exec_stmt_dynexecute(PLpgSQL_execstate *estate,
4540 : PLpgSQL_stmt_dynexecute *stmt)
4541 : {
4542 : Datum query;
4543 : bool isnull;
4544 : Oid restype;
4545 : int32 restypmod;
4546 : char *querystr;
4547 : int exec_res;
4548 : ParamListInfo paramLI;
4549 : SPIExecuteOptions options;
4550 10599 : MemoryContext stmt_mcontext = get_stmt_mcontext(estate);
4551 :
4552 : /*
4553 : * First we evaluate the string expression after the EXECUTE keyword. Its
4554 : * result is the querystring we have to execute.
4555 : */
4556 10599 : query = exec_eval_expr(estate, stmt->query, &isnull, &restype, &restypmod);
4557 10599 : if (isnull)
4558 0 : ereport(ERROR,
4559 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
4560 : errmsg("query string argument of EXECUTE is null")));
4561 :
4562 : /* Get the C-String representation */
4563 10599 : querystr = convert_value_to_string(estate, query, restype);
4564 :
4565 : /* copy it into the stmt_mcontext before we clean up */
4566 10599 : querystr = MemoryContextStrdup(stmt_mcontext, querystr);
4567 :
4568 10599 : exec_eval_cleanup(estate);
4569 :
4570 : /*
4571 : * Execute the query without preparing a saved plan.
4572 : */
4573 10599 : paramLI = exec_eval_using_params(estate, stmt->params);
4574 :
4575 10599 : memset(&options, 0, sizeof(options));
4576 10599 : options.params = paramLI;
4577 10599 : options.read_only = estate->readonly_func;
4578 :
4579 10599 : exec_res = SPI_execute_extended(querystr, &options);
4580 :
4581 10446 : switch (exec_res)
4582 : {
4583 10443 : case SPI_OK_SELECT:
4584 : case SPI_OK_INSERT:
4585 : case SPI_OK_UPDATE:
4586 : case SPI_OK_DELETE:
4587 : case SPI_OK_MERGE:
4588 : case SPI_OK_INSERT_RETURNING:
4589 : case SPI_OK_UPDATE_RETURNING:
4590 : case SPI_OK_DELETE_RETURNING:
4591 : case SPI_OK_MERGE_RETURNING:
4592 : case SPI_OK_UTILITY:
4593 : case SPI_OK_REWRITTEN:
4594 10443 : break;
4595 :
4596 0 : case 0:
4597 :
4598 : /*
4599 : * Also allow a zero return, which implies the querystring
4600 : * contained no commands.
4601 : */
4602 0 : break;
4603 :
4604 0 : case SPI_OK_SELINTO:
4605 :
4606 : /*
4607 : * We want to disallow SELECT INTO for now, because its behavior
4608 : * is not consistent with SELECT INTO in a normal plpgsql context.
4609 : * (We need to reimplement EXECUTE to parse the string as a
4610 : * plpgsql command, not just feed it to SPI_execute.) This is not
4611 : * a functional limitation because CREATE TABLE AS is allowed.
4612 : */
4613 0 : ereport(ERROR,
4614 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4615 : errmsg("EXECUTE of SELECT ... INTO is not implemented"),
4616 : errhint("You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead.")));
4617 : break;
4618 :
4619 : /* Some SPI errors deserve specific error messages */
4620 2 : case SPI_ERROR_COPY:
4621 2 : ereport(ERROR,
4622 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4623 : errmsg("cannot COPY to/from client in PL/pgSQL")));
4624 : break;
4625 :
4626 1 : case SPI_ERROR_TRANSACTION:
4627 1 : ereport(ERROR,
4628 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4629 : errmsg("EXECUTE of transaction commands is not implemented")));
4630 : break;
4631 :
4632 0 : default:
4633 0 : elog(ERROR, "SPI_execute_extended failed executing query \"%s\": %s",
4634 : querystr, SPI_result_code_string(exec_res));
4635 : break;
4636 : }
4637 :
4638 : /* Save result info for GET DIAGNOSTICS */
4639 10443 : estate->eval_processed = SPI_processed;
4640 :
4641 : /* Process INTO if present */
4642 10443 : if (stmt->into)
4643 : {
4644 3944 : SPITupleTable *tuptab = SPI_tuptable;
4645 3944 : uint64 n = SPI_processed;
4646 : PLpgSQL_variable *target;
4647 :
4648 : /* If the statement did not return a tuple table, complain */
4649 3944 : if (tuptab == NULL)
4650 0 : ereport(ERROR,
4651 : (errcode(ERRCODE_SYNTAX_ERROR),
4652 : errmsg("INTO used with a command that cannot return data")));
4653 :
4654 : /* Fetch target's datum entry */
4655 3944 : target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
4656 :
4657 : /*
4658 : * If SELECT ... INTO specified STRICT, and the query didn't find
4659 : * exactly one row, throw an error. If STRICT was not specified, then
4660 : * allow the query to find any number of rows.
4661 : */
4662 3944 : if (n == 0)
4663 : {
4664 8 : if (stmt->strict)
4665 : {
4666 : char *errdetail;
4667 :
4668 8 : if (estate->func->print_strict_params)
4669 4 : errdetail = format_preparedparamsdata(estate, paramLI);
4670 : else
4671 4 : errdetail = NULL;
4672 :
4673 8 : ereport(ERROR,
4674 : (errcode(ERRCODE_NO_DATA_FOUND),
4675 : errmsg("query returned no rows"),
4676 : errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
4677 : }
4678 : /* set the target to NULL(s) */
4679 0 : exec_move_row(estate, target, NULL, tuptab->tupdesc);
4680 : }
4681 : else
4682 : {
4683 3936 : if (n > 1 && stmt->strict)
4684 : {
4685 : char *errdetail;
4686 :
4687 12 : if (estate->func->print_strict_params)
4688 8 : errdetail = format_preparedparamsdata(estate, paramLI);
4689 : else
4690 4 : errdetail = NULL;
4691 :
4692 12 : ereport(ERROR,
4693 : (errcode(ERRCODE_TOO_MANY_ROWS),
4694 : errmsg("query returned more than one row"),
4695 : errdetail ? errdetail_internal("parameters: %s", errdetail) : 0));
4696 : }
4697 :
4698 : /* Put the first result row into the target */
4699 3924 : exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
4700 : }
4701 : /* clean up after exec_move_row() */
4702 3924 : exec_eval_cleanup(estate);
4703 : }
4704 : else
4705 : {
4706 : /*
4707 : * It might be a good idea to raise an error if the query returned
4708 : * tuples that are being ignored, but historically we have not done
4709 : * that.
4710 : */
4711 : }
4712 :
4713 : /* Release any result from SPI_execute, as well as transient data */
4714 10423 : SPI_freetuptable(SPI_tuptable);
4715 10423 : MemoryContextReset(stmt_mcontext);
4716 :
4717 10423 : return PLPGSQL_RC_OK;
4718 : }
4719 :
4720 :
4721 : /* ----------
4722 : * exec_stmt_dynfors Execute a dynamic query, assign each
4723 : * tuple to a record or row and
4724 : * execute a group of statements
4725 : * for it.
4726 : * ----------
4727 : */
4728 : static int
4729 6355 : exec_stmt_dynfors(PLpgSQL_execstate *estate, PLpgSQL_stmt_dynfors *stmt)
4730 : {
4731 : Portal portal;
4732 : int rc;
4733 :
4734 6355 : portal = exec_dynquery_with_params(estate, stmt->query, stmt->params,
4735 : NULL, CURSOR_OPT_NO_SCROLL);
4736 :
4737 : /*
4738 : * Execute the loop
4739 : */
4740 6355 : rc = exec_for_query(estate, (PLpgSQL_stmt_forq *) stmt, portal, true);
4741 :
4742 : /*
4743 : * Close the implicit cursor
4744 : */
4745 6351 : SPI_cursor_close(portal);
4746 :
4747 6351 : return rc;
4748 : }
4749 :
4750 :
4751 : /* ----------
4752 : * exec_stmt_open Execute an OPEN cursor statement
4753 : * ----------
4754 : */
4755 : static int
4756 93 : exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt)
4757 : {
4758 : PLpgSQL_var *curvar;
4759 93 : MemoryContext stmt_mcontext = NULL;
4760 93 : char *curname = NULL;
4761 : PLpgSQL_expr *query;
4762 : Portal portal;
4763 : ParamListInfo paramLI;
4764 :
4765 : /* ----------
4766 : * Get the cursor variable and if it has an assigned name, check
4767 : * that it's not in use currently.
4768 : * ----------
4769 : */
4770 93 : curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
4771 93 : if (!curvar->isnull)
4772 : {
4773 : MemoryContext oldcontext;
4774 :
4775 : /* We only need stmt_mcontext to hold the cursor name string */
4776 16 : stmt_mcontext = get_stmt_mcontext(estate);
4777 16 : oldcontext = MemoryContextSwitchTo(stmt_mcontext);
4778 16 : curname = TextDatumGetCString(curvar->value);
4779 16 : MemoryContextSwitchTo(oldcontext);
4780 :
4781 16 : if (SPI_cursor_find(curname) != NULL)
4782 0 : ereport(ERROR,
4783 : (errcode(ERRCODE_DUPLICATE_CURSOR),
4784 : errmsg("cursor \"%s\" already in use", curname)));
4785 : }
4786 :
4787 : /* ----------
4788 : * Process the OPEN according to its type.
4789 : * ----------
4790 : */
4791 93 : if (stmt->query != NULL)
4792 : {
4793 : /* ----------
4794 : * This is an OPEN refcursor FOR SELECT ...
4795 : *
4796 : * We just make sure the query is planned. The real work is
4797 : * done downstairs.
4798 : * ----------
4799 : */
4800 33 : query = stmt->query;
4801 33 : if (query->plan == NULL)
4802 25 : exec_prepare_plan(estate, query, stmt->cursor_options);
4803 : }
4804 60 : else if (stmt->dynquery != NULL)
4805 : {
4806 : /* ----------
4807 : * This is an OPEN refcursor FOR EXECUTE ...
4808 : * ----------
4809 : */
4810 12 : portal = exec_dynquery_with_params(estate,
4811 : stmt->dynquery,
4812 : stmt->params,
4813 : curname,
4814 : stmt->cursor_options);
4815 :
4816 : /*
4817 : * If cursor variable was NULL, store the generated portal name in it,
4818 : * after verifying it's okay to assign to.
4819 : *
4820 : * Note: exec_dynquery_with_params already reset the stmt_mcontext, so
4821 : * curname is a dangling pointer here; but testing it for nullness is
4822 : * OK.
4823 : */
4824 12 : if (curname == NULL)
4825 : {
4826 12 : exec_check_assignable(estate, stmt->curvar);
4827 12 : assign_text_var(estate, curvar, portal->name);
4828 : }
4829 :
4830 12 : return PLPGSQL_RC_OK;
4831 : }
4832 : else
4833 : {
4834 : /* ----------
4835 : * This is an OPEN cursor
4836 : *
4837 : * Note: parser should already have checked that statement supplies
4838 : * args iff cursor needs them, but we check again to be safe.
4839 : * ----------
4840 : */
4841 48 : if (stmt->argquery != NULL)
4842 : {
4843 : /* ----------
4844 : * OPEN CURSOR with args. We fake a SELECT ... INTO ...
4845 : * statement to evaluate the args and put 'em into the
4846 : * internal row.
4847 : * ----------
4848 : */
4849 : PLpgSQL_stmt_execsql set_args;
4850 :
4851 32 : if (curvar->cursor_explicit_argrow < 0)
4852 0 : ereport(ERROR,
4853 : (errcode(ERRCODE_SYNTAX_ERROR),
4854 : errmsg("arguments given for cursor without arguments")));
4855 :
4856 32 : memset(&set_args, 0, sizeof(set_args));
4857 32 : set_args.cmd_type = PLPGSQL_STMT_EXECSQL;
4858 32 : set_args.lineno = stmt->lineno;
4859 32 : set_args.sqlstmt = stmt->argquery;
4860 32 : set_args.into = true;
4861 : /* XXX historically this has not been STRICT */
4862 32 : set_args.target = (PLpgSQL_variable *)
4863 32 : (estate->datums[curvar->cursor_explicit_argrow]);
4864 :
4865 32 : if (exec_stmt_execsql(estate, &set_args) != PLPGSQL_RC_OK)
4866 0 : elog(ERROR, "open cursor failed during argument processing");
4867 : }
4868 : else
4869 : {
4870 16 : if (curvar->cursor_explicit_argrow >= 0)
4871 0 : ereport(ERROR,
4872 : (errcode(ERRCODE_SYNTAX_ERROR),
4873 : errmsg("arguments required for cursor")));
4874 : }
4875 :
4876 44 : query = curvar->cursor_explicit_expr;
4877 44 : if (query->plan == NULL)
4878 36 : exec_prepare_plan(estate, query, curvar->cursor_options);
4879 : }
4880 :
4881 : /*
4882 : * Set up ParamListInfo for this query
4883 : */
4884 77 : paramLI = setup_param_list(estate, query);
4885 :
4886 : /*
4887 : * Open the cursor (the paramlist will get copied into the portal)
4888 : */
4889 77 : portal = SPI_cursor_open_with_paramlist(curname, query->plan,
4890 : paramLI,
4891 77 : estate->readonly_func);
4892 77 : if (portal == NULL)
4893 0 : elog(ERROR, "could not open cursor: %s",
4894 : SPI_result_code_string(SPI_result));
4895 :
4896 : /*
4897 : * If cursor variable was NULL, store the generated portal name in it,
4898 : * after verifying it's okay to assign to.
4899 : */
4900 77 : if (curname == NULL)
4901 : {
4902 61 : exec_check_assignable(estate, stmt->curvar);
4903 57 : assign_text_var(estate, curvar, portal->name);
4904 : }
4905 :
4906 : /* If we had any transient data, clean it up */
4907 73 : exec_eval_cleanup(estate);
4908 73 : if (stmt_mcontext)
4909 16 : MemoryContextReset(stmt_mcontext);
4910 :
4911 73 : return PLPGSQL_RC_OK;
4912 : }
4913 :
4914 :
4915 : /* ----------
4916 : * exec_stmt_fetch Fetch from a cursor into a target, or just
4917 : * move the current position of the cursor
4918 : * ----------
4919 : */
4920 : static int
4921 229 : exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
4922 : {
4923 : PLpgSQL_var *curvar;
4924 229 : long how_many = stmt->how_many;
4925 : SPITupleTable *tuptab;
4926 : Portal portal;
4927 : char *curname;
4928 : uint64 n;
4929 : MemoryContext oldcontext;
4930 :
4931 : /* ----------
4932 : * Get the portal of the cursor by name
4933 : * ----------
4934 : */
4935 229 : curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
4936 229 : if (curvar->isnull)
4937 0 : ereport(ERROR,
4938 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
4939 : errmsg("cursor variable \"%s\" is null", curvar->refname)));
4940 :
4941 : /* Use eval_mcontext for short-lived string */
4942 229 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
4943 229 : curname = TextDatumGetCString(curvar->value);
4944 229 : MemoryContextSwitchTo(oldcontext);
4945 :
4946 229 : portal = SPI_cursor_find(curname);
4947 229 : if (portal == NULL)
4948 0 : ereport(ERROR,
4949 : (errcode(ERRCODE_UNDEFINED_CURSOR),
4950 : errmsg("cursor \"%s\" does not exist", curname)));
4951 :
4952 : /* Calculate position for FETCH_RELATIVE or FETCH_ABSOLUTE */
4953 229 : if (stmt->expr)
4954 : {
4955 : bool isnull;
4956 :
4957 : /* XXX should be doing this in LONG not INT width */
4958 44 : how_many = exec_eval_integer(estate, stmt->expr, &isnull);
4959 :
4960 44 : if (isnull)
4961 0 : ereport(ERROR,
4962 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
4963 : errmsg("relative or absolute cursor position is null")));
4964 :
4965 44 : exec_eval_cleanup(estate);
4966 : }
4967 :
4968 229 : if (!stmt->is_move)
4969 : {
4970 : PLpgSQL_variable *target;
4971 :
4972 : /* ----------
4973 : * Fetch 1 tuple from the cursor
4974 : * ----------
4975 : */
4976 201 : SPI_scroll_cursor_fetch(portal, stmt->direction, how_many);
4977 197 : tuptab = SPI_tuptable;
4978 197 : n = SPI_processed;
4979 :
4980 : /* ----------
4981 : * Set the target appropriately.
4982 : * ----------
4983 : */
4984 197 : target = (PLpgSQL_variable *) estate->datums[stmt->target->dno];
4985 197 : if (n == 0)
4986 32 : exec_move_row(estate, target, NULL, tuptab->tupdesc);
4987 : else
4988 165 : exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc);
4989 :
4990 197 : exec_eval_cleanup(estate);
4991 197 : SPI_freetuptable(tuptab);
4992 : }
4993 : else
4994 : {
4995 : /* Move the cursor */
4996 28 : SPI_scroll_cursor_move(portal, stmt->direction, how_many);
4997 28 : n = SPI_processed;
4998 : }
4999 :
5000 : /* Set the ROW_COUNT and the global FOUND variable appropriately. */
5001 225 : estate->eval_processed = n;
5002 225 : exec_set_found(estate, n != 0);
5003 :
5004 225 : return PLPGSQL_RC_OK;
5005 : }
5006 :
5007 : /* ----------
5008 : * exec_stmt_close Close a cursor
5009 : * ----------
5010 : */
5011 : static int
5012 48 : exec_stmt_close(PLpgSQL_execstate *estate, PLpgSQL_stmt_close *stmt)
5013 : {
5014 : PLpgSQL_var *curvar;
5015 : Portal portal;
5016 : char *curname;
5017 : MemoryContext oldcontext;
5018 :
5019 : /* ----------
5020 : * Get the portal of the cursor by name
5021 : * ----------
5022 : */
5023 48 : curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]);
5024 48 : if (curvar->isnull)
5025 0 : ereport(ERROR,
5026 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5027 : errmsg("cursor variable \"%s\" is null", curvar->refname)));
5028 :
5029 : /* Use eval_mcontext for short-lived string */
5030 48 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
5031 48 : curname = TextDatumGetCString(curvar->value);
5032 48 : MemoryContextSwitchTo(oldcontext);
5033 :
5034 48 : portal = SPI_cursor_find(curname);
5035 48 : if (portal == NULL)
5036 0 : ereport(ERROR,
5037 : (errcode(ERRCODE_UNDEFINED_CURSOR),
5038 : errmsg("cursor \"%s\" does not exist", curname)));
5039 :
5040 : /* ----------
5041 : * And close it.
5042 : * ----------
5043 : */
5044 48 : SPI_cursor_close(portal);
5045 :
5046 48 : return PLPGSQL_RC_OK;
5047 : }
5048 :
5049 : /*
5050 : * exec_stmt_commit
5051 : *
5052 : * Commit the transaction.
5053 : */
5054 : static int
5055 2083 : exec_stmt_commit(PLpgSQL_execstate *estate, PLpgSQL_stmt_commit *stmt)
5056 : {
5057 2083 : if (stmt->chain)
5058 2 : SPI_commit_and_chain();
5059 : else
5060 2081 : SPI_commit();
5061 :
5062 : /*
5063 : * We need to build new simple-expression infrastructure, since the old
5064 : * data structures are gone.
5065 : */
5066 2072 : estate->simple_eval_estate = NULL;
5067 2072 : estate->simple_eval_resowner = NULL;
5068 2072 : plpgsql_create_econtext(estate);
5069 :
5070 2072 : return PLPGSQL_RC_OK;
5071 : }
5072 :
5073 : /*
5074 : * exec_stmt_rollback
5075 : *
5076 : * Abort the transaction.
5077 : */
5078 : static int
5079 53 : exec_stmt_rollback(PLpgSQL_execstate *estate, PLpgSQL_stmt_rollback *stmt)
5080 : {
5081 53 : if (stmt->chain)
5082 2 : SPI_rollback_and_chain();
5083 : else
5084 51 : SPI_rollback();
5085 :
5086 : /*
5087 : * We need to build new simple-expression infrastructure, since the old
5088 : * data structures are gone.
5089 : */
5090 50 : estate->simple_eval_estate = NULL;
5091 50 : estate->simple_eval_resowner = NULL;
5092 50 : plpgsql_create_econtext(estate);
5093 :
5094 50 : return PLPGSQL_RC_OK;
5095 : }
5096 :
5097 : /* ----------
5098 : * exec_assign_expr Put an expression's result into a variable.
5099 : * ----------
5100 : */
5101 : static void
5102 66303 : exec_assign_expr(PLpgSQL_execstate *estate, PLpgSQL_datum *target,
5103 : PLpgSQL_expr *expr)
5104 : {
5105 : Datum value;
5106 : bool isnull;
5107 : Oid valtype;
5108 : int32 valtypmod;
5109 :
5110 : /*
5111 : * If first time through, create a plan for this expression.
5112 : */
5113 66303 : if (expr->plan == NULL)
5114 2757 : exec_prepare_plan(estate, expr, 0);
5115 :
5116 66281 : value = exec_eval_expr(estate, expr, &isnull, &valtype, &valtypmod);
5117 66158 : exec_assign_value(estate, target, value, isnull, valtype, valtypmod);
5118 66124 : exec_eval_cleanup(estate);
5119 66124 : }
5120 :
5121 :
5122 : /* ----------
5123 : * exec_assign_c_string Put a C string into a text variable.
5124 : *
5125 : * We take a NULL pointer as signifying empty string, not SQL null.
5126 : *
5127 : * As with the underlying exec_assign_value, caller is expected to do
5128 : * exec_eval_cleanup later.
5129 : * ----------
5130 : */
5131 : static void
5132 85 : exec_assign_c_string(PLpgSQL_execstate *estate, PLpgSQL_datum *target,
5133 : const char *str)
5134 : {
5135 : text *value;
5136 : MemoryContext oldcontext;
5137 :
5138 : /* Use eval_mcontext for short-lived text value */
5139 85 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
5140 85 : if (str != NULL)
5141 85 : value = cstring_to_text(str);
5142 : else
5143 0 : value = cstring_to_text("");
5144 85 : MemoryContextSwitchTo(oldcontext);
5145 :
5146 85 : exec_assign_value(estate, target, PointerGetDatum(value), false,
5147 : TEXTOID, -1);
5148 85 : }
5149 :
5150 :
5151 : /* ----------
5152 : * exec_assign_value Put a value into a target datum
5153 : *
5154 : * Note: in some code paths, this will leak memory in the eval_mcontext;
5155 : * we assume that will be cleaned up later by exec_eval_cleanup. We cannot
5156 : * call exec_eval_cleanup here for fear of destroying the input Datum value.
5157 : * ----------
5158 : */
5159 : static void
5160 116035 : exec_assign_value(PLpgSQL_execstate *estate,
5161 : PLpgSQL_datum *target,
5162 : Datum value, bool isNull,
5163 : Oid valtype, int32 valtypmod)
5164 : {
5165 116035 : switch (target->dtype)
5166 : {
5167 114062 : case PLPGSQL_DTYPE_VAR:
5168 : case PLPGSQL_DTYPE_PROMISE:
5169 : {
5170 : /*
5171 : * Target is a variable
5172 : */
5173 114062 : PLpgSQL_var *var = (PLpgSQL_var *) target;
5174 : Datum newvalue;
5175 :
5176 114062 : newvalue = exec_cast_value(estate,
5177 : value,
5178 : &isNull,
5179 : valtype,
5180 : valtypmod,
5181 114062 : var->datatype->typoid,
5182 114062 : var->datatype->atttypmod);
5183 :
5184 114046 : if (isNull && var->notnull)
5185 6 : ereport(ERROR,
5186 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5187 : errmsg("null value cannot be assigned to variable \"%s\" declared NOT NULL",
5188 : var->refname)));
5189 :
5190 : /*
5191 : * If type is by-reference, copy the new value (which is
5192 : * probably in the eval_mcontext) into the procedure's main
5193 : * memory context. But if it's a read/write reference to an
5194 : * expanded object, no physical copy needs to happen; at most
5195 : * we need to reparent the object's memory context.
5196 : *
5197 : * If it's an array, we force the value to be stored in R/W
5198 : * expanded form. This wins if the function later does, say,
5199 : * a lot of array subscripting operations on the variable, and
5200 : * otherwise might lose. We might need to use a different
5201 : * heuristic, but it's too soon to tell. Also, are there
5202 : * cases where it'd be useful to force non-array values into
5203 : * expanded form?
5204 : */
5205 114040 : if (!var->datatype->typbyval && !isNull)
5206 : {
5207 79668 : if (var->datatype->typisarray &&
5208 6946 : !VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(newvalue)))
5209 : {
5210 : /* array and not already R/W, so apply expand_array */
5211 6821 : newvalue = expand_array(newvalue,
5212 : estate->datum_context,
5213 : NULL);
5214 : }
5215 : else
5216 : {
5217 : /* else transfer value if R/W, else just datumCopy */
5218 72847 : newvalue = datumTransfer(newvalue,
5219 : false,
5220 72847 : var->datatype->typlen);
5221 : }
5222 : }
5223 :
5224 : /*
5225 : * Now free the old value, if any, and assign the new one. But
5226 : * skip the assignment if old and new values are the same.
5227 : * Note that for expanded objects, this test is necessary and
5228 : * cannot reliably be made any earlier; we have to be looking
5229 : * at the object's standard R/W pointer to be sure pointer
5230 : * equality is meaningful.
5231 : *
5232 : * Also, if it's a promise variable, we should disarm the
5233 : * promise in any case --- otherwise, assigning null to an
5234 : * armed promise variable would fail to disarm the promise.
5235 : */
5236 114040 : if (var->value != newvalue || var->isnull || isNull)
5237 112349 : assign_simple_var(estate, var, newvalue, isNull,
5238 112349 : (!var->datatype->typbyval && !isNull));
5239 : else
5240 1691 : var->promise = PLPGSQL_PROMISE_NONE;
5241 114040 : break;
5242 : }
5243 :
5244 28 : case PLPGSQL_DTYPE_ROW:
5245 : {
5246 : /*
5247 : * Target is a row variable
5248 : */
5249 28 : PLpgSQL_row *row = (PLpgSQL_row *) target;
5250 :
5251 28 : if (isNull)
5252 : {
5253 : /* If source is null, just assign nulls to the row */
5254 0 : exec_move_row(estate, (PLpgSQL_variable *) row,
5255 : NULL, NULL);
5256 : }
5257 : else
5258 : {
5259 : /* Source must be of RECORD or composite type */
5260 28 : if (!type_is_rowtype(valtype))
5261 0 : ereport(ERROR,
5262 : (errcode(ERRCODE_DATATYPE_MISMATCH),
5263 : errmsg("cannot assign non-composite value to a row variable")));
5264 28 : exec_move_row_from_datum(estate, (PLpgSQL_variable *) row,
5265 : value);
5266 : }
5267 28 : break;
5268 : }
5269 :
5270 438 : case PLPGSQL_DTYPE_REC:
5271 : {
5272 : /*
5273 : * Target is a record variable
5274 : */
5275 438 : PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
5276 :
5277 438 : if (isNull)
5278 : {
5279 89 : if (rec->notnull)
5280 4 : ereport(ERROR,
5281 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5282 : errmsg("null value cannot be assigned to variable \"%s\" declared NOT NULL",
5283 : rec->refname)));
5284 :
5285 : /* Set variable to a simple NULL */
5286 85 : exec_move_row(estate, (PLpgSQL_variable *) rec,
5287 : NULL, NULL);
5288 : }
5289 : else
5290 : {
5291 : /* Source must be of RECORD or composite type */
5292 349 : if (!type_is_rowtype(valtype))
5293 0 : ereport(ERROR,
5294 : (errcode(ERRCODE_DATATYPE_MISMATCH),
5295 : errmsg("cannot assign non-composite value to a record variable")));
5296 349 : exec_move_row_from_datum(estate, (PLpgSQL_variable *) rec,
5297 : value);
5298 : }
5299 425 : break;
5300 : }
5301 :
5302 1507 : case PLPGSQL_DTYPE_RECFIELD:
5303 : {
5304 : /*
5305 : * Target is a field of a record
5306 : */
5307 1507 : PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) target;
5308 : PLpgSQL_rec *rec;
5309 : ExpandedRecordHeader *erh;
5310 :
5311 1507 : rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5312 1507 : erh = rec->erh;
5313 :
5314 : /*
5315 : * If record variable is NULL, instantiate it if it has a
5316 : * named composite type, else complain. (This won't change
5317 : * the logical state of the record, but if we successfully
5318 : * assign below, the unassigned fields will all become NULLs.)
5319 : */
5320 1507 : if (erh == NULL)
5321 : {
5322 37 : instantiate_empty_record_variable(estate, rec);
5323 36 : erh = rec->erh;
5324 : }
5325 :
5326 : /*
5327 : * Look up the field's properties if we have not already, or
5328 : * if the tuple descriptor ID changed since last time.
5329 : */
5330 1506 : if (unlikely(recfield->rectupledescid != erh->er_tupdesc_id))
5331 : {
5332 25 : if (!expanded_record_lookup_field(erh,
5333 25 : recfield->fieldname,
5334 : &recfield->finfo))
5335 1 : ereport(ERROR,
5336 : (errcode(ERRCODE_UNDEFINED_COLUMN),
5337 : errmsg("record \"%s\" has no field \"%s\"",
5338 : rec->refname, recfield->fieldname)));
5339 24 : recfield->rectupledescid = erh->er_tupdesc_id;
5340 : }
5341 :
5342 : /* We don't support assignments to system columns. */
5343 1505 : if (recfield->finfo.fnumber <= 0)
5344 0 : ereport(ERROR,
5345 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5346 : errmsg("cannot assign to system column \"%s\"",
5347 : recfield->fieldname)));
5348 :
5349 : /* Cast the new value to the right type, if needed. */
5350 1505 : value = exec_cast_value(estate,
5351 : value,
5352 : &isNull,
5353 : valtype,
5354 : valtypmod,
5355 : recfield->finfo.ftypeid,
5356 : recfield->finfo.ftypmod);
5357 :
5358 : /* And assign it. */
5359 1505 : expanded_record_set_field(erh, recfield->finfo.fnumber,
5360 : value, isNull, !estate->atomic);
5361 1502 : break;
5362 : }
5363 :
5364 0 : default:
5365 0 : elog(ERROR, "unrecognized dtype: %d", target->dtype);
5366 : }
5367 115995 : }
5368 :
5369 : /*
5370 : * exec_eval_datum Get current value of a PLpgSQL_datum
5371 : *
5372 : * The type oid, typmod, value in Datum format, and null flag are returned.
5373 : *
5374 : * At present this doesn't handle PLpgSQL_expr datums; that's not needed
5375 : * because we never pass references to such datums to SPI.
5376 : *
5377 : * NOTE: the returned Datum points right at the stored value in the case of
5378 : * pass-by-reference datatypes. Generally callers should take care not to
5379 : * modify the stored value. Some callers intentionally manipulate variables
5380 : * referenced by R/W expanded pointers, though; it is those callers'
5381 : * responsibility that the results are semantically OK.
5382 : *
5383 : * In some cases we have to palloc a return value, and in such cases we put
5384 : * it into the estate's eval_mcontext.
5385 : */
5386 : static void
5387 46754 : exec_eval_datum(PLpgSQL_execstate *estate,
5388 : PLpgSQL_datum *datum,
5389 : Oid *typeid,
5390 : int32 *typetypmod,
5391 : Datum *value,
5392 : bool *isnull)
5393 : {
5394 : MemoryContext oldcontext;
5395 :
5396 46754 : switch (datum->dtype)
5397 : {
5398 14891 : case PLPGSQL_DTYPE_PROMISE:
5399 : /* fulfill promise if needed, then handle like regular var */
5400 14891 : plpgsql_fulfill_promise(estate, (PLpgSQL_var *) datum);
5401 :
5402 : pg_fallthrough;
5403 :
5404 30158 : case PLPGSQL_DTYPE_VAR:
5405 : {
5406 30158 : PLpgSQL_var *var = (PLpgSQL_var *) datum;
5407 :
5408 30158 : *typeid = var->datatype->typoid;
5409 30158 : *typetypmod = var->datatype->atttypmod;
5410 30158 : *value = var->value;
5411 30158 : *isnull = var->isnull;
5412 30158 : break;
5413 : }
5414 :
5415 4096 : case PLPGSQL_DTYPE_ROW:
5416 : {
5417 4096 : PLpgSQL_row *row = (PLpgSQL_row *) datum;
5418 : HeapTuple tup;
5419 :
5420 : /* We get here if there are multiple OUT parameters */
5421 4096 : if (!row->rowtupdesc) /* should not happen */
5422 0 : elog(ERROR, "row variable has no tupdesc");
5423 : /* Make sure we have a valid type/typmod setting */
5424 4096 : BlessTupleDesc(row->rowtupdesc);
5425 4096 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
5426 4096 : tup = make_tuple_from_row(estate, row, row->rowtupdesc);
5427 4096 : if (tup == NULL) /* should not happen */
5428 0 : elog(ERROR, "row not compatible with its own tupdesc");
5429 4096 : *typeid = row->rowtupdesc->tdtypeid;
5430 4096 : *typetypmod = row->rowtupdesc->tdtypmod;
5431 4096 : *value = HeapTupleGetDatum(tup);
5432 4096 : *isnull = false;
5433 4096 : MemoryContextSwitchTo(oldcontext);
5434 4096 : break;
5435 : }
5436 :
5437 10987 : case PLPGSQL_DTYPE_REC:
5438 : {
5439 10987 : PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5440 :
5441 10987 : if (rec->erh == NULL)
5442 : {
5443 : /* Treat uninstantiated record as a simple NULL */
5444 124 : *value = (Datum) 0;
5445 124 : *isnull = true;
5446 : /* Report variable's declared type */
5447 124 : *typeid = rec->rectypeid;
5448 124 : *typetypmod = -1;
5449 : }
5450 : else
5451 : {
5452 10863 : if (ExpandedRecordIsEmpty(rec->erh))
5453 : {
5454 : /* Empty record is also a NULL */
5455 99 : *value = (Datum) 0;
5456 99 : *isnull = true;
5457 : }
5458 : else
5459 : {
5460 10764 : *value = ExpandedRecordGetDatum(rec->erh);
5461 10764 : *isnull = false;
5462 : }
5463 10863 : if (rec->rectypeid != RECORDOID)
5464 : {
5465 : /* Report variable's declared type, if not RECORD */
5466 689 : *typeid = rec->rectypeid;
5467 689 : *typetypmod = -1;
5468 : }
5469 : else
5470 : {
5471 : /* Report record's actual type if declared RECORD */
5472 10174 : *typeid = rec->erh->er_typeid;
5473 10174 : *typetypmod = rec->erh->er_typmod;
5474 : }
5475 : }
5476 10987 : break;
5477 : }
5478 :
5479 1513 : case PLPGSQL_DTYPE_RECFIELD:
5480 : {
5481 1513 : PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5482 : PLpgSQL_rec *rec;
5483 : ExpandedRecordHeader *erh;
5484 :
5485 1513 : rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5486 1513 : erh = rec->erh;
5487 :
5488 : /*
5489 : * If record variable is NULL, instantiate it if it has a
5490 : * named composite type, else complain. (This won't change
5491 : * the logical state of the record: it's still NULL.)
5492 : */
5493 1513 : if (erh == NULL)
5494 : {
5495 0 : instantiate_empty_record_variable(estate, rec);
5496 0 : erh = rec->erh;
5497 : }
5498 :
5499 : /*
5500 : * Look up the field's properties if we have not already, or
5501 : * if the tuple descriptor ID changed since last time.
5502 : */
5503 1513 : if (unlikely(recfield->rectupledescid != erh->er_tupdesc_id))
5504 : {
5505 0 : if (!expanded_record_lookup_field(erh,
5506 0 : recfield->fieldname,
5507 : &recfield->finfo))
5508 0 : ereport(ERROR,
5509 : (errcode(ERRCODE_UNDEFINED_COLUMN),
5510 : errmsg("record \"%s\" has no field \"%s\"",
5511 : rec->refname, recfield->fieldname)));
5512 0 : recfield->rectupledescid = erh->er_tupdesc_id;
5513 : }
5514 :
5515 : /* Report type data. */
5516 1513 : *typeid = recfield->finfo.ftypeid;
5517 1513 : *typetypmod = recfield->finfo.ftypmod;
5518 :
5519 : /* And fetch the field value. */
5520 1513 : *value = expanded_record_get_field(erh,
5521 : recfield->finfo.fnumber,
5522 : isnull);
5523 1513 : break;
5524 : }
5525 :
5526 0 : default:
5527 0 : elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5528 : }
5529 46754 : }
5530 :
5531 : /*
5532 : * plpgsql_exec_get_datum_type Get datatype of a PLpgSQL_datum
5533 : *
5534 : * This is the same logic as in exec_eval_datum, but we skip acquiring
5535 : * the actual value of the variable. Also, needn't support DTYPE_ROW.
5536 : */
5537 : Oid
5538 101 : plpgsql_exec_get_datum_type(PLpgSQL_execstate *estate,
5539 : PLpgSQL_datum *datum)
5540 : {
5541 : Oid typeid;
5542 :
5543 101 : switch (datum->dtype)
5544 : {
5545 101 : case PLPGSQL_DTYPE_VAR:
5546 : case PLPGSQL_DTYPE_PROMISE:
5547 : {
5548 101 : PLpgSQL_var *var = (PLpgSQL_var *) datum;
5549 :
5550 101 : typeid = var->datatype->typoid;
5551 101 : break;
5552 : }
5553 :
5554 0 : case PLPGSQL_DTYPE_REC:
5555 : {
5556 0 : PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5557 :
5558 0 : if (rec->erh == NULL || rec->rectypeid != RECORDOID)
5559 : {
5560 : /* Report variable's declared type */
5561 0 : typeid = rec->rectypeid;
5562 : }
5563 : else
5564 : {
5565 : /* Report record's actual type if declared RECORD */
5566 0 : typeid = rec->erh->er_typeid;
5567 : }
5568 0 : break;
5569 : }
5570 :
5571 0 : case PLPGSQL_DTYPE_RECFIELD:
5572 : {
5573 0 : PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5574 : PLpgSQL_rec *rec;
5575 :
5576 0 : rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5577 :
5578 : /*
5579 : * If record variable is NULL, instantiate it if it has a
5580 : * named composite type, else complain. (This won't change
5581 : * the logical state of the record: it's still NULL.)
5582 : */
5583 0 : if (rec->erh == NULL)
5584 0 : instantiate_empty_record_variable(estate, rec);
5585 :
5586 : /*
5587 : * Look up the field's properties if we have not already, or
5588 : * if the tuple descriptor ID changed since last time.
5589 : */
5590 0 : if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
5591 : {
5592 0 : if (!expanded_record_lookup_field(rec->erh,
5593 0 : recfield->fieldname,
5594 : &recfield->finfo))
5595 0 : ereport(ERROR,
5596 : (errcode(ERRCODE_UNDEFINED_COLUMN),
5597 : errmsg("record \"%s\" has no field \"%s\"",
5598 : rec->refname, recfield->fieldname)));
5599 0 : recfield->rectupledescid = rec->erh->er_tupdesc_id;
5600 : }
5601 :
5602 0 : typeid = recfield->finfo.ftypeid;
5603 0 : break;
5604 : }
5605 :
5606 0 : default:
5607 0 : elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5608 : typeid = InvalidOid; /* keep compiler quiet */
5609 : break;
5610 : }
5611 :
5612 101 : return typeid;
5613 : }
5614 :
5615 : /*
5616 : * plpgsql_exec_get_datum_type_info Get datatype etc of a PLpgSQL_datum
5617 : *
5618 : * An extended version of plpgsql_exec_get_datum_type, which also retrieves the
5619 : * typmod and collation of the datum. Note however that we don't report the
5620 : * possibly-mutable typmod of RECORD values, but say -1 always.
5621 : */
5622 : void
5623 21814 : plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate,
5624 : PLpgSQL_datum *datum,
5625 : Oid *typeId, int32 *typMod, Oid *collation)
5626 : {
5627 21814 : switch (datum->dtype)
5628 : {
5629 16905 : case PLPGSQL_DTYPE_VAR:
5630 : case PLPGSQL_DTYPE_PROMISE:
5631 : {
5632 16905 : PLpgSQL_var *var = (PLpgSQL_var *) datum;
5633 :
5634 16905 : *typeId = var->datatype->typoid;
5635 16905 : *typMod = var->datatype->atttypmod;
5636 16905 : *collation = var->datatype->collation;
5637 16905 : break;
5638 : }
5639 :
5640 1614 : case PLPGSQL_DTYPE_REC:
5641 : {
5642 1614 : PLpgSQL_rec *rec = (PLpgSQL_rec *) datum;
5643 :
5644 1614 : if (rec->erh == NULL || rec->rectypeid != RECORDOID)
5645 : {
5646 : /* Report variable's declared type */
5647 305 : *typeId = rec->rectypeid;
5648 305 : *typMod = -1;
5649 : }
5650 : else
5651 : {
5652 : /* Report record's actual type if declared RECORD */
5653 1309 : *typeId = rec->erh->er_typeid;
5654 : /* do NOT return the mutable typmod of a RECORD variable */
5655 1309 : *typMod = -1;
5656 : }
5657 : /* composite types are never collatable */
5658 1614 : *collation = InvalidOid;
5659 1614 : break;
5660 : }
5661 :
5662 3295 : case PLPGSQL_DTYPE_RECFIELD:
5663 : {
5664 3295 : PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
5665 : PLpgSQL_rec *rec;
5666 :
5667 3295 : rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
5668 :
5669 : /*
5670 : * If record variable is NULL, instantiate it if it has a
5671 : * named composite type, else complain. (This won't change
5672 : * the logical state of the record: it's still NULL.)
5673 : */
5674 3295 : if (rec->erh == NULL)
5675 24 : instantiate_empty_record_variable(estate, rec);
5676 :
5677 : /*
5678 : * Look up the field's properties if we have not already, or
5679 : * if the tuple descriptor ID changed since last time.
5680 : */
5681 3294 : if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
5682 : {
5683 1879 : if (!expanded_record_lookup_field(rec->erh,
5684 1879 : recfield->fieldname,
5685 : &recfield->finfo))
5686 10 : ereport(ERROR,
5687 : (errcode(ERRCODE_UNDEFINED_COLUMN),
5688 : errmsg("record \"%s\" has no field \"%s\"",
5689 : rec->refname, recfield->fieldname)));
5690 1869 : recfield->rectupledescid = rec->erh->er_tupdesc_id;
5691 : }
5692 :
5693 3284 : *typeId = recfield->finfo.ftypeid;
5694 3284 : *typMod = recfield->finfo.ftypmod;
5695 3284 : *collation = recfield->finfo.fcollation;
5696 3284 : break;
5697 : }
5698 :
5699 0 : default:
5700 0 : elog(ERROR, "unrecognized dtype: %d", datum->dtype);
5701 : *typeId = InvalidOid; /* keep compiler quiet */
5702 : *typMod = -1;
5703 : *collation = InvalidOid;
5704 : break;
5705 : }
5706 21803 : }
5707 :
5708 : /* ----------
5709 : * exec_eval_integer Evaluate an expression, coerce result to int4
5710 : *
5711 : * Note we do not do exec_eval_cleanup here; the caller must do it at
5712 : * some later point. (We do this because the caller may be holding the
5713 : * results of other, pass-by-reference, expression evaluations, such as
5714 : * an array value to be subscripted.)
5715 : * ----------
5716 : */
5717 : static int
5718 44 : exec_eval_integer(PLpgSQL_execstate *estate,
5719 : PLpgSQL_expr *expr,
5720 : bool *isNull)
5721 : {
5722 : Datum exprdatum;
5723 : Oid exprtypeid;
5724 : int32 exprtypmod;
5725 :
5726 44 : exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid, &exprtypmod);
5727 44 : exprdatum = exec_cast_value(estate, exprdatum, isNull,
5728 : exprtypeid, exprtypmod,
5729 : INT4OID, -1);
5730 44 : return DatumGetInt32(exprdatum);
5731 : }
5732 :
5733 : /* ----------
5734 : * exec_eval_boolean Evaluate an expression, coerce result to bool
5735 : *
5736 : * Note we do not do exec_eval_cleanup here; the caller must do it at
5737 : * some later point.
5738 : * ----------
5739 : */
5740 : static bool
5741 81322 : exec_eval_boolean(PLpgSQL_execstate *estate,
5742 : PLpgSQL_expr *expr,
5743 : bool *isNull)
5744 : {
5745 : Datum exprdatum;
5746 : Oid exprtypeid;
5747 : int32 exprtypmod;
5748 :
5749 81322 : exprdatum = exec_eval_expr(estate, expr, isNull, &exprtypeid, &exprtypmod);
5750 81322 : exprdatum = exec_cast_value(estate, exprdatum, isNull,
5751 : exprtypeid, exprtypmod,
5752 : BOOLOID, -1);
5753 81322 : return DatumGetBool(exprdatum);
5754 : }
5755 :
5756 : /* ----------
5757 : * exec_eval_expr Evaluate an expression and return
5758 : * the result Datum, along with data type/typmod.
5759 : *
5760 : * NOTE: caller must do exec_eval_cleanup when done with the Datum.
5761 : * ----------
5762 : */
5763 : static Datum
5764 215414 : exec_eval_expr(PLpgSQL_execstate *estate,
5765 : PLpgSQL_expr *expr,
5766 : bool *isNull,
5767 : Oid *rettype,
5768 : int32 *rettypmod)
5769 : {
5770 215414 : Datum result = 0;
5771 : int rc;
5772 : Form_pg_attribute attr;
5773 :
5774 : /*
5775 : * If first time through, create a plan for this expression.
5776 : */
5777 215414 : if (expr->plan == NULL)
5778 11785 : exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
5779 :
5780 : /*
5781 : * If this is a simple expression, bypass SPI and use the executor
5782 : * directly
5783 : */
5784 215390 : if (exec_eval_simple_expr(estate, expr,
5785 : &result, isNull, rettype, rettypmod))
5786 209995 : return result;
5787 :
5788 : /*
5789 : * Else do it the hard way via exec_run_select
5790 : */
5791 5237 : rc = exec_run_select(estate, expr, 0, NULL);
5792 5220 : if (rc != SPI_OK_SELECT)
5793 0 : ereport(ERROR,
5794 : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
5795 : errmsg("query did not return data"),
5796 : errcontext("query: %s", expr->query)));
5797 :
5798 : /*
5799 : * Check that the expression returns exactly one column...
5800 : */
5801 5220 : if (estate->eval_tuptable->tupdesc->natts != 1)
5802 0 : ereport(ERROR,
5803 : (errcode(ERRCODE_SYNTAX_ERROR),
5804 : errmsg_plural("query returned %d column",
5805 : "query returned %d columns",
5806 : estate->eval_tuptable->tupdesc->natts,
5807 : estate->eval_tuptable->tupdesc->natts),
5808 : errcontext("query: %s", expr->query)));
5809 :
5810 : /*
5811 : * ... and get the column's datatype.
5812 : */
5813 5220 : attr = TupleDescAttr(estate->eval_tuptable->tupdesc, 0);
5814 5220 : *rettype = attr->atttypid;
5815 5220 : *rettypmod = attr->atttypmod;
5816 :
5817 : /*
5818 : * If there are no rows selected, the result is a NULL of that type.
5819 : */
5820 5220 : if (estate->eval_processed == 0)
5821 : {
5822 0 : *isNull = true;
5823 0 : return (Datum) 0;
5824 : }
5825 :
5826 : /*
5827 : * Check that the expression returned no more than one row.
5828 : */
5829 5220 : if (estate->eval_processed != 1)
5830 1 : ereport(ERROR,
5831 : (errcode(ERRCODE_CARDINALITY_VIOLATION),
5832 : errmsg("query returned more than one row"),
5833 : errcontext("query: %s", expr->query)));
5834 :
5835 : /*
5836 : * Return the single result Datum.
5837 : */
5838 5219 : return SPI_getbinval(estate->eval_tuptable->vals[0],
5839 5219 : estate->eval_tuptable->tupdesc, 1, isNull);
5840 : }
5841 :
5842 :
5843 : /* ----------
5844 : * exec_run_select Execute a select query
5845 : *
5846 : * Note: passing maxtuples different from 0 ("return all tuples") is
5847 : * deprecated because it will prevent parallel execution of the query.
5848 : * However, we retain the parameter in case we need it someday.
5849 : * ----------
5850 : */
5851 : static int
5852 10779 : exec_run_select(PLpgSQL_execstate *estate,
5853 : PLpgSQL_expr *expr, long maxtuples, Portal *portalP)
5854 : {
5855 : ParamListInfo paramLI;
5856 : int rc;
5857 :
5858 : /*
5859 : * On the first call for this expression generate the plan.
5860 : *
5861 : * If we don't need to return a portal, then we're just going to execute
5862 : * the query immediately, which means it's OK to use a parallel plan, even
5863 : * if the number of rows being fetched is limited. If we do need to
5864 : * return a portal (i.e., this is for a FOR loop), the user's code might
5865 : * invoke additional operations inside the FOR loop, making parallel query
5866 : * unsafe. In any case, we don't expect any cursor operations to be done,
5867 : * so specify NO_SCROLL for efficiency and semantic safety.
5868 : */
5869 10779 : if (expr->plan == NULL)
5870 : {
5871 687 : int cursorOptions = CURSOR_OPT_NO_SCROLL;
5872 :
5873 687 : if (portalP == NULL)
5874 491 : cursorOptions |= CURSOR_OPT_PARALLEL_OK;
5875 687 : exec_prepare_plan(estate, expr, cursorOptions);
5876 : }
5877 :
5878 : /*
5879 : * Set up ParamListInfo to pass to executor
5880 : */
5881 10754 : paramLI = setup_param_list(estate, expr);
5882 :
5883 : /*
5884 : * If a portal was requested, put the query and paramlist into the portal
5885 : */
5886 10754 : if (portalP != NULL)
5887 : {
5888 3256 : *portalP = SPI_cursor_open_with_paramlist(NULL, expr->plan,
5889 : paramLI,
5890 1628 : estate->readonly_func);
5891 1628 : if (*portalP == NULL)
5892 0 : elog(ERROR, "could not open implicit cursor for query \"%s\": %s",
5893 : expr->query, SPI_result_code_string(SPI_result));
5894 1628 : exec_eval_cleanup(estate);
5895 1628 : return SPI_OK_CURSOR;
5896 : }
5897 :
5898 : /*
5899 : * Execute the query
5900 : */
5901 9126 : rc = SPI_execute_plan_with_paramlist(expr->plan, paramLI,
5902 9126 : estate->readonly_func, maxtuples);
5903 8147 : if (rc != SPI_OK_SELECT)
5904 : {
5905 : /*
5906 : * SELECT INTO deserves a special error message, because "query is not
5907 : * a SELECT" is not very helpful in that case.
5908 : */
5909 0 : if (rc == SPI_OK_SELINTO)
5910 0 : ereport(ERROR,
5911 : (errcode(ERRCODE_SYNTAX_ERROR),
5912 : errmsg("query is SELECT INTO, but it should be plain SELECT"),
5913 : errcontext("query: %s", expr->query)));
5914 : else
5915 0 : ereport(ERROR,
5916 : (errcode(ERRCODE_SYNTAX_ERROR),
5917 : errmsg("query is not a SELECT"),
5918 : errcontext("query: %s", expr->query)));
5919 : }
5920 :
5921 : /* Save query results for eventual cleanup */
5922 : Assert(estate->eval_tuptable == NULL);
5923 8147 : estate->eval_tuptable = SPI_tuptable;
5924 8147 : estate->eval_processed = SPI_processed;
5925 :
5926 8147 : return rc;
5927 : }
5928 :
5929 :
5930 : /*
5931 : * exec_for_query --- execute body of FOR loop for each row from a portal
5932 : *
5933 : * Used by exec_stmt_fors, exec_stmt_forc and exec_stmt_dynfors
5934 : */
5935 : static int
5936 8052 : exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
5937 : Portal portal, bool prefetch_ok)
5938 : {
5939 : PLpgSQL_variable *var;
5940 : SPITupleTable *tuptab;
5941 8052 : bool found = false;
5942 8052 : int rc = PLPGSQL_RC_OK;
5943 8052 : uint64 previous_id = INVALID_TUPLEDESC_IDENTIFIER;
5944 8052 : bool tupdescs_match = true;
5945 : uint64 n;
5946 :
5947 : /* Fetch loop variable's datum entry */
5948 8052 : var = (PLpgSQL_variable *) estate->datums[stmt->var->dno];
5949 :
5950 : /*
5951 : * Make sure the portal doesn't get closed by the user statements we
5952 : * execute.
5953 : */
5954 8052 : PinPortal(portal);
5955 :
5956 : /*
5957 : * In a non-atomic context, we dare not prefetch, even if it would
5958 : * otherwise be safe. Aside from any semantic hazards that that might
5959 : * create, if we prefetch toasted data and then the user commits the
5960 : * transaction, the toast references could turn into dangling pointers.
5961 : * (Rows we haven't yet fetched from the cursor are safe, because the
5962 : * PersistHoldablePortal mechanism handles this scenario.)
5963 : */
5964 8052 : if (!estate->atomic)
5965 5022 : prefetch_ok = false;
5966 :
5967 : /*
5968 : * Fetch the initial tuple(s). If prefetching is allowed then we grab a
5969 : * few more rows to avoid multiple trips through executor startup
5970 : * overhead.
5971 : */
5972 8052 : SPI_cursor_fetch(portal, true, prefetch_ok ? 10 : 1);
5973 8048 : tuptab = SPI_tuptable;
5974 8048 : n = SPI_processed;
5975 :
5976 : /*
5977 : * If the query didn't return any rows, set the target to NULL and fall
5978 : * through with found = false.
5979 : */
5980 8048 : if (n == 0)
5981 : {
5982 1147 : exec_move_row(estate, var, NULL, tuptab->tupdesc);
5983 1147 : exec_eval_cleanup(estate);
5984 : }
5985 : else
5986 6901 : found = true; /* processed at least one tuple */
5987 :
5988 : /*
5989 : * Now do the loop
5990 : */
5991 29242 : while (n > 0)
5992 : {
5993 : uint64 i;
5994 :
5995 56655 : for (i = 0; i < n; i++)
5996 : {
5997 : /*
5998 : * Assign the tuple to the target. Here, because we know that all
5999 : * loop iterations should be assigning the same tupdesc, we can
6000 : * optimize away repeated creations of expanded records with
6001 : * identical tupdescs. Testing for changes of er_tupdesc_id is
6002 : * reliable even if the loop body contains assignments that
6003 : * replace the target's value entirely, because it's assigned from
6004 : * a process-global counter. The case where the tupdescs don't
6005 : * match could possibly be handled more efficiently than this
6006 : * coding does, but it's not clear extra effort is worthwhile.
6007 : */
6008 35461 : if (var->dtype == PLPGSQL_DTYPE_REC)
6009 : {
6010 4575 : PLpgSQL_rec *rec = (PLpgSQL_rec *) var;
6011 :
6012 4575 : if (rec->erh &&
6013 4021 : rec->erh->er_tupdesc_id == previous_id &&
6014 : tupdescs_match)
6015 : {
6016 : /* Only need to assign a new tuple value */
6017 3975 : expanded_record_set_tuple(rec->erh, tuptab->vals[i],
6018 3975 : true, !estate->atomic);
6019 : }
6020 : else
6021 : {
6022 : /*
6023 : * First time through, or var's tupdesc changed in loop,
6024 : * or we have to do it the hard way because type coercion
6025 : * is needed.
6026 : */
6027 600 : exec_move_row(estate, var,
6028 600 : tuptab->vals[i], tuptab->tupdesc);
6029 :
6030 : /*
6031 : * Check to see if physical assignment is OK next time.
6032 : * Once the tupdesc comparison has failed once, we don't
6033 : * bother rechecking in subsequent loop iterations.
6034 : */
6035 599 : if (tupdescs_match)
6036 : {
6037 595 : tupdescs_match =
6038 607 : (rec->rectypeid == RECORDOID ||
6039 607 : rec->rectypeid == tuptab->tupdesc->tdtypeid ||
6040 12 : compatible_tupdescs(tuptab->tupdesc,
6041 : expanded_record_get_tupdesc(rec->erh)));
6042 : }
6043 599 : previous_id = rec->erh->er_tupdesc_id;
6044 : }
6045 : }
6046 : else
6047 30886 : exec_move_row(estate, var, tuptab->vals[i], tuptab->tupdesc);
6048 :
6049 35459 : exec_eval_cleanup(estate);
6050 :
6051 : /*
6052 : * Execute the statements
6053 : */
6054 35459 : rc = exec_stmts(estate, stmt->body);
6055 :
6056 35441 : LOOP_RC_PROCESSING(stmt->label, goto loop_exit);
6057 : }
6058 :
6059 21194 : SPI_freetuptable(tuptab);
6060 :
6061 : /*
6062 : * Fetch more tuples. If prefetching is allowed, grab 50 at a time.
6063 : */
6064 21194 : SPI_cursor_fetch(portal, true, prefetch_ok ? 50 : 1);
6065 21194 : tuptab = SPI_tuptable;
6066 21194 : n = SPI_processed;
6067 : }
6068 :
6069 7780 : loop_exit:
6070 :
6071 : /*
6072 : * Release last group of tuples (if any)
6073 : */
6074 8028 : SPI_freetuptable(tuptab);
6075 :
6076 8028 : UnpinPortal(portal);
6077 :
6078 : /*
6079 : * Set the FOUND variable to indicate the result of executing the loop
6080 : * (namely, whether we looped one or more times). This must be set last so
6081 : * that it does not interfere with the value of the FOUND variable inside
6082 : * the loop processing itself.
6083 : */
6084 8028 : exec_set_found(estate, found);
6085 :
6086 8028 : return rc;
6087 : }
6088 :
6089 :
6090 : /* ----------
6091 : * exec_eval_simple_expr - Evaluate a simple expression returning
6092 : * a Datum by directly calling ExecEvalExpr().
6093 : *
6094 : * If successful, store results into *result, *isNull, *rettype, *rettypmod
6095 : * and return true. If the expression cannot be handled by simple evaluation,
6096 : * return false.
6097 : *
6098 : * Because we only store one execution tree for a simple expression, we
6099 : * can't handle recursion cases. So, if we see the tree is already busy
6100 : * with an evaluation in the current xact, we just return false and let the
6101 : * caller run the expression the hard way. (Other alternatives such as
6102 : * creating a new tree for a recursive call either introduce memory leaks,
6103 : * or add enough bookkeeping to be doubtful wins anyway.) Another case that
6104 : * is covered by the expr_simple_in_use test is where a previous execution
6105 : * of the tree was aborted by an error: the tree may contain bogus state
6106 : * so we dare not re-use it.
6107 : *
6108 : * It is possible that we'd need to replan a simple expression; for example,
6109 : * someone might redefine a SQL function that had been inlined into the simple
6110 : * expression. That cannot cause a simple expression to become non-simple (or
6111 : * vice versa), but we do have to handle replacing the expression tree.
6112 : *
6113 : * Note: if pass-by-reference, the result is in the eval_mcontext.
6114 : * It will be freed when exec_eval_cleanup is done.
6115 : * ----------
6116 : */
6117 : static bool
6118 215390 : exec_eval_simple_expr(PLpgSQL_execstate *estate,
6119 : PLpgSQL_expr *expr,
6120 : Datum *result,
6121 : bool *isNull,
6122 : Oid *rettype,
6123 : int32 *rettypmod)
6124 : {
6125 215390 : ExprContext *econtext = estate->eval_econtext;
6126 215390 : LocalTransactionId curlxid = MyProc->vxid.lxid;
6127 : ParamListInfo paramLI;
6128 : void *save_setup_arg;
6129 : bool need_snapshot;
6130 : MemoryContext oldcontext;
6131 :
6132 : /*
6133 : * Forget it if expression wasn't simple before.
6134 : */
6135 215390 : if (expr->expr_simple_expr == NULL)
6136 4863 : return false;
6137 :
6138 : /*
6139 : * If expression is in use in current xact, don't touch it.
6140 : */
6141 210527 : if (unlikely(expr->expr_simple_in_use) &&
6142 417 : expr->expr_simple_lxid == curlxid)
6143 373 : return false;
6144 :
6145 : /*
6146 : * Ensure that there's a portal-level snapshot, in case this simple
6147 : * expression is the first thing evaluated after a COMMIT or ROLLBACK.
6148 : * We'd have to do this anyway before executing the expression, so we
6149 : * might as well do it now to ensure that any possible replanning doesn't
6150 : * need to take a new snapshot.
6151 : */
6152 210154 : EnsurePortalSnapshotExists();
6153 :
6154 : /*
6155 : * Check to see if the cached plan has been invalidated. If not, and this
6156 : * is the first use in the current transaction, save a plan refcount in
6157 : * the simple-expression resowner.
6158 : */
6159 210154 : if (likely(CachedPlanIsSimplyValid(expr->expr_simple_plansource,
6160 : expr->expr_simple_plan,
6161 : (expr->expr_simple_plan_lxid != curlxid ?
6162 : estate->simple_eval_resowner : NULL))))
6163 : {
6164 : /*
6165 : * It's still good, so just remember that we have a refcount on the
6166 : * plan in the current transaction. (If we already had one, this
6167 : * assignment is a no-op.)
6168 : */
6169 206864 : expr->expr_simple_plan_lxid = curlxid;
6170 : }
6171 : else
6172 : {
6173 : /* Need to replan */
6174 : CachedPlan *cplan;
6175 :
6176 : /*
6177 : * If we have a valid refcount on some previous version of the plan,
6178 : * release it, so we don't leak plans intra-transaction.
6179 : */
6180 3290 : if (expr->expr_simple_plan_lxid == curlxid)
6181 1574 : ReleaseCachedPlan(expr->expr_simple_plan,
6182 : estate->simple_eval_resowner);
6183 :
6184 : /*
6185 : * Reset to "not simple" to leave sane state (with no dangling
6186 : * pointers) in case we fail while replanning. We'll need to
6187 : * re-determine simplicity and R/W optimizability anyway, since those
6188 : * could change with the new plan. expr_simple_plansource can be left
6189 : * alone however, as that cannot move.
6190 : */
6191 3290 : expr->expr_simple_expr = NULL;
6192 3290 : expr->expr_rwopt = PLPGSQL_RWOPT_UNKNOWN;
6193 3290 : expr->expr_rw_param = NULL;
6194 3290 : expr->expr_simple_plan = NULL;
6195 3290 : expr->expr_simple_plan_lxid = InvalidLocalTransactionId;
6196 :
6197 : /* Do the replanning work in the eval_mcontext */
6198 3290 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
6199 3290 : cplan = SPI_plan_get_cached_plan(expr->plan);
6200 3290 : MemoryContextSwitchTo(oldcontext);
6201 :
6202 : /*
6203 : * We can't get a failure here, because the number of
6204 : * CachedPlanSources in the SPI plan can't change from what
6205 : * exec_simple_check_plan saw; it's a property of the raw parsetree
6206 : * generated from the query text.
6207 : */
6208 : Assert(cplan != NULL);
6209 :
6210 : /*
6211 : * Recheck exec_is_simple_query, which could now report false in
6212 : * edge-case scenarios such as a non-SRF having been replaced with a
6213 : * SRF. Also recheck CachedPlanAllowsSimpleValidityCheck, just to be
6214 : * sure. If either test fails, cope by declaring the plan to be
6215 : * non-simple. On success, we'll acquire a refcount on the new plan,
6216 : * stored in simple_eval_resowner.
6217 : */
6218 6579 : if (exec_is_simple_query(expr) &&
6219 3289 : CachedPlanAllowsSimpleValidityCheck(expr->expr_simple_plansource,
6220 : cplan,
6221 : estate->simple_eval_resowner))
6222 : {
6223 : /* Remember that we have the refcount */
6224 3289 : expr->expr_simple_plan = cplan;
6225 3289 : expr->expr_simple_plan_lxid = curlxid;
6226 : }
6227 : else
6228 : {
6229 : /* Release SPI_plan_get_cached_plan's refcount */
6230 1 : ReleaseCachedPlan(cplan, CurrentResourceOwner);
6231 1 : return false;
6232 : }
6233 :
6234 : /*
6235 : * SPI_plan_get_cached_plan acquired a plan refcount stored in the
6236 : * active resowner. We don't need that anymore, so release it.
6237 : */
6238 3289 : ReleaseCachedPlan(cplan, CurrentResourceOwner);
6239 :
6240 : /* Extract desired scalar expression from cached plan */
6241 3289 : exec_save_simple_expr(expr, cplan);
6242 : }
6243 :
6244 : /*
6245 : * Pass back previously-determined result type.
6246 : */
6247 210153 : *rettype = expr->expr_simple_type;
6248 210153 : *rettypmod = expr->expr_simple_typmod;
6249 :
6250 : /*
6251 : * Set up ParamListInfo to pass to executor. For safety, save and restore
6252 : * estate->paramLI->parserSetupArg around our use of the param list.
6253 : */
6254 210153 : paramLI = estate->paramLI;
6255 210153 : save_setup_arg = paramLI->parserSetupArg;
6256 :
6257 : /*
6258 : * We can skip using setup_param_list() in favor of just doing this
6259 : * unconditionally, because there's no need for the optimization of
6260 : * possibly setting ecxt_param_list_info to NULL; we've already forced use
6261 : * of a generic plan.
6262 : */
6263 210153 : paramLI->parserSetupArg = expr;
6264 210153 : econtext->ecxt_param_list_info = paramLI;
6265 :
6266 : /*
6267 : * Prepare the expression for execution, if it's not been done already in
6268 : * the current transaction. (This will be forced to happen if we called
6269 : * exec_save_simple_expr above.)
6270 : */
6271 210153 : if (unlikely(expr->expr_simple_lxid != curlxid))
6272 : {
6273 51624 : oldcontext = MemoryContextSwitchTo(estate->simple_eval_estate->es_query_cxt);
6274 51624 : expr->expr_simple_state =
6275 51624 : ExecInitExprWithParams(expr->expr_simple_expr,
6276 : econtext->ecxt_param_list_info);
6277 51624 : expr->expr_simple_in_use = false;
6278 51624 : expr->expr_simple_lxid = curlxid;
6279 51624 : MemoryContextSwitchTo(oldcontext);
6280 : }
6281 :
6282 : /*
6283 : * We have to do some of the things SPI_execute_plan would do, in
6284 : * particular push a new snapshot so that stable functions within the
6285 : * expression can see updates made so far by our own function. However,
6286 : * we can skip doing that (and just invoke the expression with the same
6287 : * snapshot passed to our function) in some cases, which is useful because
6288 : * it's quite expensive relative to the cost of a simple expression. We
6289 : * can skip it if the expression contains no stable or volatile functions;
6290 : * immutable functions shouldn't need to see our updates. Also, if this
6291 : * is a read-only function, we haven't made any updates so again it's okay
6292 : * to skip.
6293 : */
6294 210153 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
6295 210153 : need_snapshot = (expr->expr_simple_mutable && !estate->readonly_func);
6296 210153 : if (need_snapshot)
6297 : {
6298 22283 : CommandCounterIncrement();
6299 22283 : PushActiveSnapshot(GetTransactionSnapshot());
6300 : }
6301 :
6302 : /*
6303 : * Mark expression as busy for the duration of the ExecEvalExpr call.
6304 : */
6305 210153 : expr->expr_simple_in_use = true;
6306 :
6307 : /*
6308 : * Finally we can call the executor to evaluate the expression
6309 : */
6310 210153 : *result = ExecEvalExpr(expr->expr_simple_state,
6311 : econtext,
6312 : isNull);
6313 :
6314 : /* Assorted cleanup */
6315 209995 : expr->expr_simple_in_use = false;
6316 :
6317 209995 : econtext->ecxt_param_list_info = NULL;
6318 :
6319 209995 : paramLI->parserSetupArg = save_setup_arg;
6320 :
6321 209995 : if (need_snapshot)
6322 22251 : PopActiveSnapshot();
6323 :
6324 209995 : MemoryContextSwitchTo(oldcontext);
6325 :
6326 : /*
6327 : * That's it.
6328 : */
6329 209995 : return true;
6330 : }
6331 :
6332 :
6333 : /*
6334 : * Create a ParamListInfo to pass to SPI
6335 : *
6336 : * We use a single ParamListInfo struct for all SPI calls made to evaluate
6337 : * PLpgSQL_exprs in this estate. It contains no per-param data, just hook
6338 : * functions, so it's effectively read-only for SPI.
6339 : *
6340 : * An exception from pure read-only-ness is that the parserSetupArg points
6341 : * to the specific PLpgSQL_expr being evaluated. This is not an issue for
6342 : * statement-level callers, but lower-level callers must save and restore
6343 : * estate->paramLI->parserSetupArg just in case there's an active evaluation
6344 : * at an outer call level. (A plausible alternative design would be to
6345 : * create a ParamListInfo struct for each PLpgSQL_expr, but for the moment
6346 : * that seems like a waste of memory.)
6347 : */
6348 : static ParamListInfo
6349 51741 : setup_param_list(PLpgSQL_execstate *estate, PLpgSQL_expr *expr)
6350 : {
6351 : ParamListInfo paramLI;
6352 :
6353 : /*
6354 : * We must have created the SPIPlan already (hence, query text has been
6355 : * parsed/analyzed at least once); else we cannot rely on expr->paramnos.
6356 : */
6357 : Assert(expr->plan != NULL);
6358 :
6359 : /*
6360 : * We only need a ParamListInfo if the expression has parameters.
6361 : */
6362 51741 : if (!bms_is_empty(expr->paramnos))
6363 : {
6364 : /* Use the common ParamListInfo */
6365 22117 : paramLI = estate->paramLI;
6366 :
6367 : /*
6368 : * Set up link to active expr where the hook functions can find it.
6369 : * Callers must save and restore parserSetupArg if there is any chance
6370 : * that they are interrupting an active use of parameters.
6371 : */
6372 22117 : paramLI->parserSetupArg = expr;
6373 : }
6374 : else
6375 : {
6376 : /*
6377 : * Expression requires no parameters. Be sure we represent this case
6378 : * as a NULL ParamListInfo, so that plancache.c knows there is no
6379 : * point in a custom plan.
6380 : */
6381 29624 : paramLI = NULL;
6382 : }
6383 51741 : return paramLI;
6384 : }
6385 :
6386 : /*
6387 : * plpgsql_param_fetch paramFetch callback for dynamic parameter fetch
6388 : *
6389 : * We always use the caller's workspace to construct the returned struct.
6390 : *
6391 : * Note: this is no longer used during query execution. It is used during
6392 : * planning (with speculative == true) and when the ParamListInfo we supply
6393 : * to the executor is copied into a cursor portal or transferred to a
6394 : * parallel child process.
6395 : */
6396 : static ParamExternData *
6397 7001 : plpgsql_param_fetch(ParamListInfo params,
6398 : int paramid, bool speculative,
6399 : ParamExternData *prm)
6400 : {
6401 : int dno;
6402 : PLpgSQL_execstate *estate;
6403 : PLpgSQL_expr *expr;
6404 : PLpgSQL_datum *datum;
6405 7001 : bool ok = true;
6406 : int32 prmtypmod;
6407 :
6408 : /* paramid's are 1-based, but dnos are 0-based */
6409 7001 : dno = paramid - 1;
6410 : Assert(dno >= 0 && dno < params->numParams);
6411 :
6412 : /* fetch back the hook data */
6413 7001 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6414 7001 : expr = (PLpgSQL_expr *) params->parserSetupArg;
6415 : Assert(params->numParams == estate->ndatums);
6416 :
6417 : /* now we can access the target datum */
6418 7001 : datum = estate->datums[dno];
6419 :
6420 : /*
6421 : * Since copyParamList() or SerializeParamList() will try to materialize
6422 : * every single parameter slot, it's important to return a dummy param
6423 : * when asked for a datum that's not supposed to be used by this SQL
6424 : * expression. Otherwise we risk failures in exec_eval_datum(), or
6425 : * copying a lot more data than necessary.
6426 : */
6427 7001 : if (!bms_is_member(dno, expr->paramnos))
6428 2205 : ok = false;
6429 :
6430 : /*
6431 : * If the access is speculative, we prefer to return no data rather than
6432 : * to fail in exec_eval_datum(). Check the likely failure cases.
6433 : */
6434 4796 : else if (speculative)
6435 : {
6436 4151 : switch (datum->dtype)
6437 : {
6438 2371 : case PLPGSQL_DTYPE_VAR:
6439 : case PLPGSQL_DTYPE_PROMISE:
6440 : /* always safe */
6441 2371 : break;
6442 :
6443 0 : case PLPGSQL_DTYPE_ROW:
6444 : /* should be safe in all interesting cases */
6445 0 : break;
6446 :
6447 304 : case PLPGSQL_DTYPE_REC:
6448 : /* always safe (might return NULL, that's fine) */
6449 304 : break;
6450 :
6451 1476 : case PLPGSQL_DTYPE_RECFIELD:
6452 : {
6453 1476 : PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum;
6454 : PLpgSQL_rec *rec;
6455 :
6456 1476 : rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
6457 :
6458 : /*
6459 : * If record variable is NULL, don't risk anything.
6460 : */
6461 1476 : if (rec->erh == NULL)
6462 0 : ok = false;
6463 :
6464 : /*
6465 : * Look up the field's properties if we have not already,
6466 : * or if the tuple descriptor ID changed since last time.
6467 : */
6468 1476 : else if (unlikely(recfield->rectupledescid != rec->erh->er_tupdesc_id))
6469 : {
6470 11 : if (expanded_record_lookup_field(rec->erh,
6471 11 : recfield->fieldname,
6472 : &recfield->finfo))
6473 11 : recfield->rectupledescid = rec->erh->er_tupdesc_id;
6474 : else
6475 0 : ok = false;
6476 : }
6477 1476 : break;
6478 : }
6479 :
6480 0 : default:
6481 0 : ok = false;
6482 0 : break;
6483 : }
6484 : }
6485 :
6486 : /* Return "no such parameter" if not ok */
6487 7001 : if (!ok)
6488 : {
6489 2205 : prm->value = (Datum) 0;
6490 2205 : prm->isnull = true;
6491 2205 : prm->pflags = 0;
6492 2205 : prm->ptype = InvalidOid;
6493 2205 : return prm;
6494 : }
6495 :
6496 : /* OK, evaluate the value and store into the return struct */
6497 4796 : exec_eval_datum(estate, datum,
6498 : &prm->ptype, &prmtypmod,
6499 : &prm->value, &prm->isnull);
6500 : /* We can always mark params as "const" for executor's purposes */
6501 4796 : prm->pflags = PARAM_FLAG_CONST;
6502 :
6503 : /*
6504 : * If it's a read/write expanded datum, convert reference to read-only.
6505 : * (There's little point in trying to optimize read/write parameters,
6506 : * given the cases in which this function is used.)
6507 : */
6508 4796 : if (datum->dtype == PLPGSQL_DTYPE_VAR)
6509 2849 : prm->value = MakeExpandedObjectReadOnly(prm->value,
6510 : prm->isnull,
6511 : ((PLpgSQL_var *) datum)->datatype->typlen);
6512 1947 : else if (datum->dtype == PLPGSQL_DTYPE_REC)
6513 304 : prm->value = MakeExpandedObjectReadOnly(prm->value,
6514 : prm->isnull,
6515 : -1);
6516 :
6517 4796 : return prm;
6518 : }
6519 :
6520 : /*
6521 : * plpgsql_param_compile paramCompile callback for plpgsql parameters
6522 : */
6523 : static void
6524 94723 : plpgsql_param_compile(ParamListInfo params, Param *param,
6525 : ExprState *state,
6526 : Datum *resv, bool *resnull)
6527 : {
6528 : PLpgSQL_execstate *estate;
6529 : PLpgSQL_expr *expr;
6530 : int dno;
6531 : PLpgSQL_datum *datum;
6532 : ExprEvalStep scratch;
6533 :
6534 : /* fetch back the hook data */
6535 94723 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6536 94723 : expr = (PLpgSQL_expr *) params->parserSetupArg;
6537 :
6538 : /* paramid's are 1-based, but dnos are 0-based */
6539 94723 : dno = param->paramid - 1;
6540 : Assert(dno >= 0 && dno < estate->ndatums);
6541 :
6542 : /* now we can access the target datum */
6543 94723 : datum = estate->datums[dno];
6544 :
6545 94723 : scratch.opcode = EEOP_PARAM_CALLBACK;
6546 94723 : scratch.resvalue = resv;
6547 94723 : scratch.resnull = resnull;
6548 :
6549 : /*
6550 : * Select appropriate eval function.
6551 : *
6552 : * First, if this Param references the same varlena-type DTYPE_VAR datum
6553 : * that is the target of the assignment containing this simple expression,
6554 : * then it's possible we will be able to optimize handling of R/W expanded
6555 : * datums. We don't want to do the work needed to determine that unless
6556 : * we actually see a R/W expanded datum at runtime, so install a checking
6557 : * function that will figure that out when needed.
6558 : *
6559 : * Otherwise, it seems worth special-casing DTYPE_VAR and DTYPE_RECFIELD
6560 : * for performance. Also, we can determine in advance whether
6561 : * MakeExpandedObjectReadOnly() will be required. Currently, only
6562 : * VAR/PROMISE and REC datums could contain read/write expanded objects.
6563 : */
6564 94723 : if (datum->dtype == PLPGSQL_DTYPE_VAR)
6565 : {
6566 61053 : bool isvarlena = (((PLpgSQL_var *) datum)->datatype->typlen == -1);
6567 :
6568 61053 : if (isvarlena && dno == expr->target_param && expr->expr_simple_expr)
6569 1928 : scratch.d.cparam.paramfunc = plpgsql_param_eval_var_check;
6570 59125 : else if (isvarlena)
6571 45199 : scratch.d.cparam.paramfunc = plpgsql_param_eval_var_ro;
6572 : else
6573 13926 : scratch.d.cparam.paramfunc = plpgsql_param_eval_var;
6574 : }
6575 33670 : else if (datum->dtype == PLPGSQL_DTYPE_RECFIELD)
6576 17440 : scratch.d.cparam.paramfunc = plpgsql_param_eval_recfield;
6577 16230 : else if (datum->dtype == PLPGSQL_DTYPE_PROMISE)
6578 : {
6579 13629 : if (((PLpgSQL_var *) datum)->datatype->typlen == -1)
6580 11923 : scratch.d.cparam.paramfunc = plpgsql_param_eval_generic_ro;
6581 : else
6582 1706 : scratch.d.cparam.paramfunc = plpgsql_param_eval_generic;
6583 : }
6584 2601 : else if (datum->dtype == PLPGSQL_DTYPE_REC)
6585 2601 : scratch.d.cparam.paramfunc = plpgsql_param_eval_generic_ro;
6586 : else
6587 0 : scratch.d.cparam.paramfunc = plpgsql_param_eval_generic;
6588 :
6589 : /*
6590 : * Note: it's tempting to use paramarg to store the estate pointer and
6591 : * thereby save an indirection or two in the eval functions. But that
6592 : * doesn't work because the compiled expression might be used with
6593 : * different estates for the same PL/pgSQL function. Instead, store
6594 : * pointers to the PLpgSQL_expr as well as this specific Param, to support
6595 : * plpgsql_param_eval_var_check().
6596 : */
6597 94723 : scratch.d.cparam.paramarg = expr;
6598 94723 : scratch.d.cparam.paramarg2 = param;
6599 94723 : scratch.d.cparam.paramid = param->paramid;
6600 94723 : scratch.d.cparam.paramtype = param->paramtype;
6601 94723 : ExprEvalPushStep(state, &scratch);
6602 94723 : }
6603 :
6604 : /*
6605 : * plpgsql_param_eval_var_check evaluation of EEOP_PARAM_CALLBACK step
6606 : *
6607 : * This is specialized to the case of DTYPE_VAR variables for which
6608 : * we may need to determine the applicability of a read/write optimization,
6609 : * but we've not done that yet. The work to determine applicability will
6610 : * be done at most once (per construction of the PL/pgSQL function's cache
6611 : * entry) when we first see that the target variable's old value is a R/W
6612 : * expanded object. If we never do see that, nothing is lost: the amount
6613 : * of work done by this function in that case is just about the same as
6614 : * what would be done by plpgsql_param_eval_var_ro, which is what we'd
6615 : * have used otherwise.
6616 : */
6617 : static void
6618 20980 : plpgsql_param_eval_var_check(ExprState *state, ExprEvalStep *op,
6619 : ExprContext *econtext)
6620 : {
6621 : ParamListInfo params;
6622 : PLpgSQL_execstate *estate;
6623 20980 : int dno = op->d.cparam.paramid - 1;
6624 : PLpgSQL_var *var;
6625 :
6626 : /* fetch back the hook data */
6627 20980 : params = econtext->ecxt_param_list_info;
6628 20980 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6629 : Assert(dno >= 0 && dno < estate->ndatums);
6630 :
6631 : /* now we can access the target datum */
6632 20980 : var = (PLpgSQL_var *) estate->datums[dno];
6633 : Assert(var->dtype == PLPGSQL_DTYPE_VAR);
6634 :
6635 : /*
6636 : * If the variable's current value is a R/W expanded object, it's time to
6637 : * decide whether/how to optimize the assignment.
6638 : */
6639 41919 : if (!var->isnull &&
6640 20939 : VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(var->value)))
6641 : {
6642 106 : PLpgSQL_expr *expr = (PLpgSQL_expr *) op->d.cparam.paramarg;
6643 106 : Param *param = (Param *) op->d.cparam.paramarg2;
6644 :
6645 : /*
6646 : * We might have already figured this out while evaluating some other
6647 : * Param referencing the same variable, so check expr_rwopt first.
6648 : */
6649 106 : if (expr->expr_rwopt == PLPGSQL_RWOPT_UNKNOWN)
6650 65 : exec_check_rw_parameter(expr, op->d.cparam.paramid);
6651 :
6652 : /*
6653 : * Update the callback pointer to match what we decided to do, so that
6654 : * this function will not be called again. Then pass off this
6655 : * execution to the newly-selected function.
6656 : */
6657 106 : switch (expr->expr_rwopt)
6658 : {
6659 0 : case PLPGSQL_RWOPT_UNKNOWN:
6660 : Assert(false);
6661 0 : break;
6662 2 : case PLPGSQL_RWOPT_NOPE:
6663 : /* Force the value to read-only in all future executions */
6664 2 : op->d.cparam.paramfunc = plpgsql_param_eval_var_ro;
6665 2 : plpgsql_param_eval_var_ro(state, op, econtext);
6666 2 : break;
6667 98 : case PLPGSQL_RWOPT_TRANSFER:
6668 : /* There can be only one matching Param in this case */
6669 : Assert(param == expr->expr_rw_param);
6670 : /* When the value is read/write, transfer to exec context */
6671 98 : op->d.cparam.paramfunc = plpgsql_param_eval_var_transfer;
6672 98 : plpgsql_param_eval_var_transfer(state, op, econtext);
6673 98 : break;
6674 6 : case PLPGSQL_RWOPT_INPLACE:
6675 6 : if (param == expr->expr_rw_param)
6676 : {
6677 : /* When the value is read/write, deliver it as-is */
6678 3 : op->d.cparam.paramfunc = plpgsql_param_eval_var;
6679 3 : plpgsql_param_eval_var(state, op, econtext);
6680 : }
6681 : else
6682 : {
6683 : /* Not the optimizable reference, so force to read-only */
6684 3 : op->d.cparam.paramfunc = plpgsql_param_eval_var_ro;
6685 3 : plpgsql_param_eval_var_ro(state, op, econtext);
6686 : }
6687 6 : break;
6688 : }
6689 106 : return;
6690 : }
6691 :
6692 : /*
6693 : * Otherwise, continue to postpone that decision, and execute an inlined
6694 : * version of exec_eval_datum(). Although this value could potentially
6695 : * need MakeExpandedObjectReadOnly, we know it doesn't right now.
6696 : */
6697 20874 : *op->resvalue = var->value;
6698 20874 : *op->resnull = var->isnull;
6699 :
6700 : /* safety check -- an assertion should be sufficient */
6701 : Assert(var->datatype->typoid == op->d.cparam.paramtype);
6702 : }
6703 :
6704 : /*
6705 : * plpgsql_param_eval_var_transfer evaluation of EEOP_PARAM_CALLBACK step
6706 : *
6707 : * This is specialized to the case of DTYPE_VAR variables for which
6708 : * we have determined that a read/write expanded value can be handed off
6709 : * into execution of the expression (and then possibly returned to our
6710 : * function's ownership afterwards). We have to test though, because the
6711 : * variable might not contain a read/write expanded value during this
6712 : * execution.
6713 : */
6714 : static void
6715 150 : plpgsql_param_eval_var_transfer(ExprState *state, ExprEvalStep *op,
6716 : ExprContext *econtext)
6717 : {
6718 : ParamListInfo params;
6719 : PLpgSQL_execstate *estate;
6720 150 : int dno = op->d.cparam.paramid - 1;
6721 : PLpgSQL_var *var;
6722 :
6723 : /* fetch back the hook data */
6724 150 : params = econtext->ecxt_param_list_info;
6725 150 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6726 : Assert(dno >= 0 && dno < estate->ndatums);
6727 :
6728 : /* now we can access the target datum */
6729 150 : var = (PLpgSQL_var *) estate->datums[dno];
6730 : Assert(var->dtype == PLPGSQL_DTYPE_VAR);
6731 :
6732 : /*
6733 : * If the variable's current value is a R/W expanded object, transfer its
6734 : * ownership into the expression execution context, then drop our own
6735 : * reference to the value by setting the variable to NULL. That'll be
6736 : * overwritten (perhaps with this same object) when control comes back
6737 : * from the expression.
6738 : */
6739 300 : if (!var->isnull &&
6740 150 : VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(var->value)))
6741 : {
6742 300 : *op->resvalue = TransferExpandedObject(var->value,
6743 150 : get_eval_mcontext(estate));
6744 150 : *op->resnull = false;
6745 :
6746 150 : var->value = (Datum) 0;
6747 150 : var->isnull = true;
6748 150 : var->freeval = false;
6749 : }
6750 : else
6751 : {
6752 : /*
6753 : * Otherwise we can pass the variable's value directly; we now know
6754 : * that MakeExpandedObjectReadOnly isn't needed.
6755 : */
6756 0 : *op->resvalue = var->value;
6757 0 : *op->resnull = var->isnull;
6758 : }
6759 :
6760 : /* safety check -- an assertion should be sufficient */
6761 : Assert(var->datatype->typoid == op->d.cparam.paramtype);
6762 150 : }
6763 :
6764 : /*
6765 : * plpgsql_param_eval_var evaluation of EEOP_PARAM_CALLBACK step
6766 : *
6767 : * This is specialized to the case of DTYPE_VAR variables for which
6768 : * we do not need to invoke MakeExpandedObjectReadOnly.
6769 : */
6770 : static void
6771 87933 : plpgsql_param_eval_var(ExprState *state, ExprEvalStep *op,
6772 : ExprContext *econtext)
6773 : {
6774 : ParamListInfo params;
6775 : PLpgSQL_execstate *estate;
6776 87933 : int dno = op->d.cparam.paramid - 1;
6777 : PLpgSQL_var *var;
6778 :
6779 : /* fetch back the hook data */
6780 87933 : params = econtext->ecxt_param_list_info;
6781 87933 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6782 : Assert(dno >= 0 && dno < estate->ndatums);
6783 :
6784 : /* now we can access the target datum */
6785 87933 : var = (PLpgSQL_var *) estate->datums[dno];
6786 : Assert(var->dtype == PLPGSQL_DTYPE_VAR);
6787 :
6788 : /* inlined version of exec_eval_datum() */
6789 87933 : *op->resvalue = var->value;
6790 87933 : *op->resnull = var->isnull;
6791 :
6792 : /* safety check -- an assertion should be sufficient */
6793 : Assert(var->datatype->typoid == op->d.cparam.paramtype);
6794 87933 : }
6795 :
6796 : /*
6797 : * plpgsql_param_eval_var_ro evaluation of EEOP_PARAM_CALLBACK step
6798 : *
6799 : * This is specialized to the case of DTYPE_VAR variables for which
6800 : * we need to invoke MakeExpandedObjectReadOnly.
6801 : */
6802 : static void
6803 104585 : plpgsql_param_eval_var_ro(ExprState *state, ExprEvalStep *op,
6804 : ExprContext *econtext)
6805 : {
6806 : ParamListInfo params;
6807 : PLpgSQL_execstate *estate;
6808 104585 : int dno = op->d.cparam.paramid - 1;
6809 : PLpgSQL_var *var;
6810 :
6811 : /* fetch back the hook data */
6812 104585 : params = econtext->ecxt_param_list_info;
6813 104585 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6814 : Assert(dno >= 0 && dno < estate->ndatums);
6815 :
6816 : /* now we can access the target datum */
6817 104585 : var = (PLpgSQL_var *) estate->datums[dno];
6818 : Assert(var->dtype == PLPGSQL_DTYPE_VAR);
6819 :
6820 : /*
6821 : * Inlined version of exec_eval_datum() ... and while we're at it, force
6822 : * expanded datums to read-only.
6823 : */
6824 104585 : *op->resvalue = MakeExpandedObjectReadOnly(var->value,
6825 : var->isnull,
6826 : -1);
6827 104585 : *op->resnull = var->isnull;
6828 :
6829 : /* safety check -- an assertion should be sufficient */
6830 : Assert(var->datatype->typoid == op->d.cparam.paramtype);
6831 104585 : }
6832 :
6833 : /*
6834 : * plpgsql_param_eval_recfield evaluation of EEOP_PARAM_CALLBACK step
6835 : *
6836 : * This is specialized to the case of DTYPE_RECFIELD variables, for which
6837 : * we never need to invoke MakeExpandedObjectReadOnly.
6838 : */
6839 : static void
6840 43518 : plpgsql_param_eval_recfield(ExprState *state, ExprEvalStep *op,
6841 : ExprContext *econtext)
6842 : {
6843 : ParamListInfo params;
6844 : PLpgSQL_execstate *estate;
6845 43518 : int dno = op->d.cparam.paramid - 1;
6846 : PLpgSQL_recfield *recfield;
6847 : PLpgSQL_rec *rec;
6848 : ExpandedRecordHeader *erh;
6849 :
6850 : /* fetch back the hook data */
6851 43518 : params = econtext->ecxt_param_list_info;
6852 43518 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6853 : Assert(dno >= 0 && dno < estate->ndatums);
6854 :
6855 : /* now we can access the target datum */
6856 43518 : recfield = (PLpgSQL_recfield *) estate->datums[dno];
6857 : Assert(recfield->dtype == PLPGSQL_DTYPE_RECFIELD);
6858 :
6859 : /* inline the relevant part of exec_eval_datum */
6860 43518 : rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]);
6861 43518 : erh = rec->erh;
6862 :
6863 : /*
6864 : * If record variable is NULL, instantiate it if it has a named composite
6865 : * type, else complain. (This won't change the logical state of the
6866 : * record: it's still NULL.)
6867 : */
6868 43518 : if (erh == NULL)
6869 : {
6870 1 : instantiate_empty_record_variable(estate, rec);
6871 1 : erh = rec->erh;
6872 : }
6873 :
6874 : /*
6875 : * Look up the field's properties if we have not already, or if the tuple
6876 : * descriptor ID changed since last time.
6877 : */
6878 43518 : if (unlikely(recfield->rectupledescid != erh->er_tupdesc_id))
6879 : {
6880 2621 : if (!expanded_record_lookup_field(erh,
6881 2621 : recfield->fieldname,
6882 : &recfield->finfo))
6883 1 : ereport(ERROR,
6884 : (errcode(ERRCODE_UNDEFINED_COLUMN),
6885 : errmsg("record \"%s\" has no field \"%s\"",
6886 : rec->refname, recfield->fieldname)));
6887 2620 : recfield->rectupledescid = erh->er_tupdesc_id;
6888 : }
6889 :
6890 : /* OK to fetch the field value. */
6891 43517 : *op->resvalue = expanded_record_get_field(erh,
6892 : recfield->finfo.fnumber,
6893 : op->resnull);
6894 :
6895 : /* safety check -- needed for, eg, record fields */
6896 43517 : if (unlikely(recfield->finfo.ftypeid != op->d.cparam.paramtype))
6897 2 : ereport(ERROR,
6898 : (errcode(ERRCODE_DATATYPE_MISMATCH),
6899 : errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
6900 : op->d.cparam.paramid,
6901 : format_type_be(recfield->finfo.ftypeid),
6902 : format_type_be(op->d.cparam.paramtype))));
6903 43515 : }
6904 :
6905 : /*
6906 : * plpgsql_param_eval_generic evaluation of EEOP_PARAM_CALLBACK step
6907 : *
6908 : * This handles all variable types, but assumes we do not need to invoke
6909 : * MakeExpandedObjectReadOnly.
6910 : */
6911 : static void
6912 1863 : plpgsql_param_eval_generic(ExprState *state, ExprEvalStep *op,
6913 : ExprContext *econtext)
6914 : {
6915 : ParamListInfo params;
6916 : PLpgSQL_execstate *estate;
6917 1863 : int dno = op->d.cparam.paramid - 1;
6918 : PLpgSQL_datum *datum;
6919 : Oid datumtype;
6920 : int32 datumtypmod;
6921 :
6922 : /* fetch back the hook data */
6923 1863 : params = econtext->ecxt_param_list_info;
6924 1863 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6925 : Assert(dno >= 0 && dno < estate->ndatums);
6926 :
6927 : /* now we can access the target datum */
6928 1863 : datum = estate->datums[dno];
6929 :
6930 : /* fetch datum's value */
6931 1863 : exec_eval_datum(estate, datum,
6932 : &datumtype, &datumtypmod,
6933 : op->resvalue, op->resnull);
6934 :
6935 : /* safety check -- needed for, eg, record fields */
6936 1863 : if (unlikely(datumtype != op->d.cparam.paramtype))
6937 0 : ereport(ERROR,
6938 : (errcode(ERRCODE_DATATYPE_MISMATCH),
6939 : errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
6940 : op->d.cparam.paramid,
6941 : format_type_be(datumtype),
6942 : format_type_be(op->d.cparam.paramtype))));
6943 1863 : }
6944 :
6945 : /*
6946 : * plpgsql_param_eval_generic_ro evaluation of EEOP_PARAM_CALLBACK step
6947 : *
6948 : * This handles all variable types, but assumes we need to invoke
6949 : * MakeExpandedObjectReadOnly (hence, variable must be of a varlena type).
6950 : */
6951 : static void
6952 15205 : plpgsql_param_eval_generic_ro(ExprState *state, ExprEvalStep *op,
6953 : ExprContext *econtext)
6954 : {
6955 : ParamListInfo params;
6956 : PLpgSQL_execstate *estate;
6957 15205 : int dno = op->d.cparam.paramid - 1;
6958 : PLpgSQL_datum *datum;
6959 : Oid datumtype;
6960 : int32 datumtypmod;
6961 :
6962 : /* fetch back the hook data */
6963 15205 : params = econtext->ecxt_param_list_info;
6964 15205 : estate = (PLpgSQL_execstate *) params->paramFetchArg;
6965 : Assert(dno >= 0 && dno < estate->ndatums);
6966 :
6967 : /* now we can access the target datum */
6968 15205 : datum = estate->datums[dno];
6969 :
6970 : /* fetch datum's value */
6971 15205 : exec_eval_datum(estate, datum,
6972 : &datumtype, &datumtypmod,
6973 : op->resvalue, op->resnull);
6974 :
6975 : /* safety check -- needed for, eg, record fields */
6976 15205 : if (unlikely(datumtype != op->d.cparam.paramtype))
6977 0 : ereport(ERROR,
6978 : (errcode(ERRCODE_DATATYPE_MISMATCH),
6979 : errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
6980 : op->d.cparam.paramid,
6981 : format_type_be(datumtype),
6982 : format_type_be(op->d.cparam.paramtype))));
6983 :
6984 : /* force the value to read-only */
6985 15205 : *op->resvalue = MakeExpandedObjectReadOnly(*op->resvalue,
6986 : *op->resnull,
6987 : -1);
6988 15205 : }
6989 :
6990 :
6991 : /*
6992 : * exec_move_row Move one tuple's values into a record or row
6993 : *
6994 : * tup and tupdesc may both be NULL if we're just assigning an indeterminate
6995 : * composite NULL to the target. Alternatively, can have tup be NULL and
6996 : * tupdesc not NULL, in which case we assign a row of NULLs to the target.
6997 : *
6998 : * Since this uses the mcontext for workspace, caller should eventually call
6999 : * exec_eval_cleanup to prevent long-term memory leaks.
7000 : */
7001 : static void
7002 47447 : exec_move_row(PLpgSQL_execstate *estate,
7003 : PLpgSQL_variable *target,
7004 : HeapTuple tup, TupleDesc tupdesc)
7005 : {
7006 47447 : ExpandedRecordHeader *newerh = NULL;
7007 :
7008 : /*
7009 : * If target is RECORD, we may be able to avoid field-by-field processing.
7010 : */
7011 47447 : if (target->dtype == PLPGSQL_DTYPE_REC)
7012 : {
7013 7015 : PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
7014 :
7015 : /*
7016 : * If we have no source tupdesc, just set the record variable to NULL.
7017 : * (If we have a source tupdesc but not a tuple, we'll set the
7018 : * variable to a row of nulls, instead. This is odd perhaps, but
7019 : * backwards compatible.)
7020 : */
7021 7015 : if (tupdesc == NULL)
7022 : {
7023 3222 : if (rec->datatype &&
7024 3222 : rec->datatype->typtype == TYPTYPE_DOMAIN)
7025 : {
7026 : /*
7027 : * If it's a composite domain, NULL might not be a legal
7028 : * value, so we instead need to make an empty expanded record
7029 : * and ensure that domain type checking gets done. If there
7030 : * is already an expanded record, piggyback on its lookups.
7031 : */
7032 17 : newerh = make_expanded_record_for_rec(estate, rec,
7033 : NULL, rec->erh);
7034 17 : expanded_record_set_tuple(newerh, NULL, false, false);
7035 13 : assign_record_var(estate, rec, newerh);
7036 : }
7037 : else
7038 : {
7039 : /* Just clear it to NULL */
7040 3205 : if (rec->erh)
7041 81 : DeleteExpandedObject(ExpandedRecordGetDatum(rec->erh));
7042 3205 : rec->erh = NULL;
7043 : }
7044 3218 : return;
7045 : }
7046 :
7047 : /*
7048 : * Build a new expanded record with appropriate tupdesc.
7049 : */
7050 3793 : newerh = make_expanded_record_for_rec(estate, rec, tupdesc, NULL);
7051 :
7052 : /*
7053 : * If the rowtypes match, or if we have no tuple anyway, we can
7054 : * complete the assignment without field-by-field processing.
7055 : *
7056 : * The tests here are ordered more or less in order of cheapness. We
7057 : * can easily detect it will work if the target is declared RECORD or
7058 : * has the same typeid as the source. But when assigning from a query
7059 : * result, it's common to have a source tupdesc that's labeled RECORD
7060 : * but is actually physically compatible with a named-composite-type
7061 : * target, so it's worth spending extra cycles to check for that.
7062 : */
7063 3793 : if (rec->rectypeid == RECORDOID ||
7064 128 : rec->rectypeid == tupdesc->tdtypeid ||
7065 128 : !HeapTupleIsValid(tup) ||
7066 128 : compatible_tupdescs(tupdesc, expanded_record_get_tupdesc(newerh)))
7067 : {
7068 3740 : if (!HeapTupleIsValid(tup))
7069 : {
7070 : /* No data, so force the record into all-nulls state */
7071 1083 : deconstruct_expanded_record(newerh);
7072 : }
7073 : else
7074 : {
7075 : /* No coercion is needed, so just assign the row value */
7076 2657 : expanded_record_set_tuple(newerh, tup, true, !estate->atomic);
7077 : }
7078 :
7079 : /* Complete the assignment */
7080 3737 : assign_record_var(estate, rec, newerh);
7081 :
7082 3737 : return;
7083 : }
7084 : }
7085 :
7086 : /*
7087 : * Otherwise, deconstruct the tuple and do field-by-field assignment,
7088 : * using exec_move_row_from_fields.
7089 : */
7090 40485 : if (tupdesc && HeapTupleIsValid(tup))
7091 40339 : {
7092 40360 : int td_natts = tupdesc->natts;
7093 : Datum *values;
7094 : bool *nulls;
7095 : Datum values_local[64];
7096 : bool nulls_local[64];
7097 :
7098 : /*
7099 : * Need workspace arrays. If td_natts is small enough, use local
7100 : * arrays to save doing a palloc. Even if it's not small, we can
7101 : * allocate both the Datum and isnull arrays in one palloc chunk.
7102 : */
7103 40360 : if (td_natts <= lengthof(values_local))
7104 : {
7105 40360 : values = values_local;
7106 40360 : nulls = nulls_local;
7107 : }
7108 : else
7109 : {
7110 : char *chunk;
7111 :
7112 0 : chunk = eval_mcontext_alloc(estate,
7113 : td_natts * (sizeof(Datum) + sizeof(bool)));
7114 0 : values = (Datum *) chunk;
7115 0 : nulls = (bool *) (chunk + td_natts * sizeof(Datum));
7116 : }
7117 :
7118 40360 : heap_deform_tuple(tup, tupdesc, values, nulls);
7119 :
7120 40360 : exec_move_row_from_fields(estate, target, newerh,
7121 : values, nulls, tupdesc);
7122 : }
7123 : else
7124 : {
7125 : /*
7126 : * Assign all-nulls.
7127 : */
7128 125 : exec_move_row_from_fields(estate, target, newerh,
7129 : NULL, NULL, NULL);
7130 : }
7131 : }
7132 :
7133 : /*
7134 : * Verify that a PLpgSQL_rec's rectypeid is up-to-date.
7135 : */
7136 : static void
7137 384 : revalidate_rectypeid(PLpgSQL_rec *rec)
7138 : {
7139 384 : PLpgSQL_type *typ = rec->datatype;
7140 : TypeCacheEntry *typentry;
7141 :
7142 384 : if (rec->rectypeid == RECORDOID)
7143 150 : return; /* it's RECORD, so nothing to do */
7144 : Assert(typ != NULL);
7145 234 : if (typ->tcache &&
7146 234 : typ->tcache->tupDesc_identifier == typ->tupdesc_id)
7147 : {
7148 : /*
7149 : * Although *typ is known up-to-date, it's possible that rectypeid
7150 : * isn't, because *rec is cloned during each function startup from a
7151 : * copy that we don't have a good way to update. Hence, forcibly fix
7152 : * rectypeid before returning.
7153 : */
7154 228 : rec->rectypeid = typ->typoid;
7155 228 : return;
7156 : }
7157 :
7158 : /*
7159 : * typcache entry has suffered invalidation, so re-look-up the type name
7160 : * if possible, and then recheck the type OID. If we don't have a
7161 : * TypeName, then we just have to soldier on with the OID we've got.
7162 : */
7163 6 : if (typ->origtypname != NULL)
7164 : {
7165 : /* this bit should match parse_datatype() in pl_gram.y */
7166 4 : typenameTypeIdAndMod(NULL, typ->origtypname,
7167 : &typ->typoid,
7168 : &typ->atttypmod);
7169 : }
7170 :
7171 : /* this bit should match build_datatype() in pl_comp.c */
7172 5 : typentry = lookup_type_cache(typ->typoid,
7173 : TYPECACHE_TUPDESC |
7174 : TYPECACHE_DOMAIN_BASE_INFO);
7175 5 : if (typentry->typtype == TYPTYPE_DOMAIN)
7176 0 : typentry = lookup_type_cache(typentry->domainBaseType,
7177 : TYPECACHE_TUPDESC);
7178 5 : if (typentry->tupDesc == NULL)
7179 : {
7180 : /*
7181 : * If we get here, user tried to replace a composite type with a
7182 : * non-composite one. We're not gonna support that.
7183 : */
7184 0 : ereport(ERROR,
7185 : (errcode(ERRCODE_WRONG_OBJECT_TYPE),
7186 : errmsg("type %s is not composite",
7187 : format_type_be(typ->typoid))));
7188 : }
7189 :
7190 : /*
7191 : * Update tcache and tupdesc_id. Since we don't support changing to a
7192 : * non-composite type, none of the rest of *typ needs to change.
7193 : */
7194 5 : typ->tcache = typentry;
7195 5 : typ->tupdesc_id = typentry->tupDesc_identifier;
7196 :
7197 : /*
7198 : * Update *rec, too. (We'll deal with subsidiary RECFIELDs as needed.)
7199 : */
7200 5 : rec->rectypeid = typ->typoid;
7201 : }
7202 :
7203 : /*
7204 : * Build an expanded record object suitable for assignment to "rec".
7205 : *
7206 : * Caller must supply either a source tuple descriptor or a source expanded
7207 : * record (not both). If the record variable has declared type RECORD,
7208 : * it'll adopt the source's rowtype. Even if it doesn't, we may be able to
7209 : * piggyback on a source expanded record to save a typcache lookup.
7210 : *
7211 : * Caller must fill the object with data, then do assign_record_var().
7212 : *
7213 : * The new record is initially put into the mcontext, so it will be cleaned up
7214 : * if we fail before reaching assign_record_var().
7215 : */
7216 : static ExpandedRecordHeader *
7217 3971 : make_expanded_record_for_rec(PLpgSQL_execstate *estate,
7218 : PLpgSQL_rec *rec,
7219 : TupleDesc srctupdesc,
7220 : ExpandedRecordHeader *srcerh)
7221 : {
7222 : ExpandedRecordHeader *newerh;
7223 3971 : MemoryContext mcontext = get_eval_mcontext(estate);
7224 :
7225 3971 : if (rec->rectypeid != RECORDOID)
7226 : {
7227 : /*
7228 : * Make sure rec->rectypeid is up-to-date before using it.
7229 : */
7230 157 : revalidate_rectypeid(rec);
7231 :
7232 : /*
7233 : * New record must be of desired type, but maybe srcerh has already
7234 : * done all the same lookups.
7235 : */
7236 157 : if (srcerh && rec->rectypeid == srcerh->er_decltypeid)
7237 13 : newerh = make_expanded_record_from_exprecord(srcerh,
7238 : mcontext);
7239 : else
7240 144 : newerh = make_expanded_record_from_typeid(rec->rectypeid, -1,
7241 : mcontext);
7242 : }
7243 : else
7244 : {
7245 : /*
7246 : * We'll adopt the input tupdesc. We can still use
7247 : * make_expanded_record_from_exprecord, if srcerh isn't a composite
7248 : * domain. (If it is, we effectively adopt its base type.)
7249 : */
7250 3814 : if (srcerh && !ExpandedRecordIsDomain(srcerh))
7251 149 : newerh = make_expanded_record_from_exprecord(srcerh,
7252 : mcontext);
7253 : else
7254 : {
7255 3665 : if (!srctupdesc)
7256 0 : srctupdesc = expanded_record_get_tupdesc(srcerh);
7257 3665 : newerh = make_expanded_record_from_tupdesc(srctupdesc,
7258 : mcontext);
7259 : }
7260 : }
7261 :
7262 3971 : return newerh;
7263 : }
7264 :
7265 : /*
7266 : * exec_move_row_from_fields Move arrays of field values into a record or row
7267 : *
7268 : * When assigning to a record, the caller must have already created a suitable
7269 : * new expanded record object, newerh. Pass NULL when assigning to a row.
7270 : *
7271 : * tupdesc describes the input row, which might have different column
7272 : * types and/or different dropped-column positions than the target.
7273 : * values/nulls/tupdesc can all be NULL if we just want to assign nulls to
7274 : * all fields of the record or row.
7275 : *
7276 : * Since this uses the mcontext for workspace, caller should eventually call
7277 : * exec_eval_cleanup to prevent long-term memory leaks.
7278 : */
7279 : static void
7280 40495 : exec_move_row_from_fields(PLpgSQL_execstate *estate,
7281 : PLpgSQL_variable *target,
7282 : ExpandedRecordHeader *newerh,
7283 : Datum *values, bool *nulls,
7284 : TupleDesc tupdesc)
7285 : {
7286 40495 : int td_natts = tupdesc ? tupdesc->natts : 0;
7287 : int fnum;
7288 : int anum;
7289 40495 : int strict_multiassignment_level = 0;
7290 :
7291 : /*
7292 : * The extra check strict strict_multi_assignment can be active, only when
7293 : * input tupdesc is specified.
7294 : */
7295 40495 : if (tupdesc != NULL)
7296 : {
7297 40370 : if (plpgsql_extra_errors & PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT)
7298 24 : strict_multiassignment_level = ERROR;
7299 40346 : else if (plpgsql_extra_warnings & PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT)
7300 12 : strict_multiassignment_level = WARNING;
7301 : }
7302 :
7303 : /* Handle RECORD-target case */
7304 40495 : if (target->dtype == PLPGSQL_DTYPE_REC)
7305 : {
7306 63 : PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
7307 : TupleDesc var_tupdesc;
7308 : Datum newvalues_local[64];
7309 : bool newnulls_local[64];
7310 :
7311 : Assert(newerh != NULL); /* caller must have built new object */
7312 :
7313 63 : var_tupdesc = expanded_record_get_tupdesc(newerh);
7314 :
7315 : /*
7316 : * Coerce field values if needed. This might involve dealing with
7317 : * different sets of dropped columns and/or coercing individual column
7318 : * types. That's sort of a pain, but historically plpgsql has allowed
7319 : * it, so we preserve the behavior. However, it's worth a quick check
7320 : * to see if the tupdescs are identical. (Since expandedrecord.c
7321 : * prefers to use refcounted tupdescs from the typcache, expanded
7322 : * records with the same rowtype will have pointer-equal tupdescs.)
7323 : */
7324 63 : if (var_tupdesc != tupdesc)
7325 : {
7326 56 : int vtd_natts = var_tupdesc->natts;
7327 : Datum *newvalues;
7328 : bool *newnulls;
7329 :
7330 : /*
7331 : * Need workspace arrays. If vtd_natts is small enough, use local
7332 : * arrays to save doing a palloc. Even if it's not small, we can
7333 : * allocate both the Datum and isnull arrays in one palloc chunk.
7334 : */
7335 56 : if (vtd_natts <= lengthof(newvalues_local))
7336 : {
7337 56 : newvalues = newvalues_local;
7338 56 : newnulls = newnulls_local;
7339 : }
7340 : else
7341 : {
7342 : char *chunk;
7343 :
7344 0 : chunk = eval_mcontext_alloc(estate,
7345 : vtd_natts * (sizeof(Datum) + sizeof(bool)));
7346 0 : newvalues = (Datum *) chunk;
7347 0 : newnulls = (bool *) (chunk + vtd_natts * sizeof(Datum));
7348 : }
7349 :
7350 : /* Walk over destination columns */
7351 56 : anum = 0;
7352 176 : for (fnum = 0; fnum < vtd_natts; fnum++)
7353 : {
7354 125 : Form_pg_attribute attr = TupleDescAttr(var_tupdesc, fnum);
7355 : Datum value;
7356 : bool isnull;
7357 : Oid valtype;
7358 : int32 valtypmod;
7359 :
7360 125 : if (attr->attisdropped)
7361 : {
7362 : /* expanded_record_set_fields should ignore this column */
7363 13 : continue; /* skip dropped column in record */
7364 : }
7365 :
7366 112 : while (anum < td_natts &&
7367 108 : TupleDescAttr(tupdesc, anum)->attisdropped)
7368 0 : anum++; /* skip dropped column in tuple */
7369 :
7370 112 : if (anum < td_natts)
7371 : {
7372 108 : value = values[anum];
7373 108 : isnull = nulls[anum];
7374 108 : valtype = TupleDescAttr(tupdesc, anum)->atttypid;
7375 108 : valtypmod = TupleDescAttr(tupdesc, anum)->atttypmod;
7376 108 : anum++;
7377 : }
7378 : else
7379 : {
7380 : /* no source for destination column */
7381 4 : value = (Datum) 0;
7382 4 : isnull = true;
7383 4 : valtype = UNKNOWNOID;
7384 4 : valtypmod = -1;
7385 :
7386 : /* When source value is missing */
7387 4 : if (strict_multiassignment_level)
7388 4 : ereport(strict_multiassignment_level,
7389 : (errcode(ERRCODE_DATATYPE_MISMATCH),
7390 : errmsg("number of source and target fields in assignment does not match"),
7391 : /* translator: %s represents a name of an extra check */
7392 : errdetail("%s check of %s is active.",
7393 : "strict_multi_assignment",
7394 : strict_multiassignment_level == ERROR ? "extra_errors" :
7395 : "extra_warnings"),
7396 : errhint("Make sure the query returns the exact list of columns.")));
7397 : }
7398 :
7399 : /* Cast the new value to the right type, if needed. */
7400 108 : newvalues[fnum] = exec_cast_value(estate,
7401 : value,
7402 : &isnull,
7403 : valtype,
7404 : valtypmod,
7405 : attr->atttypid,
7406 : attr->atttypmod);
7407 107 : newnulls[fnum] = isnull;
7408 : }
7409 :
7410 : /*
7411 : * When strict_multiassignment extra check is active, then ensure
7412 : * there are no unassigned source attributes.
7413 : */
7414 51 : if (strict_multiassignment_level && anum < td_natts)
7415 : {
7416 : /* skip dropped columns in the source descriptor */
7417 4 : while (anum < td_natts &&
7418 4 : TupleDescAttr(tupdesc, anum)->attisdropped)
7419 0 : anum++;
7420 :
7421 4 : if (anum < td_natts)
7422 4 : ereport(strict_multiassignment_level,
7423 : (errcode(ERRCODE_DATATYPE_MISMATCH),
7424 : errmsg("number of source and target fields in assignment does not match"),
7425 : /* translator: %s represents a name of an extra check */
7426 : errdetail("%s check of %s is active.",
7427 : "strict_multi_assignment",
7428 : strict_multiassignment_level == ERROR ? "extra_errors" :
7429 : "extra_warnings"),
7430 : errhint("Make sure the query returns the exact list of columns.")));
7431 : }
7432 :
7433 47 : values = newvalues;
7434 47 : nulls = newnulls;
7435 : }
7436 :
7437 : /* Insert the coerced field values into the new expanded record */
7438 54 : expanded_record_set_fields(newerh, values, nulls, !estate->atomic);
7439 :
7440 : /* Complete the assignment */
7441 50 : assign_record_var(estate, rec, newerh);
7442 :
7443 50 : return;
7444 : }
7445 :
7446 : /* newerh should not have been passed in non-RECORD cases */
7447 : Assert(newerh == NULL);
7448 :
7449 : /*
7450 : * For a row, we assign the individual field values to the variables the
7451 : * row points to.
7452 : *
7453 : * NOTE: both this code and the record code above silently ignore extra
7454 : * columns in the source and assume NULL for missing columns. This is
7455 : * pretty dubious but it's the historical behavior.
7456 : *
7457 : * If we have no input data at all, we'll assign NULL to all columns of
7458 : * the row variable.
7459 : */
7460 40432 : if (target->dtype == PLPGSQL_DTYPE_ROW)
7461 : {
7462 40432 : PLpgSQL_row *row = (PLpgSQL_row *) target;
7463 :
7464 40432 : anum = 0;
7465 85068 : for (fnum = 0; fnum < row->nfields; fnum++)
7466 : {
7467 : PLpgSQL_var *var;
7468 : Datum value;
7469 : bool isnull;
7470 : Oid valtype;
7471 : int32 valtypmod;
7472 :
7473 44640 : var = (PLpgSQL_var *) (estate->datums[row->varnos[fnum]]);
7474 :
7475 44640 : while (anum < td_natts &&
7476 44503 : TupleDescAttr(tupdesc, anum)->attisdropped)
7477 0 : anum++; /* skip dropped column in tuple */
7478 :
7479 44640 : if (anum < td_natts)
7480 : {
7481 44503 : value = values[anum];
7482 44503 : isnull = nulls[anum];
7483 44503 : valtype = TupleDescAttr(tupdesc, anum)->atttypid;
7484 44503 : valtypmod = TupleDescAttr(tupdesc, anum)->atttypmod;
7485 44503 : anum++;
7486 : }
7487 : else
7488 : {
7489 : /* no source for destination column */
7490 137 : value = (Datum) 0;
7491 137 : isnull = true;
7492 137 : valtype = UNKNOWNOID;
7493 137 : valtypmod = -1;
7494 :
7495 137 : if (strict_multiassignment_level)
7496 8 : ereport(strict_multiassignment_level,
7497 : (errcode(ERRCODE_DATATYPE_MISMATCH),
7498 : errmsg("number of source and target fields in assignment does not match"),
7499 : /* translator: %s represents a name of an extra check */
7500 : errdetail("%s check of %s is active.",
7501 : "strict_multi_assignment",
7502 : strict_multiassignment_level == ERROR ? "extra_errors" :
7503 : "extra_warnings"),
7504 : errhint("Make sure the query returns the exact list of columns.")));
7505 : }
7506 :
7507 44636 : exec_assign_value(estate, (PLpgSQL_datum *) var,
7508 : value, isnull, valtype, valtypmod);
7509 : }
7510 :
7511 : /*
7512 : * When strict_multiassignment extra check is active, ensure there are
7513 : * no unassigned source attributes.
7514 : */
7515 40428 : if (strict_multiassignment_level && anum < td_natts)
7516 : {
7517 8 : while (anum < td_natts &&
7518 8 : TupleDescAttr(tupdesc, anum)->attisdropped)
7519 0 : anum++; /* skip dropped column in tuple */
7520 :
7521 8 : if (anum < td_natts)
7522 8 : ereport(strict_multiassignment_level,
7523 : (errcode(ERRCODE_DATATYPE_MISMATCH),
7524 : errmsg("number of source and target fields in assignment does not match"),
7525 : /* translator: %s represents a name of an extra check */
7526 : errdetail("%s check of %s is active.",
7527 : "strict_multi_assignment",
7528 : strict_multiassignment_level == ERROR ? "extra_errors" :
7529 : "extra_warnings"),
7530 : errhint("Make sure the query returns the exact list of columns.")));
7531 : }
7532 :
7533 40424 : return;
7534 : }
7535 :
7536 0 : elog(ERROR, "unsupported target type: %d", target->dtype);
7537 : }
7538 :
7539 : /*
7540 : * compatible_tupdescs: detect whether two tupdescs are physically compatible
7541 : *
7542 : * TRUE indicates that a tuple satisfying src_tupdesc can be used directly as
7543 : * a value for a composite variable using dst_tupdesc.
7544 : */
7545 : static bool
7546 140 : compatible_tupdescs(TupleDesc src_tupdesc, TupleDesc dst_tupdesc)
7547 : {
7548 : int i;
7549 :
7550 : /* Possibly we could allow src_tupdesc to have extra columns? */
7551 140 : if (dst_tupdesc->natts != src_tupdesc->natts)
7552 13 : return false;
7553 :
7554 339 : for (i = 0; i < dst_tupdesc->natts; i++)
7555 : {
7556 255 : Form_pg_attribute dattr = TupleDescAttr(dst_tupdesc, i);
7557 255 : Form_pg_attribute sattr = TupleDescAttr(src_tupdesc, i);
7558 :
7559 255 : if (dattr->attisdropped != sattr->attisdropped)
7560 4 : return false;
7561 251 : if (!dattr->attisdropped)
7562 : {
7563 : /* Normal columns must match by type and typmod */
7564 251 : if (dattr->atttypid != sattr->atttypid ||
7565 212 : (dattr->atttypmod >= 0 &&
7566 8 : dattr->atttypmod != sattr->atttypmod))
7567 39 : return false;
7568 : }
7569 : else
7570 : {
7571 : /* Dropped columns are OK as long as length/alignment match */
7572 0 : if (dattr->attlen != sattr->attlen ||
7573 0 : dattr->attalign != sattr->attalign)
7574 0 : return false;
7575 : }
7576 : }
7577 84 : return true;
7578 : }
7579 :
7580 : /* ----------
7581 : * make_tuple_from_row Make a tuple from the values of a row object
7582 : *
7583 : * A NULL return indicates rowtype mismatch; caller must raise suitable error
7584 : *
7585 : * The result tuple is freshly palloc'd in caller's context. Some junk
7586 : * may be left behind in eval_mcontext, too.
7587 : * ----------
7588 : */
7589 : static HeapTuple
7590 4192 : make_tuple_from_row(PLpgSQL_execstate *estate,
7591 : PLpgSQL_row *row,
7592 : TupleDesc tupdesc)
7593 : {
7594 4192 : int natts = tupdesc->natts;
7595 : HeapTuple tuple;
7596 : Datum *dvalues;
7597 : bool *nulls;
7598 : int i;
7599 :
7600 4192 : if (natts != row->nfields)
7601 0 : return NULL;
7602 :
7603 4192 : dvalues = (Datum *) eval_mcontext_alloc0(estate, natts * sizeof(Datum));
7604 4192 : nulls = (bool *) eval_mcontext_alloc(estate, natts * sizeof(bool));
7605 :
7606 16578 : for (i = 0; i < natts; i++)
7607 : {
7608 : Oid fieldtypeid;
7609 : int32 fieldtypmod;
7610 :
7611 12386 : if (TupleDescAttr(tupdesc, i)->attisdropped)
7612 : {
7613 0 : nulls[i] = true; /* leave the column as null */
7614 0 : continue;
7615 : }
7616 :
7617 12386 : exec_eval_datum(estate, estate->datums[row->varnos[i]],
7618 : &fieldtypeid, &fieldtypmod,
7619 12386 : &dvalues[i], &nulls[i]);
7620 12386 : if (fieldtypeid != TupleDescAttr(tupdesc, i)->atttypid)
7621 0 : return NULL;
7622 : /* XXX should we insist on typmod match, too? */
7623 : }
7624 :
7625 4192 : tuple = heap_form_tuple(tupdesc, dvalues, nulls);
7626 :
7627 4192 : return tuple;
7628 : }
7629 :
7630 : /*
7631 : * deconstruct_composite_datum extract tuple+tupdesc from composite Datum
7632 : *
7633 : * The caller must supply a HeapTupleData variable, in which we set up a
7634 : * tuple header pointing to the composite datum's body. To make the tuple
7635 : * value outlive that variable, caller would need to apply heap_copytuple...
7636 : * but current callers only need a short-lived tuple value anyway.
7637 : *
7638 : * Returns a pointer to the TupleDesc of the datum's rowtype.
7639 : * Caller is responsible for calling ReleaseTupleDesc when done with it.
7640 : *
7641 : * Note: it's caller's responsibility to be sure value is of composite type.
7642 : * Also, best to call this in a short-lived context, as it might leak memory.
7643 : */
7644 : static TupleDesc
7645 4438 : deconstruct_composite_datum(Datum value, HeapTupleData *tmptup)
7646 : {
7647 : HeapTupleHeader td;
7648 : Oid tupType;
7649 : int32 tupTypmod;
7650 :
7651 : /* Get tuple body (note this could involve detoasting) */
7652 4438 : td = DatumGetHeapTupleHeader(value);
7653 :
7654 : /* Build a temporary HeapTuple control structure */
7655 4438 : tmptup->t_len = HeapTupleHeaderGetDatumLength(td);
7656 4438 : ItemPointerSetInvalid(&(tmptup->t_self));
7657 4438 : tmptup->t_tableOid = InvalidOid;
7658 4438 : tmptup->t_data = td;
7659 :
7660 : /* Extract rowtype info and find a tupdesc */
7661 4438 : tupType = HeapTupleHeaderGetTypeId(td);
7662 4438 : tupTypmod = HeapTupleHeaderGetTypMod(td);
7663 4438 : return lookup_rowtype_tupdesc(tupType, tupTypmod);
7664 : }
7665 :
7666 : /*
7667 : * exec_move_row_from_datum Move a composite Datum into a record or row
7668 : *
7669 : * This is equivalent to deconstruct_composite_datum() followed by
7670 : * exec_move_row(), but we can optimize things if the Datum is an
7671 : * expanded-record reference.
7672 : *
7673 : * Note: it's caller's responsibility to be sure value is of composite type.
7674 : */
7675 : static void
7676 857 : exec_move_row_from_datum(PLpgSQL_execstate *estate,
7677 : PLpgSQL_variable *target,
7678 : Datum value)
7679 : {
7680 : /* Check to see if source is an expanded record */
7681 857 : if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(value)))
7682 : {
7683 166 : ExpandedRecordHeader *erh = (ExpandedRecordHeader *) DatumGetEOHP(value);
7684 166 : ExpandedRecordHeader *newerh = NULL;
7685 :
7686 : Assert(erh->er_magic == ER_MAGIC);
7687 :
7688 : /* These cases apply if the target is record not row... */
7689 166 : if (target->dtype == PLPGSQL_DTYPE_REC)
7690 : {
7691 166 : PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
7692 :
7693 : /*
7694 : * If it's the same record already stored in the variable, do
7695 : * nothing. This would happen only in silly cases like "r := r",
7696 : * but we need some check to avoid possibly freeing the variable's
7697 : * live value below. Note that this applies even if what we have
7698 : * is a R/O pointer.
7699 : */
7700 166 : if (erh == rec->erh)
7701 1 : return;
7702 :
7703 : /*
7704 : * Make sure rec->rectypeid is up-to-date before using it.
7705 : */
7706 165 : revalidate_rectypeid(rec);
7707 :
7708 : /*
7709 : * If we have a R/W pointer, we're allowed to just commandeer
7710 : * ownership of the expanded record. If it's of the right type to
7711 : * put into the record variable, do that. (Note we don't accept
7712 : * an expanded record of a composite-domain type as a RECORD
7713 : * value. We'll treat it as the base composite type instead;
7714 : * compare logic in make_expanded_record_for_rec.)
7715 : */
7716 165 : if (VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(value)) &&
7717 3 : (rec->rectypeid == erh->er_decltypeid ||
7718 1 : (rec->rectypeid == RECORDOID &&
7719 1 : !ExpandedRecordIsDomain(erh))))
7720 : {
7721 3 : assign_record_var(estate, rec, erh);
7722 3 : return;
7723 : }
7724 :
7725 : /*
7726 : * If we already have an expanded record object in the target
7727 : * variable, and the source record contains a valid tuple
7728 : * representation with the right rowtype, then we can skip making
7729 : * a new expanded record and just assign the tuple with
7730 : * expanded_record_set_tuple. (We can't do the equivalent if we
7731 : * have to do field-by-field assignment, since that wouldn't be
7732 : * atomic if there's an error.) We consider that there's a
7733 : * rowtype match only if it's the same named composite type or
7734 : * same registered rowtype; checking for matches of anonymous
7735 : * rowtypes would be more expensive than this is worth.
7736 : */
7737 162 : if (rec->erh &&
7738 4 : (erh->flags & ER_FLAG_FVALUE_VALID) &&
7739 2 : erh->er_typeid == rec->erh->er_typeid &&
7740 1 : (erh->er_typeid != RECORDOID ||
7741 0 : (erh->er_typmod == rec->erh->er_typmod &&
7742 0 : erh->er_typmod >= 0)))
7743 : {
7744 1 : expanded_record_set_tuple(rec->erh, erh->fvalue,
7745 1 : true, !estate->atomic);
7746 1 : return;
7747 : }
7748 :
7749 : /*
7750 : * Otherwise we're gonna need a new expanded record object. Make
7751 : * it here in hopes of piggybacking on the source object's
7752 : * previous typcache lookup.
7753 : */
7754 161 : newerh = make_expanded_record_for_rec(estate, rec, NULL, erh);
7755 :
7756 : /*
7757 : * If the expanded record contains a valid tuple representation,
7758 : * and we don't need rowtype conversion, then just copying the
7759 : * tuple is probably faster than field-by-field processing. (This
7760 : * isn't duplicative of the previous check, since here we will
7761 : * catch the case where the record variable was previously empty.)
7762 : */
7763 161 : if ((erh->flags & ER_FLAG_FVALUE_VALID) &&
7764 152 : (rec->rectypeid == RECORDOID ||
7765 4 : rec->rectypeid == erh->er_typeid))
7766 : {
7767 151 : expanded_record_set_tuple(newerh, erh->fvalue,
7768 151 : true, !estate->atomic);
7769 151 : assign_record_var(estate, rec, newerh);
7770 151 : return;
7771 : }
7772 :
7773 : /*
7774 : * Need to special-case empty source record, else code below would
7775 : * leak newerh.
7776 : */
7777 10 : if (ExpandedRecordIsEmpty(erh))
7778 : {
7779 : /* Set newerh to a row of NULLs */
7780 0 : deconstruct_expanded_record(newerh);
7781 0 : assign_record_var(estate, rec, newerh);
7782 0 : return;
7783 : }
7784 : } /* end of record-target-only cases */
7785 :
7786 : /*
7787 : * If the source expanded record is empty, we should treat that like a
7788 : * NULL tuple value. (We're unlikely to see such a case, but we must
7789 : * check this; deconstruct_expanded_record would cause a change of
7790 : * logical state, which is not OK.)
7791 : */
7792 10 : if (ExpandedRecordIsEmpty(erh))
7793 : {
7794 0 : exec_move_row(estate, target, NULL,
7795 : expanded_record_get_tupdesc(erh));
7796 0 : return;
7797 : }
7798 :
7799 : /*
7800 : * Otherwise, ensure that the source record is deconstructed, and
7801 : * assign from its field values.
7802 : */
7803 10 : deconstruct_expanded_record(erh);
7804 10 : exec_move_row_from_fields(estate, target, newerh,
7805 : erh->dvalues, erh->dnulls,
7806 : expanded_record_get_tupdesc(erh));
7807 : }
7808 : else
7809 : {
7810 : /*
7811 : * Nope, we've got a plain composite Datum. Deconstruct it; but we
7812 : * don't use deconstruct_composite_datum(), because we may be able to
7813 : * skip calling lookup_rowtype_tupdesc().
7814 : */
7815 : HeapTupleHeader td;
7816 : HeapTupleData tmptup;
7817 : Oid tupType;
7818 : int32 tupTypmod;
7819 : TupleDesc tupdesc;
7820 : MemoryContext oldcontext;
7821 :
7822 : /* Ensure that any detoasted data winds up in the eval_mcontext */
7823 691 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
7824 : /* Get tuple body (note this could involve detoasting) */
7825 691 : td = DatumGetHeapTupleHeader(value);
7826 691 : MemoryContextSwitchTo(oldcontext);
7827 :
7828 : /* Build a temporary HeapTuple control structure */
7829 691 : tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
7830 691 : ItemPointerSetInvalid(&(tmptup.t_self));
7831 691 : tmptup.t_tableOid = InvalidOid;
7832 691 : tmptup.t_data = td;
7833 :
7834 : /* Extract rowtype info */
7835 691 : tupType = HeapTupleHeaderGetTypeId(td);
7836 691 : tupTypmod = HeapTupleHeaderGetTypMod(td);
7837 :
7838 : /* Now, if the target is record not row, maybe we can optimize ... */
7839 691 : if (target->dtype == PLPGSQL_DTYPE_REC)
7840 : {
7841 663 : PLpgSQL_rec *rec = (PLpgSQL_rec *) target;
7842 :
7843 : /*
7844 : * If we already have an expanded record object in the target
7845 : * variable, and the source datum has a matching rowtype, then we
7846 : * can skip making a new expanded record and just assign the tuple
7847 : * with expanded_record_set_tuple. We consider that there's a
7848 : * rowtype match only if it's the same named composite type or
7849 : * same registered rowtype. (Checking to reject an anonymous
7850 : * rowtype here should be redundant, but let's be safe.)
7851 : */
7852 663 : if (rec->erh &&
7853 102 : tupType == rec->erh->er_typeid &&
7854 2 : (tupType != RECORDOID ||
7855 2 : (tupTypmod == rec->erh->er_typmod &&
7856 : tupTypmod >= 0)))
7857 : {
7858 88 : expanded_record_set_tuple(rec->erh, &tmptup,
7859 88 : true, !estate->atomic);
7860 613 : return;
7861 : }
7862 :
7863 : /*
7864 : * If the source datum has a rowtype compatible with the target
7865 : * variable, just build a new expanded record and assign the tuple
7866 : * into it. Using make_expanded_record_from_typeid() here saves
7867 : * one typcache lookup compared to the code below.
7868 : */
7869 575 : if (rec->rectypeid == RECORDOID || rec->rectypeid == tupType)
7870 : {
7871 : ExpandedRecordHeader *newerh;
7872 525 : MemoryContext mcontext = get_eval_mcontext(estate);
7873 :
7874 525 : newerh = make_expanded_record_from_typeid(tupType, tupTypmod,
7875 : mcontext);
7876 525 : expanded_record_set_tuple(newerh, &tmptup,
7877 525 : true, !estate->atomic);
7878 525 : assign_record_var(estate, rec, newerh);
7879 525 : return;
7880 : }
7881 :
7882 : /*
7883 : * Otherwise, we're going to need conversion, so fall through to
7884 : * do it the hard way.
7885 : */
7886 : }
7887 :
7888 : /*
7889 : * ROW target, or unoptimizable RECORD target, so we have to expend a
7890 : * lookup to obtain the source datum's tupdesc.
7891 : */
7892 78 : tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
7893 :
7894 : /* Do the move */
7895 78 : exec_move_row(estate, target, &tmptup, tupdesc);
7896 :
7897 : /* Release tupdesc usage count */
7898 71 : ReleaseTupleDesc(tupdesc);
7899 : }
7900 : }
7901 :
7902 : /*
7903 : * If we have not created an expanded record to hold the record variable's
7904 : * value, do so. The expanded record will be "empty", so this does not
7905 : * change the logical state of the record variable: it's still NULL.
7906 : * However, now we'll have a tupdesc with which we can e.g. look up fields.
7907 : */
7908 : static void
7909 64 : instantiate_empty_record_variable(PLpgSQL_execstate *estate, PLpgSQL_rec *rec)
7910 : {
7911 : Assert(rec->erh == NULL); /* else caller error */
7912 :
7913 : /* If declared type is RECORD, we can't instantiate */
7914 64 : if (rec->rectypeid == RECORDOID)
7915 2 : ereport(ERROR,
7916 : (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
7917 : errmsg("record \"%s\" is not assigned yet", rec->refname),
7918 : errdetail("The tuple structure of a not-yet-assigned record is indeterminate.")));
7919 :
7920 : /* Make sure rec->rectypeid is up-to-date before using it */
7921 62 : revalidate_rectypeid(rec);
7922 :
7923 : /* OK, do it */
7924 61 : rec->erh = make_expanded_record_from_typeid(rec->rectypeid, -1,
7925 : estate->datum_context);
7926 61 : }
7927 :
7928 : /* ----------
7929 : * convert_value_to_string Convert a non-null Datum to C string
7930 : *
7931 : * Note: the result is in the estate's eval_mcontext, and will be cleared
7932 : * by the next exec_eval_cleanup() call. The invoked output function might
7933 : * leave additional cruft there as well, so just pfree'ing the result string
7934 : * would not be enough to avoid memory leaks if we did not do it like this.
7935 : * In most usages the Datum being passed in is also in that context (if
7936 : * pass-by-reference) and so an exec_eval_cleanup() call is needed anyway.
7937 : *
7938 : * Note: not caching the conversion function lookup is bad for performance.
7939 : * However, this function isn't currently used in any places where an extra
7940 : * catalog lookup or two seems like a big deal.
7941 : * ----------
7942 : */
7943 : static char *
7944 47601 : convert_value_to_string(PLpgSQL_execstate *estate, Datum value, Oid valtype)
7945 : {
7946 : char *result;
7947 : MemoryContext oldcontext;
7948 : Oid typoutput;
7949 : bool typIsVarlena;
7950 :
7951 47601 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
7952 47601 : getTypeOutputInfo(valtype, &typoutput, &typIsVarlena);
7953 47601 : result = OidOutputFunctionCall(typoutput, value);
7954 47601 : MemoryContextSwitchTo(oldcontext);
7955 :
7956 47601 : return result;
7957 : }
7958 :
7959 : /* ----------
7960 : * exec_cast_value Cast a value if required
7961 : *
7962 : * Note that *isnull is an input and also an output parameter. While it's
7963 : * unlikely that a cast operation would produce null from non-null or vice
7964 : * versa, that could happen in principle.
7965 : *
7966 : * Note: the estate's eval_mcontext is used for temporary storage, and may
7967 : * also contain the result Datum if we have to do a conversion to a pass-
7968 : * by-reference data type. Be sure to do an exec_eval_cleanup() call when
7969 : * done with the result.
7970 : * ----------
7971 : */
7972 : static inline Datum
7973 242088 : exec_cast_value(PLpgSQL_execstate *estate,
7974 : Datum value, bool *isnull,
7975 : Oid valtype, int32 valtypmod,
7976 : Oid reqtype, int32 reqtypmod)
7977 : {
7978 : /*
7979 : * If the type of the given value isn't what's requested, convert it.
7980 : */
7981 242088 : if (valtype != reqtype ||
7982 0 : (valtypmod != reqtypmod && reqtypmod != -1))
7983 : {
7984 : /* We keep the slow path out-of-line. */
7985 2108 : value = do_cast_value(estate, value, isnull, valtype, valtypmod,
7986 : reqtype, reqtypmod);
7987 : }
7988 :
7989 242048 : return value;
7990 : }
7991 :
7992 : /* ----------
7993 : * do_cast_value Slow path for exec_cast_value.
7994 : * ----------
7995 : */
7996 : static Datum
7997 2108 : do_cast_value(PLpgSQL_execstate *estate,
7998 : Datum value, bool *isnull,
7999 : Oid valtype, int32 valtypmod,
8000 : Oid reqtype, int32 reqtypmod)
8001 : {
8002 : plpgsql_CastHashEntry *cast_entry;
8003 :
8004 2108 : cast_entry = get_cast_hashentry(estate,
8005 : valtype, valtypmod,
8006 : reqtype, reqtypmod);
8007 2108 : if (cast_entry)
8008 : {
8009 2108 : ExprContext *econtext = estate->eval_econtext;
8010 : MemoryContext oldcontext;
8011 :
8012 2108 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
8013 :
8014 2108 : econtext->caseValue_datum = value;
8015 2108 : econtext->caseValue_isNull = *isnull;
8016 :
8017 2108 : cast_entry->cast_in_use = true;
8018 :
8019 2108 : value = ExecEvalExpr(cast_entry->cast_exprstate, econtext,
8020 : isnull);
8021 :
8022 2068 : cast_entry->cast_in_use = false;
8023 :
8024 2068 : MemoryContextSwitchTo(oldcontext);
8025 : }
8026 :
8027 2068 : return value;
8028 : }
8029 :
8030 : /* ----------
8031 : * get_cast_hashentry Look up how to perform a type cast
8032 : *
8033 : * Returns a plpgsql_CastHashEntry if an expression has to be evaluated,
8034 : * or NULL if the cast is a mere no-op relabeling. If there's work to be
8035 : * done, the cast_exprstate field contains an expression evaluation tree
8036 : * based on a CaseTestExpr input, and the cast_in_use field should be set
8037 : * true while executing it.
8038 : * ----------
8039 : */
8040 : static plpgsql_CastHashEntry *
8041 2108 : get_cast_hashentry(PLpgSQL_execstate *estate,
8042 : Oid srctype, int32 srctypmod,
8043 : Oid dsttype, int32 dsttypmod)
8044 : {
8045 : plpgsql_CastHashKey cast_key;
8046 : plpgsql_CastHashEntry *cast_entry;
8047 : plpgsql_CastExprHashEntry *expr_entry;
8048 : bool found;
8049 : LocalTransactionId curlxid;
8050 : MemoryContext oldcontext;
8051 :
8052 : /* Look for existing entry */
8053 2108 : cast_key.srctype = srctype;
8054 2108 : cast_key.dsttype = dsttype;
8055 2108 : cast_key.srctypmod = srctypmod;
8056 2108 : cast_key.dsttypmod = dsttypmod;
8057 2108 : cast_entry = (plpgsql_CastHashEntry *) hash_search(estate->cast_hash,
8058 : &cast_key,
8059 : HASH_ENTER, &found);
8060 2108 : if (!found) /* initialize if new entry */
8061 : {
8062 : /* We need a second lookup to see if a cast_expr_hash entry exists */
8063 248 : expr_entry = (plpgsql_CastExprHashEntry *) hash_search(cast_expr_hash,
8064 : &cast_key,
8065 : HASH_ENTER,
8066 : &found);
8067 248 : if (!found) /* initialize if new expr entry */
8068 211 : expr_entry->cast_cexpr = NULL;
8069 :
8070 248 : cast_entry->cast_centry = expr_entry;
8071 248 : cast_entry->cast_exprstate = NULL;
8072 248 : cast_entry->cast_in_use = false;
8073 248 : cast_entry->cast_lxid = InvalidLocalTransactionId;
8074 : }
8075 : else
8076 : {
8077 : /* Use always-valid link to avoid a second hash lookup */
8078 1860 : expr_entry = cast_entry->cast_centry;
8079 : }
8080 :
8081 2108 : if (expr_entry->cast_cexpr == NULL ||
8082 1897 : !expr_entry->cast_cexpr->is_valid)
8083 : {
8084 : /*
8085 : * We've not looked up this coercion before, or we have but the cached
8086 : * expression has been invalidated.
8087 : */
8088 : Node *cast_expr;
8089 : CachedExpression *cast_cexpr;
8090 : CaseTestExpr *placeholder;
8091 :
8092 : /*
8093 : * Drop old cached expression if there is one.
8094 : */
8095 254 : if (expr_entry->cast_cexpr)
8096 : {
8097 43 : FreeCachedExpression(expr_entry->cast_cexpr);
8098 43 : expr_entry->cast_cexpr = NULL;
8099 : }
8100 :
8101 : /*
8102 : * Since we could easily fail (no such coercion), construct a
8103 : * temporary coercion expression tree in the short-lived
8104 : * eval_mcontext, then if successful save it as a CachedExpression.
8105 : */
8106 254 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
8107 :
8108 : /*
8109 : * We use a CaseTestExpr as the base of the coercion tree, since it's
8110 : * very cheap to insert the source value for that.
8111 : */
8112 254 : placeholder = makeNode(CaseTestExpr);
8113 254 : placeholder->typeId = srctype;
8114 254 : placeholder->typeMod = srctypmod;
8115 254 : placeholder->collation = get_typcollation(srctype);
8116 :
8117 : /*
8118 : * Apply coercion. We use the special coercion context
8119 : * COERCION_PLPGSQL to match plpgsql's historical behavior, namely
8120 : * that any cast not available at ASSIGNMENT level will be implemented
8121 : * as an I/O coercion. (It's somewhat dubious that we prefer I/O
8122 : * coercion over cast pathways that exist at EXPLICIT level. Changing
8123 : * that would cause assorted minor behavioral differences though, and
8124 : * a user who wants the explicit-cast behavior can always write an
8125 : * explicit cast.)
8126 : *
8127 : * If source type is UNKNOWN, coerce_to_target_type will fail (it only
8128 : * expects to see that for Const input nodes), so don't call it; we'll
8129 : * apply CoerceViaIO instead. Likewise, it doesn't currently work for
8130 : * coercing RECORD to some other type, so skip for that too.
8131 : */
8132 254 : if (srctype == UNKNOWNOID || srctype == RECORDOID)
8133 74 : cast_expr = NULL;
8134 : else
8135 180 : cast_expr = coerce_to_target_type(NULL,
8136 : (Node *) placeholder, srctype,
8137 : dsttype, dsttypmod,
8138 : COERCION_PLPGSQL,
8139 : COERCE_IMPLICIT_CAST,
8140 : -1);
8141 :
8142 : /*
8143 : * If there's no cast path according to the parser, fall back to using
8144 : * an I/O coercion; this is semantically dubious but matches plpgsql's
8145 : * historical behavior. We would need something of the sort for
8146 : * UNKNOWN literals in any case. (This is probably now only reachable
8147 : * in the case where srctype is UNKNOWN/RECORD.)
8148 : */
8149 254 : if (cast_expr == NULL)
8150 : {
8151 74 : CoerceViaIO *iocoerce = makeNode(CoerceViaIO);
8152 :
8153 74 : iocoerce->arg = (Expr *) placeholder;
8154 74 : iocoerce->resulttype = dsttype;
8155 74 : iocoerce->resultcollid = InvalidOid;
8156 74 : iocoerce->coerceformat = COERCE_IMPLICIT_CAST;
8157 74 : iocoerce->location = -1;
8158 74 : cast_expr = (Node *) iocoerce;
8159 74 : if (dsttypmod != -1)
8160 0 : cast_expr = coerce_to_target_type(NULL,
8161 : cast_expr, dsttype,
8162 : dsttype, dsttypmod,
8163 : COERCION_ASSIGNMENT,
8164 : COERCE_IMPLICIT_CAST,
8165 : -1);
8166 : }
8167 :
8168 : /* Note: we don't bother labeling the expression tree with collation */
8169 :
8170 : /* Plan the expression and build a CachedExpression */
8171 254 : cast_cexpr = GetCachedExpression(cast_expr);
8172 254 : cast_expr = cast_cexpr->expr;
8173 :
8174 : /* Detect whether we have a no-op (RelabelType) coercion */
8175 254 : if (IsA(cast_expr, RelabelType) &&
8176 14 : ((RelabelType *) cast_expr)->arg == (Expr *) placeholder)
8177 0 : cast_expr = NULL;
8178 :
8179 : /* Now we can fill in the expression hashtable entry. */
8180 254 : expr_entry->cast_cexpr = cast_cexpr;
8181 254 : expr_entry->cast_expr = (Expr *) cast_expr;
8182 :
8183 : /* Be sure to reset the exprstate hashtable entry, too. */
8184 254 : cast_entry->cast_exprstate = NULL;
8185 254 : cast_entry->cast_in_use = false;
8186 254 : cast_entry->cast_lxid = InvalidLocalTransactionId;
8187 :
8188 254 : MemoryContextSwitchTo(oldcontext);
8189 : }
8190 :
8191 : /* Done if we have determined that this is a no-op cast. */
8192 2108 : if (expr_entry->cast_expr == NULL)
8193 0 : return NULL;
8194 :
8195 : /*
8196 : * Prepare the expression for execution, if it's not been done already in
8197 : * the current transaction; also, if it's marked busy in the current
8198 : * transaction, abandon that expression tree and build a new one, so as to
8199 : * avoid potential problems with recursive cast expressions and failed
8200 : * executions. (We will leak some memory intra-transaction if that
8201 : * happens a lot, but we don't expect it to.) It's okay to update the
8202 : * hash table with the new tree because all plpgsql functions within a
8203 : * given transaction share the same simple_eval_estate. (Well, regular
8204 : * functions do; DO blocks have private simple_eval_estates, and private
8205 : * cast hash tables to go with them.)
8206 : */
8207 2108 : curlxid = MyProc->vxid.lxid;
8208 2108 : if (cast_entry->cast_lxid != curlxid || cast_entry->cast_in_use)
8209 : {
8210 473 : oldcontext = MemoryContextSwitchTo(estate->simple_eval_estate->es_query_cxt);
8211 473 : cast_entry->cast_exprstate = ExecInitExpr(expr_entry->cast_expr, NULL);
8212 473 : cast_entry->cast_in_use = false;
8213 473 : cast_entry->cast_lxid = curlxid;
8214 473 : MemoryContextSwitchTo(oldcontext);
8215 : }
8216 :
8217 2108 : return cast_entry;
8218 : }
8219 :
8220 :
8221 : /* ----------
8222 : * exec_simple_check_plan - Check if a plan is simple enough to
8223 : * be evaluated by ExecEvalExpr() instead
8224 : * of SPI.
8225 : *
8226 : * Note: the refcount manipulations in this function assume that expr->plan
8227 : * is a "saved" SPI plan. That's a bit annoying from the caller's standpoint,
8228 : * but it's otherwise difficult to avoid leaking the plan on failure.
8229 : * ----------
8230 : */
8231 : static void
8232 17016 : exec_simple_check_plan(PLpgSQL_execstate *estate, PLpgSQL_expr *expr)
8233 : {
8234 : List *plansources;
8235 : CachedPlanSource *plansource;
8236 : CachedPlan *cplan;
8237 : MemoryContext oldcontext;
8238 :
8239 : /*
8240 : * Initialize to "not simple", and reset R/W optimizability.
8241 : */
8242 17016 : expr->expr_simple_expr = NULL;
8243 17016 : expr->expr_rwopt = PLPGSQL_RWOPT_UNKNOWN;
8244 17016 : expr->expr_rw_param = NULL;
8245 :
8246 : /*
8247 : * Check the analyzed-and-rewritten form of the query to see if we will be
8248 : * able to treat it as a simple expression. Since this function is only
8249 : * called immediately after creating the CachedPlanSource, we need not
8250 : * worry about the query being stale.
8251 : */
8252 17016 : if (!exec_is_simple_query(expr))
8253 2361 : return;
8254 :
8255 : /* exec_is_simple_query verified that there's just one CachedPlanSource */
8256 14655 : plansources = SPI_plan_get_plan_sources(expr->plan);
8257 14655 : plansource = (CachedPlanSource *) linitial(plansources);
8258 :
8259 : /*
8260 : * Get the generic plan for the query. If replanning is needed, do that
8261 : * work in the eval_mcontext. (Note that replanning could throw an error,
8262 : * in which case the expr is left marked "not simple", which is fine.)
8263 : */
8264 14655 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
8265 14655 : cplan = SPI_plan_get_cached_plan(expr->plan);
8266 14630 : MemoryContextSwitchTo(oldcontext);
8267 :
8268 : /* Can't fail, because we checked for a single CachedPlanSource above */
8269 : Assert(cplan != NULL);
8270 :
8271 : /*
8272 : * Verify that plancache.c thinks the plan is simple enough to use
8273 : * CachedPlanIsSimplyValid. Given the restrictions above, it's unlikely
8274 : * that this could fail, but if it does, just treat plan as not simple. On
8275 : * success, save a refcount on the plan in the simple-expression resowner.
8276 : */
8277 14630 : if (CachedPlanAllowsSimpleValidityCheck(plansource, cplan,
8278 : estate->simple_eval_resowner))
8279 : {
8280 : /* Remember that we have the refcount */
8281 14630 : expr->expr_simple_plansource = plansource;
8282 14630 : expr->expr_simple_plan = cplan;
8283 14630 : expr->expr_simple_plan_lxid = MyProc->vxid.lxid;
8284 :
8285 : /* Share the remaining work with the replan code path */
8286 14630 : exec_save_simple_expr(expr, cplan);
8287 : }
8288 :
8289 : /*
8290 : * Release the plan refcount obtained by SPI_plan_get_cached_plan. (This
8291 : * refcount is held by the wrong resowner, so we can't just repurpose it.)
8292 : */
8293 14630 : ReleaseCachedPlan(cplan, CurrentResourceOwner);
8294 : }
8295 :
8296 : /*
8297 : * exec_is_simple_query - precheck a query tree to see if it might be simple
8298 : *
8299 : * Check the analyzed-and-rewritten form of a query to see if we will be
8300 : * able to treat it as a simple expression. It is caller's responsibility
8301 : * that the CachedPlanSource be up-to-date.
8302 : */
8303 : static bool
8304 20306 : exec_is_simple_query(PLpgSQL_expr *expr)
8305 : {
8306 : List *plansources;
8307 : CachedPlanSource *plansource;
8308 : Query *query;
8309 :
8310 : /*
8311 : * We can only test queries that resulted in exactly one CachedPlanSource.
8312 : */
8313 20306 : plansources = SPI_plan_get_plan_sources(expr->plan);
8314 20306 : if (list_length(plansources) != 1)
8315 0 : return false;
8316 20306 : plansource = (CachedPlanSource *) linitial(plansources);
8317 :
8318 : /*
8319 : * 1. There must be one single querytree.
8320 : */
8321 20306 : if (list_length(plansource->query_list) != 1)
8322 0 : return false;
8323 20306 : query = (Query *) linitial(plansource->query_list);
8324 :
8325 : /*
8326 : * 2. It must be a plain SELECT query without any input tables.
8327 : */
8328 20306 : if (!IsA(query, Query))
8329 0 : return false;
8330 20306 : if (query->commandType != CMD_SELECT)
8331 1214 : return false;
8332 19092 : if (query->rtable != NIL)
8333 720 : return false;
8334 :
8335 : /*
8336 : * 3. Can't have any subplans, aggregates, qual clauses either. (These
8337 : * tests should generally match what inline_function() checks before
8338 : * inlining a SQL function; otherwise, inlining could change our
8339 : * conclusion about whether an expression is simple, which we don't want.)
8340 : */
8341 18372 : if (query->hasAggs ||
8342 18372 : query->hasWindowFuncs ||
8343 18372 : query->hasTargetSRFs ||
8344 18346 : query->hasSubLinks ||
8345 18021 : query->cteList ||
8346 18021 : query->jointree->fromlist ||
8347 18021 : query->jointree->quals ||
8348 18021 : query->groupClause ||
8349 18021 : query->groupingSets ||
8350 18021 : query->havingQual ||
8351 18021 : query->windowClause ||
8352 18021 : query->distinctClause ||
8353 18021 : query->sortClause ||
8354 18021 : query->limitOffset ||
8355 18021 : query->limitCount ||
8356 18021 : query->setOperations)
8357 351 : return false;
8358 :
8359 : /*
8360 : * 4. The query must have a single attribute as result.
8361 : */
8362 18021 : if (list_length(query->targetList) != 1)
8363 77 : return false;
8364 :
8365 : /*
8366 : * OK, we can treat it as a simple plan.
8367 : */
8368 17944 : return true;
8369 : }
8370 :
8371 : /*
8372 : * exec_save_simple_expr --- extract simple expression from CachedPlan
8373 : */
8374 : static void
8375 17919 : exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan)
8376 : {
8377 : PlannedStmt *stmt;
8378 : Plan *plan;
8379 : Expr *tle_expr;
8380 :
8381 : /*
8382 : * Given the checks that exec_simple_check_plan did, none of the Asserts
8383 : * here should ever fail.
8384 : */
8385 :
8386 : /* Extract the single PlannedStmt */
8387 : Assert(list_length(cplan->stmt_list) == 1);
8388 17919 : stmt = linitial_node(PlannedStmt, cplan->stmt_list);
8389 : Assert(stmt->commandType == CMD_SELECT);
8390 :
8391 : /*
8392 : * Ordinarily, the plan node should be a simple Result. However, if
8393 : * debug_parallel_query is on, the planner might've stuck a Gather node
8394 : * atop that; and/or if this plan is for a scrollable cursor, the planner
8395 : * might've stuck a Material node atop it. The simplest way to deal with
8396 : * this is to look through the Gather and/or Material nodes. The upper
8397 : * node's tlist would normally contain a Var referencing the child node's
8398 : * output ... but setrefs.c might also have copied a Const as-is.
8399 : */
8400 17919 : plan = stmt->planTree;
8401 : for (;;)
8402 : {
8403 : /* Extract the single tlist expression */
8404 0 : Assert(list_length(plan->targetlist) == 1);
8405 17919 : tle_expr = linitial_node(TargetEntry, plan->targetlist)->expr;
8406 :
8407 17919 : if (IsA(plan, Result))
8408 : {
8409 : Assert(plan->lefttree == NULL &&
8410 : plan->righttree == NULL &&
8411 : plan->initPlan == NULL &&
8412 : plan->qual == NULL &&
8413 : ((Result *) plan)->resconstantqual == NULL);
8414 17918 : break;
8415 : }
8416 1 : else if (IsA(plan, Gather) || IsA(plan, Material))
8417 : {
8418 : Assert(plan->lefttree != NULL &&
8419 : plan->righttree == NULL &&
8420 : plan->initPlan == NULL &&
8421 : plan->qual == NULL);
8422 : /* If setrefs.c copied up a Const, no need to look further */
8423 1 : if (IsA(tle_expr, Const))
8424 1 : break;
8425 : /* Otherwise, it better be an outer Var */
8426 : Assert(IsA(tle_expr, Var));
8427 : Assert(((Var *) tle_expr)->varno == OUTER_VAR);
8428 : /* Descend to the child node */
8429 0 : plan = plan->lefttree;
8430 : }
8431 : else
8432 0 : elog(ERROR, "unexpected plan node type: %d",
8433 : (int) nodeTag(plan));
8434 : }
8435 :
8436 : /*
8437 : * Save the simple expression, and initialize state to "not valid in
8438 : * current transaction".
8439 : */
8440 17919 : expr->expr_simple_expr = tle_expr;
8441 17919 : expr->expr_simple_state = NULL;
8442 17919 : expr->expr_simple_in_use = false;
8443 17919 : expr->expr_simple_lxid = InvalidLocalTransactionId;
8444 : /* Also stash away the expression result type */
8445 17919 : expr->expr_simple_type = exprType((Node *) tle_expr);
8446 17919 : expr->expr_simple_typmod = exprTypmod((Node *) tle_expr);
8447 : /* We also want to remember if it is immutable or not */
8448 17919 : expr->expr_simple_mutable = contain_mutable_functions((Node *) tle_expr);
8449 17919 : }
8450 :
8451 : /*
8452 : * exec_check_rw_parameter --- can we pass expanded object as read/write param?
8453 : *
8454 : * There are two separate cases in which we can optimize an update to a
8455 : * variable that has a read/write expanded value by letting the called
8456 : * expression operate directly on the expanded value. In both cases we
8457 : * are considering assignments like "var := array_append(var, foo)" where
8458 : * the assignment target is also an input to the RHS expression.
8459 : *
8460 : * Case 1 (RWOPT_TRANSFER rule): if the variable is "local" in the sense that
8461 : * its declaration is not outside any BEGIN...EXCEPTION block surrounding the
8462 : * assignment, then we do not need to worry about preserving its value if the
8463 : * RHS expression throws an error. If in addition the variable is referenced
8464 : * exactly once in the RHS expression, then we can optimize by converting the
8465 : * read/write expanded value into a transient value within the expression
8466 : * evaluation context, and then setting the variable's recorded value to NULL
8467 : * to prevent double-free attempts. This works regardless of any other
8468 : * details of the RHS expression. If the expression eventually returns that
8469 : * same expanded object (possibly modified) then the variable will re-acquire
8470 : * ownership; while if it returns something else or throws an error, the
8471 : * expanded object will be discarded as part of cleanup of the evaluation
8472 : * context.
8473 : *
8474 : * Case 2 (RWOPT_INPLACE rule): if we have a non-local assignment or if
8475 : * it looks like "var := array_append(var, var[1])" with multiple references
8476 : * to the target variable, then we can't use case 1. Nonetheless, if the
8477 : * top-level function is trusted not to corrupt its argument in case of an
8478 : * error, then when the var has an expanded object as value, it is safe to
8479 : * pass the value as a read/write pointer to the top-level function and let
8480 : * the function modify the value in-place. (Any other references have to be
8481 : * passed as read-only pointers as usual.) Only the top-level function has to
8482 : * be trusted, since if anything further down fails, the object hasn't been
8483 : * modified yet.
8484 : *
8485 : * This function checks to see if the assignment is optimizable according
8486 : * to either rule, and updates expr->expr_rwopt accordingly. In addition,
8487 : * it sets expr->expr_rw_param to the address of the Param within the
8488 : * expression that can be passed as read/write (there can be only one);
8489 : * or to NULL when there is no safe Param.
8490 : *
8491 : * Note that this mechanism intentionally allows just one Param to emit a
8492 : * read/write pointer; in case 2, the expression could contain other Params
8493 : * referencing the target variable, but those must be treated as read-only.
8494 : *
8495 : * Also note that we only apply this optimization within simple expressions.
8496 : * There's no point in it for non-simple expressions, because the
8497 : * exec_run_select code path will flatten any expanded result anyway.
8498 : */
8499 : static void
8500 65 : exec_check_rw_parameter(PLpgSQL_expr *expr, int paramid)
8501 : {
8502 65 : Expr *sexpr = expr->expr_simple_expr;
8503 : Oid funcid;
8504 : List *fargs;
8505 : Oid prosupport;
8506 :
8507 : /* Assume unsafe */
8508 65 : expr->expr_rwopt = PLPGSQL_RWOPT_NOPE;
8509 65 : expr->expr_rw_param = NULL;
8510 :
8511 : /* Shouldn't be here for non-simple expression */
8512 : Assert(sexpr != NULL);
8513 :
8514 : /* Param should match the expression's assignment target, too */
8515 : Assert(paramid == expr->target_param + 1);
8516 :
8517 : /*
8518 : * If the assignment is to a "local" variable (one whose value won't
8519 : * matter anymore if expression evaluation fails), and this Param is the
8520 : * only reference to that variable in the expression, then we can
8521 : * unconditionally optimize using the "transfer" method.
8522 : */
8523 65 : if (expr->target_is_local)
8524 : {
8525 : count_param_references_context context;
8526 :
8527 : /* See how many references there are, and find one of them */
8528 65 : context.paramid = paramid;
8529 65 : context.count = 0;
8530 65 : context.last_param = NULL;
8531 65 : (void) count_param_references((Node *) sexpr, &context);
8532 :
8533 : /* If we're here, the expr must contain some reference to the var */
8534 : Assert(context.count > 0);
8535 :
8536 : /* If exactly one reference, success! */
8537 65 : if (context.count == 1)
8538 : {
8539 61 : expr->expr_rwopt = PLPGSQL_RWOPT_TRANSFER;
8540 61 : expr->expr_rw_param = context.last_param;
8541 61 : return;
8542 : }
8543 : }
8544 :
8545 : /*
8546 : * Otherwise, see if we can trust the expression's top-level function to
8547 : * apply the "inplace" method.
8548 : *
8549 : * Top level of expression must be a simple FuncExpr, OpExpr, or
8550 : * SubscriptingRef, else we can't identify which function is relevant. But
8551 : * it's okay to look through any RelabelType above that, since that can't
8552 : * fail.
8553 : */
8554 4 : if (IsA(sexpr, RelabelType))
8555 0 : sexpr = ((RelabelType *) sexpr)->arg;
8556 4 : if (IsA(sexpr, FuncExpr))
8557 : {
8558 0 : FuncExpr *fexpr = (FuncExpr *) sexpr;
8559 :
8560 0 : funcid = fexpr->funcid;
8561 0 : fargs = fexpr->args;
8562 : }
8563 4 : else if (IsA(sexpr, OpExpr))
8564 : {
8565 3 : OpExpr *opexpr = (OpExpr *) sexpr;
8566 :
8567 3 : funcid = opexpr->opfuncid;
8568 3 : fargs = opexpr->args;
8569 : }
8570 1 : else if (IsA(sexpr, SubscriptingRef))
8571 : {
8572 1 : SubscriptingRef *sbsref = (SubscriptingRef *) sexpr;
8573 :
8574 1 : funcid = get_typsubscript(sbsref->refcontainertype, NULL);
8575 :
8576 : /*
8577 : * We assume that only the refexpr and refassgnexpr (if any) are
8578 : * relevant to the support function's decision. If that turns out to
8579 : * be a bad idea, we could incorporate the subscript expressions into
8580 : * the fargs list somehow.
8581 : */
8582 1 : fargs = list_make2(sbsref->refexpr, sbsref->refassgnexpr);
8583 : }
8584 : else
8585 0 : return;
8586 :
8587 : /*
8588 : * The top-level function must be one that can handle in-place update
8589 : * safely. We allow functions to declare their ability to do that via a
8590 : * support function request.
8591 : */
8592 4 : prosupport = get_func_support(funcid);
8593 4 : if (OidIsValid(prosupport))
8594 : {
8595 : SupportRequestModifyInPlace req;
8596 : Param *param;
8597 :
8598 3 : req.type = T_SupportRequestModifyInPlace;
8599 3 : req.funcid = funcid;
8600 3 : req.args = fargs;
8601 3 : req.paramid = paramid;
8602 :
8603 : param = (Param *)
8604 3 : DatumGetPointer(OidFunctionCall1(prosupport,
8605 : PointerGetDatum(&req)));
8606 :
8607 3 : if (param == NULL)
8608 0 : return; /* support function fails */
8609 :
8610 : /* Verify support function followed the API */
8611 : Assert(IsA(param, Param));
8612 : Assert(param->paramkind == PARAM_EXTERN);
8613 : Assert(param->paramid == paramid);
8614 :
8615 : /* Found the Param we want to pass as read/write */
8616 3 : expr->expr_rwopt = PLPGSQL_RWOPT_INPLACE;
8617 3 : expr->expr_rw_param = param;
8618 3 : return;
8619 : }
8620 : }
8621 :
8622 : /*
8623 : * Count Params referencing the specified paramid, and return one of them
8624 : * if there are any.
8625 : *
8626 : * We actually only need to distinguish 0, 1, and N references; so we can
8627 : * abort the tree traversal as soon as we've found two.
8628 : */
8629 : static bool
8630 307 : count_param_references(Node *node, count_param_references_context *context)
8631 : {
8632 307 : if (node == NULL)
8633 1 : return false;
8634 306 : else if (IsA(node, Param))
8635 : {
8636 110 : Param *param = (Param *) node;
8637 :
8638 110 : if (param->paramkind == PARAM_EXTERN &&
8639 110 : param->paramid == context->paramid)
8640 : {
8641 69 : context->last_param = param;
8642 69 : if (++(context->count) > 1)
8643 4 : return true; /* abort tree traversal */
8644 : }
8645 106 : return false;
8646 : }
8647 : else
8648 196 : return expression_tree_walker(node, count_param_references, context);
8649 : }
8650 :
8651 : /*
8652 : * exec_check_assignable --- is it OK to assign to the indicated datum?
8653 : *
8654 : * This should match pl_gram.y's check_assignable().
8655 : */
8656 : static void
8657 181 : exec_check_assignable(PLpgSQL_execstate *estate, int dno)
8658 : {
8659 : PLpgSQL_datum *datum;
8660 :
8661 : Assert(dno >= 0 && dno < estate->ndatums);
8662 181 : datum = estate->datums[dno];
8663 181 : switch (datum->dtype)
8664 : {
8665 179 : case PLPGSQL_DTYPE_VAR:
8666 : case PLPGSQL_DTYPE_PROMISE:
8667 : case PLPGSQL_DTYPE_REC:
8668 179 : if (((PLpgSQL_variable *) datum)->isconst)
8669 5 : ereport(ERROR,
8670 : (errcode(ERRCODE_ERROR_IN_ASSIGNMENT),
8671 : errmsg("variable \"%s\" is declared CONSTANT",
8672 : ((PLpgSQL_variable *) datum)->refname)));
8673 174 : break;
8674 0 : case PLPGSQL_DTYPE_ROW:
8675 : /* always assignable; member vars were checked at compile time */
8676 0 : break;
8677 2 : case PLPGSQL_DTYPE_RECFIELD:
8678 : /* assignable if parent record is */
8679 2 : exec_check_assignable(estate,
8680 : ((PLpgSQL_recfield *) datum)->recparentno);
8681 2 : break;
8682 0 : default:
8683 0 : elog(ERROR, "unrecognized dtype: %d", datum->dtype);
8684 : break;
8685 : }
8686 176 : }
8687 :
8688 : /* ----------
8689 : * exec_set_found Set the global found variable to true/false
8690 : * ----------
8691 : */
8692 : static void
8693 94961 : exec_set_found(PLpgSQL_execstate *estate, bool state)
8694 : {
8695 : PLpgSQL_var *var;
8696 :
8697 94961 : var = (PLpgSQL_var *) (estate->datums[estate->found_varno]);
8698 :
8699 : /*
8700 : * Use pg_assume() to avoid a spurious warning with some compilers, by
8701 : * telling the compiler that the VARATT_IS_EXTERNAL_NON_EXPANDED() branch
8702 : * in assign_simple_var() will never be reached when called from here, due
8703 : * to "found" being a boolean (i.e. a byvalue type), not a varlena.
8704 : */
8705 94961 : pg_assume(var->datatype->typlen != -1);
8706 :
8707 94961 : assign_simple_var(estate, var, BoolGetDatum(state), false, false);
8708 94961 : }
8709 :
8710 : /*
8711 : * plpgsql_create_econtext --- create an eval_econtext for the current function
8712 : *
8713 : * We may need to create a new shared_simple_eval_estate too, if there's not
8714 : * one already for the current transaction. The EState will be cleaned up at
8715 : * transaction end. Ditto for shared_simple_eval_resowner.
8716 : */
8717 : static void
8718 65201 : plpgsql_create_econtext(PLpgSQL_execstate *estate)
8719 : {
8720 : SimpleEcontextStackEntry *entry;
8721 :
8722 : /*
8723 : * Create an EState for evaluation of simple expressions, if there's not
8724 : * one already in the current transaction. The EState is made a child of
8725 : * TopTransactionContext so it will have the right lifespan.
8726 : *
8727 : * Note that this path is never taken when beginning a DO block; the
8728 : * required EState was already made by plpgsql_inline_handler. However,
8729 : * if the DO block executes COMMIT or ROLLBACK, then we'll come here and
8730 : * make a shared EState to use for the rest of the DO block. That's OK;
8731 : * see the comments for shared_simple_eval_estate. (Note also that a DO
8732 : * block will continue to use its private cast hash table for the rest of
8733 : * the block. That's okay for now, but it might cause problems someday.)
8734 : */
8735 65201 : if (estate->simple_eval_estate == NULL)
8736 : {
8737 : MemoryContext oldcontext;
8738 :
8739 10250 : if (shared_simple_eval_estate == NULL)
8740 : {
8741 10246 : oldcontext = MemoryContextSwitchTo(TopTransactionContext);
8742 10246 : shared_simple_eval_estate = CreateExecutorState();
8743 10246 : MemoryContextSwitchTo(oldcontext);
8744 : }
8745 10250 : estate->simple_eval_estate = shared_simple_eval_estate;
8746 : }
8747 :
8748 : /*
8749 : * Likewise for the simple-expression resource owner.
8750 : */
8751 65201 : if (estate->simple_eval_resowner == NULL)
8752 : {
8753 10250 : if (shared_simple_eval_resowner == NULL)
8754 10246 : shared_simple_eval_resowner =
8755 10246 : ResourceOwnerCreate(TopTransactionResourceOwner,
8756 : "PL/pgSQL simple expressions");
8757 10250 : estate->simple_eval_resowner = shared_simple_eval_resowner;
8758 : }
8759 :
8760 : /*
8761 : * Create a child econtext for the current function.
8762 : */
8763 65201 : estate->eval_econtext = CreateExprContext(estate->simple_eval_estate);
8764 :
8765 : /*
8766 : * Make a stack entry so we can clean up the econtext at subxact end.
8767 : * Stack entries are kept in TopTransactionContext for simplicity.
8768 : */
8769 : entry = (SimpleEcontextStackEntry *)
8770 65201 : MemoryContextAlloc(TopTransactionContext,
8771 : sizeof(SimpleEcontextStackEntry));
8772 :
8773 65201 : entry->stack_econtext = estate->eval_econtext;
8774 65201 : entry->xact_subxid = GetCurrentSubTransactionId();
8775 :
8776 65201 : entry->next = simple_econtext_stack;
8777 65201 : simple_econtext_stack = entry;
8778 65201 : }
8779 :
8780 : /*
8781 : * plpgsql_destroy_econtext --- destroy function's econtext
8782 : *
8783 : * We check that it matches the top stack entry, and destroy the stack
8784 : * entry along with the context.
8785 : */
8786 : static void
8787 53628 : plpgsql_destroy_econtext(PLpgSQL_execstate *estate)
8788 : {
8789 : SimpleEcontextStackEntry *next;
8790 :
8791 : Assert(simple_econtext_stack != NULL);
8792 : Assert(simple_econtext_stack->stack_econtext == estate->eval_econtext);
8793 :
8794 53628 : next = simple_econtext_stack->next;
8795 53628 : pfree(simple_econtext_stack);
8796 53628 : simple_econtext_stack = next;
8797 :
8798 53628 : FreeExprContext(estate->eval_econtext, true);
8799 53628 : estate->eval_econtext = NULL;
8800 53628 : }
8801 :
8802 : /*
8803 : * plpgsql_xact_cb --- post-transaction-commit-or-abort cleanup
8804 : *
8805 : * If a simple-expression EState was created in the current transaction,
8806 : * it has to be cleaned up. The same for the simple-expression resowner.
8807 : */
8808 : void
8809 196977 : plpgsql_xact_cb(XactEvent event, void *arg)
8810 : {
8811 : /*
8812 : * If we are doing a clean transaction shutdown, free the EState and tell
8813 : * the resowner to release whatever plancache references it has, so that
8814 : * all remaining resources will be released correctly. (We don't need to
8815 : * actually delete the resowner here; deletion of the
8816 : * TopTransactionResourceOwner will take care of that.)
8817 : *
8818 : * In an abort, we expect the regular abort recovery procedures to release
8819 : * everything of interest, so just clear our pointers.
8820 : */
8821 196977 : if (event == XACT_EVENT_COMMIT ||
8822 103090 : event == XACT_EVENT_PARALLEL_COMMIT ||
8823 : event == XACT_EVENT_PREPARE)
8824 : {
8825 93905 : simple_econtext_stack = NULL;
8826 :
8827 93905 : if (shared_simple_eval_estate)
8828 9342 : FreeExecutorState(shared_simple_eval_estate);
8829 93905 : shared_simple_eval_estate = NULL;
8830 93905 : if (shared_simple_eval_resowner)
8831 9342 : ReleaseAllPlanCacheRefsInOwner(shared_simple_eval_resowner);
8832 93905 : shared_simple_eval_resowner = NULL;
8833 : }
8834 103072 : else if (event == XACT_EVENT_ABORT ||
8835 : event == XACT_EVENT_PARALLEL_ABORT)
8836 : {
8837 9115 : simple_econtext_stack = NULL;
8838 9115 : shared_simple_eval_estate = NULL;
8839 9115 : shared_simple_eval_resowner = NULL;
8840 : }
8841 196977 : }
8842 :
8843 : /*
8844 : * plpgsql_subxact_cb --- post-subtransaction-commit-or-abort cleanup
8845 : *
8846 : * Make sure any simple-expression econtexts created in the current
8847 : * subtransaction get cleaned up. We have to do this explicitly because
8848 : * no other code knows which econtexts belong to which level of subxact.
8849 : */
8850 : void
8851 23761 : plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
8852 : SubTransactionId parentSubid, void *arg)
8853 : {
8854 23761 : if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
8855 : {
8856 18570 : while (simple_econtext_stack != NULL &&
8857 17710 : simple_econtext_stack->xact_subxid == mySubid)
8858 : {
8859 : SimpleEcontextStackEntry *next;
8860 :
8861 8958 : FreeExprContext(simple_econtext_stack->stack_econtext,
8862 : (event == SUBXACT_EVENT_COMMIT_SUB));
8863 8958 : next = simple_econtext_stack->next;
8864 8958 : pfree(simple_econtext_stack);
8865 8958 : simple_econtext_stack = next;
8866 : }
8867 : }
8868 23761 : }
8869 :
8870 : /*
8871 : * assign_simple_var --- assign a new value to any VAR datum.
8872 : *
8873 : * This should be the only mechanism for assignment to simple variables,
8874 : * lest we do the release of the old value incorrectly (not to mention
8875 : * the detoasting business).
8876 : */
8877 : static void
8878 320372 : assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var,
8879 : Datum newvalue, bool isnull, bool freeable)
8880 : {
8881 : Assert(var->dtype == PLPGSQL_DTYPE_VAR ||
8882 : var->dtype == PLPGSQL_DTYPE_PROMISE);
8883 :
8884 : /*
8885 : * In non-atomic contexts, we do not want to store TOAST pointers in
8886 : * variables, because such pointers might become stale after a commit.
8887 : * Forcibly detoast in such cases. We don't want to detoast (flatten)
8888 : * expanded objects, however; those should be OK across a transaction
8889 : * boundary since they're just memory-resident objects. (Elsewhere in
8890 : * this module, operations on expanded records likewise need to request
8891 : * detoasting of record fields when !estate->atomic. Expanded arrays are
8892 : * not a problem since all array entries are always detoasted.)
8893 : */
8894 350096 : if (!estate->atomic && !isnull && var->datatype->typlen == -1 &&
8895 29724 : VARATT_IS_EXTERNAL_NON_EXPANDED(DatumGetPointer(newvalue)))
8896 : {
8897 : MemoryContext oldcxt;
8898 : Datum detoasted;
8899 :
8900 : /*
8901 : * Do the detoasting in the eval_mcontext to avoid long-term leakage
8902 : * of whatever memory toast fetching might leak. Then we have to copy
8903 : * the detoasted datum to the function's main context, which is a
8904 : * pain, but there's little choice.
8905 : */
8906 8 : oldcxt = MemoryContextSwitchTo(get_eval_mcontext(estate));
8907 8 : detoasted = PointerGetDatum(detoast_external_attr((varlena *) DatumGetPointer(newvalue)));
8908 8 : MemoryContextSwitchTo(oldcxt);
8909 : /* Now's a good time to not leak the input value if it's freeable */
8910 8 : if (freeable)
8911 8 : pfree(DatumGetPointer(newvalue));
8912 : /* Once we copy the value, it's definitely freeable */
8913 8 : newvalue = datumCopy(detoasted, false, -1);
8914 8 : freeable = true;
8915 : /* Can't clean up eval_mcontext here, but it'll happen before long */
8916 : }
8917 :
8918 : /* Free the old value if needed */
8919 320372 : if (var->freeval)
8920 : {
8921 63698 : if (DatumIsReadWriteExpandedObject(var->value,
8922 : var->isnull,
8923 : var->datatype->typlen))
8924 4747 : DeleteExpandedObject(var->value);
8925 : else
8926 58951 : pfree(DatumGetPointer(var->value));
8927 : }
8928 : /* Assign new value to datum */
8929 320372 : var->value = newvalue;
8930 320372 : var->isnull = isnull;
8931 320372 : var->freeval = freeable;
8932 :
8933 : /*
8934 : * If it's a promise variable, then either we just assigned the promised
8935 : * value, or the user explicitly assigned an overriding value. Either
8936 : * way, cancel the promise.
8937 : */
8938 320372 : var->promise = PLPGSQL_PROMISE_NONE;
8939 320372 : }
8940 :
8941 : /*
8942 : * free old value of a text variable and assign new value from C string
8943 : */
8944 : static void
8945 15895 : assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, const char *str)
8946 : {
8947 15895 : assign_simple_var(estate, var, CStringGetTextDatum(str), false, true);
8948 15895 : }
8949 :
8950 : /*
8951 : * assign_record_var --- assign a new value to any REC datum.
8952 : */
8953 : static void
8954 4479 : assign_record_var(PLpgSQL_execstate *estate, PLpgSQL_rec *rec,
8955 : ExpandedRecordHeader *erh)
8956 : {
8957 : Assert(rec->dtype == PLPGSQL_DTYPE_REC);
8958 :
8959 : /* Transfer new record object into datum_context */
8960 4479 : TransferExpandedRecord(erh, estate->datum_context);
8961 :
8962 : /* Free the old value ... */
8963 4479 : if (rec->erh)
8964 1230 : DeleteExpandedObject(ExpandedRecordGetDatum(rec->erh));
8965 :
8966 : /* ... and install the new */
8967 4479 : rec->erh = erh;
8968 4479 : }
8969 :
8970 : /*
8971 : * exec_eval_using_params --- evaluate params of USING clause
8972 : *
8973 : * The result data structure is created in the stmt_mcontext, and should
8974 : * be freed by resetting that context.
8975 : */
8976 : static ParamListInfo
8977 17138 : exec_eval_using_params(PLpgSQL_execstate *estate, List *params)
8978 : {
8979 : ParamListInfo paramLI;
8980 : int nargs;
8981 : MemoryContext stmt_mcontext;
8982 : MemoryContext oldcontext;
8983 : int i;
8984 : ListCell *lc;
8985 :
8986 : /* Fast path for no parameters: we can just return NULL */
8987 17138 : if (params == NIL)
8988 16841 : return NULL;
8989 :
8990 297 : nargs = list_length(params);
8991 297 : stmt_mcontext = get_stmt_mcontext(estate);
8992 297 : oldcontext = MemoryContextSwitchTo(stmt_mcontext);
8993 297 : paramLI = makeParamList(nargs);
8994 297 : MemoryContextSwitchTo(oldcontext);
8995 :
8996 297 : i = 0;
8997 879 : foreach(lc, params)
8998 : {
8999 582 : PLpgSQL_expr *param = (PLpgSQL_expr *) lfirst(lc);
9000 582 : ParamExternData *prm = ¶mLI->params[i];
9001 : int32 ppdtypmod;
9002 :
9003 : /*
9004 : * Always mark params as const, since we only use the result with
9005 : * one-shot plans.
9006 : */
9007 582 : prm->pflags = PARAM_FLAG_CONST;
9008 :
9009 582 : prm->value = exec_eval_expr(estate, param,
9010 : &prm->isnull,
9011 : &prm->ptype,
9012 : &ppdtypmod);
9013 :
9014 582 : oldcontext = MemoryContextSwitchTo(stmt_mcontext);
9015 :
9016 582 : if (prm->ptype == UNKNOWNOID)
9017 : {
9018 : /*
9019 : * Treat 'unknown' parameters as text, since that's what most
9020 : * people would expect. The SPI functions can coerce unknown
9021 : * constants in a more intelligent way, but not unknown Params.
9022 : * This code also takes care of copying into the right context.
9023 : * Note we assume 'unknown' has the representation of C-string.
9024 : */
9025 0 : prm->ptype = TEXTOID;
9026 0 : if (!prm->isnull)
9027 0 : prm->value = CStringGetTextDatum(DatumGetCString(prm->value));
9028 : }
9029 : /* pass-by-ref non null values must be copied into stmt_mcontext */
9030 582 : else if (!prm->isnull)
9031 : {
9032 : int16 typLen;
9033 : bool typByVal;
9034 :
9035 582 : get_typlenbyval(prm->ptype, &typLen, &typByVal);
9036 582 : if (!typByVal)
9037 554 : prm->value = datumCopy(prm->value, typByVal, typLen);
9038 : }
9039 :
9040 582 : MemoryContextSwitchTo(oldcontext);
9041 :
9042 582 : exec_eval_cleanup(estate);
9043 :
9044 582 : i++;
9045 : }
9046 :
9047 297 : return paramLI;
9048 : }
9049 :
9050 : /*
9051 : * Open portal for dynamic query
9052 : *
9053 : * Caution: this resets the stmt_mcontext at exit. We might eventually need
9054 : * to move that responsibility to the callers, but currently no caller needs
9055 : * to have statement-lifetime temp data that survives past this, so it's
9056 : * simpler to do it here.
9057 : */
9058 : static Portal
9059 6367 : exec_dynquery_with_params(PLpgSQL_execstate *estate,
9060 : PLpgSQL_expr *dynquery,
9061 : List *params,
9062 : const char *portalname,
9063 : int cursorOptions)
9064 : {
9065 : Portal portal;
9066 : Datum query;
9067 : bool isnull;
9068 : Oid restype;
9069 : int32 restypmod;
9070 : char *querystr;
9071 : SPIParseOpenOptions options;
9072 6367 : MemoryContext stmt_mcontext = get_stmt_mcontext(estate);
9073 :
9074 : /*
9075 : * Evaluate the string expression after the EXECUTE keyword. Its result is
9076 : * the querystring we have to execute.
9077 : */
9078 6367 : query = exec_eval_expr(estate, dynquery, &isnull, &restype, &restypmod);
9079 6367 : if (isnull)
9080 0 : ereport(ERROR,
9081 : (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
9082 : errmsg("query string argument of EXECUTE is null")));
9083 :
9084 : /* Get the C-String representation */
9085 6367 : querystr = convert_value_to_string(estate, query, restype);
9086 :
9087 : /* copy it into the stmt_mcontext before we clean up */
9088 6367 : querystr = MemoryContextStrdup(stmt_mcontext, querystr);
9089 :
9090 6367 : exec_eval_cleanup(estate);
9091 :
9092 : /*
9093 : * Open an implicit cursor for the query. We use SPI_cursor_parse_open
9094 : * even when there are no params, because this avoids making and freeing
9095 : * one copy of the plan.
9096 : */
9097 6367 : memset(&options, 0, sizeof(options));
9098 6367 : options.params = exec_eval_using_params(estate, params);
9099 6367 : options.cursorOptions = cursorOptions;
9100 6367 : options.read_only = estate->readonly_func;
9101 :
9102 6367 : portal = SPI_cursor_parse_open(portalname, querystr, &options);
9103 :
9104 6367 : if (portal == NULL)
9105 0 : elog(ERROR, "could not open implicit cursor for query \"%s\": %s",
9106 : querystr, SPI_result_code_string(SPI_result));
9107 :
9108 : /* Release transient data */
9109 6367 : MemoryContextReset(stmt_mcontext);
9110 :
9111 6367 : return portal;
9112 : }
9113 :
9114 : /*
9115 : * Return a formatted string with information about an expression's parameters,
9116 : * or NULL if the expression does not take any parameters.
9117 : * The result is in the eval_mcontext.
9118 : */
9119 : static char *
9120 20 : format_expr_params(PLpgSQL_execstate *estate,
9121 : const PLpgSQL_expr *expr)
9122 : {
9123 : int paramno;
9124 : int dno;
9125 : StringInfoData paramstr;
9126 : MemoryContext oldcontext;
9127 :
9128 20 : if (!expr->paramnos)
9129 4 : return NULL;
9130 :
9131 16 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
9132 :
9133 16 : initStringInfo(¶mstr);
9134 16 : paramno = 0;
9135 16 : dno = -1;
9136 48 : while ((dno = bms_next_member(expr->paramnos, dno)) >= 0)
9137 : {
9138 : Datum paramdatum;
9139 : Oid paramtypeid;
9140 : bool paramisnull;
9141 : int32 paramtypmod;
9142 : PLpgSQL_var *curvar;
9143 :
9144 32 : curvar = (PLpgSQL_var *) estate->datums[dno];
9145 :
9146 32 : exec_eval_datum(estate, (PLpgSQL_datum *) curvar,
9147 : ¶mtypeid, ¶mtypmod,
9148 : ¶mdatum, ¶misnull);
9149 :
9150 32 : appendStringInfo(¶mstr, "%s%s = ",
9151 : paramno > 0 ? ", " : "",
9152 : curvar->refname);
9153 :
9154 32 : if (paramisnull)
9155 0 : appendStringInfoString(¶mstr, "NULL");
9156 : else
9157 32 : appendStringInfoStringQuoted(¶mstr,
9158 32 : convert_value_to_string(estate,
9159 : paramdatum,
9160 : paramtypeid),
9161 : -1);
9162 :
9163 32 : paramno++;
9164 : }
9165 :
9166 16 : MemoryContextSwitchTo(oldcontext);
9167 :
9168 16 : return paramstr.data;
9169 : }
9170 :
9171 : /*
9172 : * Return a formatted string with information about the parameter values,
9173 : * or NULL if there are no parameters.
9174 : * The result is in the eval_mcontext.
9175 : */
9176 : static char *
9177 12 : format_preparedparamsdata(PLpgSQL_execstate *estate,
9178 : ParamListInfo paramLI)
9179 : {
9180 : int paramno;
9181 : StringInfoData paramstr;
9182 : MemoryContext oldcontext;
9183 :
9184 12 : if (!paramLI)
9185 4 : return NULL;
9186 :
9187 8 : oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
9188 :
9189 8 : initStringInfo(¶mstr);
9190 20 : for (paramno = 0; paramno < paramLI->numParams; paramno++)
9191 : {
9192 12 : ParamExternData *prm = ¶mLI->params[paramno];
9193 :
9194 : /*
9195 : * Note: for now, this is only used on ParamListInfos produced by
9196 : * exec_eval_using_params(), so we don't worry about invoking the
9197 : * paramFetch hook or skipping unused parameters.
9198 : */
9199 12 : appendStringInfo(¶mstr, "%s$%d = ",
9200 : paramno > 0 ? ", " : "",
9201 : paramno + 1);
9202 :
9203 12 : if (prm->isnull)
9204 0 : appendStringInfoString(¶mstr, "NULL");
9205 : else
9206 12 : appendStringInfoStringQuoted(¶mstr,
9207 12 : convert_value_to_string(estate,
9208 : prm->value,
9209 : prm->ptype),
9210 : -1);
9211 : }
9212 :
9213 8 : MemoryContextSwitchTo(oldcontext);
9214 :
9215 8 : return paramstr.data;
9216 : }
|