-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.147 2007/03/22 15:46:56 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.148 2007/03/26 16:58:37 tgl Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
<entry>Name of the language</entry>
</row>
+ <row>
+ <entry><structfield>lanowner</structfield></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
+ <entry>Owner of the language</entry>
+ </row>
+
<row>
<entry><structfield>lanispl</structfield></entry>
<entry><type>bool</type></entry>
<table>
<title><structname>pg_pltemplate</> Columns</title>
- <tgroup cols=4>
+ <tgroup cols=3>
<thead>
<row>
<entry>Name</entry>
<entry>True if language is considered trusted</entry>
</row>
+ <row>
+ <entry><structfield>tmpldbacreate</structfield></entry>
+ <entry><type>boolean</type></entry>
+ <entry>True if language may be created by a database owner</entry>
+ </row>
+
<row>
<entry><structfield>tmplhandler</structfield></entry>
<entry><type>text</type></entry>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/alter_language.sgml,v 1.6 2006/09/16 00:30:16 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/alter_language.sgml,v 1.7 2007/03/26 16:58:38 tgl Exp $
PostgreSQL documentation
-->
<refsynopsisdiv>
<synopsis>
-ALTER LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>newname</replaceable>
+ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>newname</replaceable>
+ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
</synopsis>
</refsynopsisdiv>
<para>
<command>ALTER LANGUAGE</command> changes the definition of a
- language. The only functionality is to rename the language. Only
- a superuser can rename languages.
+ procedural language. The only functionality is to rename the language or
+ assign a new owner. You must be superuser or owner of the language to
+ use <command>ALTER LANGUAGE</command>.
</para>
</refsect1>
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><replaceable>new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the language
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_language.sgml,v 1.43 2007/01/31 23:26:03 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_language.sgml,v 1.44 2007/03/26 16:58:38 tgl Exp $
PostgreSQL documentation
-->
<productname>PostgreSQL</productname> user can register a new
procedural language with a <productname>PostgreSQL</productname>
database. Subsequently, functions and trigger procedures can be
- defined in this new language. The user must have the
- <productname>PostgreSQL</productname> superuser privilege to
- register a new language.
+ defined in this new language.
</para>
<para>
old dump files, which are likely to contain out-of-date information
about language support functions.
</para>
+
+ <para>
+ Ordinarily, the user must have the
+ <productname>PostgreSQL</productname> superuser privilege to
+ register a new language. However, the owner of a database can register
+ a new language within that database if the language is listed in
+ the <structname>pg_pltemplate</structname> catalog and is marked
+ as allowed to be created by database owners (<structfield>tmpldbacreate</>
+ is true). The default is that trusted languages can be created
+ by database owners, but this can be adjusted by superusers by modifying
+ the contents of <structname>pg_pltemplate</structname>.
+ The creator of a language becomes its owner and can later
+ drop it, rename it, or assign it to a new owner.
+ </para>
</refsect1>
<refsect1 id="sql-createlanguage-parameters">
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/drop_language.sgml,v 1.24 2007/01/31 23:26:03 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/drop_language.sgml,v 1.25 2007/03/26 16:58:38 tgl Exp $
PostgreSQL documentation
-->
<command>DROP LANGUAGE</command> will remove the definition
of the previously registered procedural language called
<replaceable class="parameter">name</replaceable>.
+ You must be superuser or owner of the language to
+ use <command>DROP LANGUAGE</command>.
</para>
</refsect1>
<term><literal>IF EXISTS</literal></term>
<listitem>
<para>
- Do not throw an error if the function does not exist. A notice is issued
+ Do not throw an error if the language does not exist. A notice is issued
in this case.
</para>
</listitem>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.137 2007/02/14 01:58:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.138 2007/03/26 16:58:38 tgl Exp $
*
* NOTES
* See acl.h.
/*
* Get owner ID and working copy of existing ACL. If there's no ACL,
* substitute the proper default.
- *
- * Note: for now, languages are treated as owned by the bootstrap
- * user. We should add an owner column to pg_language instead.
*/
- ownerId = BOOTSTRAP_SUPERUSERID;
+ ownerId = pg_language_tuple->lanowner;
aclDatum = SysCacheGetAttr(LANGNAME, tuple, Anum_pg_language_lanacl,
&isNull);
if (isNull)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("language with OID %u does not exist", lang_oid)));
- /* XXX pg_language should have an owner column, but doesn't */
- ownerId = BOOTSTRAP_SUPERUSERID;
+ ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
&isNull);
return has_privs_of_role(roleid, ownerId);
}
+/*
+ * Ownership check for a procedural language (specified by OID)
+ */
+bool
+pg_language_ownercheck(Oid lan_oid, Oid roleid)
+{
+ HeapTuple tuple;
+ Oid ownerId;
+
+ /* Superusers bypass all permission checking. */
+ if (superuser_arg(roleid))
+ return true;
+
+ tuple = SearchSysCache(LANGOID,
+ ObjectIdGetDatum(lan_oid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_FUNCTION),
+ errmsg("language with OID %u does not exist", lan_oid)));
+
+ ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
+
+ ReleaseSysCache(tuple);
+
+ return has_privs_of_role(roleid, ownerId);
+}
+
/*
* Ownership check for a namespace (specified by OID).
*/
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.22 2007/01/23 05:07:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.23 2007/03/26 16:58:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
AlterFunctionOwner(stmt->object, stmt->objarg, newowner);
break;
+ case OBJECT_LANGUAGE:
+ AlterLanguageOwner((char *) linitial(stmt->object), newowner);
+ break;
+
case OBJECT_OPERATOR:
Assert(list_length(stmt->objarg) == 2);
AlterOperatorOwner(stmt->object,
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.71 2007/01/22 01:35:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.72 2007/03/26 16:58:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "access/heapam.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
+#include "catalog/pg_authid.h"
#include "catalog/pg_language.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_pltemplate.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
+#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/proclang.h"
#include "miscadmin.h"
#include "parser/gramparse.h"
#include "parser/parse_func.h"
+#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
typedef struct
{
bool tmpltrusted; /* trusted? */
+ bool tmpldbacreate; /* db owner allowed to create? */
char *tmplhandler; /* name of handler function */
char *tmplvalidator; /* name of validator function, or NULL */
char *tmpllibrary; /* path of shared library */
} PLTemplate;
static void create_proc_lang(const char *languageName,
- Oid handlerOid, Oid valOid, bool trusted);
+ Oid languageOwner, Oid handlerOid, Oid valOid, bool trusted);
static PLTemplate *find_language_template(const char *languageName);
Oid funcrettype;
Oid funcargtypes[1];
- /*
- * Check permission
- */
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to create procedural language")));
-
/*
* Translate the language name and check that this language doesn't
* already exist
ereport(NOTICE,
(errmsg("using pg_pltemplate information instead of CREATE LANGUAGE parameters")));
+ /*
+ * Check permission
+ */
+ if (!superuser())
+ {
+ if (!pltemplate->tmpldbacreate)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to create procedural language \"%s\"",
+ languageName)));
+ if (!pg_database_ownercheck(MyDatabaseId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
+ get_database_name(MyDatabaseId));
+ }
+
/*
* Find or create the handler function, which we force to be in the
* pg_catalog schema. If already present, it must have the correct
valOid = InvalidOid;
/* ok, create it */
- create_proc_lang(languageName, handlerOid, valOid,
+ create_proc_lang(languageName, GetUserId(), handlerOid, valOid,
pltemplate->tmpltrusted);
}
else
languageName),
errhint("The supported languages are listed in the pg_pltemplate system catalog.")));
+ /*
+ * Check permission
+ */
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to create custom procedural language")));
+
/*
* Lookup the PL handler function and check that it is of the expected
* return type
valOid = InvalidOid;
/* ok, create it */
- create_proc_lang(languageName, handlerOid, valOid, stmt->pltrusted);
+ create_proc_lang(languageName, GetUserId(), handlerOid, valOid,
+ stmt->pltrusted);
}
}
*/
static void
create_proc_lang(const char *languageName,
- Oid handlerOid, Oid valOid, bool trusted)
+ Oid languageOwner, Oid handlerOid, Oid valOid, bool trusted)
{
Relation rel;
TupleDesc tupDesc;
namestrcpy(&langname, languageName);
values[Anum_pg_language_lanname - 1] = NameGetDatum(&langname);
+ values[Anum_pg_language_lanowner - 1] = ObjectIdGetDatum(languageOwner);
values[Anum_pg_language_lanispl - 1] = BoolGetDatum(true);
values[Anum_pg_language_lanpltrusted - 1] = BoolGetDatum(trusted);
values[Anum_pg_language_lanplcallfoid - 1] = ObjectIdGetDatum(handlerOid);
myself.objectId = HeapTupleGetOid(tup);
myself.objectSubId = 0;
+ /* dependency on owner of language */
+ referenced.classId = AuthIdRelationId;
+ referenced.objectId = languageOwner;
+ referenced.objectSubId = 0;
+ recordSharedDependencyOn(&myself, &referenced, SHARED_DEPENDENCY_OWNER);
+
/* dependency on the PL handler function */
referenced.classId = ProcedureRelationId;
referenced.objectId = handlerOid;
result = (PLTemplate *) palloc0(sizeof(PLTemplate));
result->tmpltrusted = tmpl->tmpltrusted;
+ result->tmpldbacreate = tmpl->tmpldbacreate;
/* Remaining fields are variable-width so we need heap_getattr */
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplhandler,
HeapTuple langTup;
ObjectAddress object;
- /*
- * Check permission
- */
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to drop procedural language")));
-
/*
* Translate the language name, check that the language exists
*/
return;
}
+ /*
+ * Check permission
+ */
+ if (!pg_language_ownercheck(HeapTupleGetOid(langTup), GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
+ languageName);
+
object.classId = LanguageRelationId;
object.objectId = HeapTupleGetOid(langTup);
object.objectSubId = 0;
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("language \"%s\" already exists", newname)));
- /* must be superuser, since we do not have owners for PLs */
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to rename procedural language")));
+ /* must be owner of PL */
+ if (!pg_language_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
+ oldname);
/* rename */
namestrcpy(&(((Form_pg_language) GETSTRUCT(tup))->lanname), newname);
heap_close(rel, NoLock);
heap_freetuple(tup);
}
+
+/*
+ * Change language owner
+ */
+void
+AlterLanguageOwner(const char *name, Oid newOwnerId)
+{
+ HeapTuple tup;
+ Relation rel;
+ Form_pg_language lanForm;
+
+ /* Translate name for consistency with CREATE */
+ name = case_translate_language_name(name);
+
+ rel = heap_open(LanguageRelationId, RowExclusiveLock);
+
+ tup = SearchSysCache(LANGNAME,
+ CStringGetDatum(name),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("language \"%s\" does not exist", name)));
+ lanForm = (Form_pg_language) GETSTRUCT(tup);
+
+ /*
+ * If the new owner is the same as the existing owner, consider the
+ * command to have succeeded. This is for dump restoration purposes.
+ */
+ if (lanForm->lanowner != newOwnerId)
+ {
+ Datum repl_val[Natts_pg_language];
+ char repl_null[Natts_pg_language];
+ char repl_repl[Natts_pg_language];
+ Acl *newAcl;
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple newtuple;
+
+ /* Otherwise, must be owner of the existing object */
+ if (!pg_language_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
+ NameStr(lanForm->lanname));
+
+ /* Must be able to become new owner */
+ check_is_member_of_role(GetUserId(), newOwnerId);
+
+ memset(repl_null, ' ', sizeof(repl_null));
+ memset(repl_repl, ' ', sizeof(repl_repl));
+
+ repl_repl[Anum_pg_language_lanowner - 1] = 'r';
+ repl_val[Anum_pg_language_lanowner - 1] = ObjectIdGetDatum(newOwnerId);
+
+ /*
+ * Determine the modified ACL for the new owner. This is only
+ * necessary when the ACL is non-null.
+ */
+ aclDatum = SysCacheGetAttr(LANGNAME, tup,
+ Anum_pg_language_lanacl,
+ &isNull);
+ if (!isNull)
+ {
+ newAcl = aclnewowner(DatumGetAclP(aclDatum),
+ lanForm->lanowner, newOwnerId);
+ repl_repl[Anum_pg_language_lanacl - 1] = 'r';
+ repl_val[Anum_pg_language_lanacl - 1] = PointerGetDatum(newAcl);
+ }
+
+ newtuple = heap_modifytuple(tup, RelationGetDescr(rel),
+ repl_val, repl_null, repl_repl);
+
+ simple_heap_update(rel, &newtuple->t_self, newtuple);
+ CatalogUpdateIndexes(rel, newtuple);
+
+ heap_freetuple(newtuple);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(LanguageRelationId, HeapTupleGetOid(tup),
+ newOwnerId);
+ }
+
+ ReleaseSysCache(tup);
+ heap_close(rel, RowExclusiveLock);
+}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.583 2007/03/19 23:38:29 wieck Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.584 2007/03/26 16:58:39 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
n->newname = $6;
$$ = (Node *)n;
}
- | ALTER LANGUAGE name RENAME TO name
+ | ALTER opt_procedural LANGUAGE name RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_LANGUAGE;
- n->subname = $3;
- n->newname = $6;
+ n->subname = $4;
+ n->newname = $7;
$$ = (Node *)n;
}
| ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
n->newowner = $7;
$$ = (Node *)n;
}
+ | ALTER opt_procedural LANGUAGE name OWNER TO RoleId
+ {
+ AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
+ n->objectType = OBJECT_LANGUAGE;
+ n->object = list_make1($4);
+ n->newowner = $7;
+ $$ = (Node *)n;
+ }
| ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.274 2007/03/13 00:33:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.275 2007/03/26 16:58:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
case OBJECT_FUNCTION:
tag = "ALTER FUNCTION";
break;
+ case OBJECT_LANGUAGE:
+ tag = "ALTER LANGUAGE";
+ break;
case OBJECT_OPERATOR:
tag = "ALTER OPERATOR";
break;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.143 2007/03/18 16:50:44 neilc Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.144 2007/03/26 16:58:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* objects named by just a name */
if (strcmp(type, "DATABASE") == 0 ||
+ strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
strcmp(type, "SCHEMA") == 0)
{
appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
strcmp(te->desc, "OPERATOR") == 0 ||
strcmp(te->desc, "OPERATOR CLASS") == 0 ||
strcmp(te->desc, "OPERATOR FAMILY") == 0 ||
+ strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
strcmp(te->desc, "SCHEMA") == 0 ||
strcmp(te->desc, "TABLE") == 0 ||
strcmp(te->desc, "TYPE") == 0 ||
strcmp(te->desc, "DEFAULT") == 0 ||
strcmp(te->desc, "FK CONSTRAINT") == 0 ||
strcmp(te->desc, "INDEX") == 0 ||
- strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
strcmp(te->desc, "RULE") == 0 ||
strcmp(te->desc, "TRIGGER") == 0)
{
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.464 2007/03/22 20:47:12 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.465 2007/03/26 16:58:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* Make sure we are in proper schema */
selectSourceSchema("pg_catalog");
- if (g_fout->remoteVersion >= 80100)
+ if (g_fout->remoteVersion >= 80300)
+ {
+ /* pg_language has a lanowner column */
+ appendPQExpBuffer(query, "SELECT tableoid, oid, "
+ "lanname, lanpltrusted, lanplcallfoid, "
+ "lanvalidator, lanacl, "
+ "(%s lanowner) as lanowner "
+ "FROM pg_language "
+ "WHERE lanispl "
+ "ORDER BY oid",
+ username_subquery);
+ }
+ else if (g_fout->remoteVersion >= 80100)
{
/* Languages are owned by the bootstrap superuser, OID 10 */
appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
*
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.159 2007/02/23 18:20:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.160 2007/03/26 16:58:40 tgl Exp $
*/
/*----------------------------------------------------------------------
/* ALTER LANGUAGE <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "LANGUAGE") == 0)
- COMPLETE_WITH_CONST("RENAME TO");
+ {
+ static const char *const list_ALTERLANGUAGE[] =
+ {"OWNER TO", "RENAME TO", NULL};
+
+ COMPLETE_WITH_LIST(list_ALTERLANGUAGE);
+ }
/* ALTER USER,ROLE <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.394 2007/03/25 11:56:04 ishii Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.395 2007/03/26 16:58:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200703251
+#define CATALOG_VERSION_NO 200703261
#endif
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_language.h,v 1.29 2007/01/05 22:19:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_language.h,v 1.30 2007/03/26 16:58:41 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
CATALOG(pg_language,2612)
{
- NameData lanname;
+ NameData lanname; /* Language name */
+ Oid lanowner; /* Language's owner */
bool lanispl; /* Is a procedural language */
bool lanpltrusted; /* PL is trusted */
Oid lanplcallfoid; /* Call handler for PL */
- Oid lanvalidator; /* optional validation function */
+ Oid lanvalidator; /* Optional validation function */
aclitem lanacl[1]; /* Access privileges */
} FormData_pg_language;
* compiler constants for pg_language
* ----------------
*/
-#define Natts_pg_language 6
+#define Natts_pg_language 7
#define Anum_pg_language_lanname 1
-#define Anum_pg_language_lanispl 2
-#define Anum_pg_language_lanpltrusted 3
-#define Anum_pg_language_lanplcallfoid 4
-#define Anum_pg_language_lanvalidator 5
-#define Anum_pg_language_lanacl 6
+#define Anum_pg_language_lanowner 2
+#define Anum_pg_language_lanispl 3
+#define Anum_pg_language_lanpltrusted 4
+#define Anum_pg_language_lanplcallfoid 5
+#define Anum_pg_language_lanvalidator 6
+#define Anum_pg_language_lanacl 7
/* ----------------
* initial contents of pg_language
* ----------------
*/
-DATA(insert OID = 12 ( "internal" f f 0 2246 _null_ ));
+DATA(insert OID = 12 ( "internal" PGUID f f 0 2246 _null_ ));
DESCR("Built-in functions");
#define INTERNALlanguageId 12
-DATA(insert OID = 13 ( "c" f f 0 2247 _null_ ));
+DATA(insert OID = 13 ( "c" PGUID f f 0 2247 _null_ ));
DESCR("Dynamically-loaded C functions");
#define ClanguageId 13
-DATA(insert OID = 14 ( "sql" f t 0 2248 _null_ ));
+DATA(insert OID = 14 ( "sql" PGUID f t 0 2248 _null_ ));
DESCR("SQL-language functions");
#define SQLlanguageId 14
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_pltemplate.h,v 1.3 2007/01/05 22:19:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_pltemplate.h,v 1.4 2007/03/26 16:58:41 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
{
NameData tmplname; /* name of PL */
bool tmpltrusted; /* PL is trusted? */
+ bool tmpldbacreate; /* PL is installable by db owner? */
text tmplhandler; /* name of call handler function */
text tmplvalidator; /* name of validator function, or NULL */
text tmpllibrary; /* path of shared library */
* compiler constants for pg_pltemplate
* ----------------
*/
-#define Natts_pg_pltemplate 6
+#define Natts_pg_pltemplate 7
#define Anum_pg_pltemplate_tmplname 1
#define Anum_pg_pltemplate_tmpltrusted 2
-#define Anum_pg_pltemplate_tmplhandler 3
-#define Anum_pg_pltemplate_tmplvalidator 4
-#define Anum_pg_pltemplate_tmpllibrary 5
-#define Anum_pg_pltemplate_tmplacl 6
+#define Anum_pg_pltemplate_tmpldbacreate 3
+#define Anum_pg_pltemplate_tmplhandler 4
+#define Anum_pg_pltemplate_tmplvalidator 5
+#define Anum_pg_pltemplate_tmpllibrary 6
+#define Anum_pg_pltemplate_tmplacl 7
/* ----------------
* ----------------
*/
-DATA(insert ( "plpgsql" t "plpgsql_call_handler" "plpgsql_validator" "$libdir/plpgsql" _null_ ));
-DATA(insert ( "pltcl" t "pltcl_call_handler" _null_ "$libdir/pltcl" _null_ ));
-DATA(insert ( "pltclu" f "pltclu_call_handler" _null_ "$libdir/pltcl" _null_ ));
-DATA(insert ( "plperl" t "plperl_call_handler" "plperl_validator" "$libdir/plperl" _null_ ));
-DATA(insert ( "plperlu" f "plperl_call_handler" "plperl_validator" "$libdir/plperl" _null_ ));
-DATA(insert ( "plpythonu" f "plpython_call_handler" _null_ "$libdir/plpython" _null_ ));
+DATA(insert ( "plpgsql" t t "plpgsql_call_handler" "plpgsql_validator" "$libdir/plpgsql" _null_ ));
+DATA(insert ( "pltcl" t t "pltcl_call_handler" _null_ "$libdir/pltcl" _null_ ));
+DATA(insert ( "pltclu" f f "pltclu_call_handler" _null_ "$libdir/pltcl" _null_ ));
+DATA(insert ( "plperl" t t "plperl_call_handler" "plperl_validator" "$libdir/plperl" _null_ ));
+DATA(insert ( "plperlu" f f "plperl_call_handler" "plperl_validator" "$libdir/plperl" _null_ ));
+DATA(insert ( "plpythonu" f f "plpython_call_handler" _null_ "$libdir/plpython" _null_ ));
#endif /* PG_PLTEMPLATE_H */
extern void DropProceduralLanguage(DropPLangStmt *stmt);
extern void DropProceduralLanguageById(Oid langOid);
extern void RenameLanguage(const char *oldname, const char *newname);
+extern void AlterLanguageOwner(const char *name, Oid newOwnerId);
extern bool PLTemplateExists(const char *languageName);
#endif /* PROCLANG_H */
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.100 2007/01/23 05:07:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.101 2007/03/26 16:58:41 tgl Exp $
*
* NOTES
* An ACL array is simply an array of AclItems, representing the union
extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid);
extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid);
+extern bool pg_language_ownercheck(Oid lan_oid, Oid roleid);
extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid);
extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);