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