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