Patch to add a primary key using an existing index

Started by Gurjeet Singhover 15 years ago50 messageshackers
Jump to latest
#1Gurjeet Singh
singh.gurjeet@gmail.com

This is a continuation from this thread:
http://archives.postgresql.org/pgsql-hackers/2010-09/msg02153.php

The attached patch allows creating a primary key using an existing index.

This capability would be helpful in situations where one wishes to
rebuild/reindex the primary key, but associated downtime is not desirable.
It also allows one to create a table and start using it, while creating a
unique index 'concurrently' and later adding the primary key using the
concurrently built index. Maybe pg_dump can also use it.

The command syntax is:

ALTER TABLE sometable ADD PRIMARY KEY( col1, col2 ) WITH ( INDEX =
'indexname' );

A typical use case:

CREATE INDEX CONCURRENTLY new_pkey_idx ON sometable( a, b );

ALTER TABLE sometable ADD PRIMARY KEY ( a, b ) WITH (INDEX = 'new_pkey_idx'
);

- OR -

ALTER TABLE sometable DROP CONSTRAINT sometable_pkey,
ADD PRIMARY KEY ( a, b ) WITH (INDEX = 'new_pkey_idx' );

Notes for the reviewers:
------------------------

Don't be scared by the size of changes to index.c :) These are mostly
indentation diffs. I have attached two versions of the patch: one is context
diff, and the other is the same except ignoring whitespace changes.

The pseudocode is as follows:

In ATExecAddIndex()
If this ALTER command specifies a PRIMARY KEY
Call get_pkey_index_oid() to perform checks.

In get_pkey_index_oid()
Look for the WITH INDEX option
Reject
if more than one WITH INDEX clause specified
if the index doesn't exist or not found in table's schema
if the index is associated with any CONSTRAINT
if index is not ready or not valid (CONCURRENT buiild? Canceled
CONCURRENT?)
if index is on some other table
if index is not unique
if index is an expression index
if index is a partial index
if index columns do not match the PRIMARY KEY clause in the command
if index is not B-tree
If PRIMARY KEY clause doesn't have a constraint name, assign it one.
(code comments explain why)
Rename the index to match constraint name in the PRIMARY KEY clause

Back in ATExecAddIndex()
Use the index OID returned by get_pkey_index_oid() to tell DefineIndex()
to not create index.
Now mark the index as having 'indisprimary' flag.

In DefineIndex() and index_create() APIs
pass an additional flag: index_exists
Skip various actions based on this flag.

The patch contains a few tests, and doesn't yet have a docs patch.

The development branch is at
http://github.com/gurjeet/postgres/tree/replace_pkey_index

Regards,
--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

Attachments:

add_pkey_with_index.patchtext/x-diff; charset=US-ASCII; name=add_pkey_with_index.patchDownload+464-96
add_pkey_with_index.ignore_ws.patchtext/x-diff; charset=US-ASCII; name=add_pkey_with_index.ignore_ws.patchDownload+376-8
#2Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Gurjeet Singh (#1)
Re: Patch to add a primary key using an existing index

On Sat, Oct 9, 2010 at 2:07 PM, Gurjeet Singh <singh.gurjeet@gmail.com>wrote:

This is a continuation from this thread:
http://archives.postgresql.org/pgsql-hackers/2010-09/msg02153.php

The attached patch allows creating a primary key using an existing index.

I have attached two versions of the patch: one is context diff, and the
other is the same except ignoring whitespace changes.

Attached are gzip'd patches for archives. Archive shows the previous mail
attachments all inline... horrible.
--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

Attachments:

add_pkey_with_index.patch.gzapplication/x-gzip; name=add_pkey_with_index.patch.gzDownload
add_pkey_with_index.ignore_ws.patch.gzapplication/x-gzip; name=add_pkey_with_index.ignore_ws.patch.gzDownload
#3Andrew Dunstan
andrew@dunslane.net
In reply to: Gurjeet Singh (#2)
Re: Patch to add a primary key using an existing index

On 10/09/2010 02:19 PM, Gurjeet Singh wrote:

On Sat, Oct 9, 2010 at 2:07 PM, Gurjeet Singh <singh.gurjeet@gmail.com
<mailto:singh.gurjeet@gmail.com>> wrote:

This is a continuation from this thread:
http://archives.postgresql.org/pgsql-hackers/2010-09/msg02153.php

The attached patch allows creating a primary key using an existing
index.

I have attached two versions of the patch: one is context diff,
and the other is the same except ignoring whitespace changes.

Attached are gzip'd patches for archives. Archive shows the previous
mail attachments all inline... horrible.

I wish we could get the archive processor to provide access to the
attachments even if they have a MIME type of text/whatever. That's a
horrid inefficiency. Maybe we could restrict it to text attachments that
have a Content-Type with a name attribute that contains the string
'patch', or a similar Content-Disposition filename attribute.

cheers

andrew

#4Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Andrew Dunstan (#3)
archives, attachments, etc (was: Patch to add a primary key using an existing index)

Andrew Dunstan <andrew@dunslane.net> writes:

I wish we could get the archive processor to provide access to the
attachments even if they have a MIME type of text/whatever. That's a
horrid inefficiency. Maybe we could restrict it to text attachments
that have a Content-Type with a name attribute that contains the
string 'patch', or a similar Content-Disposition filename attribute.

I wish our super admins would have some time to resume the work on the
new archives infrastructure, that was about ready for integration if not
prime time:

http://archives.beccati.org/pgsql-hackers/message/276290

As you see it doesn't suffer from this problem, the threading is not
split arbitrarily, and less obvious but it runs from a PostgreSQL
database. Yes, that means the threading code is exercising our recursive
querying facility, as far as I understand it.

Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support

#5Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Dimitri Fontaine (#4)
Re: archives, attachments, etc (was: Patch to add a primary key using an existing index)

On Sat, Oct 9, 2010 at 3:30 PM, Dimitri Fontaine <dimitri@2ndquadrant.fr>wrote:

Andrew Dunstan <andrew@dunslane.net> writes:

I wish we could get the archive processor to provide access to the
attachments even if they have a MIME type of text/whatever. That's a
horrid inefficiency. Maybe we could restrict it to text attachments
that have a Content-Type with a name attribute that contains the
string 'patch', or a similar Content-Disposition filename attribute.

I wish our super admins would have some time to resume the work on the
new archives infrastructure, that was about ready for integration if not
prime time:

http://archives.beccati.org/pgsql-hackers/message/276290

As you see it doesn't suffer from this problem, the threading is not
split arbitrarily, and less obvious but it runs from a PostgreSQL
database. Yes, that means the threading code is exercising our recursive
querying facility, as far as I understand it.

Something looks wrong with that thread. The message text in my mails is
missing. Perhaps that is contained in the .bin files but I can't tell as the
link leads to 404 Not Found.

Regards,
--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

#6Matteo Beccati
php@beccati.com
In reply to: Gurjeet Singh (#5)
Re: archives, attachments, etc

Hi Gurjeet,

On 09/10/2010 22:54, Gurjeet Singh wrote:

On Sat, Oct 9, 2010 at 3:30 PM, Dimitri Fontaine <dimitri@2ndquadrant.fr
<mailto:dimitri@2ndquadrant.fr>> wrote:
I wish our super admins would have some time to resume the work on the
new archives infrastructure, that was about ready for integration if not
prime time:

http://archives.beccati.org/pgsql-hackers/message/276290

As you see it doesn't suffer from this problem, the threading is not
split arbitrarily, and less obvious but it runs from a PostgreSQL
database. Yes, that means the threading code is exercising our recursive
querying facility, as far as I understand it.

Something looks wrong with that thread. The message text in my mails is
missing. Perhaps that is contained in the .bin files but I can't tell as
the link leads to 404 Not Found.

Thanks for the private email to point this thread out. I've been overly
busy lately and missed it.

I'll try to debug what happens with your message formatting as soon as I
can find some time.

Cheers
--
Matteo Beccati

Development & Consulting - http://www.beccati.com/

#7Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Gurjeet Singh (#1)
Re: Patch to add a primary key using an existing index

UNIQUE constraints suffer from the same behavior; feel like fixing that too? :)

On Oct 9, 2010, at 1:07 PM, Gurjeet Singh wrote:

This is a continuation from this thread: http://archives.postgresql.org/pgsql-hackers/2010-09/msg02153.php

The attached patch allows creating a primary key using an existing index.

This capability would be helpful in situations where one wishes to rebuild/reindex the primary key, but associated downtime is not desirable. It also allows one to create a table and start using it, while creating a unique index 'concurrently' and later adding the primary key using the concurrently built index. Maybe pg_dump can also use it.

The command syntax is:

ALTER TABLE sometable ADD PRIMARY KEY( col1, col2 ) WITH ( INDEX = 'indexname' );

A typical use case:

CREATE INDEX CONCURRENTLY new_pkey_idx ON sometable( a, b );

ALTER TABLE sometable ADD PRIMARY KEY ( a, b ) WITH (INDEX = 'new_pkey_idx' );

- OR -

ALTER TABLE sometable DROP CONSTRAINT sometable_pkey,
ADD PRIMARY KEY ( a, b ) WITH (INDEX = 'new_pkey_idx' );

Notes for the reviewers:
------------------------

Don't be scared by the size of changes to index.c :) These are mostly indentation diffs. I have attached two versions of the patch: one is context diff, and the other is the same except ignoring whitespace changes.

The pseudocode is as follows:

In ATExecAddIndex()
If this ALTER command specifies a PRIMARY KEY
Call get_pkey_index_oid() to perform checks.

In get_pkey_index_oid()
Look for the WITH INDEX option
Reject
if more than one WITH INDEX clause specified
if the index doesn't exist or not found in table's schema
if the index is associated with any CONSTRAINT
if index is not ready or not valid (CONCURRENT buiild? Canceled CONCURRENT?)
if index is on some other table
if index is not unique
if index is an expression index
if index is a partial index
if index columns do not match the PRIMARY KEY clause in the command
if index is not B-tree
If PRIMARY KEY clause doesn't have a constraint name, assign it one. (code comments explain why)
Rename the index to match constraint name in the PRIMARY KEY clause

Back in ATExecAddIndex()
Use the index OID returned by get_pkey_index_oid() to tell DefineIndex() to not create index.
Now mark the index as having 'indisprimary' flag.

In DefineIndex() and index_create() APIs
pass an additional flag: index_exists
Skip various actions based on this flag.

The patch contains a few tests, and doesn't yet have a docs patch.

The development branch is at http://github.com/gurjeet/postgres/tree/replace_pkey_index

Regards,
--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device
<add_pkey_with_index.patch><add_pkey_with_index.ignore_ws.patch>
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

--
Jim C. Nasby, Database Architect jim@nasby.net
512.569.9461 (cell) http://jim.nasby.net

#8Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Jim Nasby (#7)
Re: Patch to add a primary key using an existing index

Depesz brought that to my attention a few days after the initial submission,
and adding support for UNIQUE was not much pain. I implemented it almost
immediately, but didn't announce it as I was hoping I could submit some doc
changes too with that.

If you are the adventurous kind, you can follow the Git branch here:
https://github.com/gurjeet/postgres/tree/replace_pkey_index

Regards,

On Mon, Nov 1, 2010 at 10:29 PM, Jim Nasby <jim@nasby.net> wrote:

UNIQUE constraints suffer from the same behavior; feel like fixing that
too? :)

On Oct 9, 2010, at 1:07 PM, Gurjeet Singh wrote:

This is a continuation from this thread:

http://archives.postgresql.org/pgsql-hackers/2010-09/msg02153.php

The attached patch allows creating a primary key using an existing index.

This capability would be helpful in situations where one wishes to

rebuild/reindex the primary key, but associated downtime is not desirable.
It also allows one to create a table and start using it, while creating a
unique index 'concurrently' and later adding the primary key using the
concurrently built index. Maybe pg_dump can also use it.

The command syntax is:

ALTER TABLE sometable ADD PRIMARY KEY( col1, col2 ) WITH ( INDEX =

'indexname' );

A typical use case:

CREATE INDEX CONCURRENTLY new_pkey_idx ON sometable( a, b );

ALTER TABLE sometable ADD PRIMARY KEY ( a, b ) WITH (INDEX =

'new_pkey_idx' );

- OR -

ALTER TABLE sometable DROP CONSTRAINT sometable_pkey,
ADD PRIMARY KEY ( a, b ) WITH (INDEX = 'new_pkey_idx' );

Notes for the reviewers:
------------------------

Don't be scared by the size of changes to index.c :) These are mostly

indentation diffs. I have attached two versions of the patch: one is context
diff, and the other is the same except ignoring whitespace changes.

The pseudocode is as follows:

In ATExecAddIndex()
If this ALTER command specifies a PRIMARY KEY
Call get_pkey_index_oid() to perform checks.

In get_pkey_index_oid()
Look for the WITH INDEX option
Reject
if more than one WITH INDEX clause specified
if the index doesn't exist or not found in table's schema
if the index is associated with any CONSTRAINT
if index is not ready or not valid (CONCURRENT buiild? Canceled

CONCURRENT?)

if index is on some other table
if index is not unique
if index is an expression index
if index is a partial index
if index columns do not match the PRIMARY KEY clause in the

command

if index is not B-tree
If PRIMARY KEY clause doesn't have a constraint name, assign it one.

(code comments explain why)

Rename the index to match constraint name in the PRIMARY KEY clause

Back in ATExecAddIndex()
Use the index OID returned by get_pkey_index_oid() to tell

DefineIndex() to not create index.

Now mark the index as having 'indisprimary' flag.

In DefineIndex() and index_create() APIs
pass an additional flag: index_exists
Skip various actions based on this flag.

The patch contains a few tests, and doesn't yet have a docs patch.

The development branch is at

http://github.com/gurjeet/postgres/tree/replace_pkey_index

Regards,
--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device
<add_pkey_with_index.patch><add_pkey_with_index.ignore_ws.patch>
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

--
Jim C. Nasby, Database Architect jim@nasby.net
512.569.9461 (cell) http://jim.nasby.net

--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

#9Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Gurjeet Singh (#8)
Re: Patch to add a primary key using an existing index

Attached is the patch that extends the same feature for UNIQUE indexes.

It also includes some doc changes for the ALTER TABLE command, but I could
not verify the resulting changes since I don't have the doc-building
infrastructure installed.

Regards,

On Mon, Nov 8, 2010 at 1:39 AM, Gurjeet Singh <singh.gurjeet@gmail.com>wrote:

Depesz brought that to my attention a few days after the initial
submission, and adding support for UNIQUE was not much pain. I implemented
it almost immediately, but didn't announce it as I was hoping I could submit
some doc changes too with that.

If you are the adventurous kind, you can follow the Git branch here:
https://github.com/gurjeet/postgres/tree/replace_pkey_index

Regards,

On Mon, Nov 1, 2010 at 10:29 PM, Jim Nasby <jim@nasby.net> wrote:

UNIQUE constraints suffer from the same behavior; feel like fixing that
too? :)

On Oct 9, 2010, at 1:07 PM, Gurjeet Singh wrote:

This is a continuation from this thread:

http://archives.postgresql.org/pgsql-hackers/2010-09/msg02153.php

The attached patch allows creating a primary key using an existing

index.

This capability would be helpful in situations where one wishes to

rebuild/reindex the primary key, but associated downtime is not desirable.
It also allows one to create a table and start using it, while creating a
unique index 'concurrently' and later adding the primary key using the
concurrently built index. Maybe pg_dump can also use it.

The command syntax is:

ALTER TABLE sometable ADD PRIMARY KEY( col1, col2 ) WITH ( INDEX =

'indexname' );

A typical use case:

CREATE INDEX CONCURRENTLY new_pkey_idx ON sometable( a, b );

ALTER TABLE sometable ADD PRIMARY KEY ( a, b ) WITH (INDEX =

'new_pkey_idx' );

- OR -

ALTER TABLE sometable DROP CONSTRAINT sometable_pkey,
ADD PRIMARY KEY ( a, b ) WITH (INDEX = 'new_pkey_idx' );

Notes for the reviewers:
------------------------

Don't be scared by the size of changes to index.c :) These are mostly

indentation diffs. I have attached two versions of the patch: one is context
diff, and the other is the same except ignoring whitespace changes.

The pseudocode is as follows:

In ATExecAddIndex()
If this ALTER command specifies a PRIMARY KEY
Call get_pkey_index_oid() to perform checks.

In get_pkey_index_oid()
Look for the WITH INDEX option
Reject
if more than one WITH INDEX clause specified
if the index doesn't exist or not found in table's schema
if the index is associated with any CONSTRAINT
if index is not ready or not valid (CONCURRENT buiild? Canceled

CONCURRENT?)

if index is on some other table
if index is not unique
if index is an expression index
if index is a partial index
if index columns do not match the PRIMARY KEY clause in the

command

if index is not B-tree
If PRIMARY KEY clause doesn't have a constraint name, assign it one.

(code comments explain why)

Rename the index to match constraint name in the PRIMARY KEY clause

Back in ATExecAddIndex()
Use the index OID returned by get_pkey_index_oid() to tell

DefineIndex() to not create index.

Now mark the index as having 'indisprimary' flag.

In DefineIndex() and index_create() APIs
pass an additional flag: index_exists
Skip various actions based on this flag.

The patch contains a few tests, and doesn't yet have a docs patch.

The development branch is at

http://github.com/gurjeet/postgres/tree/replace_pkey_index

Regards,
--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device
<add_pkey_with_index.patch><add_pkey_with_index.ignore_ws.patch>
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

--
Jim C. Nasby, Database Architect jim@nasby.net
512.569.9461 (cell) http://jim.nasby.net

--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

Attachments:

replace_pkey_index.uniq+doc.patch.gzapplication/x-gzip; name=replace_pkey_index.uniq+doc.patch.gzDownload
#10Steve Singer
steve@ssinger.info
In reply to: Gurjeet Singh (#9)
Re: Patch to add a primary key using an existing index

On 10-11-07 01:54 PM, Gurjeet Singh wrote:

Attached is the patch that extends the same feature for UNIQUE indexes.

It also includes some doc changes for the ALTER TABLE command, but I
could not verify the resulting changes since I don't have the
doc-building infrastructure installed.

Regards,

Gurjeet,

I've taken a stab at reviewing this.

Submission Review:
========================

Tests
--------
The expected output for the regression tests you added don't match
what I'm getting when I run the tests with your patch applied.
I think you just need to regenerate the expected results they seem
to be from a previous version of the patch (different error messages etc..).

Documentation
---------------

I was able to generate the docs.

The ALTER TABLE page under the synopsis has

ADD table_constraint

where table_constraint is defined on the CREATE TABLE page.
On the CREATE TABLE page table_constraint isn't defined as having the WITH
, the WITH is part of index_parameters.

I propose the alter table page instead have

ADD table_constraint [index_parameters]

where index_parameters also references the CREATE TABLE page like
table_constraint.

Usability Review
====================

Behaviour
-------------
I feel that if the ALTER TABLE ... renames the the index
a NOTICE should be generated. We generate notices about creating an
index for a new pkey. We should give them a notice that we are renaming
an index on them.

Coding Review:
======================

Error Messages
-----------------
in tablecmds your errdetail messages often don't start with a capital
letter. I belive the preference is to have the errdetail strings start
with a capital letter and end with a period.

tablecmds.c - get_constraint_index_oid

contains the check

/* Currently only B-tree indexes are suupported for primary keys */
if (index_rel->rd_rel->relam != BTREE_AM_OID)
elog(ERROR, "\"%s\" is not a B-Tree index", index_name);

but above we already validate that the index is a unique index with
another check. Today only B-tree indexes support unique constraints.
If this changed at some point and we could have a unique index of some
other type, would something in this patch need to be changed to support
them? If we are only depending on the uniqueness property then I think
this check is covered by the uniquness one higher in the function.

Also note the typo in your comment above (suupported)

Comments
-----------------

index.c: Line 671 and 694. Your indentation changes make the comments
run over 80 characters. If you end up submitting a new version
of the patch I'd reformat those two comments.

Other than those issues the patch looks good to me.

Steve

#11Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Steve Singer (#10)
Re: Patch to add a primary key using an existing index

On Sat, Nov 20, 2010 at 9:00 AM, Steve Singer <ssinger_pg@sympatico.ca>wrote:

Submission Review:
========================

Tests
--------
The expected output for the regression tests you added don't match
what I'm getting when I run the tests with your patch applied.
I think you just need to regenerate the expected results they seem
to be from a previous version of the patch (different error messages
etc..).

Fixed. Also modified one test to cover the case where constraint name is
provided.

Documentation
---------------

I was able to generate the docs.

The ALTER TABLE page under the synopsis has

ADD table_constraint

where table_constraint is defined on the CREATE TABLE page.
On the CREATE TABLE page table_constraint isn't defined as having the WITH
, the WITH is part of index_parameters.

I propose the alter table page instead have

ADD table_constraint [index_parameters]

where index_parameters also references the CREATE TABLE page like
table_constraint.

IMHO index_parameters is an optional component of table_constraint, and
hence can't be mentioned here, at least not the way shown above.

I have made slight improvements to the doc which might help the user
understand that this WITH(INDEX=) option is exclusive to ALTER TABLE and not
provided by CREATE TABLE.

Usability Review
====================

Behaviour
-------------
I feel that if the ALTER TABLE ... renames the the index
a NOTICE should be generated. We generate notices about creating an index
for a new pkey. We should give them a notice that we are renaming an index
on them.

Done.

Coding Review:
======================

Error Messages
-----------------
in tablecmds your errdetail messages often don't start with a capital
letter. I belive the preference is to have the errdetail strings start with
a capital letter and end with a period.

Fixed.

tablecmds.c - get_constraint_index_oid

contains the check

/* Currently only B-tree indexes are suupported for primary keys */
if (index_rel->rd_rel->relam != BTREE_AM_OID)
elog(ERROR, "\"%s\" is not a B-Tree index",
index_name);

but above we already validate that the index is a unique index with another
check. Today only B-tree indexes support unique constraints. If this
changed at some point and we could have a unique index of some other type,
would something in this patch need to be changed to support them? If we are
only depending on the uniqueness property then I think this check is covered
by the uniquness one higher in the function.

Also note the typo in your comment above (suupported)

I agree; code removed.

Comments
-----------------

index.c: Line 671 and 694. Your indentation changes make the comments
run over 80 characters. If you end up submitting a new version
of the patch I'd reformat those two comments.

Fixed.

Other than those issues the patch looks good to me.

Thanks for your time Steve.

Regards,

PS: I will be mostly unavailable between 11/25 and 12/6, so wouldn't mind if
somebody took ownership of this patch for that duration.
--
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

Attachments:

replace_pkey_index.revised.patch.gzapplication/x-gzip; name=replace_pkey_index.revised.patch.gzDownload
#12Steve Singer
steve@ssinger.info
In reply to: Gurjeet Singh (#11)
Re: Patch to add a primary key using an existing index

On 10-11-22 09:37 AM, Gurjeet Singh wrote:

On Sat, Nov 20, 2010 at 9:00 AM, Steve Singer <ssinger_pg@sympatico.ca
<mailto:ssinger_pg@sympatico.ca>> wrote:

Submission Review:
========================

Tests
--------
The expected output for the regression tests you added don't match
what I'm getting when I run the tests with your patch applied.
I think you just need to regenerate the expected results they seem
to be from a previous version of the patch (different error
messages etc..).

Fixed. Also modified one test to cover the case where constraint name
is provided.

Almost fixed.
I still get an unexpected difference.

! DETAIL:  cannot create PRIMARY KEY/UNIQUE constraint with a non-unique 
index.
   CREATE UNIQUE INDEX rpi_idx2 ON rpi_test(a , b);
   -- should fail; WITH INDEX option specified more than once.
   ALTER TABLE rpi_test ADD PRIMARY KEY (a, b)
--- 35,41 ----
   -- should fail; non-unique
   ALTER TABLE rpi_test ADD primary key(a, b) WITH (INDEX = 'rpi_idx1');
   ERROR:  "rpi_idx1" is not a unique index
! DETAIL:  Cannot create PRIMARY KEY/UNIQUE constraint using a 
non-unique index.

Documentation
---------------

I was able to generate the docs.

The ALTER TABLE page under the synopsis has

ADD table_constraint

where table_constraint is defined on the CREATE TABLE page.
On the CREATE TABLE page table_constraint isn't defined as having
the WITH
, the WITH is part of index_parameters.

I propose the alter table page instead have

ADD table_constraint [index_parameters]

where index_parameters also references the CREATE TABLE page like
table_constraint.

IMHO index_parameters is an optional component of table_constraint,
and hence can't be mentioned here, at least not the way shown above.

My reading of CREATE TABLE is that index_parameters is an optional
parameter that comes after table_constraint and isn't part of
table_constraint. Any other opinions?

Everything else I mentioned seems fixed in this version

Show quoted text

gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

#13Steve Singer
steve@ssinger.info
In reply to: Steve Singer (#12)
Re: Patch to add a primary key using an existing index

On 10-11-22 03:24 PM, Steve Singer wrote:

On 10-11-22 09:37 AM, Gurjeet Singh wrote:

On Sat, Nov 20, 2010 at 9:00 AM, Steve Singer <ssinger_pg@sympatico.ca

Almost fixed.
I still get an unexpected difference.

! DETAIL: cannot create PRIMARY KEY/UNIQUE constraint with a non-unique
index.
CREATE UNIQUE INDEX rpi_idx2 ON rpi_test(a , b);
-- should fail; WITH INDEX option specified more than once.
ALTER TABLE rpi_test ADD PRIMARY KEY (a, b)
--- 35,41 ----
-- should fail; non-unique
ALTER TABLE rpi_test ADD primary key(a, b) WITH (INDEX = 'rpi_idx1');
ERROR: "rpi_idx1" is not a unique index
! DETAIL: Cannot create PRIMARY KEY/UNIQUE constraint using a non-unique
index.

The attached version of the patch gets your regression tests to pass.

I'm going to mark this as ready for a committer.

Attachments:

replace_pkey_index.revised2.patch.gzapplication/x-gzip; name=replace_pkey_index.revised2.patch.gzDownload
#14Itagaki Takahiro
itagaki.takahiro@gmail.com
In reply to: Steve Singer (#13)
Re: Patch to add a primary key using an existing index

On Fri, Nov 26, 2010 at 05:58, Steve Singer <ssinger@ca.afilias.info> wrote:

The attached version of the patch gets your regression tests to pass.
I'm going to mark this as ready for a committer.

I think we need more discussions about the syntax:
ALTER TABLE table_name ADD PRIMARY KEY (...) WITH (INDEX='index_name')

Issues:
* WITH (...) is designed for storage parameters. I think treating "INDEX"
as a special keyword in the way might be confusable.
* 'index_name' needs to be single-quoted, but object identifiers should
be double-quoted literals in normal cases.
* The key specifier is a duplicated option because the index has own keys.
Do we need it? It might be for safety, but redundant.
Note that the patch raises a reasonable error on conflict:
ERROR: PRIMARY KEY/UNIQUE constraint definition does not match the index

And, I found a bug:
* USING INDEX TABLESPACE clause is silently ignored, even if the index
uses another tablespace.

After all, do we need a special syntax for the functionality?
Reusing WITH (...) syntax seems to be a trouble for me.
"ADD PRIMARY KEY USING index_name" might be a candidate, but we'd
better reserve USING for non-btree PRIMARY KEY/UNIQUE indexes.
Ideas and suggestions?

--
Itagaki Takahiro

#15Robert Haas
robertmhaas@gmail.com
In reply to: Itagaki Takahiro (#14)
Re: Patch to add a primary key using an existing index

On Sun, Nov 28, 2010 at 8:06 PM, Itagaki Takahiro
<itagaki.takahiro@gmail.com> wrote:

On Fri, Nov 26, 2010 at 05:58, Steve Singer <ssinger@ca.afilias.info> wrote:

The attached version of the patch gets your regression tests to pass.
I'm going to mark this as ready for a committer.

I think we need more discussions about the syntax:
 ALTER TABLE table_name ADD PRIMARY KEY (...) WITH (INDEX='index_name')

Why not:

ALTER TABLE table_name ADD PRIMARY KEY (...) INDEX index_name;

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#16David Fetter
david@fetter.org
In reply to: Robert Haas (#15)
Re: Patch to add a primary key using an existing index

On Sun, Nov 28, 2010 at 08:40:08PM -0500, Robert Haas wrote:

On Sun, Nov 28, 2010 at 8:06 PM, Itagaki Takahiro
<itagaki.takahiro@gmail.com> wrote:

On Fri, Nov 26, 2010 at 05:58, Steve Singer <ssinger@ca.afilias.info> wrote:

The attached version of the patch gets your regression tests to
pass. I'm going to mark this as ready for a committer.

I think we need more discussions about the syntax: �ALTER TABLE
table_name ADD PRIMARY KEY (...) WITH (INDEX='index_name')

Why not:

ALTER TABLE table_name ADD PRIMARY KEY (...) INDEX index_name;

+1 :)

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

#17Peter Eisentraut
peter_e@gmx.net
In reply to: Robert Haas (#15)
Re: Patch to add a primary key using an existing index

On sön, 2010-11-28 at 20:40 -0500, Robert Haas wrote:

On Sun, Nov 28, 2010 at 8:06 PM, Itagaki Takahiro
<itagaki.takahiro@gmail.com> wrote:

On Fri, Nov 26, 2010 at 05:58, Steve Singer <ssinger@ca.afilias.info> wrote:

The attached version of the patch gets your regression tests to pass.
I'm going to mark this as ready for a committer.

I think we need more discussions about the syntax:
ALTER TABLE table_name ADD PRIMARY KEY (...) WITH (INDEX='index_name')

Why not:

ALTER TABLE table_name ADD PRIMARY KEY (...) INDEX index_name;

I would think that that determines that name of the index that the
command creates. It does not convey that an existing index is to be
used.

#18Robert Haas
robertmhaas@gmail.com
In reply to: Peter Eisentraut (#17)
Re: Patch to add a primary key using an existing index

On Fri, Dec 3, 2010 at 2:23 PM, Peter Eisentraut <peter_e@gmx.net> wrote:

On sön, 2010-11-28 at 20:40 -0500, Robert Haas wrote:

On Sun, Nov 28, 2010 at 8:06 PM, Itagaki Takahiro
<itagaki.takahiro@gmail.com> wrote:

On Fri, Nov 26, 2010 at 05:58, Steve Singer <ssinger@ca.afilias.info> wrote:

The attached version of the patch gets your regression tests to pass.
I'm going to mark this as ready for a committer.

I think we need more discussions about the syntax:
 ALTER TABLE table_name ADD PRIMARY KEY (...) WITH (INDEX='index_name')

Why not:

ALTER TABLE table_name ADD PRIMARY KEY (...) INDEX index_name;

I would think that that determines that name of the index that the
command creates.  It does not convey that an existing index is to be
used.

Well, that'll become clear pretty quickly if you try to use it that
way, but I'm certainly open to other ideas.

Random thoughts:

ALTER TABLE table_name SET PRIMARY KEY INDEX index_name
ALTER INDEX index_name PRIMARY KEY

Other suggestions?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#19Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Robert Haas (#18)
Re: Patch to add a primary key using an existing index

On 03.12.2010 21:43, Robert Haas wrote:

On Fri, Dec 3, 2010 at 2:23 PM, Peter Eisentraut<peter_e@gmx.net> wrote:

On s�n, 2010-11-28 at 20:40 -0500, Robert Haas wrote:

On Sun, Nov 28, 2010 at 8:06 PM, Itagaki Takahiro
<itagaki.takahiro@gmail.com> wrote:

On Fri, Nov 26, 2010 at 05:58, Steve Singer<ssinger@ca.afilias.info> wrote:

The attached version of the patch gets your regression tests to pass.
I'm going to mark this as ready for a committer.

I think we need more discussions about the syntax:
ALTER TABLE table_name ADD PRIMARY KEY (...) WITH (INDEX='index_name')

Why not:

ALTER TABLE table_name ADD PRIMARY KEY (...) INDEX index_name;

I would think that that determines that name of the index that the
command creates. It does not convey that an existing index is to be
used.

Well, that'll become clear pretty quickly if you try to use it that
way, but I'm certainly open to other ideas.

Random thoughts:

ALTER TABLE table_name SET PRIMARY KEY INDEX index_name
ALTER INDEX index_name PRIMARY KEY

ALTER TABLE table_name SET PRIMARY KEY USING INDEX index_name. Quite
verbose, but imho USING makes it much more clear that it's an existing
index.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#20r t
pgsql@xzilla.net
In reply to: Robert Haas (#18)
Re: Patch to add a primary key using an existing index

On Fri, Dec 3, 2010 at 2:43 PM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Dec 3, 2010 at 2:23 PM, Peter Eisentraut <peter_e@gmx.net> wrote:

On sön, 2010-11-28 at 20:40 -0500, Robert Haas wrote:

On Sun, Nov 28, 2010 at 8:06 PM, Itagaki Takahiro
<itagaki.takahiro@gmail.com> wrote:

On Fri, Nov 26, 2010 at 05:58, Steve Singer <ssinger@ca.afilias.info>

wrote:

The attached version of the patch gets your regression tests to pass.
I'm going to mark this as ready for a committer.

I think we need more discussions about the syntax:
ALTER TABLE table_name ADD PRIMARY KEY (...) WITH

(INDEX='index_name')

Why not:

ALTER TABLE table_name ADD PRIMARY KEY (...) INDEX index_name;

I would think that that determines that name of the index that the
command creates. It does not convey that an existing index is to be
used.

+1 on this being confusing

Well, that'll become clear pretty quickly if you try to use it that
way, but I'm certainly open to other ideas.

Random thoughts:

ALTER TABLE table_name SET PRIMARY KEY INDEX index_name
ALTER INDEX index_name PRIMARY KEY

Other suggestions?

What exactly was the objection to the following -->

ALTER TABLE table_name ADD PRIMARY KEY (column_list) USING index_name;

Is the objection that you might have been trying to specify a constraint
named "using" ? I'm willing to make that option more difficult. :-)

Robert Treat
play: http://www.xzilla.net
work: http://www.omniti.com/is/hiring

#21Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Heikki Linnakangas (#19)
#22Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Alvaro Herrera (#21)
#23Robert Haas
robertmhaas@gmail.com
In reply to: r t (#20)
#24Josh Berkus
josh@agliodbs.com
In reply to: Robert Haas (#23)
#25Robert Treat
xzilla@users.sourceforge.net
In reply to: Josh Berkus (#24)
#26Ross J. Reedstrom
reedstrm@rice.edu
In reply to: Robert Treat (#25)
#27Josh Berkus
josh@agliodbs.com
In reply to: Robert Treat (#25)
#28Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ross J. Reedstrom (#26)
#29Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#28)
#30Robert Treat
xzilla@users.sourceforge.net
In reply to: Robert Haas (#29)
#31Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Treat (#30)
#32Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#31)
#33Josh Berkus
josh@agliodbs.com
In reply to: Robert Haas (#32)
#34Peter Eisentraut
peter_e@gmx.net
In reply to: Robert Haas (#23)
#35Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Peter Eisentraut (#34)
#36Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gurjeet Singh (#35)
#37Kevin Grittner
Kevin.Grittner@wicourts.gov
In reply to: Tom Lane (#36)
#38Robert Haas
robertmhaas@gmail.com
In reply to: Kevin Grittner (#37)
#39Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Tom Lane (#36)
#40Steve Singer
steve@ssinger.info
In reply to: Gurjeet Singh (#39)
#41Robert Haas
robertmhaas@gmail.com
In reply to: Steve Singer (#40)
#42Tom Lane
tgl@sss.pgh.pa.us
In reply to: Steve Singer (#40)
#43Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#42)
#44Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#43)
#45Joshua Tolley
eggyknap@gmail.com
In reply to: Tom Lane (#43)
#46Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Tom Lane (#43)
#47Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gurjeet Singh (#46)
#48Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Tom Lane (#47)
#49Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gurjeet Singh (#39)
#50Gurjeet Singh
singh.gurjeet@gmail.com
In reply to: Tom Lane (#49)