On Thu, 25 Jan 2007, Jeremy Drake wrote:

> I think that an ALTER LANGUAGE OWNER TO is the proper response to these
> things, and unless I hear otherwise I will attempt to add this to my
> patch.

Here is the patch which adds this.  It also allows ALTER LANGUAGE RENAME
TO for the owner, which I missed before.  I would appreciate someone with
more knowledge of the permissions infrastructure to take a look at it
since I am fairly new to it and may not fully understand its intricacies.



-- 
The makers may make
And the users may use,
But the fixers must fix
With but minimal clues
Index: doc/src/sgml/ref/alter_language.sgml
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/doc/src/sgml/ref/alter_language.sgml,v
retrieving revision 1.6
diff -c -r1.6 alter_language.sgml
*** doc/src/sgml/ref/alter_language.sgml        16 Sep 2006 00:30:16 -0000      
1.6
--- doc/src/sgml/ref/alter_language.sgml        26 Jan 2007 01:01:40 -0000
***************
*** 21,26 ****
--- 21,28 ----
   <refsynopsisdiv>
  <synopsis>
  ALTER LANGUAGE <replaceable>name</replaceable> RENAME TO 
<replaceable>newname</replaceable>
+ 
+ ALTER LANGUAGE <replaceable>name</replaceable> OWNER TO 
<replaceable>new_owner</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 48,53 ****
--- 50,64 ----
     </varlistentry>
  
     <varlistentry>
+     <term><replaceable>new_owner</replaceable></term>
+     <listitem>
+      <para>
+       The new owner of the language.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><replaceable>newname</replaceable></term>
      <listitem>
       <para>
Index: src/backend/catalog/aclchk.c
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/backend/catalog/aclchk.c,v
retrieving revision 1.135
diff -c -r1.135 aclchk.c
*** src/backend/catalog/aclchk.c        23 Jan 2007 05:07:17 -0000      1.135
--- src/backend/catalog/aclchk.c        25 Jan 2007 06:35:21 -0000
***************
*** 1003,1013 ****
                /*
                 * 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;
                aclDatum = SysCacheGetAttr(LANGNAME, tuple, 
Anum_pg_language_lanacl,
                                                                   &isNull);
                if (isNull)
--- 1003,1010 ----
                /*
                 * Get owner ID and working copy of existing ACL. If there's no 
ACL,
                 * substitute the proper default.
                 */
!               ownerId = pg_language_tuple->lanowner;
                aclDatum = SysCacheGetAttr(LANGNAME, tuple, 
Anum_pg_language_lanacl,
                                                                   &isNull);
                if (isNull)
***************
*** 1770,1777 ****
                                (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;
  
        aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
                                                           &isNull);
--- 1767,1773 ----
                                (errcode(ERRCODE_UNDEFINED_OBJECT),
                                 errmsg("language with OID %u does not exist", 
lang_oid)));
  
!       ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
  
        aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
                                                           &isNull);
Index: src/backend/commands/alter.c
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/backend/commands/alter.c,v
retrieving revision 1.22
diff -c -r1.22 alter.c
*** src/backend/commands/alter.c        23 Jan 2007 05:07:17 -0000      1.22
--- src/backend/commands/alter.c        25 Jan 2007 23:55:41 -0000
***************
*** 203,208 ****
--- 203,212 ----
                        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,
Index: src/backend/commands/proclang.c
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/backend/commands/proclang.c,v
retrieving revision 1.71
diff -c -r1.71 proclang.c
*** src/backend/commands/proclang.c     22 Jan 2007 01:35:20 -0000      1.71
--- src/backend/commands/proclang.c     26 Jan 2007 01:17:27 -0000
***************
*** 17,22 ****
--- 17,24 ----
  #include "access/heapam.h"
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
+ #include "catalog/pg_authid.h"
+ #include "catalog/pg_database.h"
  #include "catalog/pg_language.h"
  #include "catalog/pg_namespace.h"
  #include "catalog/pg_pltemplate.h"
***************
*** 27,32 ****
--- 29,35 ----
  #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"
***************
*** 36,49 ****
  typedef struct
  {
        bool            tmpltrusted;    /* trusted? */
        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);
  static PLTemplate *find_language_template(const char *languageName);
  
  
  /* ---------------------------------------------------------------------
--- 39,56 ----
  typedef struct
  {
        bool            tmpltrusted;    /* trusted? */
+       bool            tmpldbaallowed; /* 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 languageOwner, Oid handlerOid, Oid valOid, 
bool trusted);
  static PLTemplate *find_language_template(const char *languageName);
+ static void AlterLanguageOwner_internal(HeapTuple tup, Relation rel, Oid 
newOwnerId);
+ 
+ static Oid find_desired_language_owner (PLTemplate *pltemplate);
  
  
  /* ---------------------------------------------------------------------
***************
*** 61,74 ****
        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
         */
--- 68,73 ----
***************
*** 97,102 ****
--- 96,124 ----
                                        (errmsg("using pg_pltemplate 
information instead of CREATE LANGUAGE parameters")));
  
                /*
+                * Check permission
+                */
+               if (pltemplate->tmpltrusted && pltemplate->tmpldbaallowed)
+               {
+                               if (!pg_database_ownercheck(MyDatabaseId, 
GetUserId()))
+                                       ereport(ERROR,
+                                                       
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                                        errmsg("must be 
database owner or superuser to create procedural language \"%s\"", 
languageName)));
+               }
+               else if (!superuser())
+               {
+                       if (!pltemplate->tmpltrusted)
+                               ereport(ERROR,
+                                               
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                                errmsg("must be superuser to 
create untrusted procedural language")));
+                       else
+                               ereport(ERROR,
+                                               
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                                errmsg("must be superuser to 
create procedural language \"%s\"", languageName),
+                                                errhint("Column 
pg_pltemplate.tmpldbaallowed has been set to false for this language.")));
+               }
+ 
+               /*
                 * Find or create the handler function, which we force to be in 
the
                 * pg_catalog schema.  If already present, it must have the 
correct
                 * return type.
***************
*** 171,177 ****
                        valOid = InvalidOid;
  
                /* ok, create it */
!               create_proc_lang(languageName, handlerOid, valOid,
                                                 pltemplate->tmpltrusted);
        }
        else
--- 193,199 ----
                        valOid = InvalidOid;
  
                /* ok, create it */
!               create_proc_lang(languageName, 
find_desired_language_owner(pltemplate), handlerOid, valOid,
                                                 pltemplate->tmpltrusted);
        }
        else
***************
*** 189,194 ****
--- 211,224 ----
                                         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
                 */
***************
*** 227,233 ****
                        valOid = InvalidOid;
  
                /* ok, create it */
!               create_proc_lang(languageName, handlerOid, valOid, 
stmt->pltrusted);
        }
  }
  
--- 257,263 ----
                        valOid = InvalidOid;
  
                /* ok, create it */
!               create_proc_lang(languageName, BOOTSTRAP_SUPERUSERID, 
handlerOid, valOid, stmt->pltrusted);
        }
  }
  
***************
*** 236,242 ****
   */
  static void
  create_proc_lang(const char *languageName,
!                                Oid handlerOid, Oid valOid, bool trusted)
  {
        Relation        rel;
        TupleDesc       tupDesc;
--- 266,272 ----
   */
  static void
  create_proc_lang(const char *languageName,
!                                Oid languageOwner, Oid handlerOid, Oid valOid, 
bool trusted)
  {
        Relation        rel;
        TupleDesc       tupDesc;
***************
*** 258,263 ****
--- 288,294 ----
  
        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);
***************
*** 277,282 ****
--- 308,319 ----
        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;
***************
*** 295,300 ****
--- 332,366 ----
        heap_close(rel, RowExclusiveLock);
  }
  
+ 
+ static Oid find_desired_language_owner (PLTemplate *pltemplate)
+ {
+       if (pltemplate->tmpltrusted && pltemplate->tmpldbaallowed)
+       {
+               /* find datdba for current db */
+               HeapTuple       tuple;
+               Oid                     dba;
+ 
+               tuple = SearchSysCache(DATABASEOID,
+                               ObjectIdGetDatum(MyDatabaseId),
+                               0, 0, 0);
+               if (!HeapTupleIsValid(tuple))
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_UNDEFINED_DATABASE),
+                                        errmsg("database with OID %u does not 
exist", MyDatabaseId)));
+ 
+               dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
+ 
+               ReleaseSysCache(tuple);
+               return dba;
+       }
+       else
+       {
+               /* current behaviour */
+               return BOOTSTRAP_SUPERUSERID;
+       }
+ }
+ 
  /*
   * Look to see if we have template information for the given language name.
   */
***************
*** 325,330 ****
--- 391,397 ----
  
                result = (PLTemplate *) palloc0(sizeof(PLTemplate));
                result->tmpltrusted = tmpl->tmpltrusted;
+               result->tmpldbaallowed = tmpl->tmpldbaallowed;
  
                /* Remaining fields are variable-width so we need heap_getattr 
*/
                datum = heap_getattr(tup, Anum_pg_pltemplate_tmplhandler,
***************
*** 382,395 ****
        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
         */
        languageName = case_translate_language_name(stmt->plname);
--- 449,454 ----
***************
*** 411,416 ****
--- 470,483 ----
                return;
        }
  
+       /*
+        * Check permission
+        */
+       if (!has_privs_of_role (GetUserId(), ((Form_pg_language) 
GETSTRUCT(langTup))->lanowner))
+               ereport(ERROR,
+                               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                errmsg("must be owner to drop procedural 
language")));
+ 
        object.classId = LanguageRelationId;
        object.objectId = HeapTupleGetOid(langTup);
        object.objectSubId = 0;
***************
*** 478,488 ****
                                (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")));
  
        /* rename */
        namestrcpy(&(((Form_pg_language) GETSTRUCT(tup))->lanname), newname);
--- 545,555 ----
                                (errcode(ERRCODE_DUPLICATE_OBJECT),
                                 errmsg("language \"%s\" already exists", 
newname)));
  
!       /* must be owner of PL */
!       if (!has_privs_of_role (GetUserId(), ((Form_pg_language) 
GETSTRUCT(tup))->lanowner))
                ereport(ERROR,
                                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
!                                errmsg("must be owner to rename procedural 
language")));
  
        /* rename */
        namestrcpy(&(((Form_pg_language) GETSTRUCT(tup))->lanname), newname);
***************
*** 492,494 ****
--- 559,669 ----
        heap_close(rel, NoLock);
        heap_freetuple(tup);
  }
+ 
+ /*
+  * Change language owner
+  */
+ void
+ AlterLanguageOwner(const char *name, Oid newOwnerId)
+ {
+       HeapTuple       tup;
+       Relation        rel;
+ 
+       /* 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)));
+ 
+       AlterLanguageOwner_internal(tup, rel, newOwnerId);
+ 
+       ReleaseSysCache(tup);
+       heap_close(rel, RowExclusiveLock);
+ }
+ 
+ static void
+ AlterLanguageOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
+ {
+       Form_pg_language lanForm;
+ 
+       Assert(tup->t_tableOid == LanguageRelationId);
+       Assert(RelationGetRelid(rel) == LanguageRelationId);
+ 
+       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;
+               AclResult       aclresult;
+ 
+               /* Otherwise, must be owner of the existing object */
+               if (!has_privs_of_role(GetUserId(), lanForm->lanowner))
+                       ereport(ERROR,
+                                       
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                        errmsg("must be member of role \"%s\"",
+                                                
GetUserNameFromId(lanForm->lanowner))));
+ 
+               /* Must be able to become new owner */
+               check_is_member_of_role(GetUserId(), newOwnerId);
+ 
+               /*
+                * must have rights to create this language
+                */
+               if (!has_privs_of_role(newOwnerId, find_desired_language_owner 
(find_language_template (NameStr(lanForm->lanname)))))
+               {
+                       ereport(ERROR,
+                                       
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                        errmsg("new user must be allowed to 
create this language")));
+               }
+ 
+               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);
+       }
+ }
Index: src/backend/parser/gram.y
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.577
diff -c -r2.577 gram.y
*** src/backend/parser/gram.y   25 Jan 2007 11:53:51 -0000      2.577
--- src/backend/parser/gram.y   25 Jan 2007 23:55:10 -0000
***************
*** 4596,4601 ****
--- 4596,4609 ----
                                        n->newowner = $7;
                                        $$ = (Node *)n;
                                }
+                       | ALTER LANGUAGE name OWNER TO RoleId
+                               {
+                                       AlterOwnerStmt *n = 
makeNode(AlterOwnerStmt);
+                                       n->objectType = OBJECT_LANGUAGE;
+                                       n->object = list_make1($3);
+                                       n->newowner = $6;
+                                       $$ = (Node *)n;
+                               }
                        | ALTER OPERATOR any_operator '(' oper_argtypes ')' 
OWNER TO RoleId
                                {
                                        AlterOwnerStmt *n = 
makeNode(AlterOwnerStmt);
Index: src/backend/tcop/utility.c
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/backend/tcop/utility.c,v
retrieving revision 1.271
diff -c -r1.271 utility.c
*** src/backend/tcop/utility.c  23 Jan 2007 05:07:18 -0000      1.271
--- src/backend/tcop/utility.c  26 Jan 2007 00:53:24 -0000
***************
*** 1530,1535 ****
--- 1530,1538 ----
                                case OBJECT_FUNCTION:
                                        tag = "ALTER FUNCTION";
                                        break;
+                               case OBJECT_LANGUAGE:
+                                       tag = "ALTER LANGUAGE";
+                                       break;
                                case OBJECT_OPERATOR:
                                        tag = "ALTER OPERATOR";
                                        break;
Index: src/bin/psql/tab-complete.c
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/bin/psql/tab-complete.c,v
retrieving revision 1.157
diff -c -r1.157 tab-complete.c
*** src/bin/psql/tab-complete.c 5 Jan 2007 22:19:49 -0000       1.157
--- src/bin/psql/tab-complete.c 26 Jan 2007 01:05:33 -0000
***************
*** 651,657 ****
        /* ALTER LANGUAGE <name> */
        else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
                         pg_strcasecmp(prev2_wd, "LANGUAGE") == 0)
!               COMPLETE_WITH_CONST("RENAME TO");
  
        /* ALTER USER,ROLE <name> */
        else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
--- 651,662 ----
        /* ALTER LANGUAGE <name> */
        else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
                         pg_strcasecmp(prev2_wd, "LANGUAGE") == 0)
!       {
!               static const char *const list_ALTERLANGUAGE[] =
!               {"RENAME TO", "OWNER TO", NULL};
! 
!               COMPLETE_WITH_LIST(list_ALTERLANGUAGE);
!       }
  
        /* ALTER USER,ROLE <name> */
        else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
Index: src/include/catalog/pg_language.h
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/include/catalog/pg_language.h,v
retrieving revision 1.29
diff -c -r1.29 pg_language.h
*** src/include/catalog/pg_language.h   5 Jan 2007 22:19:52 -0000       1.29
--- src/include/catalog/pg_language.h   25 Jan 2007 03:51:13 -0000
***************
*** 36,41 ****
--- 36,42 ----
  CATALOG(pg_language,2612)
  {
        NameData        lanname;
+       Oid                     lanowner;               /* language owner */
        bool            lanispl;                /* Is a procedural language */
        bool            lanpltrusted;   /* PL is trusted */
        Oid                     lanplcallfoid;  /* Call handler for PL */
***************
*** 54,79 ****
   *            compiler constants for pg_language
   * ----------------
   */
! #define Natts_pg_language                             6
  #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
  
  /* ----------------
   *            initial contents of pg_language
   * ----------------
   */
  
! DATA(insert OID = 12 ( "internal" f f 0 2246 _null_ ));
  DESCR("Built-in functions");
  #define INTERNALlanguageId 12
! DATA(insert OID = 13 ( "c" f f 0 2247 _null_ ));
  DESCR("Dynamically-loaded C functions");
  #define ClanguageId 13
! DATA(insert OID = 14 ( "sql" f t 0 2248 _null_ ));
  DESCR("SQL-language functions");
  #define SQLlanguageId 14
  
--- 55,81 ----
   *            compiler constants for pg_language
   * ----------------
   */
! #define Natts_pg_language                             7
  #define Anum_pg_language_lanname              1
! #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" PGUID f f 0 2246 _null_ ));
  DESCR("Built-in functions");
  #define INTERNALlanguageId 12
! DATA(insert OID = 13 ( "c" PGUID f f 0 2247 _null_ ));
  DESCR("Dynamically-loaded C functions");
  #define ClanguageId 13
! DATA(insert OID = 14 ( "sql" PGUID f t 0 2248 _null_ ));
  DESCR("SQL-language functions");
  #define SQLlanguageId 14
  
Index: src/include/catalog/pg_pltemplate.h
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/include/catalog/pg_pltemplate.h,v
retrieving revision 1.3
diff -c -r1.3 pg_pltemplate.h
*** src/include/catalog/pg_pltemplate.h 5 Jan 2007 22:19:53 -0000       1.3
--- src/include/catalog/pg_pltemplate.h 25 Jan 2007 01:36:57 -0000
***************
*** 37,42 ****
--- 37,43 ----
  {
        NameData        tmplname;               /* name of PL */
        bool            tmpltrusted;    /* PL is trusted? */
+       bool            tmpldbaallowed; /* 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 */
***************
*** 54,66 ****
   *            compiler constants for pg_pltemplate
   * ----------------
   */
! #define Natts_pg_pltemplate                                   6
  #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
  
  
  /* ----------------
--- 55,68 ----
   *            compiler constants for pg_pltemplate
   * ----------------
   */
! #define Natts_pg_pltemplate                                   7
  #define Anum_pg_pltemplate_tmplname                   1
  #define Anum_pg_pltemplate_tmpltrusted                2
! #define Anum_pg_pltemplate_tmpldbaallowed     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
  
  
  /* ----------------
***************
*** 68,78 ****
   * ----------------
   */
  
! 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_ ));
  
  #endif   /* PG_PLTEMPLATE_H */
--- 70,80 ----
   * ----------------
   */
  
! 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 t "pltclu_call_handler" _null_ 
"$libdir/pltcl" _null_ ));
! DATA(insert ( "plperl"                t t "plperl_call_handler" 
"plperl_validator" "$libdir/plperl" _null_ ));
! DATA(insert ( "plperlu"               f t "plperl_call_handler" 
"plperl_validator" "$libdir/plperl" _null_ ));
! DATA(insert ( "plpythonu"     f t "plpython_call_handler" _null_ 
"$libdir/plpython" _null_ ));
  
  #endif   /* PG_PLTEMPLATE_H */
Index: src/include/commands/proclang.h
===================================================================
RCS file: 
/data/local/jeremyd/postgres/cvsuproot/pgsql/src/include/commands/proclang.h,v
retrieving revision 1.11
diff -c -r1.11 proclang.h
*** src/include/commands/proclang.h     8 Sep 2005 20:07:42 -0000       1.11
--- src/include/commands/proclang.h     26 Jan 2007 00:37:51 -0000
***************
*** 15,20 ****
--- 15,21 ----
  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 */
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

Reply via email to