Re: ALTER EXTENSION UPGRADE, v3

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "David E(dot) Wheeler" <david(at)kineticode(dot)com>
Cc: Dimitri Fontaine <dimitri(at)2ndQuadrant(dot)fr>, Robert Haas <robertmhaas(at)gmail(dot)com>, Josh Berkus <josh(at)agliodbs(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ALTER EXTENSION UPGRADE, v3
Date: 2011-02-11 03:05:18
Message-ID: 12728.1297393518@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

"David E. Wheeler" <david(at)kineticode(dot)com> writes:
> On Feb 10, 2011, at 4:11 PM, Tom Lane wrote:
>> It's to tell it to create an empty extension in preparation for
>> absorbing pre-existing objects from an old-style contrib module.
>> See what I mean? WRAPPER is not a useful keyword here.

> Reminds me of creating a "shell type" so you can create I/O functions before *actually* creating the type. I don't suppose "SHELL" is available.

Actually, I was having second thoughts about that while at dinner. What
is the value of separating the bootstrap-an-extension-from-old-objects
operation into two steps? It's certainly not convenient for users, and
I don't see that the intermediate state with an empty extension has any
redeeming social value for developers either. (If you need such a thing,
just make an empty creation script.)

So: let's forget the concept of a special "null version" altogether, at
least from the user's-eye viewpoint. Instead, the way to bootstrap from
loose objects is something like

CREATE EXTENSION foo [ VERSION '1.0' ] [ FROM OLD ]

When you specify FROM OLD, this runs foo--1.0.sql instead of foo-1.0.sql
as it normally would. As before, that script contains ALTER EXTENSION
ADD commands instead of CREATE commands.

I like this because (a) it's one less step, and one less concept for
users to deal with, and (b) it's much harder to screw up. If you forget
FROM OLD when you needed it, the CREATE will fail with "object already
exists" errors. If you use FROM OLD when you shouldn't have, it will
fail with "object doesn't exist" errors. There's no way for the command
to apparently succeed while not actually creating the desired state.

(I'm not wedded to the phrase "FROM OLD" in particular, but it does
reuse already existing keywords. Also, maybe it'd be better to reserve
a version string such as "old" or "bootstrap", so that the bootstrap
script could be called something more legible like foo-bootstrap-1.0.sql.)

> That reminds me (OT), it's currently impossible to write an uninstall script for a custom data type because of the circular dependency between a type and its I/O functions. There's no way around that sort of DROP EXTENSION CASCADE, is there?

Yeah, DROP TYPE CASCADE is currently the accepted way to do that, and
it's definitely a tad risky in that you might zap more than just the
type and the I/O functions. But I don't feel a need to do anything
special to fix that, because grouping the type and the functions into
an extension will take care of the problem. You will not need to say
CASCADE unless you're actually wanting to delete objects outside the
extension.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2011-02-11 03:18:38 Re: [PERFORM] pgbench to the MAXINT
Previous Message Robert Haas 2011-02-11 02:56:16 Re: Fwd: [JDBC] Weird issues when reading UDT from stored function