1/*-------------------------------------------------------------------------
3 * pl_comp.c - Compiler part of the PL/pgSQL
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/pl/plpgsql/src/pl_comp.c
13 *-------------------------------------------------------------------------
29#include "utils/fmgroids.h"
38 * Our own local and global variables
52/* A context appropriate for short-term allocs during compilation */
56 * Lookup table for EXCEPTION condition names
66#include "plerrcodes.h"
96 * plpgsql_compile Make an execution tree for a PL/pgSQL function.
98 * If forValidator is true, we're only compiling for validation purposes,
99 * and so some checks are skipped.
101 * Note: it's important for this to fall through quickly if the function
102 * has already been compiled.
111 * funccache.c manages re-use of existing PLpgSQL_function caches.
113 * In PL/pgSQL we use fn_extra directly as the pointer to the long-lived
114 * function cache entry; we have no need for any query-lifespan cache.
115 * Also, we don't need to make the cache key depend on composite result
116 * type (at least for now).
128 * Save pointer in FmgrInfo to avoid search on subsequent calls
133 * Finally return the compiled function
145 * This is the slow part of plpgsql_compile().
147 * The passed-in "cfunc" struct is expected to be zeroes, except
148 * for the CachedFunction fields, which we don't touch here.
150 * While compiling a function, the CurrentMemoryContext is the
151 * per-function memory context of the function we are compiling. That
152 * means a palloc() will allocate storage with the same lifetime as
153 * the function itself.
155 * Because palloc()'d storage will not be immediately freed, temporary
156 * allocations should either be performed in a short-lived memory
157 * context or explicitly pfree'd. Since not all backend functions are
158 * careful about pfree'ing their allocations, it is also wise to
159 * switch into a short-term context before calling into the
160 * backend. An appropriate context for performing short-term
161 * allocations is the plpgsql_compile_tmp_cxt.
163 * NB: this code is not re-entrant. We assume that nothing we do here could
164 * result in the invocation of another plpgsql function.
180 char *proc_signature;
192 int num_out_args = 0;
196 int *in_arg_varnos = NULL;
201 * Setup the scanner input and error info.
210 * Setup error traceback support for ereport()
215 plerrcontext.arg = &cbarg;
220 * Do extra syntax checks when validating the function definition. We skip
221 * this when actually compiling functions for execution, for performance
227 /* format_procedure leaks memory, so run it in temp context */
231 * All the permanent output of compilation (e.g. parse tree) is kept in a
232 * per-function memory context, so it can be reclaimed easily.
234 * While the func_cxt needs to be long-lived, we initially make it a child
235 * of the assumed-short-lived caller's context, and reparent it under
236 * CacheMemoryContext only upon success. This arrangement avoids memory
237 * leakage during compilation of a faulty function.
249 function->out_param_varno = -1;
/* set up for no OUT param */
252 /* only promote extra warnings and errors at CREATE FUNCTION time */
258 else if (is_event_trigger)
263 function->fn_prokind = procStruct->prokind;
266 function->requires_procedure_resowner =
false;
267 function->has_exception_block =
false;
270 * Initialize the compiler, particularly the namespace stack. The
271 * outermost namespace contains function parameters and other special
272 * variables (such as FOUND), and is named after the function itself.
284 * Fetch info about the procedure's parameters. Allocations aren't
285 * needed permanently, so make them in tmp cxt.
287 * We also need to resolve any polymorphic input or output
288 * argument types. In validation mode we won't be able to, so we
289 * arbitrarily assume we are dealing with integers.
294 &argtypes, &argnames, &argmodes);
301 in_arg_varnos = (
int *)
palloc(numargs *
sizeof(
int));
307 * Create the variables for the procedure's parameters.
309 for (
i = 0;
i < numargs;
i++)
312 Oid argtypeid = argtypes[
i];
313 char argmode = argmodes ? argmodes[
i] : PROARGMODE_IN;
318 /* Create $n name for variable */
321 /* Create datatype info */
327 /* Disallow pseudotype argument */
328 /* (note we already replaced polymorphic types) */
329 /* (build_variable would do this, but wrong message) */
332 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
333 errmsg(
"PL/pgSQL functions cannot accept type %s",
337 * Build variable and add to datum list. If there's a name
338 * for the argument, use that as refname, else use $n name.
341 argnames[
i][0] !=
'0円') ?
355 /* Remember arguments in appropriate arrays */
356 if (argmode == PROARGMODE_IN ||
357 argmode == PROARGMODE_INOUT ||
358 argmode == PROARGMODE_VARIADIC)
359 in_arg_varnos[num_in_args++] = argvariable->
dno;
360 if (argmode == PROARGMODE_OUT ||
361 argmode == PROARGMODE_INOUT ||
362 argmode == PROARGMODE_TABLE)
363 out_arg_variables[num_out_args++] = argvariable;
365 /* Add to namespace under the $n name */
368 /* If there's a name for the argument, make an alias */
369 if (argnames && argnames[
i][0] !=
'0円')
375 * If there's just one OUT parameter, out_param_varno points
376 * directly to it. If there's more than one, build a row that
377 * holds all of them. Procedures return a row even for one OUT
380 if (num_out_args > 1 ||
381 (num_out_args == 1 &&
function->fn_prokind == PROKIND_PROCEDURE))
389 else if (num_out_args == 1)
390 function->out_param_varno = out_arg_variables[0]->
dno;
393 * Check for a polymorphic returntype. If found, use the actual
394 * returntype type from the caller's FuncExpr node, if we have
395 * one. (In validation mode we arbitrarily assume we are dealing
398 * Note: errcode is FEATURE_NOT_SUPPORTED because it should always
399 * work; if it doesn't we're in some context that fails to make
400 * the info available.
402 rettypeid = procStruct->prorettype;
403 if (IsPolymorphicType(rettypeid))
407 if (rettypeid == ANYARRAYOID ||
408 rettypeid == ANYCOMPATIBLEARRAYOID)
409 rettypeid = INT4ARRAYOID;
410 else if (rettypeid == ANYRANGEOID ||
411 rettypeid == ANYCOMPATIBLERANGEOID)
412 rettypeid = INT4RANGEOID;
413 else if (rettypeid == ANYMULTIRANGEOID)
414 rettypeid = INT4MULTIRANGEOID;
415 else /* ANYELEMENT or ANYNONARRAY or ANYCOMPATIBLE */
417 /* XXX what could we use for ANYENUM? */
424 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
425 errmsg(
"could not determine actual return type "
426 "for polymorphic function \"%s\"",
432 * Normal function has a defined returntype
435 function->fn_retset = procStruct->proretset;
438 * Lookup the function's return type
442 elog(
ERROR,
"cache lookup failed for type %u", rettypeid);
445 /* Disallow pseudotype result, except VOID or RECORD */
446 /* (note we already replaced polymorphic types) */
447 if (typeStruct->typtype == TYPTYPE_PSEUDO)
449 if (rettypeid == VOIDOID ||
450 rettypeid == RECORDOID)
452 else if (rettypeid == TRIGGEROID || rettypeid == EVENT_TRIGGEROID)
454 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
455 errmsg(
"trigger functions can only be called as triggers")));
458 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
459 errmsg(
"PL/pgSQL functions cannot return type %s",
464 function->fn_retisdomain = (typeStruct->typtype == TYPTYPE_DOMAIN);
465 function->fn_retbyval = typeStruct->typbyval;
466 function->fn_rettyplen = typeStruct->typlen;
469 * install 0ドル reference, but only for polymorphic return types,
470 * and not when the return is specified through an output
473 if (IsPolymorphicType(procStruct->prorettype) &&
488 /* Trigger procedure's return type is unknown yet */
495 /* shouldn't be any declared arguments */
496 if (procStruct->pronargs != 0)
498 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
499 errmsg(
"trigger functions cannot have declared arguments"),
500 errhint(
"The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.")));
502 /* Add the record for referencing NEW ROW */
506 /* Add the record for referencing OLD ROW */
510 /* Add the variable tg_name */
521 /* Add the variable tg_when */
532 /* Add the variable tg_level */
543 /* Add the variable tg_op */
554 /* Add the variable tg_relid */
565 /* Add the variable tg_relname */
576 /* tg_table_name is now preferred to tg_relname */
587 /* add the variable tg_table_schema */
598 /* Add the variable tg_nargs */
609 /* Add the variable tg_argv */
629 /* shouldn't be any declared arguments */
630 if (procStruct->pronargs != 0)
632 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
633 errmsg(
"event trigger functions cannot have declared arguments")));
635 /* Add the variable tg_event */
646 /* Add the variable tg_tag */
660 elog(
ERROR,
"unrecognized function typecode: %d",
665 /* Remember if function is STABLE/IMMUTABLE */
666 function->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
669 * Create the magic FOUND variable.
680 * Now parse the function's text
684 elog(
ERROR,
"plpgsql parser returned %d", parse_rc);
690 * If it has OUT parameters or returns VOID or returns a set, we allow
691 * control to fall off the end without an explicit RETURN statement. The
692 * easiest way to implement this is to add a RETURN statement to the end
693 * of the statement list during parsing.
695 if (num_out_args > 0 ||
function->fn_rettype == VOIDOID ||
700 * Complete the function's info
702 function->fn_nargs = procStruct->pronargs;
711 /* Debug dump for completed functions */
716 * All is well, so make the func_cxt long-lived
721 * Pop the error context stack
733 * plpgsql_compile_inline Make an execution tree for an anonymous code block.
735 * Note: this is generally parallel to plpgsql_compile_callback(); is it worth
736 * trying to merge the two?
738 * Note: we assume the block will be thrown away so there is no need to build
739 * persistent data structures.
746 char *func_name =
"inline_code_block";
755 * Setup the scanner input and error info.
762 * Setup error traceback support for ereport()
767 plerrcontext.arg = &cbarg;
771 /* Do extra syntax checking if check_function_bodies is on */
774 /* Function struct does not live past current statement */
780 * All the rest of the compile-time storage (e.g. parse tree) is kept in
781 * its own memory context, so it can be reclaimed easily.
784 "PL/pgSQL inline code context",
792 function->out_param_varno = -1;
/* set up for no OUT param */
797 * don't do extra validation for inline code as we don't want to add spam
804 function->requires_procedure_resowner =
false;
805 function->has_exception_block =
false;
812 /* Set up as though in a function returning VOID */
817 function->fn_prokind = PROKIND_FUNCTION;
818 /* a bit of hardwired knowledge about type VOID here */
823 * Remember if function is STABLE/IMMUTABLE. XXX would it be better to
824 * set this true inside a read-only transaction? Not clear.
829 * Create the magic FOUND variable.
840 * Now parse the function's text
844 elog(
ERROR,
"plpgsql parser returned %d", parse_rc);
849 * If it returns VOID (always true at the moment), we allow control to
850 * fall off the end without an explicit RETURN statement.
852 if (
function->fn_rettype == VOIDOID)
856 * Complete the function's info
865 /* Debug dump for completed functions */
870 * Pop the error context stack
884 * error context callback to let us supply a call-stack traceback.
885 * If we are validating or executing an anonymous code block, the function
886 * source text is passed as an argument.
897 * Try to convert syntax error position to reference text of original
898 * CREATE FUNCTION or DO command.
904 * Done if a syntax error position was reported; otherwise we have to
905 * fall back to a "near line N" report.
910 errcontext(
"compilation of PL/pgSQL function \"%s\" near line %d",
916 * Add a name for a function parameter to the function's namespace
922 * Before adding the name, check for duplicates. We need this even though
923 * functioncmds.c has a similar check, because that code explicitly
924 * doesn't complain about conflicting IN and OUT parameter names. In
925 * plpgsql, such names are in the same namespace, so there is no way to
932 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
933 errmsg(
"parameter name \"%s\" used more than once",
936 /* OK, add the name */
941 * Add a dummy RETURN statement to the given function's body
947 * If the outer block has an EXCEPTION clause, we need to make a new outer
948 * block, since the added RETURN shouldn't act like it is inside the
949 * EXCEPTION clause. Likewise, if it has a label, wrap it in a new outer
950 * block so that EXIT doesn't skip the RETURN.
952 if (
function->action->exceptions != NULL ||
959 new->stmtid = ++
function->nstatements;
971 new->stmtid = ++
function->nstatements;
973 new->retvarno =
function->out_param_varno;
981 * plpgsql_parser_setup set up parser hooks for dynamic parameters
983 * Note: this routine, and the hook functions it prepares for, are logically
984 * part of plpgsql parsing. But they actually run during function execution,
985 * when we are ready to evaluate a SQL query or expression that has not
986 * previously been parsed and planned.
994 /* no need to use p_coerce_param_hook */
999 * plpgsql_pre_column_ref parser callback before parsing a ColumnRef
1013 * plpgsql_post_column_ref parser callback after parsing a ColumnRef
1022 return NULL;
/* we already found there's no match */
1025 return NULL;
/* there's a table column, prefer that */
1028 * If we find a record/row variable but can't match a field name, throw
1029 * error if there was no core resolution for the ColumnRef either. In
1030 * that situation, the reference is inevitably going to fail, and
1031 * complaining about the record/row variable is likely to be more on-point
1032 * than the core parser's error message. (It's too bad we don't have
1033 * access to transformColumnRef's internal crerr state here, as in case of
1034 * a conflict with a table name this could still be less than the most
1035 * helpful error message possible.)
1039 if (myvar != NULL && var != NULL)
1042 * We could leave it to the core parser to throw this error, but we
1043 * can add a more useful detail message than the core could.
1046 (
errcode(ERRCODE_AMBIGUOUS_COLUMN),
1047 errmsg(
"column reference \"%s\" is ambiguous",
1049 errdetail(
"It could refer to either a PL/pgSQL variable or a table column."),
1057 * plpgsql_param_ref parser callback for ParamRefs ($n symbols)
1073 return NULL;
/* name not known to plpgsql */
1079 * resolve_column_ref attempt to resolve a ColumnRef as a plpgsql var
1081 * Returns the translated node structure, or NULL if name not found
1083 * error_if_no_field tells whether to throw error or quietly return NULL if
1084 * we are able to match a record/row name but don't find a field name match.
1088 ColumnRef *cref,
bool error_if_no_field)
1093 const char *name2 = NULL;
1094 const char *name3 = NULL;
1095 const char *colname = NULL;
1097 int nnames_scalar = 0;
1098 int nnames_wholerow = 0;
1099 int nnames_field = 0;
1102 * We use the function's current estate to resolve parameter data types.
1103 * This is really pretty bogus because there is no provision for updating
1104 * plans when those types change ...
1109 * The allowed syntaxes are:
1111 * A Scalar variable reference, or whole-row record reference.
1112 * A.B Qualified scalar or whole-row reference, or field reference.
1113 * A.B.C Qualified record field reference.
1114 * A.* Whole-row record reference.
1115 * A.B.* Qualified whole-row record reference.
1126 nnames_wholerow = 1;
1136 /* Whole-row reference? */
1139 /* Set name2 to prevent matches to scalar variables */
1141 nnames_wholerow = 1;
1148 nnames_wholerow = 2;
1161 /* Whole-row reference? */
1164 /* Set name3 to prevent matches to scalar variables */
1166 nnames_wholerow = 2;
1176 /* too many names, ignore */
1181 name1, name2, name3,
1185 return NULL;
/* name not known to plpgsql */
1190 if (nnames == nnames_scalar)
1194 if (nnames == nnames_wholerow)
1196 if (nnames == nnames_field)
1198 /* colname could be a field in this record */
1202 /* search for a datum referencing this field */
1210 if (strcmp(fld->
fieldname, colname) == 0)
1218 * Ideally we'd never get here, because a RECFIELD datum
1219 * should have been built at parse time for every qualified
1220 * reference to a field of this record that appears in the
1221 * source text. However, plpgsql_yylex will not build such a
1222 * datum unless the field name lexes as token type IDENT.
1223 * Hence, if the would-be field name is a PL/pgSQL reserved
1224 * word, we lose. Assume that that's what happened and tell
1225 * the user to quote it, unless the caller prefers we just
1228 if (error_if_no_field)
1230 (
errcode(ERRCODE_SYNTAX_ERROR),
1231 errmsg(
"field name \"%s\" is a reserved key word",
1233 errhint(
"Use double quotes to quote it."),
1241 /* Name format doesn't match the plpgsql variable type */
1246 * Helper for columnref parsing: build a Param referencing a plpgsql datum,
1247 * and make sure that that datum is listed in the expression's paramnos.
1257 /* see comment in resolve_column_ref */
1259 Assert(dno >= 0 && dno < estate->ndatums);
1260 datum = estate->
datums[dno];
1263 * Bitmapset must be allocated in function's permanent memory context
1279 return (
Node *) param;
1284 * plpgsql_parse_word The scanner calls this to postparse
1285 * any single word that is not a reserved keyword.
1287 * word1 is the downcased/dequoted identifier; it must be palloc'd in the
1288 * function's long-term memory context.
1290 * yytxt is the original token text; we need this to check for quoting,
1291 * so that later checks for unreserved keywords work properly.
1293 * We attempt to recognize the token as a variable only if lookup is true
1294 * and the plpgsql_IdentifierLookup context permits it.
1296 * If recognized as a variable, fill in *wdatum and return true;
1297 * if not recognized, fill in *word and return false.
1298 * (Note: those two pointers actually point to members of the same union,
1299 * but for notational reasons we pass them separately.)
1309 * We should not lookup variables in DECLARE sections. In SQL
1310 * expressions, there's no need to do so either --- lookup will happen
1311 * when the expression is compiled.
1316 * Do a lookup in the current namespace stack
1329 wdatum->
ident = word1;
1330 wdatum->
quoted = (yytxt[0] ==
'"');
1335 /* plpgsql_ns_lookup should never return anything else */
1336 elog(
ERROR,
"unrecognized plpgsql itemtype: %d",
1343 * Nothing found - up to now it's a word without any special meaning for
1346 word->ident = word1;
1347 word->quoted = (yytxt[0] ==
'"');
1353 * plpgsql_parse_dblword Same lookup for two words
1354 * separated by a dot.
1369 * We should do nothing in DECLARE sections. In SQL expressions, we
1370 * really only need to make sure that RECFIELD datums are created when
1371 * needed. In all the cases handled by this function, returning a T_DATUM
1372 * with a two-word idents string is the right thing.
1377 * Do a lookup in the current namespace stack
1387 /* Block-qualified reference to scalar variable. */
1389 wdatum->
ident = NULL;
1390 wdatum->
quoted =
false;
/* not used */
1398 * First word is a record name, so second word could
1399 * be a field in this record. We build a RECFIELD
1400 * datum whether it is or not --- any error will be
1413 /* Block-qualified reference to record variable. */
1416 wdatum->
ident = NULL;
1417 wdatum->
quoted =
false;
/* not used */
1434 * plpgsql_parse_tripword Same lookup for three words
1435 * separated by dots.
1447 * We should do nothing in DECLARE sections. In SQL expressions, we need
1448 * to make sure that RECFIELD datums are created when needed, and we need
1449 * to be careful about how many names are reported as belonging to the
1450 * T_DATUM: the third word could be a sub-field reference, which we don't
1456 * Do a lookup in the current namespace stack. Must find a record
1457 * reference, else ignore.
1460 word1, word2, word3,
1475 * First word is a record name, so second word
1476 * could be a field in this record (and the third,
1477 * a sub-field). We build a RECFIELD datum
1478 * whether it is or not --- any error will be
1487 /* Block-qualified reference to record variable. */
1494 wdatum->
ident = NULL;
1495 wdatum->
quoted =
false;
/* not used */
1516 * plpgsql_parse_wordtype The scanner found word%TYPE. word should be
1517 * a pre-existing variable name.
1519 * Returns datatype struct. Throws error if no match found for word.
1528 * Do a lookup in the current namespace stack
1547 /* No match, complain */
1549 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1550 errmsg(
"variable \"%s\" does not exist",
ident)));
1551 return NULL;
/* keep compiler quiet */
1556 * plpgsql_parse_cwordtype Same lookup for compositeword%TYPE
1558 * Here, we allow either a block-qualified variable name, or a reference
1559 * to a column of some table. (If we must throw error, we assume that the
1560 * latter case was intended.)
1570 const char *fldname = NULL;
1577 /* Avoid memory leaks in the long-term function context */
1583 * Do a lookup in the current namespace stack
1593 /* Block-qualified reference to scalar variable. */
1600 /* Block-qualified reference to record variable. */
1606 * First word could also be a table name
1616 * We could check for a block-qualified reference to a field of a
1617 * record variable, but %TYPE is documented as applying to variables,
1618 * not fields of variables. Things would get rather ambiguous if we
1619 * allowed either interpretation.
1629 /* Look up relation name. Can't lock it - we might not have privileges. */
1633 * Fetch the named table field and its type
1638 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1639 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
1646 elog(
ERROR,
"cache lookup failed for type %u", attrStruct->atttypid);
1649 * Found that - build a compiler type struct in the caller's cxt and
1650 * return it. Note that we treat the type as being found-by-OID; no
1651 * attempt to re-look-up the type name will happen during invalidations.
1655 attrStruct->atttypmod,
1656 attrStruct->attcollation,
1671 * plpgsql_parse_wordrowtype Scanner found word%ROWTYPE.
1672 * So word must be a table name.
1683 /* Avoid memory leaks in long-term function context */
1687 * Look up the relation. Note that because relation rowtypes have the
1688 * same names as their relations, this could be handled as a type lookup
1689 * equally well; we use the relation lookup code path only because the
1690 * errors thrown here have traditionally referred to relations not types.
1691 * But we'll make a TypeName in case we have to do re-look-up of the type.
1697 errmsg(
"relation \"%s\" does not exist",
ident)));
1699 /* Some relkinds lack type OIDs */
1703 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1704 errmsg(
"relation \"%s\" does not have a composite type",
1711 /* Build and return the row type struct */
1716 * plpgsql_parse_cwordrowtype Scanner found compositeword%ROWTYPE.
1717 * So word must be a namespace qualified table name.
1730 * As above, this is a relation lookup but could be a type lookup if we
1731 * weren't being backwards-compatible about error wording.
1734 /* Avoid memory leaks in long-term function context */
1737 /* Look up relation name. Can't lock it - we might not have privileges. */
1741 /* Some relkinds lack type OIDs */
1745 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1746 errmsg(
"relation \"%s\" does not have a composite type",
1753 /* Build and return the row type struct */
1758 * plpgsql_build_variable - build a datum-array entry of a given
1761 * The returned struct may be a PLpgSQL_var or PLpgSQL_rec
1762 * depending on the given datatype, and is allocated via
1763 * palloc. The struct is automatically added to the current datum
1764 * array, and optionally to the current namespace.
1772 switch (dtype->
ttype)
1776 /* Ordinary scalar datatype */
1784 /* other fields are left as 0, might be changed by caller */
1786 /* preset to NULL */
1801 /* Composite type -- build a record variable */
1812 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1813 errmsg(
"variable \"%s\" has pseudo-type %s",
1815 result = NULL;
/* keep compiler quiet */
1819 result = NULL;
/* keep compiler quiet */
1827 * Build empty named record variable, and optionally add it to namespace
1840 /* other fields are left as 0, might be changed by caller */
1853 * Build a row-variable data structure given the component variables.
1854 * Include a rowtupdesc, since we will need to materialize the row result.
1864 row->
refname =
"(unnamed row)";
1871 for (
i = 0;
i < numvars;
i++)
1878 /* Member vars of a row should never be const */
1886 typmod = ((
PLpgSQL_var *) var)->datatype->atttypmod;
1887 typcoll = ((
PLpgSQL_var *) var)->datatype->collation;
1891 /* shouldn't need to revalidate rectypeid already... */
1893 typmod = -1;
/* don't know typmod, if it's used at all */
1894 typcoll =
InvalidOid;
/* composite types have no collation */
1899 typoid =
InvalidOid;
/* keep compiler quiet */
1919 * Build a RECFIELD datum for the named field of the specified record variable
1921 * If there's already such a datum, just return it; we don't need duplicates.
1929 /* search for an existing datum referencing this field */
1937 if (strcmp(fld->
fieldname, fldname) == 0)
1942 /* nope, so make a new one */
1951 /* now we can link it into the parent's chain */
1959 * plpgsql_build_datatype
1960 * Build PLpgSQL_type struct given type OID, typmod, collation,
1961 * and type's parsed name.
1963 * If collation is not InvalidOid then it overrides the type's default
1964 * collation. But collation is ignored if the datatype is non-collatable.
1966 * origtypname is the parsed form of what the user wrote as the type name.
1967 * It can be NULL if the type could not be a composite type, or if it was
1968 * identified by OID to begin with (e.g., it's a function argument type).
1969 * origtypname is in short-lived storage and must be copied if we choose
1970 * to incorporate it into the function's parse tree.
1981 elog(
ERROR,
"cache lookup failed for type %u", typeOid);
1991 * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry
1992 * and additional details (see comments for plpgsql_build_datatype).
2001 if (!typeStruct->typisdefined)
2003 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2004 errmsg(
"type \"%s\" is only a shell",
2005 NameStr(typeStruct->typname))));
2010 typ->
typoid = typeStruct->oid;
2011 switch (typeStruct->typtype)
2016 case TYPTYPE_MULTIRANGE:
2019 case TYPTYPE_COMPOSITE:
2022 case TYPTYPE_DOMAIN:
2028 case TYPTYPE_PSEUDO:
2029 if (typ->
typoid == RECORDOID)
2036 (
int) typeStruct->typtype);
2039 typ->
typlen = typeStruct->typlen;
2040 typ->
typbyval = typeStruct->typbyval;
2041 typ->
typtype = typeStruct->typtype;
2042 typ->
collation = typeStruct->typcollation;
2045 /* Detect if type is true array, or domain thereof */
2046 /* NB: this is only used to decide whether to apply expand_array */
2047 if (typeStruct->typtype == TYPTYPE_BASE)
2050 * This test should include what get_element_type() checks. We also
2051 * disallow non-toastable array types (i.e. oidvector and int2vector).
2053 typ->
typisarray = (IsTrueArrayType(typeStruct) &&
2054 typeStruct->typstorage != TYPSTORAGE_PLAIN);
2056 else if (typeStruct->typtype == TYPTYPE_DOMAIN)
2058 /* we can short-circuit looking up base types if it's not varlena */
2059 typ->
typisarray = (typeStruct->typlen == -1 &&
2060 typeStruct->typstorage != TYPSTORAGE_PLAIN &&
2068 * If it's a named composite type (or domain over one), find the typcache
2069 * entry and record the current tupdesc ID, so we can detect changes
2070 * (including drops). We don't currently support on-the-fly replacement
2071 * of non-composite types, else we might want to do this for them too.
2080 if (typentry->
typtype == TYPTYPE_DOMAIN)
2083 if (typentry->
tupDesc == NULL)
2085 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2086 errmsg(
"type %s is not composite",
2104 * Build an array type for the element type specified as argument.
2112 * If it's already an array type, use it as-is: Postgres doesn't do nested
2121 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2122 errmsg(
"could not find array type for data type %s",
2125 /* Note we inherit typmod and collation, if any, from the element type */
2131 * plpgsql_recognize_err_condition
2132 * Check condition name and translate it to SQLSTATE.
2134 * Note: there are some cases where the same condition name has multiple
2135 * entries in the table. We arbitrarily return the first match.
2144 if (strlen(condname) == 5 &&
2145 strspn(condname,
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") == 5)
2160 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2161 errmsg(
"unrecognized exception condition \"%s\"",
2163 return 0;
/* keep compiler quiet */
2167 * plpgsql_parse_err_condition
2168 * Generate PLpgSQL_condition entry(s) for an exception condition name
2170 * This has to be able to return a list because there are some duplicate
2171 * names in the table of error code names.
2181 * XXX Eventually we will want to look for user-defined exception names
2185 if (strcmp(condname,
"others") == 0)
2189 new->condname = condname;
2201 new->condname = condname;
2209 (
errcode(ERRCODE_UNDEFINED_OBJECT),
2210 errmsg(
"unrecognized exception condition \"%s\"",
2217 * plpgsql_start_datums Initialize datum list at compile startup.
2225 /* This is short-lived, so needn't allocate in function's cxt */
2228 /* datums_last tracks what's been seen by plpgsql_add_initdatums() */
2233 * plpgsql_adddatum Add a variable, record or row
2234 * to the compiler's datum list.
2251 * plpgsql_finish_datums Copy completed datum info into function struct.
2257 Size copiable_size = 0;
2266 /* This must agree with copy_plpgsql_datums on what is copiable */
2280 function->copiable_size = copiable_size;
2285 * plpgsql_add_initdatums Make an array of the datum numbers of
2286 * all the initializable datums created since the last call
2289 * If varnos is NULL, we just forget any datum entries created since the
2292 * This is used around a DECLARE section to create a list of the datums
2293 * that have to be initialized at block entry. Note that datums can also
2294 * be created elsewhere than DECLARE, eg by a FOR-loop, but it is then
2295 * the responsibility of special-purpose code to initialize them.
2305 * The set of dtypes recognized here must match what exec_stmt_block()
2306 * cares about (re)initializing at block entry.
2326 *varnos = (
int *)
palloc(
sizeof(
int) * n);
Bitmapset * bms_add_member(Bitmapset *a, int x)
#define TextDatumGetCString(d)
#define OidIsValid(objectId)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
#define ereport(elevel,...)
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
void cfunc_resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
CachedFunction * cached_function_compile(FunctionCallInfo fcinfo, CachedFunction *function, CachedFunctionCompileCallback ccallback, CachedFunctionDeleteCallback dcallback, Size cacheEntrySize, bool includeResultType, bool forValidator)
bool check_function_bodies
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
if(TABLE==NULL||TABLE_index==NULL)
List * lappend(List *list, void *datum)
List * list_copy(const List *oldlist)
List * list_delete_last(List *list)
bool type_is_rowtype(Oid typid)
Oid get_rel_type_id(Oid relid)
Oid get_base_element_type(Oid typid)
Oid get_array_type(Oid typid)
TypeName * makeTypeNameFromNameList(List *names)
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
TypeName * makeTypeName(char *typnam)
void * MemoryContextAlloc(MemoryContext context, Size size)
char * pstrdup(const char *in)
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
MemoryContext CacheMemoryContext
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
char * NameListToString(const List *names)
RangeVar * makeRangeVarFromNameList(const List *names)
Oid RelnameGetRelid(const char *relname)
#define RangeVarGetRelid(relation, lockmode, missing_ok)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
int parser_errposition(ParseState *pstate, int location)
FormData_pg_attribute * Form_pg_attribute
on_exit_nicely_callback function
static int list_length(const List *l)
#define list_make3(x1, x2, x3)
#define list_make2(x1, x2)
bool function_parse_error_transpose(const char *prosrc)
FormData_pg_proc * Form_pg_proc
FormData_pg_type * Form_pg_type
#define ERRCODE_UNDEFINED_TABLE
static void add_dummy_return(PLpgSQL_function *function)
static PLpgSQL_row * build_row_from_vars(PLpgSQL_variable **vars, int numvars)
PLpgSQL_condition * plpgsql_parse_err_condition(char *condname)
void plpgsql_parser_setup(struct ParseState *pstate, PLpgSQL_expr *expr)
PLpgSQL_recfield * plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname)
int plpgsql_add_initdatums(int **varnos)
MemoryContext plpgsql_compile_tmp_cxt
static Node * make_datum_param(PLpgSQL_expr *expr, int dno, int location)
int plpgsql_recognize_err_condition(const char *condname, bool allow_sqlstate)
static void plpgsql_compile_error_callback(void *arg)
PLpgSQL_type * plpgsql_parse_cwordrowtype(List *idents)
static Node * plpgsql_param_ref(ParseState *pstate, ParamRef *pref)
static void plpgsql_start_datums(void)
char * plpgsql_error_funcname
bool plpgsql_check_syntax
static const ExceptionLabelMap exception_label_map[]
PLpgSQL_type * plpgsql_build_datatype_arrayof(PLpgSQL_type *dtype)
PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, TypeName *origtypname)
static void plpgsql_finish_datums(PLpgSQL_function *function)
PLpgSQL_function * plpgsql_curr_compile
PLpgSQL_function * plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
bool plpgsql_parse_dblword(char *word1, char *word2, PLwdatum *wdatum, PLcword *cword)
PLpgSQL_type * plpgsql_parse_wordtype(char *ident)
void plpgsql_adddatum(PLpgSQL_datum *newdatum)
PLpgSQL_datum ** plpgsql_Datums
bool plpgsql_parse_word(char *word1, const char *yytxt, bool lookup, PLwdatum *wdatum, PLword *word)
bool plpgsql_DumpExecTree
PLpgSQL_type * plpgsql_parse_cwordtype(List *idents)
static Node * resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, ColumnRef *cref, bool error_if_no_field)
PLpgSQL_rec * plpgsql_build_record(const char *refname, int lineno, PLpgSQL_type *dtype, Oid rectypeid, bool add2namespace)
static void add_parameter_name(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
bool plpgsql_parse_tripword(char *word1, char *word2, char *word3, PLwdatum *wdatum, PLcword *cword)
static PLpgSQL_type * build_datatype(HeapTuple typeTup, int32 typmod, Oid collation, TypeName *origtypname)
static Node * plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref)
PLpgSQL_type * plpgsql_parse_wordrowtype(char *ident)
static Node * plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
PLpgSQL_variable * plpgsql_build_variable(const char *refname, int lineno, PLpgSQL_type *dtype, bool add2namespace)
PLpgSQL_function * plpgsql_compile_inline(char *proc_source)
static void plpgsql_compile_callback(FunctionCallInfo fcinfo, HeapTuple procTup, const CachedFunctionHashKey *hashkey, CachedFunction *cfunc, bool forValidator)
void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, PLpgSQL_datum *datum, Oid *typeId, int32 *typMod, Oid *collation)
void plpgsql_ns_init(void)
PLpgSQL_nsitem * plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, const char *name1, const char *name2, const char *name3, int *names_used)
void plpgsql_delete_callback(CachedFunction *cfunc)
void plpgsql_dumptree(PLpgSQL_function *func)
void plpgsql_mark_local_assignment_targets(PLpgSQL_function *func)
void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name)
void plpgsql_ns_push(const char *label, PLpgSQL_label_type label_type)
PLpgSQL_nsitem * plpgsql_ns_top(void)
int plpgsql_variable_conflict
int plpgsql_extra_warnings
bool plpgsql_print_strict_params
IdentifierLookup plpgsql_IdentifierLookup
void plpgsql_scanner_finish(yyscan_t yyscanner)
yyscan_t plpgsql_scanner_init(const char *str)
int plpgsql_latest_lineno(yyscan_t yyscanner)
@ PLPGSQL_RESOLVE_VARIABLE
@ IDENTIFIER_LOOKUP_DECLARE
@ IDENTIFIER_LOOKUP_NORMAL
@ PLPGSQL_PROMISE_TG_RELID
@ PLPGSQL_PROMISE_TG_WHEN
@ PLPGSQL_PROMISE_TG_ARGV
@ PLPGSQL_PROMISE_TG_TABLE_SCHEMA
@ PLPGSQL_PROMISE_TG_EVENT
@ PLPGSQL_PROMISE_TG_TABLE_NAME
@ PLPGSQL_PROMISE_TG_LEVEL
@ PLPGSQL_PROMISE_TG_NARGS
@ PLPGSQL_PROMISE_TG_NAME
int plpgsql_yyparse(PLpgSQL_stmt_block **plpgsql_parse_result_p, yyscan_t yyscanner)
static Datum ObjectIdGetDatum(Oid X)
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
char * format_procedure(Oid procedure_oid)
struct ErrorContextCallback * previous
struct PLpgSQL_nsitem * ns
struct PLpgSQL_function * func
struct PLpgSQL_execstate * cur_estate
PLpgSQL_resolve_option resolve_option
PLpgSQL_nsitem_type itemtype
ExpandedRecordHeader * erh
ParseParamRefHook p_paramref_hook
PreParseColumnRefHook p_pre_columnref_hook
PostParseColumnRefHook p_post_columnref_hook
uint64 tupDesc_identifier
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
HeapTuple SearchSysCacheAttName(Oid relid, const char *attname)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
#define CALLED_AS_TRIGGER(fcinfo)
TupleDesc CreateTemplateTupleDesc(int natts)
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
#define INVALID_TUPLEDESC_IDENTIFIER
#define TYPECACHE_TUPDESC
#define TYPECACHE_DOMAIN_BASE_INFO
String * makeString(char *str)