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