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