1 /*-------------------------------------------------------------------------
5 * Routines for CREATE and DROP FUNCTION commands and CREATE and DROP
8 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/commands/functioncmds.c
16 * These routines take the parse tree and pick out the
17 * appropriate arguments/flags, and pass the results to the
18 * corresponding "FooCreate" routines (in src/backend/catalog) that do
19 * the actual catalog-munging. These routines also verify permission
20 * of the user to execute the command.
23 * These things must be defined and committed in the following order:
25 * input/output, recv/send procedures
31 *-------------------------------------------------------------------------
35 #include "access/htup_details.h"
36 #include "access/table.h"
37 #include "catalog/catalog.h"
38 #include "catalog/dependency.h"
39 #include "catalog/indexing.h"
40 #include "catalog/objectaccess.h"
41 #include "catalog/pg_aggregate.h"
42 #include "catalog/pg_cast.h"
43 #include "catalog/pg_language.h"
44 #include "catalog/pg_namespace.h"
45 #include "catalog/pg_proc.h"
46 #include "catalog/pg_transform.h"
47 #include "catalog/pg_type.h"
48 #include "commands/defrem.h"
49 #include "commands/extension.h"
50 #include "commands/proclang.h"
51 #include "executor/executor.h"
52 #include "executor/functions.h"
54 #include "miscadmin.h"
55 #include "nodes/nodeFuncs.h"
56 #include "optimizer/optimizer.h"
57 #include "parser/analyze.h"
58 #include "parser/parse_coerce.h"
59 #include "parser/parse_collate.h"
60 #include "parser/parse_expr.h"
61 #include "parser/parse_func.h"
62 #include "parser/parse_type.h"
64 #include "tcop/pquery.h"
65 #include "tcop/utility.h"
66 #include "utils/acl.h"
67 #include "utils/builtins.h"
68 #include "utils/guc.h"
69 #include "utils/lsyscache.h"
70 #include "utils/rel.h"
71 #include "utils/snapmgr.h"
72 #include "utils/syscache.h"
73 #include "utils/typcache.h"
76 * Examine the RETURNS clause of the CREATE FUNCTION statement
77 * and return information about it as *prorettype_p and *returnsSet_p.
79 * This is more complex than the average typename lookup because we want to
80 * allow a shell type to be used, or even created if the specified return type
81 * doesn't exist yet. (Without this, there's no way to define the I/O procs
82 * for a new type.) But SQL function creation won't cope, so error out if
83 * the target language is SQL. (We do this here, not in the SQL-function
84 * validator, so as not to produce a NOTICE and then an ERROR for the same
88 compute_return_type(TypeName
*returnType
, Oid languageOid
,
89 Oid
*prorettype_p
, bool *returnsSet_p
)
95 typtup
= LookupTypeName(NULL
, returnType
, NULL
, false);
99 if (!((Form_pg_type
) GETSTRUCT(typtup
))->typisdefined
)
101 if (languageOid
== SQLlanguageId
)
103 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
104 errmsg("SQL function cannot return shell type %s",
105 TypeNameToString(returnType
))));
108 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
109 errmsg("return type %s is only a shell",
110 TypeNameToString(returnType
))));
112 rettype
= typeTypeId(typtup
);
113 ReleaseSysCache(typtup
);
117 char *typnam
= TypeNameToString(returnType
);
120 ObjectAddress address
;
123 * Only C-coded functions can be I/O functions. We enforce this
124 * restriction here mainly to prevent littering the catalogs with
125 * shell types due to simple typos in user-defined function
128 if (languageOid
!= INTERNALlanguageId
&&
129 languageOid
!= ClanguageId
)
131 (errcode(ERRCODE_UNDEFINED_OBJECT
),
132 errmsg("type \"%s\" does not exist", typnam
)));
134 /* Reject if there's typmod decoration, too */
135 if (returnType
->typmods
!= NIL
)
137 (errcode(ERRCODE_SYNTAX_ERROR
),
138 errmsg("type modifier cannot be specified for shell type \"%s\"",
141 /* Otherwise, go ahead and make a shell type */
143 (errcode(ERRCODE_UNDEFINED_OBJECT
),
144 errmsg("type \"%s\" is not yet defined", typnam
),
145 errdetail("Creating a shell type definition.")));
146 namespaceId
= QualifiedNameGetCreationNamespace(returnType
->names
,
148 aclresult
= object_aclcheck(NamespaceRelationId
, namespaceId
, GetUserId(),
150 if (aclresult
!= ACLCHECK_OK
)
151 aclcheck_error(aclresult
, OBJECT_SCHEMA
,
152 get_namespace_name(namespaceId
));
153 address
= TypeShellMake(typname
, namespaceId
, GetUserId());
154 rettype
= address
.objectId
;
155 Assert(OidIsValid(rettype
));
158 aclresult
= object_aclcheck(TypeRelationId
, rettype
, GetUserId(), ACL_USAGE
);
159 if (aclresult
!= ACLCHECK_OK
)
160 aclcheck_error_type(aclresult
, rettype
);
162 *prorettype_p
= rettype
;
163 *returnsSet_p
= returnType
->setof
;
167 * Interpret the function parameter list of a CREATE FUNCTION,
168 * CREATE PROCEDURE, or CREATE AGGREGATE statement.
171 * parameters: list of FunctionParameter structs
172 * languageOid: OID of function language (InvalidOid if it's CREATE AGGREGATE)
173 * objtype: identifies type of object being created
175 * Results are stored into output parameters. parameterTypes must always
176 * be created, but the other arrays/lists can be NULL pointers if not needed.
177 * variadicArgType is set to the variadic array type if there's a VARIADIC
178 * parameter (there can be only one); or to InvalidOid if not.
179 * requiredResultType is set to InvalidOid if there are no OUT parameters,
180 * else it is set to the OID of the implied result type.
183 interpret_function_parameter_list(ParseState
*pstate
,
187 oidvector
**parameterTypes
,
188 List
**parameterTypes_list
,
189 ArrayType
**allParameterTypes
,
190 ArrayType
**parameterModes
,
191 ArrayType
**parameterNames
,
192 List
**inParameterNames_list
,
193 List
**parameterDefaults
,
194 Oid
*variadicArgType
,
195 Oid
*requiredResultType
)
197 int parameterCount
= list_length(parameters
);
205 bool have_names
= false;
206 bool have_defaults
= false;
210 *variadicArgType
= InvalidOid
; /* default result */
211 *requiredResultType
= InvalidOid
; /* default result */
213 inTypes
= (Oid
*) palloc(parameterCount
* sizeof(Oid
));
214 allTypes
= (Datum
*) palloc(parameterCount
* sizeof(Datum
));
215 paramModes
= (Datum
*) palloc(parameterCount
* sizeof(Datum
));
216 paramNames
= (Datum
*) palloc0(parameterCount
* sizeof(Datum
));
217 *parameterDefaults
= NIL
;
219 /* Scan the list and extract data into work arrays */
221 foreach(x
, parameters
)
223 FunctionParameter
*fp
= (FunctionParameter
*) lfirst(x
);
224 TypeName
*t
= fp
->argType
;
225 FunctionParameterMode fpmode
= fp
->mode
;
226 bool isinput
= false;
231 /* For our purposes here, a defaulted mode spec is identical to IN */
232 if (fpmode
== FUNC_PARAM_DEFAULT
)
233 fpmode
= FUNC_PARAM_IN
;
235 typtup
= LookupTypeName(pstate
, t
, NULL
, false);
238 if (!((Form_pg_type
) GETSTRUCT(typtup
))->typisdefined
)
240 /* As above, hard error if language is SQL */
241 if (languageOid
== SQLlanguageId
)
243 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
244 errmsg("SQL function cannot accept shell type %s",
245 TypeNameToString(t
)),
246 parser_errposition(pstate
, t
->location
)));
247 /* We don't allow creating aggregates on shell types either */
248 else if (objtype
== OBJECT_AGGREGATE
)
250 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
251 errmsg("aggregate cannot accept shell type %s",
252 TypeNameToString(t
)),
253 parser_errposition(pstate
, t
->location
)));
256 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
257 errmsg("argument type %s is only a shell",
258 TypeNameToString(t
)),
259 parser_errposition(pstate
, t
->location
)));
261 toid
= typeTypeId(typtup
);
262 ReleaseSysCache(typtup
);
267 (errcode(ERRCODE_UNDEFINED_OBJECT
),
268 errmsg("type %s does not exist",
269 TypeNameToString(t
)),
270 parser_errposition(pstate
, t
->location
)));
271 toid
= InvalidOid
; /* keep compiler quiet */
274 aclresult
= object_aclcheck(TypeRelationId
, toid
, GetUserId(), ACL_USAGE
);
275 if (aclresult
!= ACLCHECK_OK
)
276 aclcheck_error_type(aclresult
, toid
);
280 if (objtype
== OBJECT_AGGREGATE
)
282 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
283 errmsg("aggregates cannot accept set arguments"),
284 parser_errposition(pstate
, fp
->location
)));
285 else if (objtype
== OBJECT_PROCEDURE
)
287 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
288 errmsg("procedures cannot accept set arguments"),
289 parser_errposition(pstate
, fp
->location
)));
292 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
293 errmsg("functions cannot accept set arguments"),
294 parser_errposition(pstate
, fp
->location
)));
297 /* handle input parameters */
298 if (fpmode
!= FUNC_PARAM_OUT
&& fpmode
!= FUNC_PARAM_TABLE
)
300 /* other input parameters can't follow a VARIADIC parameter */
303 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
304 errmsg("VARIADIC parameter must be the last input parameter"),
305 parser_errposition(pstate
, fp
->location
)));
306 inTypes
[inCount
++] = toid
;
308 if (parameterTypes_list
)
309 *parameterTypes_list
= lappend_oid(*parameterTypes_list
, toid
);
312 /* handle output parameters */
313 if (fpmode
!= FUNC_PARAM_IN
&& fpmode
!= FUNC_PARAM_VARIADIC
)
315 if (objtype
== OBJECT_PROCEDURE
)
318 * We disallow OUT-after-VARIADIC only for procedures. While
319 * such a case causes no confusion in ordinary function calls,
320 * it would cause confusion in a CALL statement.
324 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
325 errmsg("VARIADIC parameter must be the last parameter"),
326 parser_errposition(pstate
, fp
->location
)));
327 /* Procedures with output parameters always return RECORD */
328 *requiredResultType
= RECORDOID
;
330 else if (outCount
== 0) /* save first output param's type */
331 *requiredResultType
= toid
;
335 if (fpmode
== FUNC_PARAM_VARIADIC
)
337 *variadicArgType
= toid
;
339 /* validate variadic parameter type */
343 case ANYCOMPATIBLEARRAYOID
:
348 if (!OidIsValid(get_element_type(toid
)))
350 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
351 errmsg("VARIADIC parameter must be an array"),
352 parser_errposition(pstate
, fp
->location
)));
357 allTypes
[i
] = ObjectIdGetDatum(toid
);
359 paramModes
[i
] = CharGetDatum(fpmode
);
361 if (fp
->name
&& fp
->name
[0])
366 * As of Postgres 9.0 we disallow using the same name for two
367 * input or two output function parameters. Depending on the
368 * function's language, conflicting input and output names might
369 * be bad too, but we leave it to the PL to complain if so.
371 foreach(px
, parameters
)
373 FunctionParameter
*prevfp
= (FunctionParameter
*) lfirst(px
);
374 FunctionParameterMode prevfpmode
;
378 /* as above, default mode is IN */
379 prevfpmode
= prevfp
->mode
;
380 if (prevfpmode
== FUNC_PARAM_DEFAULT
)
381 prevfpmode
= FUNC_PARAM_IN
;
382 /* pure in doesn't conflict with pure out */
383 if ((fpmode
== FUNC_PARAM_IN
||
384 fpmode
== FUNC_PARAM_VARIADIC
) &&
385 (prevfpmode
== FUNC_PARAM_OUT
||
386 prevfpmode
== FUNC_PARAM_TABLE
))
388 if ((prevfpmode
== FUNC_PARAM_IN
||
389 prevfpmode
== FUNC_PARAM_VARIADIC
) &&
390 (fpmode
== FUNC_PARAM_OUT
||
391 fpmode
== FUNC_PARAM_TABLE
))
393 if (prevfp
->name
&& prevfp
->name
[0] &&
394 strcmp(prevfp
->name
, fp
->name
) == 0)
396 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
397 errmsg("parameter name \"%s\" used more than once",
399 parser_errposition(pstate
, fp
->location
)));
402 paramNames
[i
] = CStringGetTextDatum(fp
->name
);
406 if (inParameterNames_list
)
407 *inParameterNames_list
= lappend(*inParameterNames_list
, makeString(fp
->name
? fp
->name
: pstrdup("")));
415 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
416 errmsg("only input parameters can have default values"),
417 parser_errposition(pstate
, fp
->location
)));
419 def
= transformExpr(pstate
, fp
->defexpr
,
420 EXPR_KIND_FUNCTION_DEFAULT
);
421 def
= coerce_to_specific_type(pstate
, def
, toid
, "DEFAULT");
422 assign_expr_collations(pstate
, def
);
425 * Make sure no variables are referred to (this is probably dead
426 * code now that add_missing_from is history).
428 if (pstate
->p_rtable
!= NIL
||
429 contain_var_clause(def
))
431 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE
),
432 errmsg("cannot use table references in parameter default value"),
433 parser_errposition(pstate
, fp
->location
)));
436 * transformExpr() should have already rejected subqueries,
437 * aggregates, and window functions, based on the EXPR_KIND_ for a
438 * default expression.
440 * It can't return a set either --- but coerce_to_specific_type
441 * already checked that for us.
443 * Note: the point of these restrictions is to ensure that an
444 * expression that, on its face, hasn't got subplans, aggregates,
445 * etc cannot suddenly have them after function default arguments
449 *parameterDefaults
= lappend(*parameterDefaults
, def
);
450 have_defaults
= true;
454 if (isinput
&& have_defaults
)
456 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
457 errmsg("input parameters after one with a default value must also have defaults"),
458 parser_errposition(pstate
, fp
->location
)));
461 * For procedures, we also can't allow OUT parameters after one
462 * with a default, because the same sort of confusion arises in a
465 if (objtype
== OBJECT_PROCEDURE
&& have_defaults
)
467 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
468 errmsg("procedure OUT parameters cannot appear after one with a default value"),
469 parser_errposition(pstate
, fp
->location
)));
475 /* Now construct the proper outputs as needed */
476 *parameterTypes
= buildoidvector(inTypes
, inCount
);
478 if (outCount
> 0 || varCount
> 0)
480 *allParameterTypes
= construct_array_builtin(allTypes
, parameterCount
, OIDOID
);
481 *parameterModes
= construct_array_builtin(paramModes
, parameterCount
, CHAROID
);
483 *requiredResultType
= RECORDOID
;
484 /* otherwise we set requiredResultType correctly above */
488 *allParameterTypes
= NULL
;
489 *parameterModes
= NULL
;
494 for (i
= 0; i
< parameterCount
; i
++)
496 if (paramNames
[i
] == PointerGetDatum(NULL
))
497 paramNames
[i
] = CStringGetTextDatum("");
499 *parameterNames
= construct_array_builtin(paramNames
, parameterCount
, TEXTOID
);
502 *parameterNames
= NULL
;
507 * Recognize one of the options that can be passed to both CREATE
508 * FUNCTION and ALTER FUNCTION and return it via one of the out
509 * parameters. Returns true if the passed option was recognized. If
510 * the out parameter we were going to assign to points to non-NULL,
511 * raise a duplicate-clause error. (We don't try to detect duplicate
512 * SET parameters though --- if you're redundant, the last one wins.)
515 compute_common_attribute(ParseState
*pstate
,
518 DefElem
**volatility_item
,
519 DefElem
**strict_item
,
520 DefElem
**security_item
,
521 DefElem
**leakproof_item
,
525 DefElem
**support_item
,
526 DefElem
**parallel_item
)
528 if (strcmp(defel
->defname
, "volatility") == 0)
531 goto procedure_error
;
532 if (*volatility_item
)
533 errorConflictingDefElem(defel
, pstate
);
535 *volatility_item
= defel
;
537 else if (strcmp(defel
->defname
, "strict") == 0)
540 goto procedure_error
;
542 errorConflictingDefElem(defel
, pstate
);
544 *strict_item
= defel
;
546 else if (strcmp(defel
->defname
, "security") == 0)
549 errorConflictingDefElem(defel
, pstate
);
551 *security_item
= defel
;
553 else if (strcmp(defel
->defname
, "leakproof") == 0)
556 goto procedure_error
;
558 errorConflictingDefElem(defel
, pstate
);
560 *leakproof_item
= defel
;
562 else if (strcmp(defel
->defname
, "set") == 0)
564 *set_items
= lappend(*set_items
, defel
->arg
);
566 else if (strcmp(defel
->defname
, "cost") == 0)
569 goto procedure_error
;
571 errorConflictingDefElem(defel
, pstate
);
575 else if (strcmp(defel
->defname
, "rows") == 0)
578 goto procedure_error
;
580 errorConflictingDefElem(defel
, pstate
);
584 else if (strcmp(defel
->defname
, "support") == 0)
587 goto procedure_error
;
589 errorConflictingDefElem(defel
, pstate
);
591 *support_item
= defel
;
593 else if (strcmp(defel
->defname
, "parallel") == 0)
596 goto procedure_error
;
598 errorConflictingDefElem(defel
, pstate
);
600 *parallel_item
= defel
;
605 /* Recognized an option */
610 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
611 errmsg("invalid attribute in procedure definition"),
612 parser_errposition(pstate
, defel
->location
)));
617 interpret_func_volatility(DefElem
*defel
)
619 char *str
= strVal(defel
->arg
);
621 if (strcmp(str
, "immutable") == 0)
622 return PROVOLATILE_IMMUTABLE
;
623 else if (strcmp(str
, "stable") == 0)
624 return PROVOLATILE_STABLE
;
625 else if (strcmp(str
, "volatile") == 0)
626 return PROVOLATILE_VOLATILE
;
629 elog(ERROR
, "invalid volatility \"%s\"", str
);
630 return 0; /* keep compiler quiet */
635 interpret_func_parallel(DefElem
*defel
)
637 char *str
= strVal(defel
->arg
);
639 if (strcmp(str
, "safe") == 0)
640 return PROPARALLEL_SAFE
;
641 else if (strcmp(str
, "unsafe") == 0)
642 return PROPARALLEL_UNSAFE
;
643 else if (strcmp(str
, "restricted") == 0)
644 return PROPARALLEL_RESTRICTED
;
648 (errcode(ERRCODE_SYNTAX_ERROR
),
649 errmsg("parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE")));
650 return PROPARALLEL_UNSAFE
; /* keep compiler quiet */
655 * Update a proconfig value according to a list of VariableSetStmt items.
657 * The input and result may be NULL to signify a null entry.
660 update_proconfig_value(ArrayType
*a
, List
*set_items
)
664 foreach(l
, set_items
)
666 VariableSetStmt
*sstmt
= lfirst_node(VariableSetStmt
, l
);
668 if (sstmt
->kind
== VAR_RESET_ALL
)
672 char *valuestr
= ExtractSetVariableArgs(sstmt
);
675 a
= GUCArrayAdd(a
, sstmt
->name
, valuestr
);
677 a
= GUCArrayDelete(a
, sstmt
->name
);
685 interpret_func_support(DefElem
*defel
)
687 List
*procName
= defGetQualifiedName(defel
);
692 * Support functions always take one INTERNAL argument and return
695 argList
[0] = INTERNALOID
;
697 procOid
= LookupFuncName(procName
, 1, argList
, true);
698 if (!OidIsValid(procOid
))
700 (errcode(ERRCODE_UNDEFINED_FUNCTION
),
701 errmsg("function %s does not exist",
702 func_signature_string(procName
, 1, NIL
, argList
))));
704 if (get_func_rettype(procOid
) != INTERNALOID
)
706 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
707 errmsg("support function %s must return type %s",
708 NameListToString(procName
), "internal")));
711 * Someday we might want an ACL check here; but for now, we insist that
712 * you be superuser to specify a support function, so privilege on the
713 * support function is moot.
717 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
718 errmsg("must be superuser to specify a support function")));
725 * Dissect the list of options assembled in gram.y into function
729 compute_function_attributes(ParseState
*pstate
,
738 bool *security_definer
,
740 ArrayType
**proconfig
,
747 DefElem
*as_item
= NULL
;
748 DefElem
*language_item
= NULL
;
749 DefElem
*transform_item
= NULL
;
750 DefElem
*windowfunc_item
= NULL
;
751 DefElem
*volatility_item
= NULL
;
752 DefElem
*strict_item
= NULL
;
753 DefElem
*security_item
= NULL
;
754 DefElem
*leakproof_item
= NULL
;
755 List
*set_items
= NIL
;
756 DefElem
*cost_item
= NULL
;
757 DefElem
*rows_item
= NULL
;
758 DefElem
*support_item
= NULL
;
759 DefElem
*parallel_item
= NULL
;
761 foreach(option
, options
)
763 DefElem
*defel
= (DefElem
*) lfirst(option
);
765 if (strcmp(defel
->defname
, "as") == 0)
768 errorConflictingDefElem(defel
, pstate
);
771 else if (strcmp(defel
->defname
, "language") == 0)
774 errorConflictingDefElem(defel
, pstate
);
775 language_item
= defel
;
777 else if (strcmp(defel
->defname
, "transform") == 0)
780 errorConflictingDefElem(defel
, pstate
);
781 transform_item
= defel
;
783 else if (strcmp(defel
->defname
, "window") == 0)
786 errorConflictingDefElem(defel
, pstate
);
789 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
790 errmsg("invalid attribute in procedure definition"),
791 parser_errposition(pstate
, defel
->location
)));
792 windowfunc_item
= defel
;
794 else if (compute_common_attribute(pstate
,
807 /* recognized common option */
811 elog(ERROR
, "option \"%s\" not recognized",
816 *as
= (List
*) as_item
->arg
;
818 *language
= strVal(language_item
->arg
);
820 *transform
= transform_item
->arg
;
822 *windowfunc_p
= boolVal(windowfunc_item
->arg
);
824 *volatility_p
= interpret_func_volatility(volatility_item
);
826 *strict_p
= boolVal(strict_item
->arg
);
828 *security_definer
= boolVal(security_item
->arg
);
830 *leakproof_p
= boolVal(leakproof_item
->arg
);
832 *proconfig
= update_proconfig_value(NULL
, set_items
);
835 *procost
= defGetNumeric(cost_item
);
838 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
839 errmsg("COST must be positive")));
843 *prorows
= defGetNumeric(rows_item
);
846 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
847 errmsg("ROWS must be positive")));
850 *prosupport
= interpret_func_support(support_item
);
852 *parallel_p
= interpret_func_parallel(parallel_item
);
857 * For a dynamically linked C language object, the form of the clause is
859 * AS <object file name> [, <link symbol name> ]
863 * AS <object reference, or sql code>
866 interpret_AS_clause(Oid languageOid
, const char *languageName
,
867 char *funcname
, List
*as
, Node
*sql_body_in
,
868 List
*parameterTypes
, List
*inParameterNames
,
869 char **prosrc_str_p
, char **probin_str_p
,
871 const char *queryString
)
873 if (!sql_body_in
&& !as
)
875 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
876 errmsg("no function body specified")));
878 if (sql_body_in
&& as
)
880 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
881 errmsg("duplicate function body specified")));
883 if (sql_body_in
&& languageOid
!= SQLlanguageId
)
885 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
886 errmsg("inline SQL function body only valid for language SQL")));
888 *sql_body_out
= NULL
;
890 if (languageOid
== ClanguageId
)
893 * For "C" language, store the file name in probin and, when given,
894 * the link symbol name in prosrc. If link symbol is omitted,
895 * substitute procedure name. We also allow link symbol to be
896 * specified as "-", since that was the habit in PG versions before
897 * 8.4, and there might be dump files out there that don't translate
898 * that back to "omitted".
900 *probin_str_p
= strVal(linitial(as
));
901 if (list_length(as
) == 1)
902 *prosrc_str_p
= funcname
;
905 *prosrc_str_p
= strVal(lsecond(as
));
906 if (strcmp(*prosrc_str_p
, "-") == 0)
907 *prosrc_str_p
= funcname
;
910 else if (sql_body_in
)
912 SQLFunctionParseInfoPtr pinfo
;
914 pinfo
= (SQLFunctionParseInfoPtr
) palloc0(sizeof(SQLFunctionParseInfo
));
916 pinfo
->fname
= funcname
;
917 pinfo
->nargs
= list_length(parameterTypes
);
918 pinfo
->argtypes
= (Oid
*) palloc(pinfo
->nargs
* sizeof(Oid
));
919 pinfo
->argnames
= (char **) palloc(pinfo
->nargs
* sizeof(char *));
920 for (int i
= 0; i
< list_length(parameterTypes
); i
++)
922 char *s
= strVal(list_nth(inParameterNames
, i
));
924 pinfo
->argtypes
[i
] = list_nth_oid(parameterTypes
, i
);
925 if (IsPolymorphicType(pinfo
->argtypes
[i
]))
927 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
928 errmsg("SQL function with unquoted function body cannot have polymorphic arguments")));
931 pinfo
->argnames
[i
] = s
;
933 pinfo
->argnames
[i
] = NULL
;
936 if (IsA(sql_body_in
, List
))
938 List
*stmts
= linitial_node(List
, castNode(List
, sql_body_in
));
940 List
*transformed_stmts
= NIL
;
944 Node
*stmt
= lfirst(lc
);
946 ParseState
*pstate
= make_parsestate(NULL
);
948 pstate
->p_sourcetext
= queryString
;
949 sql_fn_parser_setup(pstate
, pinfo
);
950 q
= transformStmt(pstate
, stmt
);
951 if (q
->commandType
== CMD_UTILITY
)
953 errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
954 errmsg("%s is not yet supported in unquoted SQL function body",
955 GetCommandTagName(CreateCommandTag(q
->utilityStmt
))));
956 transformed_stmts
= lappend(transformed_stmts
, q
);
957 free_parsestate(pstate
);
960 *sql_body_out
= (Node
*) list_make1(transformed_stmts
);
965 ParseState
*pstate
= make_parsestate(NULL
);
967 pstate
->p_sourcetext
= queryString
;
968 sql_fn_parser_setup(pstate
, pinfo
);
969 q
= transformStmt(pstate
, sql_body_in
);
970 if (q
->commandType
== CMD_UTILITY
)
972 errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
973 errmsg("%s is not yet supported in unquoted SQL function body",
974 GetCommandTagName(CreateCommandTag(q
->utilityStmt
))));
975 free_parsestate(pstate
);
977 *sql_body_out
= (Node
*) q
;
981 * We must put something in prosrc. For the moment, just record an
982 * empty string. It might be useful to store the original text of the
983 * CREATE FUNCTION statement --- but to make actual use of that in
984 * error reports, we'd also have to adjust readfuncs.c to not throw
985 * away node location fields when reading prosqlbody.
987 *prosrc_str_p
= pstrdup("");
989 /* But we definitely don't need probin. */
990 *probin_str_p
= NULL
;
994 /* Everything else wants the given string in prosrc. */
995 *prosrc_str_p
= strVal(linitial(as
));
996 *probin_str_p
= NULL
;
998 if (list_length(as
) != 1)
1000 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
1001 errmsg("only one AS item needed for language \"%s\"",
1004 if (languageOid
== INTERNALlanguageId
)
1007 * In PostgreSQL versions before 6.5, the SQL name of the created
1008 * function could not be different from the internal name, and
1009 * "prosrc" wasn't used. So there is code out there that does
1010 * CREATE FUNCTION xyz AS '' LANGUAGE internal. To preserve some
1011 * modicum of backwards compatibility, accept an empty "prosrc"
1012 * value as meaning the supplied SQL function name.
1014 if (strlen(*prosrc_str_p
) == 0)
1015 *prosrc_str_p
= funcname
;
1023 * Execute a CREATE FUNCTION (or CREATE PROCEDURE) utility statement.
1026 CreateFunction(ParseState
*pstate
, CreateFunctionStmt
*stmt
)
1035 Oid languageValidator
;
1036 Node
*transformDefElem
= NULL
;
1039 AclResult aclresult
;
1040 oidvector
*parameterTypes
;
1041 List
*parameterTypes_list
= NIL
;
1042 ArrayType
*allParameterTypes
;
1043 ArrayType
*parameterModes
;
1044 ArrayType
*parameterNames
;
1045 List
*inParameterNames_list
= NIL
;
1046 List
*parameterDefaults
;
1047 Oid variadicArgType
;
1048 List
*trftypes_list
= NIL
;
1049 ArrayType
*trftypes
;
1050 Oid requiredResultType
;
1056 ArrayType
*proconfig
;
1060 HeapTuple languageTuple
;
1061 Form_pg_language languageStruct
;
1065 /* Convert list of names to a name and namespace */
1066 namespaceId
= QualifiedNameGetCreationNamespace(stmt
->funcname
,
1069 /* Check we have creation rights in target namespace */
1070 aclresult
= object_aclcheck(NamespaceRelationId
, namespaceId
, GetUserId(), ACL_CREATE
);
1071 if (aclresult
!= ACLCHECK_OK
)
1072 aclcheck_error(aclresult
, OBJECT_SCHEMA
,
1073 get_namespace_name(namespaceId
));
1075 /* Set default attributes */
1078 isWindowFunc
= false;
1081 isLeakProof
= false;
1082 volatility
= PROVOLATILE_VOLATILE
;
1084 procost
= -1; /* indicates not set */
1085 prorows
= -1; /* indicates not set */
1086 prosupport
= InvalidOid
;
1087 parallel
= PROPARALLEL_UNSAFE
;
1089 /* Extract non-default attributes from stmt->options list */
1090 compute_function_attributes(pstate
,
1093 &as_clause
, &language
, &transformDefElem
,
1094 &isWindowFunc
, &volatility
,
1095 &isStrict
, &security
, &isLeakProof
,
1096 &proconfig
, &procost
, &prorows
,
1097 &prosupport
, ¶llel
);
1105 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
1106 errmsg("no language specified")));
1109 /* Look up the language and validate permissions */
1110 languageTuple
= SearchSysCache1(LANGNAME
, PointerGetDatum(language
));
1111 if (!HeapTupleIsValid(languageTuple
))
1113 (errcode(ERRCODE_UNDEFINED_OBJECT
),
1114 errmsg("language \"%s\" does not exist", language
),
1115 (extension_file_exists(language
) ?
1116 errhint("Use CREATE EXTENSION to load the language into the database.") : 0)));
1118 languageStruct
= (Form_pg_language
) GETSTRUCT(languageTuple
);
1119 languageOid
= languageStruct
->oid
;
1121 if (languageStruct
->lanpltrusted
)
1123 /* if trusted language, need USAGE privilege */
1124 aclresult
= object_aclcheck(LanguageRelationId
, languageOid
, GetUserId(), ACL_USAGE
);
1125 if (aclresult
!= ACLCHECK_OK
)
1126 aclcheck_error(aclresult
, OBJECT_LANGUAGE
,
1127 NameStr(languageStruct
->lanname
));
1131 /* if untrusted language, must be superuser */
1133 aclcheck_error(ACLCHECK_NO_PRIV
, OBJECT_LANGUAGE
,
1134 NameStr(languageStruct
->lanname
));
1137 languageValidator
= languageStruct
->lanvalidator
;
1139 ReleaseSysCache(languageTuple
);
1142 * Only superuser is allowed to create leakproof functions because
1143 * leakproof functions can see tuples which have not yet been filtered out
1144 * by security barrier views or row-level security policies.
1146 if (isLeakProof
&& !superuser())
1148 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
1149 errmsg("only superuser can define a leakproof function")));
1151 if (transformDefElem
)
1155 foreach(lc
, castNode(List
, transformDefElem
))
1157 Oid
typeid = typenameTypeId(NULL
,
1158 lfirst_node(TypeName
, lc
));
1159 Oid elt
= get_base_element_type(typeid);
1161 typeid = elt
? elt
: typeid;
1163 get_transform_oid(typeid, languageOid
, false);
1164 trftypes_list
= lappend_oid(trftypes_list
, typeid);
1169 * Convert remaining parameters of CREATE to form wanted by
1172 interpret_function_parameter_list(pstate
,
1175 stmt
->is_procedure
? OBJECT_PROCEDURE
: OBJECT_FUNCTION
,
1177 ¶meterTypes_list
,
1181 &inParameterNames_list
,
1184 &requiredResultType
);
1186 if (stmt
->is_procedure
)
1188 Assert(!stmt
->returnType
);
1189 prorettype
= requiredResultType
? requiredResultType
: VOIDOID
;
1192 else if (stmt
->returnType
)
1194 /* explicit RETURNS clause */
1195 compute_return_type(stmt
->returnType
, languageOid
,
1196 &prorettype
, &returnsSet
);
1197 if (OidIsValid(requiredResultType
) && prorettype
!= requiredResultType
)
1199 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
1200 errmsg("function result type must be %s because of OUT parameters",
1201 format_type_be(requiredResultType
))));
1203 else if (OidIsValid(requiredResultType
))
1205 /* default RETURNS clause from OUT parameters */
1206 prorettype
= requiredResultType
;
1212 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION
),
1213 errmsg("function result type must be specified")));
1214 /* Alternative possibility: default to RETURNS VOID */
1215 prorettype
= VOIDOID
;
1219 if (trftypes_list
!= NIL
)
1225 arr
= palloc(list_length(trftypes_list
) * sizeof(Datum
));
1227 foreach(lc
, trftypes_list
)
1228 arr
[i
++] = ObjectIdGetDatum(lfirst_oid(lc
));
1229 trftypes
= construct_array_builtin(arr
, list_length(trftypes_list
), OIDOID
);
1233 /* store SQL NULL instead of empty array */
1237 interpret_AS_clause(languageOid
, language
, funcname
, as_clause
, stmt
->sql_body
,
1238 parameterTypes_list
, inParameterNames_list
,
1239 &prosrc_str
, &probin_str
, &prosqlbody
,
1240 pstate
->p_sourcetext
);
1243 * Set default values for COST and ROWS depending on other parameters;
1244 * reject ROWS if it's not returnsSet. NB: pg_dump knows these default
1245 * values, keep it in sync if you change them.
1249 /* SQL and PL-language functions are assumed more expensive */
1250 if (languageOid
== INTERNALlanguageId
||
1251 languageOid
== ClanguageId
)
1261 prorows
= 0; /* dummy value if not returnsSet */
1263 else if (!returnsSet
)
1265 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
1266 errmsg("ROWS is not applicable when function does not return a set")));
1269 * And now that we have all the parameters, and know we're permitted to do
1270 * so, go ahead and create the function.
1272 return ProcedureCreate(funcname
,
1280 prosrc_str
, /* converted to text later */
1281 probin_str
, /* converted to text later */
1283 stmt
->is_procedure
? PROKIND_PROCEDURE
: (isWindowFunc
? PROKIND_WINDOW
: PROKIND_FUNCTION
),
1290 PointerGetDatum(allParameterTypes
),
1291 PointerGetDatum(parameterModes
),
1292 PointerGetDatum(parameterNames
),
1294 PointerGetDatum(trftypes
),
1295 PointerGetDatum(proconfig
),
1302 * Guts of function deletion.
1304 * Note: this is also used for aggregate deletion, since the OIDs of
1305 * both functions and aggregates point to pg_proc.
1308 RemoveFunctionById(Oid funcOid
)
1315 * Delete the pg_proc tuple.
1317 relation
= table_open(ProcedureRelationId
, RowExclusiveLock
);
1319 tup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcOid
));
1320 if (!HeapTupleIsValid(tup
)) /* should not happen */
1321 elog(ERROR
, "cache lookup failed for function %u", funcOid
);
1323 prokind
= ((Form_pg_proc
) GETSTRUCT(tup
))->prokind
;
1325 CatalogTupleDelete(relation
, &tup
->t_self
);
1327 ReleaseSysCache(tup
);
1329 table_close(relation
, RowExclusiveLock
);
1331 pgstat_drop_function(funcOid
);
1334 * If there's a pg_aggregate tuple, delete that too.
1336 if (prokind
== PROKIND_AGGREGATE
)
1338 relation
= table_open(AggregateRelationId
, RowExclusiveLock
);
1340 tup
= SearchSysCache1(AGGFNOID
, ObjectIdGetDatum(funcOid
));
1341 if (!HeapTupleIsValid(tup
)) /* should not happen */
1342 elog(ERROR
, "cache lookup failed for pg_aggregate tuple for function %u", funcOid
);
1344 CatalogTupleDelete(relation
, &tup
->t_self
);
1346 ReleaseSysCache(tup
);
1348 table_close(relation
, RowExclusiveLock
);
1353 * Implements the ALTER FUNCTION utility command (except for the
1354 * RENAME and OWNER clauses, which are handled as part of the generic
1358 AlterFunction(ParseState
*pstate
, AlterFunctionStmt
*stmt
)
1362 Form_pg_proc procForm
;
1366 DefElem
*volatility_item
= NULL
;
1367 DefElem
*strict_item
= NULL
;
1368 DefElem
*security_def_item
= NULL
;
1369 DefElem
*leakproof_item
= NULL
;
1370 List
*set_items
= NIL
;
1371 DefElem
*cost_item
= NULL
;
1372 DefElem
*rows_item
= NULL
;
1373 DefElem
*support_item
= NULL
;
1374 DefElem
*parallel_item
= NULL
;
1375 ObjectAddress address
;
1377 rel
= table_open(ProcedureRelationId
, RowExclusiveLock
);
1379 funcOid
= LookupFuncWithArgs(stmt
->objtype
, stmt
->func
, false);
1381 ObjectAddressSet(address
, ProcedureRelationId
, funcOid
);
1383 tup
= SearchSysCacheCopy1(PROCOID
, ObjectIdGetDatum(funcOid
));
1384 if (!HeapTupleIsValid(tup
)) /* should not happen */
1385 elog(ERROR
, "cache lookup failed for function %u", funcOid
);
1387 procForm
= (Form_pg_proc
) GETSTRUCT(tup
);
1389 /* Permission check: must own function */
1390 if (!object_ownercheck(ProcedureRelationId
, funcOid
, GetUserId()))
1391 aclcheck_error(ACLCHECK_NOT_OWNER
, stmt
->objtype
,
1392 NameListToString(stmt
->func
->objname
));
1394 if (procForm
->prokind
== PROKIND_AGGREGATE
)
1396 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
1397 errmsg("\"%s\" is an aggregate function",
1398 NameListToString(stmt
->func
->objname
))));
1400 is_procedure
= (procForm
->prokind
== PROKIND_PROCEDURE
);
1402 /* Examine requested actions. */
1403 foreach(l
, stmt
->actions
)
1405 DefElem
*defel
= (DefElem
*) lfirst(l
);
1407 if (compute_common_attribute(pstate
,
1418 ¶llel_item
) == false)
1419 elog(ERROR
, "option \"%s\" not recognized", defel
->defname
);
1422 if (volatility_item
)
1423 procForm
->provolatile
= interpret_func_volatility(volatility_item
);
1425 procForm
->proisstrict
= boolVal(strict_item
->arg
);
1426 if (security_def_item
)
1427 procForm
->prosecdef
= boolVal(security_def_item
->arg
);
1430 procForm
->proleakproof
= boolVal(leakproof_item
->arg
);
1431 if (procForm
->proleakproof
&& !superuser())
1433 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
1434 errmsg("only superuser can define a leakproof function")));
1438 procForm
->procost
= defGetNumeric(cost_item
);
1439 if (procForm
->procost
<= 0)
1441 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
1442 errmsg("COST must be positive")));
1446 procForm
->prorows
= defGetNumeric(rows_item
);
1447 if (procForm
->prorows
<= 0)
1449 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
1450 errmsg("ROWS must be positive")));
1451 if (!procForm
->proretset
)
1453 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
1454 errmsg("ROWS is not applicable when function does not return a set")));
1458 /* interpret_func_support handles the privilege check */
1459 Oid newsupport
= interpret_func_support(support_item
);
1461 /* Add or replace dependency on support function */
1462 if (OidIsValid(procForm
->prosupport
))
1464 if (changeDependencyFor(ProcedureRelationId
, funcOid
,
1465 ProcedureRelationId
, procForm
->prosupport
,
1467 elog(ERROR
, "could not change support dependency for function %s",
1468 get_func_name(funcOid
));
1472 ObjectAddress referenced
;
1474 referenced
.classId
= ProcedureRelationId
;
1475 referenced
.objectId
= newsupport
;
1476 referenced
.objectSubId
= 0;
1477 recordDependencyOn(&address
, &referenced
, DEPENDENCY_NORMAL
);
1480 procForm
->prosupport
= newsupport
;
1483 procForm
->proparallel
= interpret_func_parallel(parallel_item
);
1489 Datum repl_val
[Natts_pg_proc
];
1490 bool repl_null
[Natts_pg_proc
];
1491 bool repl_repl
[Natts_pg_proc
];
1493 /* extract existing proconfig setting */
1494 datum
= SysCacheGetAttr(PROCOID
, tup
, Anum_pg_proc_proconfig
, &isnull
);
1495 a
= isnull
? NULL
: DatumGetArrayTypeP(datum
);
1497 /* update according to each SET or RESET item, left to right */
1498 a
= update_proconfig_value(a
, set_items
);
1500 /* update the tuple */
1501 memset(repl_repl
, false, sizeof(repl_repl
));
1502 repl_repl
[Anum_pg_proc_proconfig
- 1] = true;
1506 repl_val
[Anum_pg_proc_proconfig
- 1] = (Datum
) 0;
1507 repl_null
[Anum_pg_proc_proconfig
- 1] = true;
1511 repl_val
[Anum_pg_proc_proconfig
- 1] = PointerGetDatum(a
);
1512 repl_null
[Anum_pg_proc_proconfig
- 1] = false;
1515 tup
= heap_modify_tuple(tup
, RelationGetDescr(rel
),
1516 repl_val
, repl_null
, repl_repl
);
1518 /* DO NOT put more touches of procForm below here; it's now dangling. */
1521 CatalogTupleUpdate(rel
, &tup
->t_self
, tup
);
1523 InvokeObjectPostAlterHook(ProcedureRelationId
, funcOid
, 0);
1525 table_close(rel
, NoLock
);
1526 heap_freetuple(tup
);
1536 CreateCast(CreateCastStmt
*stmt
)
1543 Oid incastid
= InvalidOid
;
1544 Oid outcastid
= InvalidOid
;
1549 AclResult aclresult
;
1550 ObjectAddress myself
;
1552 sourcetypeid
= typenameTypeId(NULL
, stmt
->sourcetype
);
1553 targettypeid
= typenameTypeId(NULL
, stmt
->targettype
);
1554 sourcetyptype
= get_typtype(sourcetypeid
);
1555 targettyptype
= get_typtype(targettypeid
);
1557 /* No pseudo-types allowed */
1558 if (sourcetyptype
== TYPTYPE_PSEUDO
)
1560 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
1561 errmsg("source data type %s is a pseudo-type",
1562 TypeNameToString(stmt
->sourcetype
))));
1564 if (targettyptype
== TYPTYPE_PSEUDO
)
1566 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
1567 errmsg("target data type %s is a pseudo-type",
1568 TypeNameToString(stmt
->targettype
))));
1570 /* Permission check */
1571 if (!object_ownercheck(TypeRelationId
, sourcetypeid
, GetUserId())
1572 && !object_ownercheck(TypeRelationId
, targettypeid
, GetUserId()))
1574 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
1575 errmsg("must be owner of type %s or type %s",
1576 format_type_be(sourcetypeid
),
1577 format_type_be(targettypeid
))));
1579 aclresult
= object_aclcheck(TypeRelationId
, sourcetypeid
, GetUserId(), ACL_USAGE
);
1580 if (aclresult
!= ACLCHECK_OK
)
1581 aclcheck_error_type(aclresult
, sourcetypeid
);
1583 aclresult
= object_aclcheck(TypeRelationId
, targettypeid
, GetUserId(), ACL_USAGE
);
1584 if (aclresult
!= ACLCHECK_OK
)
1585 aclcheck_error_type(aclresult
, targettypeid
);
1587 /* Domains are allowed for historical reasons, but we warn */
1588 if (sourcetyptype
== TYPTYPE_DOMAIN
)
1590 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
1591 errmsg("cast will be ignored because the source data type is a domain")));
1593 else if (targettyptype
== TYPTYPE_DOMAIN
)
1595 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
1596 errmsg("cast will be ignored because the target data type is a domain")));
1598 /* Determine the cast method */
1599 if (stmt
->func
!= NULL
)
1600 castmethod
= COERCION_METHOD_FUNCTION
;
1601 else if (stmt
->inout
)
1602 castmethod
= COERCION_METHOD_INOUT
;
1604 castmethod
= COERCION_METHOD_BINARY
;
1606 if (castmethod
== COERCION_METHOD_FUNCTION
)
1608 Form_pg_proc procstruct
;
1610 funcid
= LookupFuncWithArgs(OBJECT_FUNCTION
, stmt
->func
, false);
1612 tuple
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcid
));
1613 if (!HeapTupleIsValid(tuple
))
1614 elog(ERROR
, "cache lookup failed for function %u", funcid
);
1616 procstruct
= (Form_pg_proc
) GETSTRUCT(tuple
);
1617 nargs
= procstruct
->pronargs
;
1618 if (nargs
< 1 || nargs
> 3)
1620 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1621 errmsg("cast function must take one to three arguments")));
1622 if (!IsBinaryCoercibleWithCast(sourcetypeid
,
1623 procstruct
->proargtypes
.values
[0],
1626 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1627 errmsg("argument of cast function must match or be binary-coercible from source data type")));
1628 if (nargs
> 1 && procstruct
->proargtypes
.values
[1] != INT4OID
)
1630 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1631 errmsg("second argument of cast function must be type %s",
1633 if (nargs
> 2 && procstruct
->proargtypes
.values
[2] != BOOLOID
)
1635 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1636 errmsg("third argument of cast function must be type %s",
1638 if (!IsBinaryCoercibleWithCast(procstruct
->prorettype
,
1642 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1643 errmsg("return data type of cast function must match or be binary-coercible to target data type")));
1646 * Restricting the volatility of a cast function may or may not be a
1647 * good idea in the abstract, but it definitely breaks many old
1648 * user-defined types. Disable this check --- tgl 2/1/03
1651 if (procstruct
->provolatile
== PROVOLATILE_VOLATILE
)
1653 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1654 errmsg("cast function must not be volatile")));
1656 if (procstruct
->prokind
!= PROKIND_FUNCTION
)
1658 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1659 errmsg("cast function must be a normal function")));
1660 if (procstruct
->proretset
)
1662 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1663 errmsg("cast function must not return a set")));
1665 ReleaseSysCache(tuple
);
1669 funcid
= InvalidOid
;
1673 if (castmethod
== COERCION_METHOD_BINARY
)
1683 * Must be superuser to create binary-compatible casts, since
1684 * erroneous casts can easily crash the backend.
1688 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
1689 errmsg("must be superuser to create a cast WITHOUT FUNCTION")));
1692 * Also, insist that the types match as to size, alignment, and
1693 * pass-by-value attributes; this provides at least a crude check that
1694 * they have similar representations. A pair of types that fail this
1695 * test should certainly not be equated.
1697 get_typlenbyvalalign(sourcetypeid
, &typ1len
, &typ1byval
, &typ1align
);
1698 get_typlenbyvalalign(targettypeid
, &typ2len
, &typ2byval
, &typ2align
);
1699 if (typ1len
!= typ2len
||
1700 typ1byval
!= typ2byval
||
1701 typ1align
!= typ2align
)
1703 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1704 errmsg("source and target data types are not physically compatible")));
1707 * We know that composite, array, range and enum types are never
1708 * binary-compatible with each other. They all have OIDs embedded in
1711 * Theoretically you could build a user-defined base type that is
1712 * binary-compatible with such a type. But we disallow it anyway, as
1713 * in practice such a cast is surely a mistake. You can always work
1714 * around that by writing a cast function.
1716 * NOTE: if we ever have a kind of container type that doesn't need to
1717 * be rejected for this reason, we'd likely need to recursively apply
1718 * all of these same checks to the contained type(s).
1720 if (sourcetyptype
== TYPTYPE_COMPOSITE
||
1721 targettyptype
== TYPTYPE_COMPOSITE
)
1723 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1724 errmsg("composite data types are not binary-compatible")));
1726 if (OidIsValid(get_element_type(sourcetypeid
)) ||
1727 OidIsValid(get_element_type(targettypeid
)))
1729 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1730 errmsg("array data types are not binary-compatible")));
1732 if (sourcetyptype
== TYPTYPE_RANGE
||
1733 targettyptype
== TYPTYPE_RANGE
||
1734 sourcetyptype
== TYPTYPE_MULTIRANGE
||
1735 targettyptype
== TYPTYPE_MULTIRANGE
)
1737 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1738 errmsg("range data types are not binary-compatible")));
1740 if (sourcetyptype
== TYPTYPE_ENUM
||
1741 targettyptype
== TYPTYPE_ENUM
)
1743 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1744 errmsg("enum data types are not binary-compatible")));
1747 * We also disallow creating binary-compatibility casts involving
1748 * domains. Casting from a domain to its base type is already
1749 * allowed, and casting the other way ought to go through domain
1750 * coercion to permit constraint checking. Again, if you're intent on
1751 * having your own semantics for that, create a no-op cast function.
1753 * NOTE: if we were to relax this, the above checks for composites
1754 * etc. would have to be modified to look through domains to their
1757 if (sourcetyptype
== TYPTYPE_DOMAIN
||
1758 targettyptype
== TYPTYPE_DOMAIN
)
1760 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1761 errmsg("domain data types must not be marked binary-compatible")));
1765 * Allow source and target types to be same only for length coercion
1766 * functions. We assume a multi-arg function does length coercion.
1768 if (sourcetypeid
== targettypeid
&& nargs
< 2)
1770 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1771 errmsg("source data type and target data type are the same")));
1773 /* convert CoercionContext enum to char value for castcontext */
1774 switch (stmt
->context
)
1776 case COERCION_IMPLICIT
:
1777 castcontext
= COERCION_CODE_IMPLICIT
;
1779 case COERCION_ASSIGNMENT
:
1780 castcontext
= COERCION_CODE_ASSIGNMENT
;
1782 /* COERCION_PLPGSQL is intentionally not covered here */
1783 case COERCION_EXPLICIT
:
1784 castcontext
= COERCION_CODE_EXPLICIT
;
1787 elog(ERROR
, "unrecognized CoercionContext: %d", stmt
->context
);
1788 castcontext
= 0; /* keep compiler quiet */
1792 myself
= CastCreate(sourcetypeid
, targettypeid
, funcid
, incastid
, outcastid
,
1793 castcontext
, castmethod
, DEPENDENCY_NORMAL
);
1799 check_transform_function(Form_pg_proc procstruct
)
1801 if (procstruct
->provolatile
== PROVOLATILE_VOLATILE
)
1803 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1804 errmsg("transform function must not be volatile")));
1805 if (procstruct
->prokind
!= PROKIND_FUNCTION
)
1807 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1808 errmsg("transform function must be a normal function")));
1809 if (procstruct
->proretset
)
1811 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1812 errmsg("transform function must not return a set")));
1813 if (procstruct
->pronargs
!= 1)
1815 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1816 errmsg("transform function must take one argument")));
1817 if (procstruct
->proargtypes
.values
[0] != INTERNALOID
)
1819 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1820 errmsg("first argument of transform function must be type %s",
1829 CreateTransform(CreateTransformStmt
*stmt
)
1836 AclResult aclresult
;
1837 Form_pg_proc procstruct
;
1838 Datum values
[Natts_pg_transform
];
1839 bool nulls
[Natts_pg_transform
] = {0};
1840 bool replaces
[Natts_pg_transform
] = {0};
1845 ObjectAddress myself
,
1847 ObjectAddresses
*addrs
;
1853 typeid = typenameTypeId(NULL
, stmt
->type_name
);
1854 typtype
= get_typtype(typeid);
1856 if (typtype
== TYPTYPE_PSEUDO
)
1858 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
1859 errmsg("data type %s is a pseudo-type",
1860 TypeNameToString(stmt
->type_name
))));
1862 if (typtype
== TYPTYPE_DOMAIN
)
1864 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
1865 errmsg("data type %s is a domain",
1866 TypeNameToString(stmt
->type_name
))));
1868 if (!object_ownercheck(TypeRelationId
, typeid, GetUserId()))
1869 aclcheck_error_type(ACLCHECK_NOT_OWNER
, typeid);
1871 aclresult
= object_aclcheck(TypeRelationId
, typeid, GetUserId(), ACL_USAGE
);
1872 if (aclresult
!= ACLCHECK_OK
)
1873 aclcheck_error_type(aclresult
, typeid);
1878 langid
= get_language_oid(stmt
->lang
, false);
1880 aclresult
= object_aclcheck(LanguageRelationId
, langid
, GetUserId(), ACL_USAGE
);
1881 if (aclresult
!= ACLCHECK_OK
)
1882 aclcheck_error(aclresult
, OBJECT_LANGUAGE
, stmt
->lang
);
1889 fromsqlfuncid
= LookupFuncWithArgs(OBJECT_FUNCTION
, stmt
->fromsql
, false);
1891 if (!object_ownercheck(ProcedureRelationId
, fromsqlfuncid
, GetUserId()))
1892 aclcheck_error(ACLCHECK_NOT_OWNER
, OBJECT_FUNCTION
, NameListToString(stmt
->fromsql
->objname
));
1894 aclresult
= object_aclcheck(ProcedureRelationId
, fromsqlfuncid
, GetUserId(), ACL_EXECUTE
);
1895 if (aclresult
!= ACLCHECK_OK
)
1896 aclcheck_error(aclresult
, OBJECT_FUNCTION
, NameListToString(stmt
->fromsql
->objname
));
1898 tuple
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(fromsqlfuncid
));
1899 if (!HeapTupleIsValid(tuple
))
1900 elog(ERROR
, "cache lookup failed for function %u", fromsqlfuncid
);
1901 procstruct
= (Form_pg_proc
) GETSTRUCT(tuple
);
1902 if (procstruct
->prorettype
!= INTERNALOID
)
1904 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1905 errmsg("return data type of FROM SQL function must be %s",
1907 check_transform_function(procstruct
);
1908 ReleaseSysCache(tuple
);
1911 fromsqlfuncid
= InvalidOid
;
1915 tosqlfuncid
= LookupFuncWithArgs(OBJECT_FUNCTION
, stmt
->tosql
, false);
1917 if (!object_ownercheck(ProcedureRelationId
, tosqlfuncid
, GetUserId()))
1918 aclcheck_error(ACLCHECK_NOT_OWNER
, OBJECT_FUNCTION
, NameListToString(stmt
->tosql
->objname
));
1920 aclresult
= object_aclcheck(ProcedureRelationId
, tosqlfuncid
, GetUserId(), ACL_EXECUTE
);
1921 if (aclresult
!= ACLCHECK_OK
)
1922 aclcheck_error(aclresult
, OBJECT_FUNCTION
, NameListToString(stmt
->tosql
->objname
));
1924 tuple
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(tosqlfuncid
));
1925 if (!HeapTupleIsValid(tuple
))
1926 elog(ERROR
, "cache lookup failed for function %u", tosqlfuncid
);
1927 procstruct
= (Form_pg_proc
) GETSTRUCT(tuple
);
1928 if (procstruct
->prorettype
!= typeid)
1930 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION
),
1931 errmsg("return data type of TO SQL function must be the transform data type")));
1932 check_transform_function(procstruct
);
1933 ReleaseSysCache(tuple
);
1936 tosqlfuncid
= InvalidOid
;
1941 values
[Anum_pg_transform_trftype
- 1] = ObjectIdGetDatum(typeid);
1942 values
[Anum_pg_transform_trflang
- 1] = ObjectIdGetDatum(langid
);
1943 values
[Anum_pg_transform_trffromsql
- 1] = ObjectIdGetDatum(fromsqlfuncid
);
1944 values
[Anum_pg_transform_trftosql
- 1] = ObjectIdGetDatum(tosqlfuncid
);
1946 relation
= table_open(TransformRelationId
, RowExclusiveLock
);
1948 tuple
= SearchSysCache2(TRFTYPELANG
,
1949 ObjectIdGetDatum(typeid),
1950 ObjectIdGetDatum(langid
));
1951 if (HeapTupleIsValid(tuple
))
1953 Form_pg_transform form
= (Form_pg_transform
) GETSTRUCT(tuple
);
1957 (errcode(ERRCODE_DUPLICATE_OBJECT
),
1958 errmsg("transform for type %s language \"%s\" already exists",
1959 format_type_be(typeid),
1962 replaces
[Anum_pg_transform_trffromsql
- 1] = true;
1963 replaces
[Anum_pg_transform_trftosql
- 1] = true;
1965 newtuple
= heap_modify_tuple(tuple
, RelationGetDescr(relation
), values
, nulls
, replaces
);
1966 CatalogTupleUpdate(relation
, &newtuple
->t_self
, newtuple
);
1968 transformid
= form
->oid
;
1969 ReleaseSysCache(tuple
);
1974 transformid
= GetNewOidWithIndex(relation
, TransformOidIndexId
,
1975 Anum_pg_transform_oid
);
1976 values
[Anum_pg_transform_oid
- 1] = ObjectIdGetDatum(transformid
);
1977 newtuple
= heap_form_tuple(RelationGetDescr(relation
), values
, nulls
);
1978 CatalogTupleInsert(relation
, newtuple
);
1983 deleteDependencyRecordsFor(TransformRelationId
, transformid
, true);
1985 addrs
= new_object_addresses();
1987 /* make dependency entries */
1988 ObjectAddressSet(myself
, TransformRelationId
, transformid
);
1990 /* dependency on language */
1991 ObjectAddressSet(referenced
, LanguageRelationId
, langid
);
1992 add_exact_object_address(&referenced
, addrs
);
1994 /* dependency on type */
1995 ObjectAddressSet(referenced
, TypeRelationId
, typeid);
1996 add_exact_object_address(&referenced
, addrs
);
1998 /* dependencies on functions */
1999 if (OidIsValid(fromsqlfuncid
))
2001 ObjectAddressSet(referenced
, ProcedureRelationId
, fromsqlfuncid
);
2002 add_exact_object_address(&referenced
, addrs
);
2004 if (OidIsValid(tosqlfuncid
))
2006 ObjectAddressSet(referenced
, ProcedureRelationId
, tosqlfuncid
);
2007 add_exact_object_address(&referenced
, addrs
);
2010 record_object_address_dependencies(&myself
, addrs
, DEPENDENCY_NORMAL
);
2011 free_object_addresses(addrs
);
2013 /* dependency on extension */
2014 recordDependencyOnCurrentExtension(&myself
, is_replace
);
2016 /* Post creation hook for new transform */
2017 InvokeObjectPostCreateHook(TransformRelationId
, transformid
, 0);
2019 heap_freetuple(newtuple
);
2021 table_close(relation
, RowExclusiveLock
);
2028 * get_transform_oid - given type OID and language OID, look up a transform OID
2030 * If missing_ok is false, throw an error if the transform is not found. If
2031 * true, just return InvalidOid.
2034 get_transform_oid(Oid type_id
, Oid lang_id
, bool missing_ok
)
2038 oid
= GetSysCacheOid2(TRFTYPELANG
, Anum_pg_transform_oid
,
2039 ObjectIdGetDatum(type_id
),
2040 ObjectIdGetDatum(lang_id
));
2041 if (!OidIsValid(oid
) && !missing_ok
)
2043 (errcode(ERRCODE_UNDEFINED_OBJECT
),
2044 errmsg("transform for type %s language \"%s\" does not exist",
2045 format_type_be(type_id
),
2046 get_language_name(lang_id
, false))));
2052 * Subroutine for ALTER FUNCTION/AGGREGATE SET SCHEMA/RENAME
2054 * Is there a function with the given name and signature already in the given
2055 * namespace? If so, raise an appropriate error message.
2058 IsThereFunctionInNamespace(const char *proname
, int pronargs
,
2059 oidvector
*proargtypes
, Oid nspOid
)
2061 /* check for duplicate name (more friendly than unique-index failure) */
2062 if (SearchSysCacheExists3(PROCNAMEARGSNSP
,
2063 CStringGetDatum(proname
),
2064 PointerGetDatum(proargtypes
),
2065 ObjectIdGetDatum(nspOid
)))
2067 (errcode(ERRCODE_DUPLICATE_FUNCTION
),
2068 errmsg("function %s already exists in schema \"%s\"",
2069 funcname_signature_string(proname
, pronargs
,
2070 NIL
, proargtypes
->values
),
2071 get_namespace_name(nspOid
))));
2076 * Execute inline procedural-language code
2078 * See at ExecuteCallStmt() about the atomic argument.
2081 ExecuteDoStmt(ParseState
*pstate
, DoStmt
*stmt
, bool atomic
)
2083 InlineCodeBlock
*codeblock
= makeNode(InlineCodeBlock
);
2085 DefElem
*as_item
= NULL
;
2086 DefElem
*language_item
= NULL
;
2089 HeapTuple languageTuple
;
2090 Form_pg_language languageStruct
;
2092 /* Process options we got from gram.y */
2093 foreach(arg
, stmt
->args
)
2095 DefElem
*defel
= (DefElem
*) lfirst(arg
);
2097 if (strcmp(defel
->defname
, "as") == 0)
2100 errorConflictingDefElem(defel
, pstate
);
2103 else if (strcmp(defel
->defname
, "language") == 0)
2106 errorConflictingDefElem(defel
, pstate
);
2107 language_item
= defel
;
2110 elog(ERROR
, "option \"%s\" not recognized",
2115 codeblock
->source_text
= strVal(as_item
->arg
);
2118 (errcode(ERRCODE_SYNTAX_ERROR
),
2119 errmsg("no inline code specified")));
2121 /* if LANGUAGE option wasn't specified, use the default */
2123 language
= strVal(language_item
->arg
);
2125 language
= "plpgsql";
2127 /* Look up the language and validate permissions */
2128 languageTuple
= SearchSysCache1(LANGNAME
, PointerGetDatum(language
));
2129 if (!HeapTupleIsValid(languageTuple
))
2131 (errcode(ERRCODE_UNDEFINED_OBJECT
),
2132 errmsg("language \"%s\" does not exist", language
),
2133 (extension_file_exists(language
) ?
2134 errhint("Use CREATE EXTENSION to load the language into the database.") : 0)));
2136 languageStruct
= (Form_pg_language
) GETSTRUCT(languageTuple
);
2137 codeblock
->langOid
= languageStruct
->oid
;
2138 codeblock
->langIsTrusted
= languageStruct
->lanpltrusted
;
2139 codeblock
->atomic
= atomic
;
2141 if (languageStruct
->lanpltrusted
)
2143 /* if trusted language, need USAGE privilege */
2144 AclResult aclresult
;
2146 aclresult
= object_aclcheck(LanguageRelationId
, codeblock
->langOid
, GetUserId(),
2148 if (aclresult
!= ACLCHECK_OK
)
2149 aclcheck_error(aclresult
, OBJECT_LANGUAGE
,
2150 NameStr(languageStruct
->lanname
));
2154 /* if untrusted language, must be superuser */
2156 aclcheck_error(ACLCHECK_NO_PRIV
, OBJECT_LANGUAGE
,
2157 NameStr(languageStruct
->lanname
));
2160 /* get the handler function's OID */
2161 laninline
= languageStruct
->laninline
;
2162 if (!OidIsValid(laninline
))
2164 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
2165 errmsg("language \"%s\" does not support inline code execution",
2166 NameStr(languageStruct
->lanname
))));
2168 ReleaseSysCache(languageTuple
);
2170 /* execute the inline handler */
2171 OidFunctionCall1(laninline
, PointerGetDatum(codeblock
));
2175 * Execute CALL statement
2177 * Inside a top-level CALL statement, transaction-terminating commands such as
2178 * COMMIT or a PL-specific equivalent are allowed. The terminology in the SQL
2179 * standard is that CALL establishes a non-atomic execution context. Most
2180 * other commands establish an atomic execution context, in which transaction
2181 * control actions are not allowed. If there are nested executions of CALL,
2182 * we want to track the execution context recursively, so that the nested
2183 * CALLs can also do transaction control. Note, however, that for example in
2184 * CALL -> SELECT -> CALL, the second call cannot do transaction control,
2185 * because the SELECT in between establishes an atomic execution context.
2187 * So when ExecuteCallStmt() is called from the top level, we pass in atomic =
2188 * false (recall that that means transactions = yes). We then create a
2189 * CallContext node with content atomic = false, which is passed in the
2190 * fcinfo->context field to the procedure invocation. The language
2191 * implementation should then take appropriate measures to allow or prevent
2192 * transaction commands based on that information, e.g., call
2193 * SPI_connect_ext(SPI_OPT_NONATOMIC). The language should also pass on the
2194 * atomic flag to any nested invocations to CALL.
2196 * The expression data structures and execution context that we create
2197 * within this function are children of the portalContext of the Portal
2198 * that the CALL utility statement runs in. Therefore, any pass-by-ref
2199 * values that we're passing to the procedure will survive transaction
2200 * commits that might occur inside the procedure.
2203 ExecuteCallStmt(CallStmt
*stmt
, ParamListInfo params
, bool atomic
, DestReceiver
*dest
)
2205 LOCAL_FCINFO(fcinfo
, FUNC_MAX_ARGS
);
2210 AclResult aclresult
;
2212 CallContext
*callcontext
;
2214 ExprContext
*econtext
;
2216 PgStat_FunctionCallUsage fcusage
;
2219 fexpr
= stmt
->funcexpr
;
2221 Assert(IsA(fexpr
, FuncExpr
));
2223 aclresult
= object_aclcheck(ProcedureRelationId
, fexpr
->funcid
, GetUserId(), ACL_EXECUTE
);
2224 if (aclresult
!= ACLCHECK_OK
)
2225 aclcheck_error(aclresult
, OBJECT_PROCEDURE
, get_func_name(fexpr
->funcid
));
2227 /* Prep the context object we'll pass to the procedure */
2228 callcontext
= makeNode(CallContext
);
2229 callcontext
->atomic
= atomic
;
2231 tp
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(fexpr
->funcid
));
2232 if (!HeapTupleIsValid(tp
))
2233 elog(ERROR
, "cache lookup failed for function %u", fexpr
->funcid
);
2236 * If proconfig is set we can't allow transaction commands because of the
2237 * way the GUC stacking works: The transaction boundary would have to pop
2238 * the proconfig setting off the stack. That restriction could be lifted
2239 * by redesigning the GUC nesting mechanism a bit.
2241 if (!heap_attisnull(tp
, Anum_pg_proc_proconfig
, NULL
))
2242 callcontext
->atomic
= true;
2245 * In security definer procedures, we can't allow transaction commands.
2246 * StartTransaction() insists that the security context stack is empty,
2247 * and AbortTransaction() resets the security context. This could be
2248 * reorganized, but right now it doesn't work.
2250 if (((Form_pg_proc
) GETSTRUCT(tp
))->prosecdef
)
2251 callcontext
->atomic
= true;
2253 ReleaseSysCache(tp
);
2255 /* safety check; see ExecInitFunc() */
2256 nargs
= list_length(fexpr
->args
);
2257 if (nargs
> FUNC_MAX_ARGS
)
2259 (errcode(ERRCODE_TOO_MANY_ARGUMENTS
),
2260 errmsg_plural("cannot pass more than %d argument to a procedure",
2261 "cannot pass more than %d arguments to a procedure",
2265 /* Initialize function call structure */
2266 InvokeFunctionExecuteHook(fexpr
->funcid
);
2267 fmgr_info(fexpr
->funcid
, &flinfo
);
2268 fmgr_info_set_expr((Node
*) fexpr
, &flinfo
);
2269 InitFunctionCallInfoData(*fcinfo
, &flinfo
, nargs
, fexpr
->inputcollid
,
2270 (Node
*) callcontext
, NULL
);
2273 * Evaluate procedure arguments inside a suitable execution context. Note
2274 * we can't free this context till the procedure returns.
2276 estate
= CreateExecutorState();
2277 estate
->es_param_list_info
= params
;
2278 econtext
= CreateExprContext(estate
);
2281 * If we're called in non-atomic context, we also have to ensure that the
2282 * argument expressions run with an up-to-date snapshot. Our caller will
2283 * have provided a current snapshot in atomic contexts, but not in
2284 * non-atomic contexts, because the possibility of a COMMIT/ROLLBACK
2285 * destroying the snapshot makes higher-level management too complicated.
2288 PushActiveSnapshot(GetTransactionSnapshot());
2291 foreach(lc
, fexpr
->args
)
2293 ExprState
*exprstate
;
2297 exprstate
= ExecPrepareExpr(lfirst(lc
), estate
);
2299 val
= ExecEvalExprSwitchContext(exprstate
, econtext
, &isnull
);
2301 fcinfo
->args
[i
].value
= val
;
2302 fcinfo
->args
[i
].isnull
= isnull
;
2307 /* Get rid of temporary snapshot for arguments, if we made one */
2309 PopActiveSnapshot();
2311 /* Here we actually call the procedure */
2312 pgstat_init_function_usage(fcinfo
, &fcusage
);
2313 retval
= FunctionCallInvoke(fcinfo
);
2314 pgstat_end_function_usage(&fcusage
, true);
2316 /* Handle the procedure's outputs */
2317 if (fexpr
->funcresulttype
== VOIDOID
)
2321 else if (fexpr
->funcresulttype
== RECORDOID
)
2323 /* send tuple to client */
2328 HeapTupleData rettupdata
;
2329 TupOutputState
*tstate
;
2330 TupleTableSlot
*slot
;
2333 elog(ERROR
, "procedure returned null record");
2336 * Ensure there's an active snapshot whilst we execute whatever's
2337 * involved here. Note that this is *not* sufficient to make the
2338 * world safe for TOAST pointers to be included in the returned data:
2339 * the referenced data could have gone away while we didn't hold a
2340 * snapshot. Hence, it's incumbent on PLs that can do COMMIT/ROLLBACK
2341 * to not return TOAST pointers, unless those pointers were fetched
2342 * after the last COMMIT/ROLLBACK in the procedure.
2344 * XXX that is a really nasty, hard-to-test requirement. Is there a
2347 EnsurePortalSnapshotExists();
2349 td
= DatumGetHeapTupleHeader(retval
);
2350 tupType
= HeapTupleHeaderGetTypeId(td
);
2351 tupTypmod
= HeapTupleHeaderGetTypMod(td
);
2352 retdesc
= lookup_rowtype_tupdesc(tupType
, tupTypmod
);
2354 tstate
= begin_tup_output_tupdesc(dest
, retdesc
,
2357 rettupdata
.t_len
= HeapTupleHeaderGetDatumLength(td
);
2358 ItemPointerSetInvalid(&(rettupdata
.t_self
));
2359 rettupdata
.t_tableOid
= InvalidOid
;
2360 rettupdata
.t_data
= td
;
2362 slot
= ExecStoreHeapTuple(&rettupdata
, tstate
->slot
, false);
2363 tstate
->dest
->receiveSlot(slot
, tstate
->dest
);
2365 end_tup_output(tstate
);
2367 ReleaseTupleDesc(retdesc
);
2370 elog(ERROR
, "unexpected result type for procedure: %u",
2371 fexpr
->funcresulttype
);
2373 FreeExecutorState(estate
);
2377 * Construct the tuple descriptor for a CALL statement return
2380 CallStmtResultDesc(CallStmt
*stmt
)
2386 fexpr
= stmt
->funcexpr
;
2388 tuple
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(fexpr
->funcid
));
2389 if (!HeapTupleIsValid(tuple
))
2390 elog(ERROR
, "cache lookup failed for procedure %u", fexpr
->funcid
);
2392 tupdesc
= build_function_result_tupdesc_t(tuple
);
2394 ReleaseSysCache(tuple
);
2397 * The result of build_function_result_tupdesc_t has the right column
2398 * names, but it just has the declared output argument types, which is the
2399 * wrong thing in polymorphic cases. Get the correct types by examining
2400 * stmt->outargs. We intentionally keep the atttypmod as -1 and the
2401 * attcollation as the type's default, since that's always the appropriate
2402 * thing for function outputs; there's no point in considering any
2403 * additional info available from outargs. Note that tupdesc is null if
2404 * there are no outargs.
2408 Assert(tupdesc
->natts
== list_length(stmt
->outargs
));
2409 for (int i
= 0; i
< tupdesc
->natts
; i
++)
2411 Form_pg_attribute att
= TupleDescAttr(tupdesc
, i
);
2412 Node
*outarg
= (Node
*) list_nth(stmt
->outargs
, i
);
2414 TupleDescInitEntry(tupdesc
,
2416 NameStr(att
->attname
),