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