Robert Haas <robertmh...@gmail.com> writes: > On Tue, Feb 8, 2011 at 10:25 PM, Tom Lane <t...@sss.pgh.pa.us> wrote: >> My point is that the current restriction to just one containing >> extension seems to me to be an implementation restriction, rather than >> something inherent in the concept of extensions. I have no intention of >> trying to relax that restriction in the near future --- I'm just >> pointing out that it could become an interesting thing to do.
> OK. My point was that I think we should definitely *enforce* that > restriction until we have a very clear vision of what it means to do > anything else, so it sounds like we're basically in agreement. Oh, for certain. I've been busy revising Dimitri's patch to use the get_object_address infrastructure, and here's what I've got for the actual implementation as distinct from syntax: + /* + * Execute ALTER THING SET EXTENSION + */ + void + ExecAlterObjectExtensionStmt(AlterObjectExtensionStmt *stmt) + { + ObjectAddress object; + ObjectAddress extension; + Relation relation; + + /* + * For now, insist on superuser privilege. Later we might want to + * relax this to ownership of the target object and the extension. + */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be superuser to use ALTER SET EXTENSION")))); + + /* + * Translate the parser representation that identifies this object into + * an ObjectAddress. get_object_address() will throw an error if the + * object does not exist, and will also acquire a lock on the target + * to guard against concurrent DROP and SET EXTENSION operations. + */ + object = get_object_address(stmt->objtype, stmt->objname, stmt->objargs, + &relation, ShareUpdateExclusiveLock); + + /* + * Complain if object is already attached to some extension. + */ + if (getExtensionOfObject(object.classId, object.objectId) != InvalidOid) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("%s is already a member of an extension", + getObjectDescription(&object)))); + + /* + * OK, add the dependency. + */ + extension.classId = ExtensionRelationId; + extension.objectId = get_extension_oid(stmt->extname, false); + extension.objectSubId = 0; + + recordDependencyOn(&object, &extension, DEPENDENCY_EXTENSION); + + /* + * If get_object_address() opened the relation for us, we close it to keep + * the reference count correct - but we retain any locks acquired by + * get_object_address() until commit time, to guard against concurrent + * activity. + */ + if (relation != NULL) + relation_close(relation, NoLock); + } regards, tom lane -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers