Removing pg_migrator limitations

Started by Bruce Momjianover 16 years ago73 messageshackers
Jump to latest
#1Bruce Momjian
bruce@momjian.us

There are several pg_migrator limitations that appeared late in the 8.4
development cycle and were impossible to fix at that point. I would
like to fix them for Postgres 8.5:

o a user-defined composite data type
o a user-defined array data type
o a user-defined enum data type

I have discussed this with Alvaro. I think pg_migrator needs the
ability to set the pg_type.oid and pg_enum.oid for user-defined
composites, arrays, and enums to match the values in the old server, and
hence match references to those rows in user data tables.

The general solution will involve creating place-hold rows in pg_type
and pg_enum with the desired oids, and deleting those placeholder rows
at the time pg_dump creates the new type or enum, and passing the
desired oid to the creation command. We do something similar for toast
tables now, but it is easier there because the oids are actually file
system files.

There is no ability to specify an OID column value on insert. However,
pg_migrator has the ability to call backend C functions via shared
library functions so it could potentially insert the needed system
catalog dummy rows. As far as creating rows with the proper oids, we
could modify the SQL grammar to allow it, or modify DefineType() so it
accepts oids and passes them to TypeCreate(), or a simpler approach
would be to set the oid counter before calling CREATE TYPE, but that
would be error-prone because other oids might be assigned in
indeterminate order --- we removed that code from pg_migrator for toast
tables before 8.4 shipped, so I am not excited to re-add it. The same
approach is necessary for enums.

Another approach could be to create the dummy rows, load all of the
pg_dump schema, then renumber the rows to the proper oids, but this
assumes that I will be able to find all references to the current oids
and renumber those too.

Seems I need some help here.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#2Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Bruce Momjian (#1)
Re: Removing pg_migrator limitations

Bruce Momjian wrote:

There are several pg_migrator limitations that appeared late in the 8.4
development cycle and were impossible to fix at that point. I would
like to fix them for Postgres 8.5:

o a user-defined composite data type
o a user-defined array data type
o a user-defined enum data type

I have discussed this with Alvaro. I think pg_migrator needs the
ability to set the pg_type.oid and pg_enum.oid for user-defined
composites, arrays, and enums to match the values in the old server, and
hence match references to those rows in user data tables.

To be more precise, the pg_enum.oid needs to be set for ENUM types;
there's no need for setting the pg_type.oid (for ENUM types). I don't
know about composites but I think the problem with user defined arrays
is the OID of the element type, not the array itself.

The general solution will involve creating place-hold rows in pg_type
and pg_enum with the desired oids, and deleting those placeholder rows
at the time pg_dump creates the new type or enum, and passing the
desired oid to the creation command.

I don't think there's a need for pg_enum placeholders. Just create them
with the correct OIDs as the first step. Nobody else is going to use
pg_enum.oids anyway. Again, I don't know about arrays or composites.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#3Bruce Momjian
bruce@momjian.us
In reply to: Alvaro Herrera (#2)
Re: Removing pg_migrator limitations

Alvaro Herrera wrote:

Bruce Momjian wrote:

There are several pg_migrator limitations that appeared late in the 8.4
development cycle and were impossible to fix at that point. I would
like to fix them for Postgres 8.5:

o a user-defined composite data type
o a user-defined array data type
o a user-defined enum data type

I have discussed this with Alvaro. I think pg_migrator needs the
ability to set the pg_type.oid and pg_enum.oid for user-defined
composites, arrays, and enums to match the values in the old server, and
hence match references to those rows in user data tables.

To be more precise, the pg_enum.oid needs to be set for ENUM types;
there's no need for setting the pg_type.oid (for ENUM types). I don't
know about composites but I think the problem with user defined arrays
is the OID of the element type, not the array itself.

Yes, good point. I can see where the oids are assigned in our C code:

oids[i] = GetNewOid(pg_enum);

array_oid = GetNewOid(pg_type);

I need a way of controlling that. Now, ideally, I would just be able to
add an optional oid field to DefineType() and call it from a server-side
C function called by pg_migrator, but the problem is that that function
assumes it is receiving a complex struct DefineStmt which can't easily
be created by pg_migrator.

The general solution will involve creating place-hold rows in pg_type
and pg_enum with the desired oids, and deleting those placeholder rows
at the time pg_dump creates the new type or enum, and passing the
desired oid to the creation command.

I don't think there's a need for pg_enum placeholders. Just create them
with the correct OIDs as the first step. Nobody else is going to use
pg_enum.oids anyway. Again, I don't know about arrays or composites.

That will make things easier because of the large number of oids
consumed by enumerated types.

I am now thinking that setting the oid counter before calling CREATE
TYPE/ENUM might be the cleanest, and of course with pg_dump setting this
all up when in --binary-upgrade mode. It does make pg_migrator
dependent on the order of oid allocation in those routines. It also
might make some migrations impossible if concurrent enum creation caused
gaps in the assignment of oids in a single enumerated type.

A crazier idea would be for pg_migrator to set server-side global
variables that contain the oids to be used. pg_dump would call those
functions to set and clear the global variables when in --binary-upgrade
mode, and the backend code would consult those variables before calling
GetNewOid(), or GetNewOid() would consult those global variables.

You can now see why this was not fixed in 8.4. :-(

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#4Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Bruce Momjian (#3)
Re: Removing pg_migrator limitations

Bruce Momjian wrote:

Alvaro Herrera wrote:

Bruce Momjian wrote:

There are several pg_migrator limitations that appeared late in the 8.4
development cycle and were impossible to fix at that point. I would
like to fix them for Postgres 8.5:

o a user-defined composite data type
o a user-defined array data type
o a user-defined enum data type

I have discussed this with Alvaro. I think pg_migrator needs the
ability to set the pg_type.oid and pg_enum.oid for user-defined
composites, arrays, and enums to match the values in the old server, and
hence match references to those rows in user data tables.

To be more precise, the pg_enum.oid needs to be set for ENUM types;
there's no need for setting the pg_type.oid (for ENUM types). I don't
know about composites but I think the problem with user defined arrays
is the OID of the element type, not the array itself.

Yes, good point. I can see where the oids are assigned in our C code:

oids[i] = GetNewOid(pg_enum);

array_oid = GetNewOid(pg_type);

I need a way of controlling that.

You're (partly?) missing my point which is that the important OID to
control is the one that actually gets stored on table files.

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

#5Bruce Momjian
bruce@momjian.us
In reply to: Alvaro Herrera (#4)
Re: Removing pg_migrator limitations

Alvaro Herrera wrote:

Bruce Momjian wrote:

Alvaro Herrera wrote:

Bruce Momjian wrote:

There are several pg_migrator limitations that appeared late in the 8.4
development cycle and were impossible to fix at that point. I would
like to fix them for Postgres 8.5:

o a user-defined composite data type
o a user-defined array data type
o a user-defined enum data type

I have discussed this with Alvaro. I think pg_migrator needs the
ability to set the pg_type.oid and pg_enum.oid for user-defined
composites, arrays, and enums to match the values in the old server, and
hence match references to those rows in user data tables.

To be more precise, the pg_enum.oid needs to be set for ENUM types;
there's no need for setting the pg_type.oid (for ENUM types). I don't
know about composites but I think the problem with user defined arrays
is the OID of the element type, not the array itself.

Yes, good point. I can see where the oids are assigned in our C code:

oids[i] = GetNewOid(pg_enum);

array_oid = GetNewOid(pg_type);

I need a way of controlling that.

You're (partly?) missing my point which is that the important OID to
control is the one that actually gets stored on table files.

Well, I thought the idea was to set the system table oid to match the
oids already in the user tables. I realize that is not all system oids.
What am I missing exactly?

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#6Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Bruce Momjian (#5)
Re: Removing pg_migrator limitations

Bruce Momjian wrote:

Alvaro Herrera wrote:

Bruce Momjian wrote:

Alvaro Herrera wrote:

To be more precise, the pg_enum.oid needs to be set for ENUM types;
there's no need for setting the pg_type.oid (for ENUM types). I don't
know about composites but I think the problem with user defined arrays
is the OID of the element type, not the array itself.

Yes, good point. I can see where the oids are assigned in our C code:

oids[i] = GetNewOid(pg_enum);

array_oid = GetNewOid(pg_type);

I need a way of controlling that.

You're (partly?) missing my point which is that the important OID to
control is the one that actually gets stored on table files.

Well, I thought the idea was to set the system table oid to match the
oids already in the user tables. I realize that is not all system oids.
What am I missing exactly?

I think the OIDs for user-defined arrays stored in table data are
element types, not the array type which is what you're pointing at with
the line you quote:

array_oid = GetNewOid(pg_type);

IMBFOS.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#7Bruce Momjian
bruce@momjian.us
In reply to: Alvaro Herrera (#6)
Re: Removing pg_migrator limitations

Alvaro Herrera wrote:

Bruce Momjian wrote:

Alvaro Herrera wrote:

Bruce Momjian wrote:

Alvaro Herrera wrote:

To be more precise, the pg_enum.oid needs to be set for ENUM types;
there's no need for setting the pg_type.oid (for ENUM types). I don't
know about composites but I think the problem with user defined arrays
is the OID of the element type, not the array itself.

Yes, good point. I can see where the oids are assigned in our C code:

oids[i] = GetNewOid(pg_enum);

array_oid = GetNewOid(pg_type);

I need a way of controlling that.

You're (partly?) missing my point which is that the important OID to
control is the one that actually gets stored on table files.

Well, I thought the idea was to set the system table oid to match the
oids already in the user tables. I realize that is not all system oids.
What am I missing exactly?

I think the OIDs for user-defined arrays stored in table data are
element types, not the array type which is what you're pointing at with
the line you quote:

array_oid = GetNewOid(pg_type);

IMBFOS.

Oh, yea, sorry, I was just showing examples of where we get the oids ---
I have not researched the exact calls yet, but I am doing that now and
will apply a patch that adds C comments to the C structures to identify
them. I figure it would be good to document this no matter what we do.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#8Andrew Dunstan
andrew@dunslane.net
In reply to: Bruce Momjian (#1)
Re: Removing pg_migrator limitations

Bruce Momjian wrote:

There are several pg_migrator limitations that appeared late in the 8.4
development cycle and were impossible to fix at that point. I would
like to fix them for Postgres 8.5:

o a user-defined composite data type
o a user-defined array data type
o a user-defined enum data type

I have discussed this with Alvaro. I think pg_migrator needs the
ability to set the pg_type.oid and pg_enum.oid for user-defined
composites, arrays, and enums to match the values in the old server, and
hence match references to those rows in user data tables.

The general solution will involve creating place-hold rows in pg_type
and pg_enum with the desired oids, and deleting those placeholder rows
at the time pg_dump creates the new type or enum, and passing the
desired oid to the creation command. We do something similar for toast
tables now, but it is easier there because the oids are actually file
system files.

There is no ability to specify an OID column value on insert. However,
pg_migrator has the ability to call backend C functions via shared
library functions so it could potentially insert the needed system
catalog dummy rows. As far as creating rows with the proper oids, we
could modify the SQL grammar to allow it, or modify DefineType() so it
accepts oids and passes them to TypeCreate(), or a simpler approach
would be to set the oid counter before calling CREATE TYPE, but that
would be error-prone because other oids might be assigned in
indeterminate order --- we removed that code from pg_migrator for toast
tables before 8.4 shipped, so I am not excited to re-add it. The same
approach is necessary for enums.

Another approach could be to create the dummy rows, load all of the
pg_dump schema, then renumber the rows to the proper oids, but this
assumes that I will be able to find all references to the current oids
and renumber those too.

Seems I need some help here.

I thought there was a suggestion that we would be able to specify the
oids in the SQL that creates the types, along the lines of:

create type foo as enum ( ...) with oids ( ... );

Is that a non-starter? I imagine it would need to require some special
setting to be enabled to allow it.

cheers

andrew

#9Robert Haas
robertmhaas@gmail.com
In reply to: Andrew Dunstan (#8)
Re: Removing pg_migrator limitations

On Fri, Dec 18, 2009 at 6:44 PM, Andrew Dunstan <andrew@dunslane.net> wrote:

I thought there was a suggestion that we would be able to specify the oids
in the SQL that creates the types, along the lines of:

  create type foo as enum ( ...) with oids ( ... );

Is that a non-starter? I imagine it would need to require some special
setting to be enabled to allow it.

This gets at a question that I've been wondering about. There seems
to be something about OIDs that makes us want to not ever allow users
to specify them, or only when our back is absolutely against the wall.
I have only the vaguest notions of what might be dangerous about
that, though.

...Robert

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#8)
Re: Removing pg_migrator limitations

Bruce Momjian wrote:

Seems I need some help here.

I'm willing to work on this --- it doesn't look particularly fun but
we really need it.

Andrew Dunstan <andrew@dunslane.net> writes:

I thought there was a suggestion that we would be able to specify the
oids in the SQL that creates the types, along the lines of:
create type foo as enum ( ...) with oids ( ... );
Is that a non-starter? I imagine it would need to require some special
setting to be enabled to allow it.

The more I think about it the less I want such warts placed in the
regular SQL syntax for creation commands. As soon as we add a wart like
that we'll be stuck with supporting it forever. Whatever we do here
should be off in a little corner that only pg_migrator can get at.

And we already have a way to manage that: there's already something
in pg_migrator to let it install special functions that are present
only while migrating. So I suggest that we make whatever hacks are
needed available only at the C-code level, and let pg_migrator get
at them via its special functions.

In practice, this would mean teaching pg_dump to call these functions
when it is making a --binary_upgrade dump. The reason I think this
is less of a support hazard than changing SQL statements is that there
is no promise or intention that a --binary_upgrade dump will load into
anything but the specific PG version that it's intended for. (We
could, and probably should, add some version labeling to the dump to
help enforce that.)

At the moment it appears that we need the following hacks:

* ability to control the OIDs assigned to user tables and types.
Because a table also has a rowtype, this means at least two separate
state variables. And we already knew we had to control the OIDs
assigned to toast tables. I'm imagining dump output like

select pg_migrator_set_next_table_oid(123456);
select pg_migrator_set_next_type_oid(12347);
select pg_migrator_set_next_toast_table_oid(123458);

CREATE TABLE ...

where the functions cause static variables to become set, and the
core code gets changed to look like

if (next_table_oid)
{
newoid = next_table_oid;
next_table_oid = 0;
}
else
newoid = GetNewOid(...);

in selected places where currently there's just a GetNewOid(...) call.

* ability to control the OIDs assigned to enum values. To keep this
sane I think the easiest way is to have pg_migrator have a function
that adds one value with a predetermined OID to an existing enum.
So instead of CREATE TYPE foo AS ENUM ('bar', 'baz', ...)
I envision the --binary_upgrade dump output looking like

-- force the OID of the enum type itself
select pg_migrator_set_next_type_oid(12347);

CREATE TYPE foo AS ENUM ();

select pg_migrator_add_enum_value(12347, 'bar', 12348);
select pg_migrator_add_enum_value(12347, 'baz', 12349);
...

I don't see any value in the placeholder-row approach Bruce suggests;
AFAICS it would require significantly uglier backend hacks than the
above because dealing with an already-present row would be a bigger
code change.

Comments?

regards, tom lane

#11Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#10)
Re: Removing pg_migrator limitations

Tom Lane wrote:

* ability to control the OIDs assigned to user tables and types.
Because a table also has a rowtype, this means at least two separate
state variables. And we already knew we had to control the OIDs
assigned to toast tables. I'm imagining dump output like

select pg_migrator_set_next_table_oid(123456);
select pg_migrator_set_next_type_oid(12347);
select pg_migrator_set_next_toast_table_oid(123458);

CREATE TABLE ...

Do we also need a knob for the table type's array type?

* ability to control the OIDs assigned to enum values. To keep this
sane I think the easiest way is to have pg_migrator have a function
that adds one value with a predetermined OID to an existing enum.
So instead of CREATE TYPE foo AS ENUM ('bar', 'baz', ...)
I envision the --binary_upgrade dump output looking like

-- force the OID of the enum type itself
select pg_migrator_set_next_type_oid(12347);

This part isn't necessary AFAIK, except to be used as reference here:

CREATE TYPE foo AS ENUM ();

select pg_migrator_add_enum_value(12347, 'bar', 12348);
select pg_migrator_add_enum_value(12347, 'baz', 12349);

on which we could perhaps use "foo" as a reference instead of the OID
value. However, I think array and composite types need a specific type
OID, so the set_next_type_oid function would still be necessary.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#12Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#10)
Re: Removing pg_migrator limitations

Tom Lane wrote:

At the moment it appears that we need the following hacks:

* ability to control the OIDs assigned to user tables and types.
Because a table also has a rowtype, this means at least two separate
state variables. And we already knew we had to control the OIDs
assigned to toast tables. I'm imagining dump output like

select pg_migrator_set_next_table_oid(123456);
select pg_migrator_set_next_type_oid(12347);
select pg_migrator_set_next_toast_table_oid(123458);

CREATE TABLE ...

where the functions cause static variables to become set, and the
core code gets changed to look like

if (next_table_oid)
{
newoid = next_table_oid;
next_table_oid = 0;
}
else
newoid = GetNewOid(...);

in selected places where currently there's just a GetNewOid(...) call.

* ability to control the OIDs assigned to enum values. To keep this
sane I think the easiest way is to have pg_migrator have a function
that adds one value with a predetermined OID to an existing enum.
So instead of CREATE TYPE foo AS ENUM ('bar', 'baz', ...)
I envision the --binary_upgrade dump output looking like

-- force the OID of the enum type itself
select pg_migrator_set_next_type_oid(12347);

CREATE TYPE foo AS ENUM ();

select pg_migrator_add_enum_value(12347, 'bar', 12348);
select pg_migrator_add_enum_value(12347, 'baz', 12349);
...

I don't see any value in the placeholder-row approach Bruce suggests;
AFAICS it would require significantly uglier backend hacks than the
above because dealing with an already-present row would be a bigger
code change.

Comments?

That looks fairly workable. The placeholder idea seems like a bit of a
potential footgun, so I like the idea that we can in some limited
circumstances set the oids fairly directly.

cheers

andrew

#13Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#11)
Re: Removing pg_migrator limitations

Alvaro Herrera <alvherre@commandprompt.com> writes:

Tom Lane wrote:

select pg_migrator_set_next_table_oid(123456);
select pg_migrator_set_next_type_oid(12347);
select pg_migrator_set_next_toast_table_oid(123458);

CREATE TABLE ...

Do we also need a knob for the table type's array type?

Well, we wouldn't care about the oid of the array type, except that if
the backend is allowed to assign it on its own, it might eat an oid that
we're going to need later for another type. So yeah, array oids too.
(The above is just a sketch, I don't promise it's complete ;-))

-- force the OID of the enum type itself
select pg_migrator_set_next_type_oid(12347);

This part isn't necessary AFAIK, except to be used as reference here:

CREATE TYPE foo AS ENUM ();

Exactly. We have to assign the oid of the enum type just as much as any
other type. Basically, to avoid collisions we'll need to ensure we nail
down the oids of every pg_class and pg_type row to be the same as they
were before. We might have to nail down relfilenodes similarly, not
sure yet.

regards, tom lane

#14Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#7)
Re: Removing pg_migrator limitations

Bruce Momjian wrote:

I think the OIDs for user-defined arrays stored in table data are
element types, not the array type which is what you're pointing at with
the line you quote:

array_oid = GetNewOid(pg_type);

IMBFOS.

Oh, yea, sorry, I was just showing examples of where we get the oids ---
I have not researched the exact calls yet, but I am doing that now and
will apply a patch that adds C comments to the C structures to identify
them. I figure it would be good to document this no matter what we do.

I have applied the attached patch which documents the locations where
system oids have to be preserved for binary upgrades.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

Attachments:

/rtmp/difftext/x-diffDownload+24-0
#15Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#10)
Re: Removing pg_migrator limitations

Tom Lane wrote:

The more I think about it the less I want such warts placed in the
regular SQL syntax for creation commands. As soon as we add a wart like
that we'll be stuck with supporting it forever. Whatever we do here
should be off in a little corner that only pg_migrator can get at.

Yea, and we might need more some day so a system that can be easily
enhanced would help. Adding to SQL syntax and maintaining it seems like
overkill.

And we already have a way to manage that: there's already something
in pg_migrator to let it install special functions that are present
only while migrating. So I suggest that we make whatever hacks are
needed available only at the C-code level, and let pg_migrator get
at them via its special functions.

Right.

In practice, this would mean teaching pg_dump to call these functions
when it is making a --binary_upgrade dump. The reason I think this
is less of a support hazard than changing SQL statements is that there
is no promise or intention that a --binary_upgrade dump will load into
anything but the specific PG version that it's intended for. (We
could, and probably should, add some version labeling to the dump to
help enforce that.)

Yea, that is easy.

At the moment it appears that we need the following hacks:

* ability to control the OIDs assigned to user tables and types.
Because a table also has a rowtype, this means at least two separate
state variables. And we already knew we had to control the OIDs
assigned to toast tables. I'm imagining dump output like

select pg_migrator_set_next_table_oid(123456);
select pg_migrator_set_next_type_oid(12347);
select pg_migrator_set_next_toast_table_oid(123458);

I was thinking of something even more general:

select pg_migrator_set_oid('pg_type', 100);
select pg_migrator_set_oid('pg_type_array', 101);

and you just check for the strings in pg_migrator_set_oid and set the
proper variable. The idea I had was to create a global structure:

struct pg_migrator_oids {
Oid pg_type;
Oid pg_type_array;
...
}

This would initialize to zero as a global structure, and only
pg_migrator server-side functions set it.

CREATE TABLE ...

where the functions cause static variables to become set, and the
core code gets changed to look like

if (next_table_oid)
{
newoid = next_table_oid;
next_table_oid = 0;
}
else
newoid = GetNewOid(...);

Yes, that is what I was thinking too:

if (pg_migrator_oid.pg_type)
{
newoid = pg_migrator_oid.pg_type;
pg_migrator_oid.pg_type = 0;
}
else
newoid = GetNewOid(...);

in selected places where currently there's just a GetNewOid(...) call.

* ability to control the OIDs assigned to enum values. To keep this
sane I think the easiest way is to have pg_migrator have a function
that adds one value with a predetermined OID to an existing enum.
So instead of CREATE TYPE foo AS ENUM ('bar', 'baz', ...)
I envision the --binary_upgrade dump output looking like

-- force the OID of the enum type itself
select pg_migrator_set_next_type_oid(12347);

CREATE TYPE foo AS ENUM ();

select pg_migrator_add_enum_value(12347, 'bar', 12348);
select pg_migrator_add_enum_value(12347, 'baz', 12349);
...

Good idea --- I was trying to figure out how to assign an array of oids
and couldn't think of a simple way.

I don't see any value in the placeholder-row approach Bruce suggests;
AFAICS it would require significantly uglier backend hacks than the
above because dealing with an already-present row would be a bigger
code change.

True.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#16Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#13)
Re: Removing pg_migrator limitations

Tom Lane wrote:

Alvaro Herrera <alvherre@commandprompt.com> writes:

Tom Lane wrote:

select pg_migrator_set_next_table_oid(123456);
select pg_migrator_set_next_type_oid(12347);
select pg_migrator_set_next_toast_table_oid(123458);

CREATE TABLE ...

Do we also need a knob for the table type's array type?

Well, we wouldn't care about the oid of the array type, except that if
the backend is allowed to assign it on its own, it might eat an oid that
we're going to need later for another type. So yeah, array oids too.
(The above is just a sketch, I don't promise it's complete ;-))

-- force the OID of the enum type itself
select pg_migrator_set_next_type_oid(12347);

This part isn't necessary AFAIK, except to be used as reference here:

CREATE TYPE foo AS ENUM ();

Exactly. We have to assign the oid of the enum type just as much as any
other type. Basically, to avoid collisions we'll need to ensure we nail
down the oids of every pg_class and pg_type row to be the same as they

I assume you meant pg_type and pg_class above, or I hope you were.

were before. We might have to nail down relfilenodes similarly, not
sure yet.

Yea, piggybacking on Alvaro's idea for pg_enum, if we set all the
pg_type oids we can clearly do this with no placeholders necessary.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#17Joe Conway
mail@joeconway.com
In reply to: Tom Lane (#10)
Re: Removing pg_migrator limitations

On 12/18/2009 04:09 PM, Tom Lane wrote:

At the moment it appears that we need the following hacks:

* ability to control the OIDs assigned to user tables and types.
Because a table also has a rowtype, this means at least two separate
state variables. And we already knew we had to control the OIDs
assigned to toast tables. I'm imagining dump output like

select pg_migrator_set_next_table_oid(123456);
select pg_migrator_set_next_type_oid(12347);
select pg_migrator_set_next_toast_table_oid(123458);

CREATE TABLE ...

I like this approach overall, but wonder if it would be better to do:

select pg_migrator_set_next_oid('table', 123456);
select pg_migrator_set_next_oid('type', 12347);
select pg_migrator_set_next_oid('toast_table', 123458);

etc. Later we could easily add other supported objects...

Joe

#18Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#15)
Re: Removing pg_migrator limitations

Bruce Momjian <bruce@momjian.us> writes:

... The idea I had was to create a global structure:

struct pg_migrator_oids {
Oid pg_type;
Oid pg_type_array;
...
}

This would initialize to zero as a global structure, and only
pg_migrator server-side functions set it.

I would prefer *not* to do that, as that makes the list of settable oids
far more public than I would like; also you are totally dependent on
pg_migrator and the backend to be in sync about the definition of that
struct, which is going to be problematic in alpha releases in
particular, since PG_VERSION isn't going to distinguish them.

What I had in mind was more like

static Oid next_pg_class_oid = InvalidOid;

void
set_next_pg_class_oid(Oid oid)
{
next_pg_class_oid = oid;
}

in each module that needs to be able to accept a next-oid setting,
and then the pg_migrator loadable module would expose SQL-callable
wrappers for these functions. That way, any inconsistency shows up as
a link error: function needed not present.

regards, tom lane

#19Tom Lane
tgl@sss.pgh.pa.us
In reply to: Joe Conway (#17)
Re: Removing pg_migrator limitations

Joe Conway <mail@joeconway.com> writes:

I like this approach overall, but wonder if it would be better to do:
select pg_migrator_set_next_oid('table', 123456);
select pg_migrator_set_next_oid('type', 12347);
select pg_migrator_set_next_oid('toast_table', 123458);
etc. Later we could easily add other supported objects...

Yeah, Bruce was just suggesting the same. I do like that part of what
he mentioned, just because it'll be fewer special functions to add and
drop in pg_migrator.

regards, tom lane

#20Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#18)
Re: Removing pg_migrator limitations

Tom Lane wrote:

Bruce Momjian <bruce@momjian.us> writes:

... The idea I had was to create a global structure:

struct pg_migrator_oids {
Oid pg_type;
Oid pg_type_array;
...
}

This would initialize to zero as a global structure, and only
pg_migrator server-side functions set it.

I would prefer *not* to do that, as that makes the list of settable oids
far more public than I would like; also you are totally dependent on
pg_migrator and the backend to be in sync about the definition of that
struct, which is going to be problematic in alpha releases in
particular, since PG_VERSION isn't going to distinguish them.

What I had in mind was more like

static Oid next_pg_class_oid = InvalidOid;

void
set_next_pg_class_oid(Oid oid)
{
next_pg_class_oid = oid;
}

Good point about requiring a link to a symbol; a structure offset would
not link to anything and would silently fail.

Does exporting a function buy us anything vs. exporting a variable?

in each module that needs to be able to accept a next-oid setting,
and then the pg_migrator loadable module would expose SQL-callable
wrappers for these functions. That way, any inconsistency shows up as
a link error: function needed not present.

I will work on a patch to accomplish this, and have pg_migrator link in
the .so only if the new server is >= 8.5, which allows a single
pg_migrator binary to work for migration to 8.4 and 8.5.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#21Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#10)
#22Robert Haas
robertmhaas@gmail.com
In reply to: Bruce Momjian (#21)
#23Bruce Momjian
bruce@momjian.us
In reply to: Robert Haas (#22)
#24Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#20)
#25Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#24)
#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#25)
#27Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#26)
#28Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#27)
#29Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#28)
#30Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#29)
#31Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#30)
#32The Hermit Hacker
scrappy@hub.org
In reply to: Bruce Momjian (#31)
#33Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#31)
#34Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#33)
#35Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Robert Haas (#22)
#36Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#20)
#37Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jim Nasby (#35)
#38Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#36)
#39Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#38)
#40Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#39)
#41Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#40)
#42Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#41)
#43Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#40)
#44Andrew Dunstan
andrew@dunslane.net
In reply to: Bruce Momjian (#43)
#45Bruce Momjian
bruce@momjian.us
In reply to: Andrew Dunstan (#44)
#46Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#43)
#47Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#46)
#48Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#47)
#49Andrew Dunstan
andrew@dunslane.net
In reply to: Bruce Momjian (#47)
#50Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#48)
#51Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#36)
#52Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#50)
#53Andrew Dunstan
andrew@dunslane.net
In reply to: Bruce Momjian (#50)
#54Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#52)
#55Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#54)
#56Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#55)
#57Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#56)
#58Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#54)
#59Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#58)
#60Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#58)
#61Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#57)
#62Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#61)
#63Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#1)
#64Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#62)
#65Robert Haas
robertmhaas@gmail.com
In reply to: Bruce Momjian (#63)
#66Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#64)
#67Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#66)
#68Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#67)
#69Robert Haas
robertmhaas@gmail.com
In reply to: Bruce Momjian (#68)
#70Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#65)
#71Bruce Momjian
bruce@momjian.us
In reply to: Robert Haas (#70)
#72Robert Haas
robertmhaas@gmail.com
In reply to: Bruce Momjian (#71)
#73Bruce Momjian
bruce@momjian.us
In reply to: Robert Haas (#72)