Allow non-superuser database owners to create procedural languages.
A DBA is allowed to create a language in his database if it's marked "tmpldbacreate" in pg_pltemplate. The factory default is that this is set for all standard trusted languages, but of course a superuser may adjust the settings. In service of this, add the long-foreseen owner column to pg_language; renaming, dropping, and altering owner of a PL now follow normal ownership rules instead of being superuser-only. Jeremy Drake, with some editorialization by Tom Lane.
This commit is contained in:
parent
66daeb074b
commit
55a7cf80a0
@ -1,4 +1,4 @@
|
|||||||
<!-- $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
|
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||||
-->
|
-->
|
||||||
@ -2655,6 +2655,13 @@
|
|||||||
<entry>Name of the language</entry>
|
<entry>Name of the language</entry>
|
||||||
</row>
|
</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>
|
<row>
|
||||||
<entry><structfield>lanispl</structfield></entry>
|
<entry><structfield>lanispl</structfield></entry>
|
||||||
<entry><type>bool</type></entry>
|
<entry><type>bool</type></entry>
|
||||||
@ -3265,7 +3272,7 @@
|
|||||||
<table>
|
<table>
|
||||||
<title><structname>pg_pltemplate</> Columns</title>
|
<title><structname>pg_pltemplate</> Columns</title>
|
||||||
|
|
||||||
<tgroup cols=4>
|
<tgroup cols=3>
|
||||||
<thead>
|
<thead>
|
||||||
<row>
|
<row>
|
||||||
<entry>Name</entry>
|
<entry>Name</entry>
|
||||||
@ -3287,6 +3294,12 @@
|
|||||||
<entry>True if language is considered trusted</entry>
|
<entry>True if language is considered trusted</entry>
|
||||||
</row>
|
</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>
|
<row>
|
||||||
<entry><structfield>tmplhandler</structfield></entry>
|
<entry><structfield>tmplhandler</structfield></entry>
|
||||||
<entry><type>text</type></entry>
|
<entry><type>text</type></entry>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -20,7 +20,8 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<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>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -29,8 +30,9 @@ ALTER LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>newname</r
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>ALTER LANGUAGE</command> changes the definition of a
|
<command>ALTER LANGUAGE</command> changes the definition of a
|
||||||
language. The only functionality is to rename the language. Only
|
procedural language. The only functionality is to rename the language or
|
||||||
a superuser can rename languages.
|
assign a new owner. You must be superuser or owner of the language to
|
||||||
|
use <command>ALTER LANGUAGE</command>.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
@ -55,6 +57,15 @@ ALTER LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>newname</r
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable>new_owner</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The new owner of the language
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -34,9 +34,7 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</
|
|||||||
<productname>PostgreSQL</productname> user can register a new
|
<productname>PostgreSQL</productname> user can register a new
|
||||||
procedural language with a <productname>PostgreSQL</productname>
|
procedural language with a <productname>PostgreSQL</productname>
|
||||||
database. Subsequently, functions and trigger procedures can be
|
database. Subsequently, functions and trigger procedures can be
|
||||||
defined in this new language. The user must have the
|
defined in this new language.
|
||||||
<productname>PostgreSQL</productname> superuser privilege to
|
|
||||||
register a new language.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -64,6 +62,20 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</
|
|||||||
old dump files, which are likely to contain out-of-date information
|
old dump files, which are likely to contain out-of-date information
|
||||||
about language support functions.
|
about language support functions.
|
||||||
</para>
|
</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>
|
||||||
|
|
||||||
<refsect1 id="sql-createlanguage-parameters">
|
<refsect1 id="sql-createlanguage-parameters">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -31,6 +31,8 @@ DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] <replaceable class="PARAMETER">name</
|
|||||||
<command>DROP LANGUAGE</command> will remove the definition
|
<command>DROP LANGUAGE</command> will remove the definition
|
||||||
of the previously registered procedural language called
|
of the previously registered procedural language called
|
||||||
<replaceable class="parameter">name</replaceable>.
|
<replaceable class="parameter">name</replaceable>.
|
||||||
|
You must be superuser or owner of the language to
|
||||||
|
use <command>DROP LANGUAGE</command>.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] <replaceable class="PARAMETER">name</
|
|||||||
<term><literal>IF EXISTS</literal></term>
|
<term><literal>IF EXISTS</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<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.
|
in this case.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
@ -1003,11 +1003,8 @@ ExecGrant_Language(InternalGrant *istmt)
|
|||||||
/*
|
/*
|
||||||
* Get owner ID and working copy of existing ACL. If there's no ACL,
|
* Get owner ID and working copy of existing ACL. If there's no ACL,
|
||||||
* substitute the proper default.
|
* 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,
|
aclDatum = SysCacheGetAttr(LANGNAME, tuple, Anum_pg_language_lanacl,
|
||||||
&isNull);
|
&isNull);
|
||||||
if (isNull)
|
if (isNull)
|
||||||
@ -1770,8 +1767,7 @@ pg_language_aclmask(Oid lang_oid, Oid roleid,
|
|||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
errmsg("language with OID %u does not exist", lang_oid)));
|
errmsg("language with OID %u does not exist", lang_oid)));
|
||||||
|
|
||||||
/* XXX pg_language should have an owner column, but doesn't */
|
ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
|
||||||
ownerId = BOOTSTRAP_SUPERUSERID;
|
|
||||||
|
|
||||||
aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
|
aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
|
||||||
&isNull);
|
&isNull);
|
||||||
@ -2147,6 +2143,34 @@ pg_proc_ownercheck(Oid proc_oid, Oid roleid)
|
|||||||
return has_privs_of_role(roleid, ownerId);
|
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).
|
* Ownership check for a namespace (specified by OID).
|
||||||
*/
|
*/
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -203,6 +203,10 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|||||||
AlterFunctionOwner(stmt->object, stmt->objarg, newowner);
|
AlterFunctionOwner(stmt->object, stmt->objarg, newowner);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OBJECT_LANGUAGE:
|
||||||
|
AlterLanguageOwner((char *) linitial(stmt->object), newowner);
|
||||||
|
break;
|
||||||
|
|
||||||
case OBJECT_OPERATOR:
|
case OBJECT_OPERATOR:
|
||||||
Assert(list_length(stmt->objarg) == 2);
|
Assert(list_length(stmt->objarg) == 2);
|
||||||
AlterOperatorOwner(stmt->object,
|
AlterOperatorOwner(stmt->object,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -17,16 +17,19 @@
|
|||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
|
#include "catalog/pg_authid.h"
|
||||||
#include "catalog/pg_language.h"
|
#include "catalog/pg_language.h"
|
||||||
#include "catalog/pg_namespace.h"
|
#include "catalog/pg_namespace.h"
|
||||||
#include "catalog/pg_pltemplate.h"
|
#include "catalog/pg_pltemplate.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
#include "commands/dbcommands.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/proclang.h"
|
#include "commands/proclang.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "parser/gramparse.h"
|
#include "parser/gramparse.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
@ -36,13 +39,14 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
bool tmpltrusted; /* trusted? */
|
bool tmpltrusted; /* trusted? */
|
||||||
|
bool tmpldbacreate; /* db owner allowed to create? */
|
||||||
char *tmplhandler; /* name of handler function */
|
char *tmplhandler; /* name of handler function */
|
||||||
char *tmplvalidator; /* name of validator function, or NULL */
|
char *tmplvalidator; /* name of validator function, or NULL */
|
||||||
char *tmpllibrary; /* path of shared library */
|
char *tmpllibrary; /* path of shared library */
|
||||||
} PLTemplate;
|
} PLTemplate;
|
||||||
|
|
||||||
static void create_proc_lang(const char *languageName,
|
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);
|
static PLTemplate *find_language_template(const char *languageName);
|
||||||
|
|
||||||
|
|
||||||
@ -60,14 +64,6 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
|||||||
Oid funcrettype;
|
Oid funcrettype;
|
||||||
Oid funcargtypes[1];
|
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
|
* Translate the language name and check that this language doesn't
|
||||||
* already exist
|
* already exist
|
||||||
@ -96,6 +92,21 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
|||||||
ereport(NOTICE,
|
ereport(NOTICE,
|
||||||
(errmsg("using pg_pltemplate information instead of CREATE LANGUAGE parameters")));
|
(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
|
* Find or create the handler function, which we force to be in the
|
||||||
* pg_catalog schema. If already present, it must have the correct
|
* pg_catalog schema. If already present, it must have the correct
|
||||||
@ -171,7 +182,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
|||||||
valOid = InvalidOid;
|
valOid = InvalidOid;
|
||||||
|
|
||||||
/* ok, create it */
|
/* ok, create it */
|
||||||
create_proc_lang(languageName, handlerOid, valOid,
|
create_proc_lang(languageName, GetUserId(), handlerOid, valOid,
|
||||||
pltemplate->tmpltrusted);
|
pltemplate->tmpltrusted);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -188,6 +199,14 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
|||||||
languageName),
|
languageName),
|
||||||
errhint("The supported languages are listed in the pg_pltemplate system catalog.")));
|
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
|
* Lookup the PL handler function and check that it is of the expected
|
||||||
* return type
|
* return type
|
||||||
@ -227,7 +246,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
|||||||
valOid = InvalidOid;
|
valOid = InvalidOid;
|
||||||
|
|
||||||
/* ok, create it */
|
/* ok, create it */
|
||||||
create_proc_lang(languageName, handlerOid, valOid, stmt->pltrusted);
|
create_proc_lang(languageName, GetUserId(), handlerOid, valOid,
|
||||||
|
stmt->pltrusted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +256,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
create_proc_lang(const char *languageName,
|
create_proc_lang(const char *languageName,
|
||||||
Oid handlerOid, Oid valOid, bool trusted)
|
Oid languageOwner, Oid handlerOid, Oid valOid, bool trusted)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
TupleDesc tupDesc;
|
TupleDesc tupDesc;
|
||||||
@ -258,6 +278,7 @@ create_proc_lang(const char *languageName,
|
|||||||
|
|
||||||
namestrcpy(&langname, languageName);
|
namestrcpy(&langname, languageName);
|
||||||
values[Anum_pg_language_lanname - 1] = NameGetDatum(&langname);
|
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_lanispl - 1] = BoolGetDatum(true);
|
||||||
values[Anum_pg_language_lanpltrusted - 1] = BoolGetDatum(trusted);
|
values[Anum_pg_language_lanpltrusted - 1] = BoolGetDatum(trusted);
|
||||||
values[Anum_pg_language_lanplcallfoid - 1] = ObjectIdGetDatum(handlerOid);
|
values[Anum_pg_language_lanplcallfoid - 1] = ObjectIdGetDatum(handlerOid);
|
||||||
@ -277,6 +298,12 @@ create_proc_lang(const char *languageName,
|
|||||||
myself.objectId = HeapTupleGetOid(tup);
|
myself.objectId = HeapTupleGetOid(tup);
|
||||||
myself.objectSubId = 0;
|
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 */
|
/* dependency on the PL handler function */
|
||||||
referenced.classId = ProcedureRelationId;
|
referenced.classId = ProcedureRelationId;
|
||||||
referenced.objectId = handlerOid;
|
referenced.objectId = handlerOid;
|
||||||
@ -325,6 +352,7 @@ find_language_template(const char *languageName)
|
|||||||
|
|
||||||
result = (PLTemplate *) palloc0(sizeof(PLTemplate));
|
result = (PLTemplate *) palloc0(sizeof(PLTemplate));
|
||||||
result->tmpltrusted = tmpl->tmpltrusted;
|
result->tmpltrusted = tmpl->tmpltrusted;
|
||||||
|
result->tmpldbacreate = tmpl->tmpldbacreate;
|
||||||
|
|
||||||
/* Remaining fields are variable-width so we need heap_getattr */
|
/* Remaining fields are variable-width so we need heap_getattr */
|
||||||
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplhandler,
|
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplhandler,
|
||||||
@ -381,14 +409,6 @@ DropProceduralLanguage(DropPLangStmt *stmt)
|
|||||||
HeapTuple langTup;
|
HeapTuple langTup;
|
||||||
ObjectAddress object;
|
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
|
* Translate the language name, check that the language exists
|
||||||
*/
|
*/
|
||||||
@ -411,6 +431,13 @@ DropProceduralLanguage(DropPLangStmt *stmt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check permission
|
||||||
|
*/
|
||||||
|
if (!pg_language_ownercheck(HeapTupleGetOid(langTup), GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
|
||||||
|
languageName);
|
||||||
|
|
||||||
object.classId = LanguageRelationId;
|
object.classId = LanguageRelationId;
|
||||||
object.objectId = HeapTupleGetOid(langTup);
|
object.objectId = HeapTupleGetOid(langTup);
|
||||||
object.objectSubId = 0;
|
object.objectSubId = 0;
|
||||||
@ -478,11 +505,10 @@ RenameLanguage(const char *oldname, const char *newname)
|
|||||||
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||||
errmsg("language \"%s\" already exists", newname)));
|
errmsg("language \"%s\" already exists", newname)));
|
||||||
|
|
||||||
/* must be superuser, since we do not have owners for PLs */
|
/* must be owner of PL */
|
||||||
if (!superuser())
|
if (!pg_language_ownercheck(HeapTupleGetOid(tup), GetUserId()))
|
||||||
ereport(ERROR,
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
oldname);
|
||||||
errmsg("must be superuser to rename procedural language")));
|
|
||||||
|
|
||||||
/* rename */
|
/* rename */
|
||||||
namestrcpy(&(((Form_pg_language) GETSTRUCT(tup))->lanname), newname);
|
namestrcpy(&(((Form_pg_language) GETSTRUCT(tup))->lanname), newname);
|
||||||
@ -492,3 +518,87 @@ RenameLanguage(const char *oldname, const char *newname)
|
|||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
heap_freetuple(tup);
|
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);
|
||||||
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -4447,12 +4447,12 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
|
|||||||
n->newname = $6;
|
n->newname = $6;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| ALTER LANGUAGE name RENAME TO name
|
| ALTER opt_procedural LANGUAGE name RENAME TO name
|
||||||
{
|
{
|
||||||
RenameStmt *n = makeNode(RenameStmt);
|
RenameStmt *n = makeNode(RenameStmt);
|
||||||
n->renameType = OBJECT_LANGUAGE;
|
n->renameType = OBJECT_LANGUAGE;
|
||||||
n->subname = $3;
|
n->subname = $4;
|
||||||
n->newname = $6;
|
n->newname = $7;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
|
| ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
|
||||||
@ -4654,6 +4654,14 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
|
|||||||
n->newowner = $7;
|
n->newowner = $7;
|
||||||
$$ = (Node *)n;
|
$$ = (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
|
| ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1551,6 +1551,9 @@ CreateCommandTag(Node *parsetree)
|
|||||||
case OBJECT_FUNCTION:
|
case OBJECT_FUNCTION:
|
||||||
tag = "ALTER FUNCTION";
|
tag = "ALTER FUNCTION";
|
||||||
break;
|
break;
|
||||||
|
case OBJECT_LANGUAGE:
|
||||||
|
tag = "ALTER LANGUAGE";
|
||||||
|
break;
|
||||||
case OBJECT_OPERATOR:
|
case OBJECT_OPERATOR:
|
||||||
tag = "ALTER OPERATOR";
|
tag = "ALTER OPERATOR";
|
||||||
break;
|
break;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2440,6 +2440,7 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
|
|||||||
|
|
||||||
/* objects named by just a name */
|
/* objects named by just a name */
|
||||||
if (strcmp(type, "DATABASE") == 0 ||
|
if (strcmp(type, "DATABASE") == 0 ||
|
||||||
|
strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
|
||||||
strcmp(type, "SCHEMA") == 0)
|
strcmp(type, "SCHEMA") == 0)
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
|
appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
|
||||||
@ -2583,6 +2584,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
|
|||||||
strcmp(te->desc, "OPERATOR") == 0 ||
|
strcmp(te->desc, "OPERATOR") == 0 ||
|
||||||
strcmp(te->desc, "OPERATOR CLASS") == 0 ||
|
strcmp(te->desc, "OPERATOR CLASS") == 0 ||
|
||||||
strcmp(te->desc, "OPERATOR FAMILY") == 0 ||
|
strcmp(te->desc, "OPERATOR FAMILY") == 0 ||
|
||||||
|
strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
|
||||||
strcmp(te->desc, "SCHEMA") == 0 ||
|
strcmp(te->desc, "SCHEMA") == 0 ||
|
||||||
strcmp(te->desc, "TABLE") == 0 ||
|
strcmp(te->desc, "TABLE") == 0 ||
|
||||||
strcmp(te->desc, "TYPE") == 0 ||
|
strcmp(te->desc, "TYPE") == 0 ||
|
||||||
@ -2603,7 +2605,6 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
|
|||||||
strcmp(te->desc, "DEFAULT") == 0 ||
|
strcmp(te->desc, "DEFAULT") == 0 ||
|
||||||
strcmp(te->desc, "FK CONSTRAINT") == 0 ||
|
strcmp(te->desc, "FK CONSTRAINT") == 0 ||
|
||||||
strcmp(te->desc, "INDEX") == 0 ||
|
strcmp(te->desc, "INDEX") == 0 ||
|
||||||
strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
|
|
||||||
strcmp(te->desc, "RULE") == 0 ||
|
strcmp(te->desc, "RULE") == 0 ||
|
||||||
strcmp(te->desc, "TRIGGER") == 0)
|
strcmp(te->desc, "TRIGGER") == 0)
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* by PostgreSQL
|
* by PostgreSQL
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -4030,7 +4030,19 @@ getProcLangs(int *numProcLangs)
|
|||||||
/* Make sure we are in proper schema */
|
/* Make sure we are in proper schema */
|
||||||
selectSourceSchema("pg_catalog");
|
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 */
|
/* Languages are owned by the bootstrap superuser, OID 10 */
|
||||||
appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
|
appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
|
* 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 $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
@ -651,7 +651,12 @@ psql_completion(char *text, int start, int end)
|
|||||||
/* ALTER LANGUAGE <name> */
|
/* ALTER LANGUAGE <name> */
|
||||||
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
|
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
|
||||||
pg_strcasecmp(prev2_wd, "LANGUAGE") == 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> */
|
/* ALTER USER,ROLE <name> */
|
||||||
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
|
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200703251
|
#define CATALOG_VERSION_NO 200703261
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -35,11 +35,12 @@
|
|||||||
|
|
||||||
CATALOG(pg_language,2612)
|
CATALOG(pg_language,2612)
|
||||||
{
|
{
|
||||||
NameData lanname;
|
NameData lanname; /* Language name */
|
||||||
|
Oid lanowner; /* Language's owner */
|
||||||
bool lanispl; /* Is a procedural language */
|
bool lanispl; /* Is a procedural language */
|
||||||
bool lanpltrusted; /* PL is trusted */
|
bool lanpltrusted; /* PL is trusted */
|
||||||
Oid lanplcallfoid; /* Call handler for PL */
|
Oid lanplcallfoid; /* Call handler for PL */
|
||||||
Oid lanvalidator; /* optional validation function */
|
Oid lanvalidator; /* Optional validation function */
|
||||||
aclitem lanacl[1]; /* Access privileges */
|
aclitem lanacl[1]; /* Access privileges */
|
||||||
} FormData_pg_language;
|
} FormData_pg_language;
|
||||||
|
|
||||||
@ -54,26 +55,27 @@ typedef FormData_pg_language *Form_pg_language;
|
|||||||
* compiler constants for 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_lanname 1
|
||||||
#define Anum_pg_language_lanispl 2
|
#define Anum_pg_language_lanowner 2
|
||||||
#define Anum_pg_language_lanpltrusted 3
|
#define Anum_pg_language_lanispl 3
|
||||||
#define Anum_pg_language_lanplcallfoid 4
|
#define Anum_pg_language_lanpltrusted 4
|
||||||
#define Anum_pg_language_lanvalidator 5
|
#define Anum_pg_language_lanplcallfoid 5
|
||||||
#define Anum_pg_language_lanacl 6
|
#define Anum_pg_language_lanvalidator 6
|
||||||
|
#define Anum_pg_language_lanacl 7
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* initial contents of pg_language
|
* 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");
|
DESCR("Built-in functions");
|
||||||
#define INTERNALlanguageId 12
|
#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");
|
DESCR("Dynamically-loaded C functions");
|
||||||
#define ClanguageId 13
|
#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");
|
DESCR("SQL-language functions");
|
||||||
#define SQLlanguageId 14
|
#define SQLlanguageId 14
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -37,6 +37,7 @@ CATALOG(pg_pltemplate,1136) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
|
|||||||
{
|
{
|
||||||
NameData tmplname; /* name of PL */
|
NameData tmplname; /* name of PL */
|
||||||
bool tmpltrusted; /* PL is trusted? */
|
bool tmpltrusted; /* PL is trusted? */
|
||||||
|
bool tmpldbacreate; /* PL is installable by db owner? */
|
||||||
text tmplhandler; /* name of call handler function */
|
text tmplhandler; /* name of call handler function */
|
||||||
text tmplvalidator; /* name of validator function, or NULL */
|
text tmplvalidator; /* name of validator function, or NULL */
|
||||||
text tmpllibrary; /* path of shared library */
|
text tmpllibrary; /* path of shared library */
|
||||||
@ -54,13 +55,14 @@ typedef FormData_pg_pltemplate *Form_pg_pltemplate;
|
|||||||
* compiler constants for pg_pltemplate
|
* 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_tmplname 1
|
||||||
#define Anum_pg_pltemplate_tmpltrusted 2
|
#define Anum_pg_pltemplate_tmpltrusted 2
|
||||||
#define Anum_pg_pltemplate_tmplhandler 3
|
#define Anum_pg_pltemplate_tmpldbacreate 3
|
||||||
#define Anum_pg_pltemplate_tmplvalidator 4
|
#define Anum_pg_pltemplate_tmplhandler 4
|
||||||
#define Anum_pg_pltemplate_tmpllibrary 5
|
#define Anum_pg_pltemplate_tmplvalidator 5
|
||||||
#define Anum_pg_pltemplate_tmplacl 6
|
#define Anum_pg_pltemplate_tmpllibrary 6
|
||||||
|
#define Anum_pg_pltemplate_tmplacl 7
|
||||||
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
@ -68,11 +70,11 @@ typedef FormData_pg_pltemplate *Form_pg_pltemplate;
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DATA(insert ( "plpgsql" t "plpgsql_call_handler" "plpgsql_validator" "$libdir/plpgsql" _null_ ));
|
DATA(insert ( "plpgsql" t t "plpgsql_call_handler" "plpgsql_validator" "$libdir/plpgsql" _null_ ));
|
||||||
DATA(insert ( "pltcl" t "pltcl_call_handler" _null_ "$libdir/pltcl" _null_ ));
|
DATA(insert ( "pltcl" t t "pltcl_call_handler" _null_ "$libdir/pltcl" _null_ ));
|
||||||
DATA(insert ( "pltclu" f "pltclu_call_handler" _null_ "$libdir/pltcl" _null_ ));
|
DATA(insert ( "pltclu" f f "pltclu_call_handler" _null_ "$libdir/pltcl" _null_ ));
|
||||||
DATA(insert ( "plperl" t "plperl_call_handler" "plperl_validator" "$libdir/plperl" _null_ ));
|
DATA(insert ( "plperl" t t "plperl_call_handler" "plperl_validator" "$libdir/plperl" _null_ ));
|
||||||
DATA(insert ( "plperlu" f "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 "plpython_call_handler" _null_ "$libdir/plpython" _null_ ));
|
DATA(insert ( "plpythonu" f f "plpython_call_handler" _null_ "$libdir/plpython" _null_ ));
|
||||||
|
|
||||||
#endif /* PG_PLTEMPLATE_H */
|
#endif /* PG_PLTEMPLATE_H */
|
||||||
|
@ -15,6 +15,7 @@ extern void CreateProceduralLanguage(CreatePLangStmt *stmt);
|
|||||||
extern void DropProceduralLanguage(DropPLangStmt *stmt);
|
extern void DropProceduralLanguage(DropPLangStmt *stmt);
|
||||||
extern void DropProceduralLanguageById(Oid langOid);
|
extern void DropProceduralLanguageById(Oid langOid);
|
||||||
extern void RenameLanguage(const char *oldname, const char *newname);
|
extern void RenameLanguage(const char *oldname, const char *newname);
|
||||||
|
extern void AlterLanguageOwner(const char *name, Oid newOwnerId);
|
||||||
extern bool PLTemplateExists(const char *languageName);
|
extern bool PLTemplateExists(const char *languageName);
|
||||||
|
|
||||||
#endif /* PROCLANG_H */
|
#endif /* PROCLANG_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* An ACL array is simply an array of AclItems, representing the union
|
* An ACL array is simply an array of AclItems, representing the union
|
||||||
@ -274,6 +274,7 @@ extern bool pg_class_ownercheck(Oid class_oid, Oid roleid);
|
|||||||
extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
|
extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
|
||||||
extern bool pg_oper_ownercheck(Oid oper_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_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_namespace_ownercheck(Oid nsp_oid, Oid roleid);
|
||||||
extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
|
extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
|
||||||
extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
|
extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user