@@ -43,6 +43,7 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
43
43
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> RESET ( <replaceable class="PARAMETER">attribute_option</replaceable> [, ... ] )
44
44
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
45
45
ADD <replaceable class="PARAMETER">table_constraint</replaceable>
46
+ ADD <replaceable class="PARAMETER">table_constraint_using_index</replaceable>
46
47
DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
47
48
DISABLE TRIGGER [ <replaceable class="PARAMETER">trigger_name</replaceable> | ALL | USER ]
48
49
ENABLE TRIGGER [ <replaceable class="PARAMETER">trigger_name</replaceable> | ALL | USER ]
@@ -62,6 +63,12 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
62
63
NO INHERIT <replaceable class="PARAMETER">parent_table</replaceable>
63
64
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
64
65
SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable>
66
+
67
+ <phrase>and <replaceable class="PARAMETER">table_constraint_using_index</replaceable> is:</phrase>
68
+
69
+ [ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
70
+ { UNIQUE | PRIMARY KEY } USING INDEX <replaceable class="PARAMETER">index_name</replaceable>
71
+ [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
65
72
</synopsis>
66
73
</refsynopsisdiv>
67
74
@@ -229,6 +236,57 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
229
236
</listitem>
230
237
</varlistentry>
231
238
239
+ <varlistentry>
240
+ <term><literal>ADD <replaceable class="PARAMETER">table_constraint_using_index</replaceable></literal></term>
241
+ <listitem>
242
+ <para>
243
+ This form adds a new <literal>PRIMARY KEY</> or <literal>UNIQUE</>
244
+ constraint to a table based on an existing unique index. All the
245
+ columns of the index will be included in the constraint.
246
+ </para>
247
+
248
+ <para>
249
+ The index cannot have expression columns nor be a partial index.
250
+ Also, it must be a b-tree index with default sort ordering. These
251
+ restrictions ensure that the index is equivalent to one that would be
252
+ built by a regular <literal>ADD PRIMARY KEY</> or <literal>ADD UNIQUE</>
253
+ command.
254
+ </para>
255
+
256
+ <para>
257
+ If <literal>PRIMARY KEY</> is specified, and the index's columns are not
258
+ already marked <literal>NOT NULL</>, then this command will attempt to
259
+ do <literal>ALTER COLUMN SET NOT NULL</> against each such column.
260
+ That requires a full table scan to verify the column(s) contain no
261
+ nulls. In all other cases, this is a fast operation.
262
+ </para>
263
+
264
+ <para>
265
+ If a constraint name is provided then the index will be renamed to match
266
+ the constraint name. Otherwise the constraint will be named the same as
267
+ the index.
268
+ </para>
269
+
270
+ <para>
271
+ After this command is executed, the index is <quote>owned</> by the
272
+ constraint, in the same way as if the index had been built by
273
+ a regular <literal>ADD PRIMARY KEY</> or <literal>ADD UNIQUE</>
274
+ command. In particular, dropping the constraint will make the index
275
+ disappear too.
276
+ </para>
277
+
278
+ <note>
279
+ <para>
280
+ Adding a constraint using an existing index can be helpful in
281
+ situations where a new constraint needs to be added without blocking
282
+ table updates for a long time. To do that, create the index using
283
+ <command>CREATE INDEX CONCURRENTLY</>, and then install it as an
284
+ official constraint using this syntax. See the example below.
285
+ </para>
286
+ </note>
287
+ </listitem>
288
+ </varlistentry>
289
+
232
290
<varlistentry>
233
291
<term><literal>DROP CONSTRAINT [ IF EXISTS ]</literal></term>
234
292
<listitem>
@@ -920,13 +978,24 @@ ALTER TABLE myschema.distributors SET SCHEMA yourschema;
920
978
</programlisting>
921
979
</para>
922
980
981
+ <para>
982
+ To recreate a primary key constraint, without blocking updates while the
983
+ index is rebuilt:
984
+ <programlisting>
985
+ CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx on distributors (dist_id);
986
+ ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
987
+ ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;
988
+ </programlisting>
989
+ </para>
990
+
923
991
</refsect1>
924
992
925
993
<refsect1>
926
994
<title>Compatibility</title>
927
995
928
996
<para>
929
- The forms <literal>ADD</literal>, <literal>DROP</>, <literal>SET DEFAULT</>,
997
+ The forms <literal>ADD</literal> (without <literal>USING INDEX</literal>),
998
+ <literal>DROP</>, <literal>SET DEFAULT</>,
930
999
and <literal>SET DATA TYPE</literal> (without <literal>USING</literal>)
931
1000
conform with the SQL standard. The other forms are
932
1001
<productname>PostgreSQL</productname> extensions of the SQL standard.
@@ -940,4 +1009,12 @@ ALTER TABLE myschema.distributors SET SCHEMA yourschema;
940
1009
extension of SQL, which disallows zero-column tables.
941
1010
</para>
942
1011
</refsect1>
1012
+
1013
+ <refsect1>
1014
+ <title>See Also</title>
1015
+
1016
+ <simplelist type="inline">
1017
+ <member><xref linkend="sql-createtable"></member>
1018
+ </simplelist>
1019
+ </refsect1>
943
1020
</refentry>
0 commit comments