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