* Implements the ALTER FUNCTION utility command (except for the * RENAME and OWNER clauses, which are handled as part of the generic * ALTER framework). */
| 1766 | * ALTER framework). |
| 1767 | */ |
| 1768 | ObjectAddress |
| 1769 | AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) |
| 1770 | { |
| 1771 | HeapTuple tup; |
| 1772 | Oid funcOid; |
| 1773 | Form_pg_proc procForm; |
| 1774 | bool is_procedure; |
| 1775 | Relation rel; |
| 1776 | ListCell *l; |
| 1777 | DefElem *volatility_item = NULL; |
| 1778 | DefElem *strict_item = NULL; |
| 1779 | DefElem *security_def_item = NULL; |
| 1780 | DefElem *leakproof_item = NULL; |
| 1781 | List *set_items = NIL; |
| 1782 | DefElem *cost_item = NULL; |
| 1783 | DefElem *rows_item = NULL; |
| 1784 | DefElem *support_item = NULL; |
| 1785 | DefElem *parallel_item = NULL; |
| 1786 | ObjectAddress address; |
| 1787 | DefElem *describe_item = NULL; |
| 1788 | DefElem *data_access_item = NULL; |
| 1789 | DefElem *exec_location_item = NULL; |
| 1790 | bool isnull; |
| 1791 | char data_access; |
| 1792 | char exec_location; |
| 1793 | |
| 1794 | rel = table_open(ProcedureRelationId, RowExclusiveLock); |
| 1795 | |
| 1796 | funcOid = LookupFuncWithArgs(stmt->objtype, stmt->func, false); |
| 1797 | |
| 1798 | ObjectAddressSet(address, ProcedureRelationId, funcOid); |
| 1799 | |
| 1800 | tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(funcOid)); |
| 1801 | if (!HeapTupleIsValid(tup)) /* should not happen */ |
| 1802 | elog(ERROR, "cache lookup failed for function %u", funcOid); |
| 1803 | |
| 1804 | procForm = (Form_pg_proc) GETSTRUCT(tup); |
| 1805 | |
| 1806 | /* Permission check: must own function */ |
| 1807 | if (!pg_proc_ownercheck(funcOid, GetUserId())) |
| 1808 | aclcheck_error(ACLCHECK_NOT_OWNER, stmt->objtype, |
| 1809 | NameListToString(stmt->func->objname)); |
| 1810 | |
| 1811 | /* check bootstrap object */ |
| 1812 | CheckForModifySystemFunc(funcOid, stmt->func->objname); |
| 1813 | |
| 1814 | if (procForm->prokind == PROKIND_AGGREGATE) |
| 1815 | ereport(ERROR, |
| 1816 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 1817 | errmsg("\"%s\" is an aggregate function", |
| 1818 | NameListToString(stmt->func->objname)))); |
| 1819 | |
| 1820 | is_procedure = (procForm->prokind == PROKIND_PROCEDURE); |
| 1821 | |
| 1822 | /* Examine requested actions. */ |
| 1823 | foreach(l, stmt->actions) |
| 1824 | { |
| 1825 | DefElem *defel = (DefElem *) lfirst(l); |
no test coverage detected