1999-07-22 17:09:15 +02:00
<!--
2010-09-20 22:08:53 +02:00
doc/src/sgml/ref/alter_table.sgml
2001-12-08 04:24:40 +01:00
PostgreSQL documentation
1999-07-22 17:09:15 +02:00
-->
2017-10-20 03:16:39 +02:00
<refentry id="sql-altertable">
2014-02-24 03:25:35 +01:00
<indexterm zone="sql-altertable">
<primary>ALTER TABLE</primary>
</indexterm>
1999-07-06 19:16:42 +02:00
<refmeta>
2010-04-03 09:23:02 +02:00
<refentrytitle>ALTER TABLE</refentrytitle>
2008-11-14 11:22:48 +01:00
<manvolnum>7</manvolnum>
1999-07-06 19:16:42 +02:00
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
2003-04-15 15:25:08 +02:00
1999-07-06 19:16:42 +02:00
<refnamediv>
2003-04-15 15:25:08 +02:00
<refname>ALTER TABLE</refname>
<refpurpose>change the definition of a table</refpurpose>
1999-07-06 19:16:42 +02:00
</refnamediv>
2003-04-15 15:25:08 +02:00
1999-07-06 19:16:42 +02:00
<refsynopsisdiv>
2003-04-15 15:25:08 +02:00
<synopsis>
2017-10-09 04:00:57 +02:00
ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
<replaceable class="parameter">action</replaceable> [, ... ]
ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
RENAME [ COLUMN ] <replaceable class="parameter">column_name</replaceable> TO <replaceable class="parameter">new_column_name</replaceable>
ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
RENAME CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> TO <replaceable class="parameter">new_constraint_name</replaceable>
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
RENAME TO <replaceable class="parameter">new_name</replaceable>
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
ALTER TABLE ALL IN TABLESPACE <replaceable class="parameter">name</replaceable> [ OWNED BY <replaceable class="parameter">role_name</replaceable> [, ... ] ]
SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable> [ NOWAIT ]
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
ATTACH PARTITION <replaceable class="parameter">partition_name</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
ALTER TABLE ... DETACH PARTITION ... CONCURRENTLY
Allow a partition be detached from its partitioned table without
blocking concurrent queries, by running in two transactions and only
requiring ShareUpdateExclusive in the partitioned table.
Because it runs in two transactions, it cannot be used in a transaction
block. This is the main reason to use dedicated syntax: so that users
can choose to use the original mode if they need it. But also, it
doesn't work when a default partition exists (because an exclusive lock
would still need to be obtained on it, in order to change its partition
constraint.)
In case the second transaction is cancelled or a crash occurs, there's
ALTER TABLE .. DETACH PARTITION .. FINALIZE, which executes the final
steps.
The main trick to make this work is the addition of column
pg_inherits.inhdetachpending, initially false; can only be set true in
the first part of this command. Once that is committed, concurrent
transactions that use a PartitionDirectory will include or ignore
partitions so marked: in optimizer they are ignored if the row is marked
committed for the snapshot; in executor they are always included. As a
result, and because of the way PartitionDirectory caches partition
descriptors, queries that were planned before the detach will see the
rows in the detached partition and queries that are planned after the
detach, won't.
A CHECK constraint is created that duplicates the partition constraint.
This is probably not strictly necessary, and some users will prefer to
remove it afterwards, but if the partition is re-attached to a
partitioned table, the constraint needn't be rechecked.
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Amit Langote <amitlangote09@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/20200803234854.GA24158@alvherre.pgsql
2021-03-25 22:00:28 +01:00
DETACH PARTITION <replaceable class="parameter">partition_name</replaceable> [ CONCURRENTLY | FINALIZE ]
2024-04-06 23:58:09 +02:00
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
SPLIT PARTITION <replaceable class="parameter">partition_name</replaceable> INTO
(PARTITION <replaceable class="parameter">partition_name1</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT },
PARTITION <replaceable class="parameter">partition_name2</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } [, ...])
2024-04-06 23:57:22 +02:00
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
MERGE PARTITIONS (<replaceable class="parameter">partition_name1</replaceable>, <replaceable class="parameter">partition_name2</replaceable> [, ...])
INTO <replaceable class="parameter">partition_name</replaceable>
2017-10-09 04:00:57 +02:00
<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
ADD [ COLUMN ] [ IF NOT EXISTS ] <replaceable class="parameter">column_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
DROP [ COLUMN ] [ IF EXISTS ] <replaceable class="parameter">column_name</replaceable> [ RESTRICT | CASCADE ]
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> [ SET DATA ] TYPE <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ USING <replaceable class="parameter">expression</replaceable> ]
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET DEFAULT <replaceable class="parameter">expression</replaceable>
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> DROP DEFAULT
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> { SET | DROP } NOT NULL
2024-01-04 15:45:35 +01:00
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET EXPRESSION AS ( <replaceable class="parameter">expression</replaceable> )
2020-01-14 13:09:31 +01:00
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> DROP EXPRESSION [ IF EXISTS ]
2017-10-09 04:00:57 +02:00
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ]
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> { SET GENERATED { ALWAYS | BY DEFAULT } | SET <replaceable>sequence_option</replaceable> | RESTART [ [ WITH ] <replaceable class="parameter">restart</replaceable> ] } [...]
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> DROP IDENTITY [ IF EXISTS ]
2024-01-13 18:14:53 +01:00
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STATISTICS { <replaceable class="parameter">integer</replaceable> | DEFAULT }
2017-10-09 04:00:57 +02:00
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET ( <replaceable class="parameter">attribute_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> RESET ( <replaceable class="parameter">attribute_option</replaceable> [, ... ] )
2022-11-11 00:20:49 +01:00
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT }
Allow configurable LZ4 TOAST compression.
There is now a per-column COMPRESSION option which can be set to pglz
(the default, and the only option in up until now) or lz4. Or, if you
like, you can set the new default_toast_compression GUC to lz4, and
then that will be the default for new table columns for which no value
is specified. We don't have lz4 support in the PostgreSQL code, so
to use lz4 compression, PostgreSQL must be built --with-lz4.
In general, TOAST compression means compression of individual column
values, not the whole tuple, and those values can either be compressed
inline within the tuple or compressed and then stored externally in
the TOAST table, so those properties also apply to this feature.
Prior to this commit, a TOAST pointer has two unused bits as part of
the va_extsize field, and a compessed datum has two unused bits as
part of the va_rawsize field. These bits are unused because the length
of a varlena is limited to 1GB; we now use them to indicate the
compression type that was used. This means we only have bit space for
2 more built-in compresison types, but we could work around that
problem, if necessary, by introducing a new vartag_external value for
any further types we end up wanting to add. Hopefully, it won't be
too important to offer a wide selection of algorithms here, since
each one we add not only takes more coding but also adds a build
dependency for every packager. Nevertheless, it seems worth doing
at least this much, because LZ4 gets better compression than PGLZ
with less CPU usage.
It's possible for LZ4-compressed datums to leak into composite type
values stored on disk, just as it is for PGLZ. It's also possible for
LZ4-compressed attributes to be copied into a different table via SQL
commands such as CREATE TABLE AS or INSERT .. SELECT. It would be
expensive to force such values to be decompressed, so PostgreSQL has
never done so. For the same reasons, we also don't force recompression
of already-compressed values even if the target table prefers a
different compression method than was used for the source data. These
architectural decisions are perhaps arguable but revisiting them is
well beyond the scope of what seemed possible to do as part of this
project. However, it's relatively cheap to recompress as part of
VACUUM FULL or CLUSTER, so this commit adjusts those commands to do
so, if the configured compression method of the table happens not to
match what was used for some column value stored therein.
Dilip Kumar. The original patches on which this work was based were
written by Ildus Kurbangaliev, and those were patches were based on
even earlier work by Nikita Glukhov, but the design has since changed
very substantially, since allow a potentially large number of
compression methods that could be added and dropped on a running
system proved too problematic given some of the architectural issues
mentioned above; the choice of which specific compression method to
add first is now different; and a lot of the code has been heavily
refactored. More recently, Justin Przyby helped quite a bit with
testing and reviewing and this version also includes some code
contributions from him. Other design input and review from Tomas
Vondra, Álvaro Herrera, Andres Freund, Oleg Bartunov, Alexander
Korotkov, and me.
Discussion: http://postgr.es/m/20170907194236.4cefce96%40wp.localdomain
Discussion: http://postgr.es/m/CAFiTN-uUpX3ck%3DK0mLEk-G_kUQY%3DSNOTeqdaNRR9FMdQrHKebw%40mail.gmail.com
2021-03-19 20:10:38 +01:00
ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET COMPRESSION <replaceable class="parameter">compression_method</replaceable>
2017-10-09 04:00:57 +02:00
ADD <replaceable class="parameter">table_constraint</replaceable> [ NOT VALID ]
ADD <replaceable class="parameter">table_constraint_using_index</replaceable>
ALTER CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
VALIDATE CONSTRAINT <replaceable class="parameter">constraint_name</replaceable>
DROP CONSTRAINT [ IF EXISTS ] <replaceable class="parameter">constraint_name</replaceable> [ RESTRICT | CASCADE ]
DISABLE TRIGGER [ <replaceable class="parameter">trigger_name</replaceable> | ALL | USER ]
ENABLE TRIGGER [ <replaceable class="parameter">trigger_name</replaceable> | ALL | USER ]
ENABLE REPLICA TRIGGER <replaceable class="parameter">trigger_name</replaceable>
ENABLE ALWAYS TRIGGER <replaceable class="parameter">trigger_name</replaceable>
DISABLE RULE <replaceable class="parameter">rewrite_rule_name</replaceable>
ENABLE RULE <replaceable class="parameter">rewrite_rule_name</replaceable>
ENABLE REPLICA RULE <replaceable class="parameter">rewrite_rule_name</replaceable>
ENABLE ALWAYS RULE <replaceable class="parameter">rewrite_rule_name</replaceable>
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
DISABLE ROW LEVEL SECURITY
ENABLE ROW LEVEL SECURITY
2015-10-05 03:05:08 +02:00
FORCE ROW LEVEL SECURITY
NO FORCE ROW LEVEL SECURITY
2017-10-09 04:00:57 +02:00
CLUSTER ON <replaceable class="parameter">index_name</replaceable>
2004-06-02 23:01:10 +02:00
SET WITHOUT CLUSTER
2004-07-12 01:13:58 +02:00
SET WITHOUT OIDS
2024-03-08 01:31:52 +01:00
SET ACCESS METHOD { <replaceable class="parameter">new_access_method</replaceable> | DEFAULT }
2017-10-09 04:00:57 +02:00
SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable>
2015-05-22 14:42:15 +02:00
SET { LOGGED | UNLOGGED }
2020-06-30 18:26:51 +02:00
SET ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )
2017-10-09 04:00:57 +02:00
RESET ( <replaceable class="parameter">storage_parameter</replaceable> [, ... ] )
INHERIT <replaceable class="parameter">parent_table</replaceable>
NO INHERIT <replaceable class="parameter">parent_table</replaceable>
OF <replaceable class="parameter">type_name</replaceable>
2011-04-21 03:35:15 +02:00
NOT OF
2020-09-17 11:39:28 +02:00
OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
2017-10-09 04:00:57 +02:00
REPLICA IDENTITY { DEFAULT | USING INDEX <replaceable class="parameter">index_name</replaceable> | FULL | NOTHING }
2011-01-25 21:42:03 +01:00
2018-02-02 11:30:04 +01:00
<phrase>and <replaceable class="parameter">partition_bound_spec</replaceable> is:</phrase>
2019-01-25 11:27:59 +01:00
IN ( <replaceable class="parameter">partition_bound_expr</replaceable> [, ...] ) |
FROM ( { <replaceable class="parameter">partition_bound_expr</replaceable> | MINVALUE | MAXVALUE } [, ...] )
TO ( { <replaceable class="parameter">partition_bound_expr</replaceable> | MINVALUE | MAXVALUE } [, ...] ) |
2018-02-02 11:30:04 +01:00
WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REMAINDER <replaceable class="parameter">numeric_literal</replaceable> )
<phrase>and <replaceable class="parameter">column_constraint</replaceable> is:</phrase>
[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
{ NOT NULL |
NULL |
CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] |
DEFAULT <replaceable>default_expr</replaceable> |
2019-06-11 05:58:51 +02:00
GENERATED ALWAYS AS ( <replaceable>generation_expr</replaceable> ) STORED |
2018-02-02 11:30:04 +01:00
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ] |
2022-02-03 11:29:54 +01:00
UNIQUE [ NULLS [ NOT ] DISTINCT ] <replaceable class="parameter">index_parameters</replaceable> |
2018-02-02 11:30:04 +01:00
PRIMARY KEY <replaceable class="parameter">index_parameters</replaceable> |
REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
2018-12-28 02:19:14 +01:00
[ ON DELETE <replaceable class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ] }
2018-02-02 11:30:04 +01:00
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
2017-10-28 11:20:00 +02:00
<phrase>and <replaceable class="parameter">table_constraint</replaceable> is:</phrase>
[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
{ CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] |
Catalog not-null constraints
We now create contype='n' pg_constraint rows for not-null constraints.
We propagate these constraints to other tables during operations such as
adding inheritance relationships, creating and attaching partitions and
creating tables LIKE other tables. We also spawn not-null constraints
for inheritance child tables when their parents have primary keys.
These related constraints mostly follow the well-known rules of
conislocal and coninhcount that we have for CHECK constraints, with some
adaptations: for example, as opposed to CHECK constraints, we don't
match not-null ones by name when descending a hierarchy to alter it,
instead matching by column name that they apply to. This means we don't
require the constraint names to be identical across a hierarchy.
For now, we omit them for system catalogs. Maybe this is worth
reconsidering. We don't support NOT VALID nor DEFERRABLE clauses
either; these can be added as separate features later (this patch is
already large and complicated enough.)
psql shows these constraints in \d+.
pg_dump requires some ad-hoc hacks, particularly when dumping a primary
key. We now create one "throwaway" not-null constraint for each column
in the PK together with the CREATE TABLE command, and once the PK is
created, all those throwaway constraints are removed. This avoids
having to check each tuple for nullness when the dump restores the
primary key creation.
pg_upgrading from an older release requires a somewhat brittle procedure
to create a constraint state that matches what would be created if the
database were being created fresh in Postgres 17. I have tested all the
scenarios I could think of, and it works correctly as far as I can tell,
but I could have neglected weird cases.
This patch has been very long in the making. The first patch was
written by Bernd Helmle in 2010 to add a new pg_constraint.contype value
('n'), which I (Álvaro) then hijacked in 2011 and 2012, until that one
was killed by the realization that we ought to use contype='c' instead:
manufactured CHECK constraints. However, later SQL standard
development, as well as nonobvious emergent properties of that design
(mostly, failure to distinguish them from "normal" CHECK constraints as
well as the performance implication of having to test the CHECK
expression) led us to reconsider this choice, so now the current
implementation uses contype='n' again. During Postgres 16 this had
already been introduced by commit e056c557aef4, but there were some
problems mainly with the pg_upgrade procedure that couldn't be fixed in
reasonable time, so it was reverted.
In 2016 Vitaly Burovoy also worked on this feature[1] but found no
consensus for his proposed approach, which was claimed to be closer to
the letter of the standard, requiring an additional pg_attribute column
to track the OID of the not-null constraint for that column.
[1] https://postgr.es/m/CAKOSWNkN6HSyatuys8xZxzRCR-KL1OkHS5-b9qd9bf1Rad3PLA@mail.gmail.com
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Author: Bernd Helmle <mailings@oopsware.de>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
2023-08-25 13:31:24 +02:00
NOT NULL <replaceable class="parameter">column_name</replaceable> [ NO INHERIT ] |
2022-02-03 11:29:54 +01:00
UNIQUE [ NULLS [ NOT ] DISTINCT ] ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> |
2017-10-28 11:20:00 +02:00
PRIMARY KEY ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> |
EXCLUDE [ USING <replaceable class="parameter">index_method</replaceable> ] ( <replaceable class="parameter">exclude_element</replaceable> WITH <replaceable class="parameter">operator</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> [ WHERE ( <replaceable class="parameter">predicate</replaceable> ) ] |
FOREIGN KEY ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> [, ... ] ) ]
2023-04-12 19:29:21 +02:00
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <replaceable class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ] }
2017-10-28 11:20:00 +02:00
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
2017-10-09 04:00:57 +02:00
<phrase>and <replaceable class="parameter">table_constraint_using_index</replaceable> is:</phrase>
2011-01-25 21:42:03 +01:00
2017-10-09 04:00:57 +02:00
[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
{ UNIQUE | PRIMARY KEY } USING INDEX <replaceable class="parameter">index_name</replaceable>
2011-01-25 21:42:03 +01:00
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
2018-02-02 11:30:04 +01:00
<phrase><replaceable class="parameter">index_parameters</replaceable> in <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>, and <literal>EXCLUDE</literal> constraints are:</phrase>
2018-04-18 11:44:29 +02:00
[ INCLUDE ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ]
2018-02-02 11:30:04 +01:00
[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
[ USING INDEX TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
<phrase><replaceable class="parameter">exclude_element</replaceable> in an <literal>EXCLUDE</literal> constraint is:</phrase>
{ <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
2021-11-11 10:49:44 +01:00
<phrase><replaceable class="parameter">referential_action</replaceable> in a <literal>FOREIGN KEY</literal>/<literal>REFERENCES</literal> constraint is:</phrase>
2021-12-08 11:09:44 +01:00
{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] | SET DEFAULT [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] }
2003-04-15 15:25:08 +02:00
</synopsis>
1999-07-06 19:16:42 +02:00
</refsynopsisdiv>
1998-05-13 07:34:00 +02:00
2003-04-15 15:25:08 +02:00
<refsect1>
<title>Description</title>
1999-07-06 19:16:42 +02:00
<para>
1998-09-16 16:43:12 +02:00
<command>ALTER TABLE</command> changes the definition of an existing table.
2014-04-06 17:13:43 +02:00
There are several subforms described below. Note that the lock level required
2020-04-10 19:12:58 +02:00
may differ for each subform. An <literal>ACCESS EXCLUSIVE</literal> lock is
acquired unless explicitly noted. When multiple subcommands are given, the
lock acquired will be the strictest one required by any subcommand.
1999-07-06 19:16:42 +02:00
2002-04-23 04:07:16 +02:00
<variablelist>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-add-column">
2015-07-30 03:30:00 +02:00
<term><literal>ADD COLUMN [ IF NOT EXISTS ]</literal></term>
2002-04-23 04:07:16 +02:00
<listitem>
<para>
2005-08-01 18:11:14 +02:00
This form adds a new column to the table, using the same syntax as
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-createtable"><command>CREATE TABLE</command></link>. If <literal>IF NOT EXISTS</literal>
2015-07-30 03:30:00 +02:00
is specified and a column already exists with this name,
no error is thrown.
2002-04-23 04:07:16 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-drop-column">
2009-07-20 04:42:28 +02:00
<term><literal>DROP COLUMN [ IF EXISTS ]</literal></term>
2002-08-02 20:15:10 +02:00
<listitem>
<para>
2003-04-15 15:25:08 +02:00
This form drops a column from a table. Indexes and
2002-08-02 20:15:10 +02:00
table constraints involving the column will be automatically
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
dropped as well.
Multivariate statistics referencing the dropped column will also be
removed if the removal of the column would cause the statistics to
contain data for only a single column.
2017-10-09 03:44:17 +02:00
You will need to say <literal>CASCADE</literal> if anything outside the table
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
depends on the column, for example, foreign key references or views.
2009-08-03 00:14:53 +02:00
If <literal>IF EXISTS</literal> is specified and the column
does not exist, no error is thrown. In this case a notice
2009-07-20 04:42:28 +02:00
is issued instead.
2002-08-02 20:15:10 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-data-type">
2008-10-21 10:38:16 +02:00
<term><literal>SET DATA TYPE</literal></term>
2004-05-05 06:48:48 +02:00
<listitem>
<para>
This form changes the type of a column of a table. Indexes and
simple table constraints involving the column will be automatically
converted to use the new column type by reparsing the originally
Remove collation information from TypeName, where it does not belong.
The initial collations patch treated a COLLATE spec as part of a TypeName,
following what can only be described as brain fade on the part of the SQL
committee. It's a lot more reasonable to treat COLLATE as a syntactically
separate object, so that it can be added in only the productions where it
actually belongs, rather than needing to reject it in a boatload of places
where it doesn't belong (something the original patch mostly failed to do).
In addition this change lets us meet the spec's requirement to allow
COLLATE anywhere in the clauses of a ColumnDef, and it avoids unfriendly
behavior for constructs such as "foo::type COLLATE collation".
To do this, pull collation information out of TypeName and put it in
ColumnDef instead, thus reverting most of the collation-related changes in
parse_type.c's API. I made one additional structural change, which was to
use a ColumnDef as an intermediate node in AT_AlterColumnType AlterTableCmd
nodes. This provides enough room to get rid of the "transform" wart in
AlterTableCmd too, since the ColumnDef can carry the USING expression
easily enough.
Also fix some other minor bugs that have crept in in the same areas,
like failure to copy recently-added fields of ColumnDef in copyfuncs.c.
While at it, document the formerly secret ability to specify a collation
in ALTER TABLE ALTER COLUMN TYPE, ALTER TYPE ADD ATTRIBUTE, and
ALTER TYPE ALTER ATTRIBUTE TYPE; and correct some misstatements about
what the default collation selection will be when COLLATE is omitted.
BTW, the three-parameter form of format_type() should go away too,
since it just contributes to the confusion in this area; but I'll do
that in a separate patch.
2011-03-10 04:38:52 +01:00
supplied expression.
The optional <literal>COLLATE</literal> clause specifies a collation
for the new column; if omitted, the collation is the default for the
new column type.
The optional <literal>USING</literal>
2004-05-05 06:48:48 +02:00
clause specifies how to compute the new column value from the old;
if omitted, the default conversion is the same as an assignment
cast from old data type to new. A <literal>USING</literal>
clause must be provided if there is no implicit or assignment
cast from old to new type.
</para>
2021-11-05 16:09:31 +01:00
<para>
When this form is used, the column's statistics are removed,
so running <link linkend="sql-analyze"><command>ANALYZE</command></link>
on the table afterwards is recommended.
</para>
2004-05-05 06:48:48 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-drop-default">
2003-04-15 15:25:08 +02:00
<term><literal>SET</literal>/<literal>DROP DEFAULT</literal></term>
2002-04-23 04:07:16 +02:00
<listitem>
<para>
Clarify behavior of adding and altering a column in same ALTER command.
The behavior of something like
ALTER TABLE transactions
ADD COLUMN status varchar(30) DEFAULT 'old',
ALTER COLUMN status SET default 'current';
is to fill existing table rows with 'old', not 'current'. That's
intentional and desirable for a couple of reasons:
* It makes the behavior the same whether you merge the sub-commands
into one ALTER command or give them separately;
* If we applied the new default while filling the table, there would
be no way to get the existing behavior in one SQL command.
The same reasoning applies in cases that add a column and then
manipulate its GENERATED/IDENTITY status in a second sub-command,
since the generation expression is really just a kind of default.
However, that wasn't very obvious (at least not to me; earlier in
the referenced discussion thread I'd thought it was a bug to be
fixed). And it certainly wasn't documented.
Hence, add documentation, code comments, and a test case to clarify
that this behavior is all intentional.
In passing, adjust ATExecAddColumn's defaults-related relkind check
so that it matches up exactly with ATRewriteTables, instead of being
effectively (though not literally) the negated inverse condition.
The reasoning can be explained a lot more concisely that way, too
(not to mention that the comment now matches the code, which it
did not before).
Discussion: https://postgr.es/m/10365.1558909428@sss.pgh.pa.us
2020-01-21 22:17:21 +01:00
These forms set or remove the default value for a column (where
removal is equivalent to setting the default value to NULL). The new
default value will only apply in subsequent <command>INSERT</command>
or <command>UPDATE</command> commands; it does not cause rows already
in the table to change.
2002-04-23 04:07:16 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-drop-not-null">
2003-04-15 15:25:08 +02:00
<term><literal>SET</literal>/<literal>DROP NOT NULL</literal></term>
2002-04-23 04:07:16 +02:00
<listitem>
<para>
2003-04-15 15:25:08 +02:00
These forms change whether a column is marked to allow null
2019-03-13 13:55:00 +01:00
values or to reject null values.
</para>
<para>
<literal>SET NOT NULL</literal> may only be applied to a column
2020-02-10 04:04:43 +01:00
provided none of the records in the table contain a
2019-03-13 13:55:00 +01:00
<literal>NULL</literal> value for the column. Ordinarily this is
checked during the <literal>ALTER TABLE</literal> by scanning the
entire table; however, if a valid <literal>CHECK</literal> constraint is
found which proves no <literal>NULL</literal> can exist, then the
table scan is skipped.
2002-04-23 04:07:16 +02:00
</para>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<para>
2017-03-27 17:01:33 +02:00
If this table is a partition, one cannot perform <literal>DROP NOT NULL</literal>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
on a column if it is marked <literal>NOT NULL</literal> in the parent
2017-03-27 17:01:33 +02:00
table. To drop the <literal>NOT NULL</literal> constraint from all the
partitions, perform <literal>DROP NOT NULL</literal> on the parent
2017-10-09 03:44:17 +02:00
table. Even if there is no <literal>NOT NULL</literal> constraint on the
2017-03-27 17:01:33 +02:00
parent, such a constraint can still be added to individual partitions,
if desired; that is, the children can disallow nulls even if the parent
2017-06-12 15:51:18 +02:00
allows them, but not the other way around.
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</para>
2002-04-23 04:07:16 +02:00
</listitem>
</varlistentry>
2024-01-04 15:45:35 +01:00
<varlistentry id="sql-altertable-desc-set-expression">
<term><literal>SET EXPRESSION AS</literal></term>
<listitem>
<para>
This form replaces the expression of a generated column. Existing data
in the column is rewritten and all the future changes will apply the new
generation expression.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-drop-expression">
2020-01-14 13:09:31 +01:00
<term><literal>DROP EXPRESSION [ IF EXISTS ]</literal></term>
<listitem>
<para>
This form turns a stored generated column into a normal base column.
Existing data in the columns is retained, but future changes will no
longer apply the generation expression.
</para>
<para>
If <literal>DROP EXPRESSION IF EXISTS</literal> is specified and the
column is not a stored generated column, no error is thrown. In this
case a notice is issued instead.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-generated-identity">
2017-04-06 14:33:16 +02:00
<term><literal>ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY</literal></term>
<term><literal>SET GENERATED { ALWAYS | BY DEFAULT }</literal></term>
<term><literal>DROP IDENTITY [ IF EXISTS ]</literal></term>
<listitem>
<para>
These forms change whether a column is an identity column or change the
generation attribute of an existing identity column.
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
See <link linkend="sql-createtable"><command>CREATE TABLE</command></link> for details.
Clarify behavior of adding and altering a column in same ALTER command.
The behavior of something like
ALTER TABLE transactions
ADD COLUMN status varchar(30) DEFAULT 'old',
ALTER COLUMN status SET default 'current';
is to fill existing table rows with 'old', not 'current'. That's
intentional and desirable for a couple of reasons:
* It makes the behavior the same whether you merge the sub-commands
into one ALTER command or give them separately;
* If we applied the new default while filling the table, there would
be no way to get the existing behavior in one SQL command.
The same reasoning applies in cases that add a column and then
manipulate its GENERATED/IDENTITY status in a second sub-command,
since the generation expression is really just a kind of default.
However, that wasn't very obvious (at least not to me; earlier in
the referenced discussion thread I'd thought it was a bug to be
fixed). And it certainly wasn't documented.
Hence, add documentation, code comments, and a test case to clarify
that this behavior is all intentional.
In passing, adjust ATExecAddColumn's defaults-related relkind check
so that it matches up exactly with ATRewriteTables, instead of being
effectively (though not literally) the negated inverse condition.
The reasoning can be explained a lot more concisely that way, too
(not to mention that the comment now matches the code, which it
did not before).
Discussion: https://postgr.es/m/10365.1558909428@sss.pgh.pa.us
2020-01-21 22:17:21 +01:00
Like <literal>SET DEFAULT</literal>, these forms only affect the
behavior of subsequent <command>INSERT</command>
and <command>UPDATE</command> commands; they do not cause rows
already in the table to change.
2017-04-06 14:33:16 +02:00
</para>
<para>
If <literal>DROP IDENTITY IF EXISTS</literal> is specified and the
column is not an identity column, no error is thrown. In this case a
notice is issued instead.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-sequence-option">
2017-04-06 14:33:16 +02:00
<term><literal>SET <replaceable>sequence_option</replaceable></literal></term>
<term><literal>RESTART</literal></term>
<listitem>
<para>
These forms alter the sequence that underlies an existing identity
column. <replaceable>sequence_option</replaceable> is an option
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
supported by <link linkend="sql-altersequence"><command>ALTER SEQUENCE</command></link> such
2017-04-06 14:33:16 +02:00
as <literal>INCREMENT BY</literal>.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-statistics">
2003-04-15 15:25:08 +02:00
<term><literal>SET STATISTICS</literal></term>
2002-04-23 04:07:16 +02:00
<listitem>
<para>
This form
sets the per-column statistics-gathering target for subsequent
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-analyze"><command>ANALYZE</command></link> operations.
2024-01-13 18:14:53 +01:00
The target can be set in the range 0 to 10000. Set it
to <literal>DEFAULT</literal> to revert to using the system default
statistics target (<xref linkend="guc-default-statistics-target"/>).
(Setting to a value of -1 is an obsolete way spelling to get the same
outcome.)
2005-01-04 01:39:53 +01:00
For more information on the use of statistics by the
2004-03-01 18:58:39 +01:00
<productname>PostgreSQL</productname> query planner, refer to
2017-11-23 15:39:47 +01:00
<xref linkend="planner-stats"/>.
2002-04-23 04:07:16 +02:00
</para>
2014-04-06 17:13:43 +02:00
<para>
2015-01-14 22:40:58 +01:00
<literal>SET STATISTICS</literal> acquires a
<literal>SHARE UPDATE EXCLUSIVE</literal> lock.
2014-04-06 17:13:43 +02:00
</para>
2002-04-23 04:07:16 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-attribute-option">
2017-10-09 04:00:57 +02:00
<term><literal>SET ( <replaceable class="parameter">attribute_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )</literal></term>
<term><literal>RESET ( <replaceable class="parameter">attribute_option</replaceable> [, ... ] )</literal></term>
2009-08-03 00:14:53 +02:00
<listitem>
<para>
2010-09-16 20:15:21 +02:00
This form sets or resets per-attribute options. Currently, the only
2017-10-09 03:44:17 +02:00
defined per-attribute options are <literal>n_distinct</literal> and
<literal>n_distinct_inherited</literal>, which override the
2010-09-16 20:15:21 +02:00
number-of-distinct-values estimates made by subsequent
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-analyze"><command>ANALYZE</command></link>
2017-10-09 03:44:17 +02:00
operations. <literal>n_distinct</literal> affects the statistics for the table
itself, while <literal>n_distinct_inherited</literal> affects the statistics
2010-09-16 20:15:21 +02:00
gathered for the table plus its inheritance children. When set to a
2017-10-09 03:44:17 +02:00
positive value, <command>ANALYZE</command> will assume that the column contains
2010-01-22 17:40:19 +01:00
exactly the specified number of distinct nonnull values. When set to a
negative value, which must be greater
2017-10-09 03:44:17 +02:00
than or equal to -1, <command>ANALYZE</command> will assume that the number of
2009-08-03 00:14:53 +02:00
distinct nonnull values in the column is linear in the size of the
table; the exact count is to be computed by multiplying the estimated
table size by the absolute value of the given number. For example,
a value of -1 implies that all values in the column are distinct, while
a value of -0.5 implies that each value appears twice on the average.
This can be useful when the size of the table changes over time, since
the multiplication by the number of rows in the table is not performed
until query planning time. Specify a value of 0 to revert to estimating
the number of distinct values normally. For more information on the use
of statistics by the <productname>PostgreSQL</productname> query
2017-11-23 15:39:47 +01:00
planner, refer to <xref linkend="planner-stats"/>.
2009-08-03 00:14:53 +02:00
</para>
2014-04-06 17:13:43 +02:00
<para>
Changing per-attribute options acquires a
<literal>SHARE UPDATE EXCLUSIVE</literal> lock.
</para>
2009-08-03 00:14:53 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-storage">
2014-05-07 03:28:58 +02:00
<term>
2022-11-11 00:20:49 +01:00
<literal>SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT }</literal>
2014-05-07 03:28:58 +02:00
<indexterm>
<primary>TOAST</primary>
<secondary>per-column storage settings</secondary>
</indexterm>
</term>
2002-04-23 04:07:16 +02:00
<listitem>
<para>
This form sets the storage mode for a column. This controls whether this
2022-11-11 00:20:49 +01:00
column is held inline or in a secondary <acronym>TOAST</acronym> table,
and whether the data
2002-04-23 04:07:16 +02:00
should be compressed or not. <literal>PLAIN</literal> must be used
2003-04-15 15:25:08 +02:00
for fixed-length values such as <type>integer</type> and is
2002-04-23 04:07:16 +02:00
inline, uncompressed. <literal>MAIN</literal> is for inline,
compressible data. <literal>EXTERNAL</literal> is for external,
2003-04-15 15:25:08 +02:00
uncompressed data, and <literal>EXTENDED</literal> is for external,
2022-11-11 00:20:49 +01:00
compressed data.
Writing <literal>DEFAULT</literal> sets the storage mode to the default
mode for the column's data type. <literal>EXTENDED</literal> is the
default for most data types that support non-<literal>PLAIN</literal>
storage.
2010-05-13 20:54:18 +02:00
Use of <literal>EXTERNAL</literal> will make substring operations on
very large <type>text</type> and <type>bytea</type> values run faster,
2022-11-11 00:20:49 +01:00
at the penalty of increased storage space.
Note that <literal>ALTER TABLE ... SET STORAGE</literal> doesn't itself
change anything in the table; it just sets the strategy to be pursued
during future table updates.
2017-11-23 15:39:47 +01:00
See <xref linkend="storage-toast"/> for more information.
2002-04-23 04:07:16 +02:00
</para>
Allow configurable LZ4 TOAST compression.
There is now a per-column COMPRESSION option which can be set to pglz
(the default, and the only option in up until now) or lz4. Or, if you
like, you can set the new default_toast_compression GUC to lz4, and
then that will be the default for new table columns for which no value
is specified. We don't have lz4 support in the PostgreSQL code, so
to use lz4 compression, PostgreSQL must be built --with-lz4.
In general, TOAST compression means compression of individual column
values, not the whole tuple, and those values can either be compressed
inline within the tuple or compressed and then stored externally in
the TOAST table, so those properties also apply to this feature.
Prior to this commit, a TOAST pointer has two unused bits as part of
the va_extsize field, and a compessed datum has two unused bits as
part of the va_rawsize field. These bits are unused because the length
of a varlena is limited to 1GB; we now use them to indicate the
compression type that was used. This means we only have bit space for
2 more built-in compresison types, but we could work around that
problem, if necessary, by introducing a new vartag_external value for
any further types we end up wanting to add. Hopefully, it won't be
too important to offer a wide selection of algorithms here, since
each one we add not only takes more coding but also adds a build
dependency for every packager. Nevertheless, it seems worth doing
at least this much, because LZ4 gets better compression than PGLZ
with less CPU usage.
It's possible for LZ4-compressed datums to leak into composite type
values stored on disk, just as it is for PGLZ. It's also possible for
LZ4-compressed attributes to be copied into a different table via SQL
commands such as CREATE TABLE AS or INSERT .. SELECT. It would be
expensive to force such values to be decompressed, so PostgreSQL has
never done so. For the same reasons, we also don't force recompression
of already-compressed values even if the target table prefers a
different compression method than was used for the source data. These
architectural decisions are perhaps arguable but revisiting them is
well beyond the scope of what seemed possible to do as part of this
project. However, it's relatively cheap to recompress as part of
VACUUM FULL or CLUSTER, so this commit adjusts those commands to do
so, if the configured compression method of the table happens not to
match what was used for some column value stored therein.
Dilip Kumar. The original patches on which this work was based were
written by Ildus Kurbangaliev, and those were patches were based on
even earlier work by Nikita Glukhov, but the design has since changed
very substantially, since allow a potentially large number of
compression methods that could be added and dropped on a running
system proved too problematic given some of the architectural issues
mentioned above; the choice of which specific compression method to
add first is now different; and a lot of the code has been heavily
refactored. More recently, Justin Przyby helped quite a bit with
testing and reviewing and this version also includes some code
contributions from him. Other design input and review from Tomas
Vondra, Álvaro Herrera, Andres Freund, Oleg Bartunov, Alexander
Korotkov, and me.
Discussion: http://postgr.es/m/20170907194236.4cefce96%40wp.localdomain
Discussion: http://postgr.es/m/CAFiTN-uUpX3ck%3DK0mLEk-G_kUQY%3DSNOTeqdaNRR9FMdQrHKebw%40mail.gmail.com
2021-03-19 20:10:38 +01:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-compression">
Allow configurable LZ4 TOAST compression.
There is now a per-column COMPRESSION option which can be set to pglz
(the default, and the only option in up until now) or lz4. Or, if you
like, you can set the new default_toast_compression GUC to lz4, and
then that will be the default for new table columns for which no value
is specified. We don't have lz4 support in the PostgreSQL code, so
to use lz4 compression, PostgreSQL must be built --with-lz4.
In general, TOAST compression means compression of individual column
values, not the whole tuple, and those values can either be compressed
inline within the tuple or compressed and then stored externally in
the TOAST table, so those properties also apply to this feature.
Prior to this commit, a TOAST pointer has two unused bits as part of
the va_extsize field, and a compessed datum has two unused bits as
part of the va_rawsize field. These bits are unused because the length
of a varlena is limited to 1GB; we now use them to indicate the
compression type that was used. This means we only have bit space for
2 more built-in compresison types, but we could work around that
problem, if necessary, by introducing a new vartag_external value for
any further types we end up wanting to add. Hopefully, it won't be
too important to offer a wide selection of algorithms here, since
each one we add not only takes more coding but also adds a build
dependency for every packager. Nevertheless, it seems worth doing
at least this much, because LZ4 gets better compression than PGLZ
with less CPU usage.
It's possible for LZ4-compressed datums to leak into composite type
values stored on disk, just as it is for PGLZ. It's also possible for
LZ4-compressed attributes to be copied into a different table via SQL
commands such as CREATE TABLE AS or INSERT .. SELECT. It would be
expensive to force such values to be decompressed, so PostgreSQL has
never done so. For the same reasons, we also don't force recompression
of already-compressed values even if the target table prefers a
different compression method than was used for the source data. These
architectural decisions are perhaps arguable but revisiting them is
well beyond the scope of what seemed possible to do as part of this
project. However, it's relatively cheap to recompress as part of
VACUUM FULL or CLUSTER, so this commit adjusts those commands to do
so, if the configured compression method of the table happens not to
match what was used for some column value stored therein.
Dilip Kumar. The original patches on which this work was based were
written by Ildus Kurbangaliev, and those were patches were based on
even earlier work by Nikita Glukhov, but the design has since changed
very substantially, since allow a potentially large number of
compression methods that could be added and dropped on a running
system proved too problematic given some of the architectural issues
mentioned above; the choice of which specific compression method to
add first is now different; and a lot of the code has been heavily
refactored. More recently, Justin Przyby helped quite a bit with
testing and reviewing and this version also includes some code
contributions from him. Other design input and review from Tomas
Vondra, Álvaro Herrera, Andres Freund, Oleg Bartunov, Alexander
Korotkov, and me.
Discussion: http://postgr.es/m/20170907194236.4cefce96%40wp.localdomain
Discussion: http://postgr.es/m/CAFiTN-uUpX3ck%3DK0mLEk-G_kUQY%3DSNOTeqdaNRR9FMdQrHKebw%40mail.gmail.com
2021-03-19 20:10:38 +01:00
<term>
<literal>SET COMPRESSION <replaceable class="parameter">compression_method</replaceable></literal>
</term>
<listitem>
<para>
2021-05-27 19:24:24 +02:00
This form sets the compression method for a column, determining how
values inserted in future will be compressed (if the storage mode
permits compression at all).
2021-05-06 14:22:45 +02:00
This does not cause the table to be rewritten, so existing data may still
2021-06-14 02:25:50 +02:00
be compressed with other compression methods. If the table is restored
2021-05-27 19:24:24 +02:00
with <application>pg_restore</application>, then all values are rewritten
with the configured compression method.
However, when data is inserted from another relation (for example,
by <command>INSERT ... SELECT</command>), values from the source table are
not necessarily detoasted, so any previously compressed data may retain
its existing compression method, rather than being recompressed with the
compression method of the target column.
2021-05-06 14:22:45 +02:00
The supported compression
Allow configurable LZ4 TOAST compression.
There is now a per-column COMPRESSION option which can be set to pglz
(the default, and the only option in up until now) or lz4. Or, if you
like, you can set the new default_toast_compression GUC to lz4, and
then that will be the default for new table columns for which no value
is specified. We don't have lz4 support in the PostgreSQL code, so
to use lz4 compression, PostgreSQL must be built --with-lz4.
In general, TOAST compression means compression of individual column
values, not the whole tuple, and those values can either be compressed
inline within the tuple or compressed and then stored externally in
the TOAST table, so those properties also apply to this feature.
Prior to this commit, a TOAST pointer has two unused bits as part of
the va_extsize field, and a compessed datum has two unused bits as
part of the va_rawsize field. These bits are unused because the length
of a varlena is limited to 1GB; we now use them to indicate the
compression type that was used. This means we only have bit space for
2 more built-in compresison types, but we could work around that
problem, if necessary, by introducing a new vartag_external value for
any further types we end up wanting to add. Hopefully, it won't be
too important to offer a wide selection of algorithms here, since
each one we add not only takes more coding but also adds a build
dependency for every packager. Nevertheless, it seems worth doing
at least this much, because LZ4 gets better compression than PGLZ
with less CPU usage.
It's possible for LZ4-compressed datums to leak into composite type
values stored on disk, just as it is for PGLZ. It's also possible for
LZ4-compressed attributes to be copied into a different table via SQL
commands such as CREATE TABLE AS or INSERT .. SELECT. It would be
expensive to force such values to be decompressed, so PostgreSQL has
never done so. For the same reasons, we also don't force recompression
of already-compressed values even if the target table prefers a
different compression method than was used for the source data. These
architectural decisions are perhaps arguable but revisiting them is
well beyond the scope of what seemed possible to do as part of this
project. However, it's relatively cheap to recompress as part of
VACUUM FULL or CLUSTER, so this commit adjusts those commands to do
so, if the configured compression method of the table happens not to
match what was used for some column value stored therein.
Dilip Kumar. The original patches on which this work was based were
written by Ildus Kurbangaliev, and those were patches were based on
even earlier work by Nikita Glukhov, but the design has since changed
very substantially, since allow a potentially large number of
compression methods that could be added and dropped on a running
system proved too problematic given some of the architectural issues
mentioned above; the choice of which specific compression method to
add first is now different; and a lot of the code has been heavily
refactored. More recently, Justin Przyby helped quite a bit with
testing and reviewing and this version also includes some code
contributions from him. Other design input and review from Tomas
Vondra, Álvaro Herrera, Andres Freund, Oleg Bartunov, Alexander
Korotkov, and me.
Discussion: http://postgr.es/m/20170907194236.4cefce96%40wp.localdomain
Discussion: http://postgr.es/m/CAFiTN-uUpX3ck%3DK0mLEk-G_kUQY%3DSNOTeqdaNRR9FMdQrHKebw%40mail.gmail.com
2021-03-19 20:10:38 +01:00
methods are <literal>pglz</literal> and <literal>lz4</literal>.
2021-05-27 19:24:24 +02:00
(<literal>lz4</literal> is available only if <option>--with-lz4</option>
was used when building <productname>PostgreSQL</productname>.) In
addition, <replaceable class="parameter">compression_method</replaceable>
can be <literal>default</literal>, which selects the default behavior of
consulting the <xref linkend="guc-default-toast-compression"/> setting
at the time of data insertion to determine the method to use.
Allow configurable LZ4 TOAST compression.
There is now a per-column COMPRESSION option which can be set to pglz
(the default, and the only option in up until now) or lz4. Or, if you
like, you can set the new default_toast_compression GUC to lz4, and
then that will be the default for new table columns for which no value
is specified. We don't have lz4 support in the PostgreSQL code, so
to use lz4 compression, PostgreSQL must be built --with-lz4.
In general, TOAST compression means compression of individual column
values, not the whole tuple, and those values can either be compressed
inline within the tuple or compressed and then stored externally in
the TOAST table, so those properties also apply to this feature.
Prior to this commit, a TOAST pointer has two unused bits as part of
the va_extsize field, and a compessed datum has two unused bits as
part of the va_rawsize field. These bits are unused because the length
of a varlena is limited to 1GB; we now use them to indicate the
compression type that was used. This means we only have bit space for
2 more built-in compresison types, but we could work around that
problem, if necessary, by introducing a new vartag_external value for
any further types we end up wanting to add. Hopefully, it won't be
too important to offer a wide selection of algorithms here, since
each one we add not only takes more coding but also adds a build
dependency for every packager. Nevertheless, it seems worth doing
at least this much, because LZ4 gets better compression than PGLZ
with less CPU usage.
It's possible for LZ4-compressed datums to leak into composite type
values stored on disk, just as it is for PGLZ. It's also possible for
LZ4-compressed attributes to be copied into a different table via SQL
commands such as CREATE TABLE AS or INSERT .. SELECT. It would be
expensive to force such values to be decompressed, so PostgreSQL has
never done so. For the same reasons, we also don't force recompression
of already-compressed values even if the target table prefers a
different compression method than was used for the source data. These
architectural decisions are perhaps arguable but revisiting them is
well beyond the scope of what seemed possible to do as part of this
project. However, it's relatively cheap to recompress as part of
VACUUM FULL or CLUSTER, so this commit adjusts those commands to do
so, if the configured compression method of the table happens not to
match what was used for some column value stored therein.
Dilip Kumar. The original patches on which this work was based were
written by Ildus Kurbangaliev, and those were patches were based on
even earlier work by Nikita Glukhov, but the design has since changed
very substantially, since allow a potentially large number of
compression methods that could be added and dropped on a running
system proved too problematic given some of the architectural issues
mentioned above; the choice of which specific compression method to
add first is now different; and a lot of the code has been heavily
refactored. More recently, Justin Przyby helped quite a bit with
testing and reviewing and this version also includes some code
contributions from him. Other design input and review from Tomas
Vondra, Álvaro Herrera, Andres Freund, Oleg Bartunov, Alexander
Korotkov, and me.
Discussion: http://postgr.es/m/20170907194236.4cefce96%40wp.localdomain
Discussion: http://postgr.es/m/CAFiTN-uUpX3ck%3DK0mLEk-G_kUQY%3DSNOTeqdaNRR9FMdQrHKebw%40mail.gmail.com
2021-03-19 20:10:38 +01:00
</para>
2002-04-23 04:07:16 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-add-table-constraint">
2017-10-09 04:00:57 +02:00
<term><literal>ADD <replaceable class="parameter">table_constraint</replaceable> [ NOT VALID ]</literal></term>
2003-02-13 06:20:05 +01:00
<listitem>
<para>
2020-04-10 19:12:58 +02:00
This form adds a new constraint to a table using the same constraint
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
syntax as <link linkend="sql-createtable"><command>CREATE TABLE</command></link>, plus the option <literal>NOT
2011-06-16 01:05:11 +02:00
VALID</literal>, which is currently only allowed for foreign key
2011-06-02 00:43:50 +02:00
and CHECK constraints.
2018-12-07 22:40:58 +01:00
</para>
<para>
Normally, this form will cause a scan of the table to verify that all
existing rows in the table satisfy the new constraint. But if
the <literal>NOT VALID</literal> option is used, this
potentially-lengthy scan is skipped. The constraint will still be
2011-06-16 01:05:11 +02:00
enforced against subsequent inserts or updates (that is, they'll fail
2011-06-02 00:43:50 +02:00
unless there is a matching row in the referenced table, in the case
2018-12-07 22:40:58 +01:00
of foreign keys, or they'll fail unless the new row matches the
specified check condition). But the
2011-06-16 01:05:11 +02:00
database will not assume that the constraint holds for all rows in
the table, until it is validated by using the <literal>VALIDATE
2018-12-07 22:40:58 +01:00
CONSTRAINT</literal> option.
Doc: fix "Unresolved ID reference" warnings, clean up man page cross-refs.
Use xreflabel attributes instead of endterm attributes to control the
appearance of links to subsections of SQL command reference pages.
This is simpler, it matches what we do elsewhere (e.g. for GUC variables),
and it doesn't draw "Unresolved ID reference" warnings from the PDF
toolchain.
Fix some places where the text was absolutely dependent on an <xref>
rendering exactly so, by using a <link> around the required text
instead. At least one of those spots had already been turned into
bad grammar by subsequent changes, and the whole idea is just too
fragile for my taste. <xref> does NOT have fixed output, don't write
as if it does.
Consistently include a page-level link in cross-man-page references,
because otherwise they are useless/nonsensical in man-page output.
Likewise, be consistent about mentioning "below" or "above" in same-page
references; we were doing that in about 90% of the cases, but now it's
100%.
Also get rid of another nonfunctional-in-PDF idea, of making
cross-references to functions by sticking ID tags on <row> constructs.
We can put the IDs on <indexterm>s instead --- which is probably not any
more sensible in abstract terms, but it works where the other doesn't.
(There is talk of attaching cross-reference IDs to most or all of
the docs' function descriptions, but for now I just fixed the two
that exist.)
Discussion: https://postgr.es/m/14480.1589154358@sss.pgh.pa.us
2020-05-11 20:15:49 +02:00
See <xref linkend="sql-altertable-notes"/> below for more information
2018-12-07 22:40:58 +01:00
about using the <literal>NOT VALID</literal> option.
2003-12-01 23:08:02 +01:00
</para>
2018-02-20 16:08:55 +01:00
2018-09-21 08:03:37 +02:00
<para>
2020-04-10 19:12:58 +02:00
Although most forms of <literal>ADD
<replaceable class="parameter">table_constraint</replaceable></literal>
require an <literal>ACCESS EXCLUSIVE</literal> lock, <literal>ADD
FOREIGN KEY</literal> requires only a <literal>SHARE ROW
EXCLUSIVE</literal> lock. Note that <literal>ADD FOREIGN KEY</literal>
also acquires a <literal>SHARE ROW EXCLUSIVE</literal> lock on the
referenced table, in addition to the lock on the table on which the
constraint is declared.
2018-09-21 08:03:37 +02:00
</para>
2018-02-20 16:08:55 +01:00
<para>
Additional restrictions apply when unique or primary key constraints
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
are added to partitioned tables; see <link linkend="sql-createtable"><command>CREATE TABLE</command></link>.
2018-12-07 22:40:58 +01:00
Also, foreign key constraints on partitioned
tables may not be declared <literal>NOT VALID</literal> at present.
2018-02-20 16:08:55 +01:00
</para>
2003-02-13 06:20:05 +01:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-add-table-constraint-using-index">
2017-10-09 04:00:57 +02:00
<term><literal>ADD <replaceable class="parameter">table_constraint_using_index</replaceable></literal></term>
2011-01-25 21:42:03 +01:00
<listitem>
<para>
2017-10-09 03:44:17 +02:00
This form adds a new <literal>PRIMARY KEY</literal> or <literal>UNIQUE</literal>
2011-01-25 21:42:03 +01:00
constraint to a table based on an existing unique index. All the
columns of the index will be included in the constraint.
</para>
<para>
The index cannot have expression columns nor be a partial index.
Also, it must be a b-tree index with default sort ordering. These
restrictions ensure that the index is equivalent to one that would be
2017-10-09 03:44:17 +02:00
built by a regular <literal>ADD PRIMARY KEY</literal> or <literal>ADD UNIQUE</literal>
2011-01-25 21:42:03 +01:00
command.
</para>
<para>
2017-10-09 03:44:17 +02:00
If <literal>PRIMARY KEY</literal> is specified, and the index's columns are not
already marked <literal>NOT NULL</literal>, then this command will attempt to
do <literal>ALTER COLUMN SET NOT NULL</literal> against each such column.
2011-01-25 21:42:03 +01:00
That requires a full table scan to verify the column(s) contain no
nulls. In all other cases, this is a fast operation.
</para>
<para>
If a constraint name is provided then the index will be renamed to match
the constraint name. Otherwise the constraint will be named the same as
the index.
</para>
<para>
2017-10-09 03:44:17 +02:00
After this command is executed, the index is <quote>owned</quote> by the
2011-01-25 21:42:03 +01:00
constraint, in the same way as if the index had been built by
2017-10-09 03:44:17 +02:00
a regular <literal>ADD PRIMARY KEY</literal> or <literal>ADD UNIQUE</literal>
2011-01-25 21:42:03 +01:00
command. In particular, dropping the constraint will make the index
disappear too.
</para>
2018-02-19 20:59:37 +01:00
<para>
2018-02-20 16:08:55 +01:00
This form is not currently supported on partitioned tables.
2018-02-19 20:59:37 +01:00
</para>
2011-01-25 21:42:03 +01:00
<note>
<para>
Adding a constraint using an existing index can be helpful in
situations where a new constraint needs to be added without blocking
table updates for a long time. To do that, create the index using
2023-11-25 02:07:14 +01:00
<command>CREATE UNIQUE INDEX CONCURRENTLY</command>, and then convert it to a
constraint using this syntax. See the example below.
2011-01-25 21:42:03 +01:00
</para>
</note>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-alter-constraint">
2013-06-29 01:27:30 +02:00
<term><literal>ALTER CONSTRAINT</literal></term>
<listitem>
<para>
This form alters the attributes of a constraint that was previously
created. Currently only foreign key constraints may be altered.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-validate-constraint">
2011-06-16 01:05:11 +02:00
<term><literal>VALIDATE CONSTRAINT</literal></term>
<listitem>
<para>
2018-12-07 22:40:58 +01:00
This form validates a foreign key or check constraint that was
previously created as <literal>NOT VALID</literal>, by scanning the
table to ensure there are no rows for which the constraint is not
satisfied. Nothing happens if the constraint is already marked valid.
Doc: fix "Unresolved ID reference" warnings, clean up man page cross-refs.
Use xreflabel attributes instead of endterm attributes to control the
appearance of links to subsections of SQL command reference pages.
This is simpler, it matches what we do elsewhere (e.g. for GUC variables),
and it doesn't draw "Unresolved ID reference" warnings from the PDF
toolchain.
Fix some places where the text was absolutely dependent on an <xref>
rendering exactly so, by using a <link> around the required text
instead. At least one of those spots had already been turned into
bad grammar by subsequent changes, and the whole idea is just too
fragile for my taste. <xref> does NOT have fixed output, don't write
as if it does.
Consistently include a page-level link in cross-man-page references,
because otherwise they are useless/nonsensical in man-page output.
Likewise, be consistent about mentioning "below" or "above" in same-page
references; we were doing that in about 90% of the cases, but now it's
100%.
Also get rid of another nonfunctional-in-PDF idea, of making
cross-references to functions by sticking ID tags on <row> constructs.
We can put the IDs on <indexterm>s instead --- which is probably not any
more sensible in abstract terms, but it works where the other doesn't.
(There is talk of attaching cross-reference IDs to most or all of
the docs' function descriptions, but for now I just fixed the two
that exist.)
Discussion: https://postgr.es/m/14480.1589154358@sss.pgh.pa.us
2020-05-11 20:15:49 +02:00
(See <xref linkend="sql-altertable-notes"/> below for an explanation
of the usefulness of this command.)
2011-06-16 01:05:11 +02:00
</para>
2021-05-06 23:17:57 +02:00
<para>
This command acquires a <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
</para>
2011-06-16 01:05:11 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-drop-constraint">
2009-07-20 04:42:28 +02:00
<term><literal>DROP CONSTRAINT [ IF EXISTS ]</literal></term>
2002-04-23 04:07:16 +02:00
<listitem>
<para>
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
This form drops the specified constraint on a table, along with
any index underlying the constraint.
2009-07-20 04:42:28 +02:00
If <literal>IF EXISTS</literal> is specified and the constraint
does not exist, no error is thrown. In this case a notice is issued instead.
2002-04-23 04:07:16 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-disable-enable-trigger">
2007-03-20 00:38:32 +01:00
<term><literal>DISABLE</literal>/<literal>ENABLE [ REPLICA | ALWAYS ] TRIGGER</literal></term>
2005-08-24 19:24:19 +02:00
<listitem>
<para>
2007-03-20 00:38:32 +01:00
These forms configure the firing of trigger(s) belonging to the table.
2005-08-24 19:24:19 +02:00
A disabled trigger is still known to the system, but is not executed
2023-03-04 19:32:35 +01:00
when its triggering event occurs. (For a deferred trigger, the enable
2005-08-24 19:24:19 +02:00
status is checked when the event occurs, not when the trigger function
2023-03-04 19:32:35 +01:00
is actually executed.) One can disable or enable a single
2005-08-24 19:24:19 +02:00
trigger specified by name, or all triggers on the table, or only
2010-06-09 19:48:10 +02:00
user triggers (this option excludes internally generated constraint
2023-03-04 19:32:35 +01:00
triggers, such as those that are used to implement foreign key
2010-06-09 19:48:10 +02:00
constraints or deferrable uniqueness and exclusion constraints).
Disabling or enabling internally generated constraint triggers
2005-08-24 19:24:19 +02:00
requires superuser privileges; it should be done with caution since
of course the integrity of the constraint cannot be guaranteed if the
triggers are not executed.
2018-01-18 15:34:51 +01:00
</para>
<para>
2007-03-22 16:45:56 +01:00
The trigger firing mechanism is also affected by the configuration
2017-11-23 15:39:47 +01:00
variable <xref linkend="guc-session-replication-role"/>. Simply enabled
2018-01-18 15:34:51 +01:00
triggers (the default) will fire when the replication role is <quote>origin</quote>
2017-10-09 03:44:17 +02:00
(the default) or <quote>local</quote>. Triggers configured as <literal>ENABLE
REPLICA</literal> will only fire if the session is in <quote>replica</quote>
2009-02-11 22:11:16 +01:00
mode, and triggers configured as <literal>ENABLE ALWAYS</literal> will
2018-01-18 15:34:51 +01:00
fire regardless of the current replication role.
</para>
<para>
The effect of this mechanism is that in the default configuration,
triggers do not fire on replicas. This is useful because if a trigger
is used on the origin to propagate data between tables, then the
2023-03-04 19:32:35 +01:00
replication system will also replicate the propagated data; so the
2018-01-18 15:34:51 +01:00
trigger should not fire a second time on the replica, because that would
lead to duplication. However, if a trigger is used for another purpose
such as creating external alerts, then it might be appropriate to set it
to <literal>ENABLE ALWAYS</literal> so that it is also fired on
replicas.
2007-03-20 00:38:32 +01:00
</para>
2018-01-18 15:34:51 +01:00
2023-03-04 19:32:35 +01:00
<para>
When this command is applied to a partitioned table, the states of
corresponding clone triggers in the partitions are updated too,
unless <literal>ONLY</literal> is specified.
</para>
2015-04-05 17:37:08 +02:00
<para>
This command acquires a <literal>SHARE ROW EXCLUSIVE</literal> lock.
</para>
2007-03-20 00:38:32 +01:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-disable-enable-rule">
2007-03-20 00:38:32 +01:00
<term><literal>DISABLE</literal>/<literal>ENABLE [ REPLICA | ALWAYS ] RULE</literal></term>
<listitem>
<para>
These forms configure the firing of rewrite rules belonging to the table.
A disabled rule is still known to the system, but is not applied
2007-03-22 16:45:56 +01:00
during query rewriting. The semantics are as for disabled/enabled
2007-05-18 01:36:04 +02:00
triggers. This configuration is ignored for <literal>ON SELECT</literal> rules, which
2007-03-22 16:45:56 +01:00
are always applied in order to keep views working even if the current
session is in a non-default replication role.
2005-08-24 19:24:19 +02:00
</para>
2018-01-18 15:34:51 +01:00
<para>
The rule firing mechanism is also affected by the configuration variable
<xref linkend="guc-session-replication-role"/>, analogous to triggers as
described above.
</para>
2005-08-24 19:24:19 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-disable-enable-row-level-security">
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
<term><literal>DISABLE</literal>/<literal>ENABLE ROW LEVEL SECURITY</literal></term>
<listitem>
<para>
These forms control the application of row security policies belonging
to the table. If enabled and no policies exist for the table, then a
default-deny policy is applied. Note that policies can exist for a table
2021-04-21 08:14:43 +02:00
even if row-level security is disabled. In this case, the policies will
2019-10-25 20:23:44 +02:00
<emphasis>not</emphasis> be applied and the policies will be ignored.
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
See also
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-createpolicy"><command>CREATE POLICY</command></link>.
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-force-row-level-security">
2015-10-05 03:05:08 +02:00
<term><literal>NO FORCE</literal>/<literal>FORCE ROW LEVEL SECURITY</literal></term>
<listitem>
<para>
These forms control the application of row security policies belonging
2021-04-21 08:14:43 +02:00
to the table when the user is the table owner. If enabled, row-level
2015-10-05 03:05:08 +02:00
security policies will be applied when the user is the table owner. If
2021-04-21 08:14:43 +02:00
disabled (the default) then row-level security will not be applied when
2015-10-05 03:05:08 +02:00
the user is the table owner.
See also
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-createpolicy"><command>CREATE POLICY</command></link>.
2015-10-05 03:05:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-cluster-on">
2012-05-21 18:06:56 +02:00
<term><literal>CLUSTER ON</literal></term>
2004-07-12 01:13:58 +02:00
<listitem>
<para>
2009-02-11 22:11:16 +01:00
This form selects the default index for future
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-cluster"><command>CLUSTER</command></link>
2004-07-12 01:13:58 +02:00
operations. It does not actually re-cluster the table.
</para>
2014-04-06 17:13:43 +02:00
<para>
Changing cluster options acquires a <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
</para>
2004-07-12 01:13:58 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-without-cluster">
2004-07-12 01:13:58 +02:00
<term><literal>SET WITHOUT CLUSTER</literal></term>
<listitem>
<para>
This form removes the most recently used
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-cluster"><command>CLUSTER</command></link>
2004-07-12 01:13:58 +02:00
index specification from the table. This affects
future cluster operations that don't specify an index.
</para>
2014-04-06 17:13:43 +02:00
<para>
Changing cluster options acquires a <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
</para>
2004-07-12 01:13:58 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-without-oids">
2004-05-05 06:48:48 +02:00
<term><literal>SET WITHOUT OIDS</literal></term>
2002-04-23 04:07:16 +02:00
<listitem>
<para>
2018-12-07 20:50:46 +01:00
Backward-compatible syntax for removing the <literal>oid</literal>
system column. As <literal>oid</literal> system columns cannot be
added anymore, this never has an effect.
2002-04-23 04:07:16 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-access-method">
2021-07-28 03:10:44 +02:00
<term><literal>SET ACCESS METHOD</literal></term>
<listitem>
<para>
2024-03-25 16:30:36 +01:00
This form changes the access method of the table by rewriting it
using the indicated access method; specifying
<literal>DEFAULT</literal> selects the access method set as the
<xref linkend="guc-default-table-access-method"/> configuration
parameter.
See <xref linkend="tableam"/> for more information.
</para>
<para>
When applied to a partitioned table, there is no data to rewrite,
but partitions created afterwards will default to the given access
method unless overridden by a <literal>USING</literal> clause.
Specifying <varname>DEFAULT</varname> removes a previous value,
causing future partitions to default to
<varname>default_table_access_method</varname>.
2021-07-28 03:10:44 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-tablespace">
2014-08-22 20:27:00 +02:00
<term><literal>SET TABLESPACE</literal></term>
<listitem>
<para>
This form changes the table's tablespace to the specified tablespace and
moves the data file(s) associated with the table to the new tablespace.
Indexes on the table, if any, are not moved; but they can be moved
separately with additional <literal>SET TABLESPACE</literal> commands.
2019-02-28 23:24:21 +01:00
When applied to a partitioned table, nothing is moved, but any
partitions created afterwards with
<command>CREATE TABLE PARTITION OF</command> will use that tablespace,
2020-09-21 18:43:42 +02:00
unless overridden by a <literal>TABLESPACE</literal> clause.
2019-02-28 23:24:21 +01:00
</para>
<para>
2014-08-22 20:27:00 +02:00
All tables in the current database in a tablespace can be moved by using
the <literal>ALL IN TABLESPACE</literal> form, which will lock all tables
to be moved first and then move each one. This form also supports
<literal>OWNED BY</literal>, which will only move tables owned by the
roles specified. If the <literal>NOWAIT</literal> option is specified
then the command will fail if it is unable to acquire all of the locks
required immediately. Note that system catalogs are not moved by this
2019-02-28 23:24:21 +01:00
command; use <command>ALTER DATABASE</command> or explicit
2014-08-22 20:27:00 +02:00
<command>ALTER TABLE</command> invocations instead if desired. The
<literal>information_schema</literal> relations are not considered part
of the system catalogs and will be moved.
See also
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-createtablespace"><command>CREATE TABLESPACE</command></link>.
2014-08-22 20:27:00 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-logged-unlogged">
2015-05-22 14:42:15 +02:00
<term><literal>SET { LOGGED | UNLOGGED }</literal></term>
2014-08-22 20:27:00 +02:00
<listitem>
<para>
This form changes the table from unlogged to logged or vice-versa
2017-11-23 15:39:47 +01:00
(see <xref linkend="sql-createtable-unlogged"/>). It cannot be applied
2014-08-22 20:27:00 +02:00
to a temporary table.
</para>
2022-04-07 16:13:23 +02:00
<para>
This also changes the persistence of any sequences linked to the table
(for identity or serial columns). However, it is also possible to
change the persistence of such sequences separately.
</para>
2014-08-22 20:27:00 +02:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-storage-parameter">
2020-06-30 18:26:51 +02:00
<term><literal>SET ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
2006-07-02 03:58:36 +02:00
<listitem>
<para>
2006-07-04 20:07:24 +02:00
This form changes one or more storage parameters for the table. See
Doc: fix "Unresolved ID reference" warnings, clean up man page cross-refs.
Use xreflabel attributes instead of endterm attributes to control the
appearance of links to subsections of SQL command reference pages.
This is simpler, it matches what we do elsewhere (e.g. for GUC variables),
and it doesn't draw "Unresolved ID reference" warnings from the PDF
toolchain.
Fix some places where the text was absolutely dependent on an <xref>
rendering exactly so, by using a <link> around the required text
instead. At least one of those spots had already been turned into
bad grammar by subsequent changes, and the whole idea is just too
fragile for my taste. <xref> does NOT have fixed output, don't write
as if it does.
Consistently include a page-level link in cross-man-page references,
because otherwise they are useless/nonsensical in man-page output.
Likewise, be consistent about mentioning "below" or "above" in same-page
references; we were doing that in about 90% of the cases, but now it's
100%.
Also get rid of another nonfunctional-in-PDF idea, of making
cross-references to functions by sticking ID tags on <row> constructs.
We can put the IDs on <indexterm>s instead --- which is probably not any
more sensible in abstract terms, but it works where the other doesn't.
(There is talk of attaching cross-reference IDs to most or all of
the docs' function descriptions, but for now I just fixed the two
that exist.)
Discussion: https://postgr.es/m/14480.1589154358@sss.pgh.pa.us
2020-05-11 20:15:49 +02:00
<xref linkend="sql-createtable-storage-parameters"/> in the
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-createtable"><command>CREATE TABLE</command></link> documentation
2006-07-04 20:07:24 +02:00
for details on the available parameters. Note that the table contents
will not be modified immediately by this command; depending on the
Update reference documentation on may/can/might:
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
2007-02-01 00:26:05 +01:00
parameter you might need to rewrite the table to get the desired effects.
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
That can be done with <link linkend="sql-vacuum"><command>VACUUM
FULL</command></link>, <link linkend="sql-cluster"><command>CLUSTER</command></link> or one of the forms
2017-10-09 03:44:17 +02:00
of <command>ALTER TABLE</command> that forces a table rewrite.
2017-03-06 12:18:12 +01:00
For planner related parameters, changes will take effect from the next
time the table is locked so currently executing queries will not be
affected.
2006-07-04 20:07:24 +02:00
</para>
2015-08-14 15:19:28 +02:00
<para>
2017-06-12 15:51:18 +02:00
<literal>SHARE UPDATE EXCLUSIVE</literal> lock will be taken for
2017-11-19 23:50:10 +01:00
fillfactor, toast and autovacuum storage parameters, as well as the
2021-03-24 06:40:12 +01:00
planner parameter <varname>parallel_workers</varname>.
2015-08-14 15:19:28 +02:00
</para>
2006-07-04 20:07:24 +02:00
</listitem>
</varlistentry>
2006-07-02 03:58:36 +02:00
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-reset-storage-parameter">
2017-10-09 04:00:57 +02:00
<term><literal>RESET ( <replaceable class="parameter">storage_parameter</replaceable> [, ... ] )</literal></term>
2006-07-04 20:07:24 +02:00
<listitem>
<para>
This form resets one or more storage parameters to their
2017-10-09 03:44:17 +02:00
defaults. As with <literal>SET</literal>, a table rewrite might be
2006-07-04 20:07:24 +02:00
needed to update the table entirely.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-inherit">
2017-10-09 04:00:57 +02:00
<term><literal>INHERIT <replaceable class="parameter">parent_table</replaceable></literal></term>
2006-07-04 20:07:24 +02:00
<listitem>
<para>
2006-10-13 23:43:19 +02:00
This form adds the target table as a new child of the specified parent
table. Subsequently, queries against the parent will include records
of the target table. To be added as a child, the target table must
already contain all the same columns as the parent (it could have
additional columns, too). The columns must have matching data types,
2006-07-02 03:58:36 +02:00
and if they have <literal>NOT NULL</literal> constraints in the parent
then they must also have <literal>NOT NULL</literal> constraints in the
child.
2006-07-04 20:07:24 +02:00
</para>
2006-07-02 03:58:36 +02:00
2006-07-04 20:07:24 +02:00
<para>
2006-10-13 23:43:19 +02:00
There must also be matching child-table constraints for all
2012-01-16 23:19:42 +01:00
<literal>CHECK</literal> constraints of the parent, except those
2012-07-24 21:49:54 +02:00
marked non-inheritable (that is, created with <literal>ALTER TABLE ... ADD CONSTRAINT ... NO INHERIT</literal>)
2012-01-16 23:19:42 +01:00
in the parent, which are ignored; all child-table constraints matched
must not be marked non-inheritable.
Currently
2006-07-02 03:58:36 +02:00
<literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>, and
2006-10-13 23:43:19 +02:00
<literal>FOREIGN KEY</literal> constraints are not considered, but
Update reference documentation on may/can/might:
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
2007-02-01 00:26:05 +01:00
this might change in the future.
2006-07-02 03:58:36 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-no-inherit">
2017-10-09 04:00:57 +02:00
<term><literal>NO INHERIT <replaceable class="parameter">parent_table</replaceable></literal></term>
2006-07-02 03:58:36 +02:00
<listitem>
<para>
2006-10-13 23:43:19 +02:00
This form removes the target table from the list of children of the
specified parent table.
2006-07-04 20:07:24 +02:00
Queries against the parent table will no longer include records drawn
from the target table.
2006-07-02 03:58:36 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-of">
2017-10-09 04:00:57 +02:00
<term><literal>OF <replaceable class="parameter">type_name</replaceable></literal></term>
2011-04-21 03:35:15 +02:00
<listitem>
<para>
This form links the table to a composite type as though <command>CREATE
2017-10-09 03:44:17 +02:00
TABLE OF</command> had formed it. The table's list of column names and types
2018-12-07 20:50:46 +01:00
must precisely match that of the composite type. The table must
2011-04-21 03:35:15 +02:00
not inherit from any other table. These restrictions ensure
2017-10-09 03:44:17 +02:00
that <command>CREATE TABLE OF</command> would permit an equivalent table
2011-04-21 03:35:15 +02:00
definition.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-not-of">
2011-04-21 03:35:15 +02:00
<term><literal>NOT OF</literal></term>
<listitem>
<para>
This form dissociates a typed table from its type.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-owner-to">
2017-10-18 13:29:16 +02:00
<term><literal>OWNER TO</literal></term>
2002-04-23 04:07:16 +02:00
<listitem>
<para>
2014-04-14 16:43:53 +02:00
This form changes the owner of the table, sequence, view, materialized view,
or foreign table to the specified user.
2002-04-23 04:07:16 +02:00
</para>
</listitem>
</varlistentry>
2003-03-20 19:52:48 +01:00
2020-09-03 12:38:32 +02:00
<varlistentry id="sql-altertable-replica-identity">
2013-11-08 18:30:43 +01:00
<term><literal>REPLICA IDENTITY</literal></term>
<listitem>
<para>
This form changes the information which is written to the write-ahead log
2022-02-14 04:25:58 +01:00
to identify rows which are updated or deleted.
In most cases, the old value of each column is only logged if it differs
from the new value; however, if the old value is stored externally, it is
always logged regardless of whether it changed.
This option has no effect except when logical replication is in use.
2021-12-22 08:37:58 +01:00
<variablelist>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-replica-identity-default">
2021-12-22 08:37:58 +01:00
<term><literal>DEFAULT</literal></term>
<listitem>
<para>
Records the old values of the columns of the primary key, if any.
2022-01-27 18:28:21 +01:00
This is the default for non-system tables.
2021-12-22 08:37:58 +01:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-replica-identity-using-index">
2021-12-22 08:37:58 +01:00
<term><literal>USING INDEX <replaceable class="parameter">index_name</replaceable></literal></term>
<listitem>
<para>
Records the old values of the columns covered by the named index,
that must be unique, not partial, not deferrable, and include only
columns marked <literal>NOT NULL</literal>. If this index is
dropped, the behavior is the same as <literal>NOTHING</literal>.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-replica-identity-full">
2021-12-22 08:37:58 +01:00
<term><literal>FULL</literal></term>
<listitem>
<para>
Records the old values of all columns in the row.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-replica-identity-nothing">
2021-12-22 08:37:58 +01:00
<term><literal>NOTHING</literal></term>
<listitem>
<para>
Records no information about the old row. This is the default for
system tables.
</para>
</listitem>
</varlistentry>
2022-04-07 18:23:28 +02:00
</variablelist></para>
2013-11-08 18:30:43 +01:00
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-rename">
2004-05-05 06:48:48 +02:00
<term><literal>RENAME</literal></term>
<listitem>
<para>
The <literal>RENAME</literal> forms change the name of a table
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
(or an index, sequence, view, materialized view, or foreign table), the
name of an individual column in a table, or the name of a constraint of
the table. When renaming a constraint that has an underlying index,
the index is renamed as well.
2014-04-14 16:43:53 +02:00
There is no effect on the stored data.
2004-05-05 06:48:48 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-desc-set-schema">
2005-08-01 18:11:14 +02:00
<term><literal>SET SCHEMA</literal></term>
<listitem>
<para>
This form moves the table into another schema. Associated indexes,
2006-08-21 02:57:26 +02:00
constraints, and sequences owned by table columns are moved as well.
2005-08-01 18:11:14 +02:00
</para>
</listitem>
</varlistentry>
2019-09-29 09:50:36 +02:00
<varlistentry id="sql-altertable-attach-partition">
2017-10-09 04:00:57 +02:00
<term><literal>ATTACH PARTITION <replaceable class="parameter">partition_name</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }</literal></term>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<listitem>
<para>
This form attaches an existing table (which might itself be partitioned)
Allow a partitioned table to have a default partition.
Any tuples that don't route to any other partition will route to the
default partition.
Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, and Robert
Haas, with review and testing at various stages by (at least) Rushabh
Lathia, Keith Fiske, Amit Langote, Amul Sul, Rajkumar Raghuanshi, Sven
Kunze, Kyotaro Horiguchi, Thom Brown, Rafia Sabih, and Dilip Kumar.
Discussion: http://postgr.es/m/CAH2L28tbN4SYyhS7YV1YBWcitkqbhSWfQCy0G=apRcC_PEO-bg@mail.gmail.com
Discussion: http://postgr.es/m/CAOG9ApEYj34fWMcvBMBQ-YtqR9fTdXhdN82QEKG0SVZ6zeL1xg@mail.gmail.com
2017-09-08 23:28:04 +02:00
as a partition of the target table. The table can be attached
2018-02-19 20:59:37 +01:00
as a partition for specific values using <literal>FOR VALUES</literal>
or as a default partition by using <literal>DEFAULT</literal>.
For each index in the target table, a corresponding
Local partitioned indexes
When CREATE INDEX is run on a partitioned table, create catalog entries
for an index on the partitioned table (which is just a placeholder since
the table proper has no data of its own), and recurse to create actual
indexes on the existing partitions; create them in future partitions
also.
As a convenience gadget, if the new index definition matches some
existing index in partitions, these are picked up and used instead of
creating new ones. Whichever way these indexes come about, they become
attached to the index on the parent table and are dropped alongside it,
and cannot be dropped on isolation unless they are detached first.
To support pg_dump'ing these indexes, add commands
CREATE INDEX ON ONLY <table>
(which creates the index on the parent partitioned table, without
recursing) and
ALTER INDEX ATTACH PARTITION
(which is used after the indexes have been created individually on each
partition, to attach them to the parent index). These reconstruct prior
database state exactly.
Reviewed-by: (in alphabetical order) Peter Eisentraut, Robert Haas, Amit
Langote, Jesper Pedersen, Simon Riggs, David Rowley
Discussion: https://postgr.es/m/20171113170646.gzweigyrgg6pwsg4@alvherre.pgsql
2018-01-19 15:49:22 +01:00
one will be created in the attached table; or, if an equivalent
2019-11-05 02:17:33 +01:00
index already exists, it will be attached to the target table's index,
Local partitioned indexes
When CREATE INDEX is run on a partitioned table, create catalog entries
for an index on the partitioned table (which is just a placeholder since
the table proper has no data of its own), and recurse to create actual
indexes on the existing partitions; create them in future partitions
also.
As a convenience gadget, if the new index definition matches some
existing index in partitions, these are picked up and used instead of
creating new ones. Whichever way these indexes come about, they become
attached to the index on the parent table and are dropped alongside it,
and cannot be dropped on isolation unless they are detached first.
To support pg_dump'ing these indexes, add commands
CREATE INDEX ON ONLY <table>
(which creates the index on the parent partitioned table, without
recursing) and
ALTER INDEX ATTACH PARTITION
(which is used after the indexes have been created individually on each
partition, to attach them to the parent index). These reconstruct prior
database state exactly.
Reviewed-by: (in alphabetical order) Peter Eisentraut, Robert Haas, Amit
Langote, Jesper Pedersen, Simon Riggs, David Rowley
Discussion: https://postgr.es/m/20171113170646.gzweigyrgg6pwsg4@alvherre.pgsql
2018-01-19 15:49:22 +01:00
as if <command>ALTER INDEX ATTACH PARTITION</command> had been executed.
2019-04-05 13:55:06 +02:00
Note that if the existing table is a foreign table, it is currently not
allowed to attach the table as a partition of the target table if there
2019-06-27 00:38:51 +02:00
are <literal>UNIQUE</literal> indexes on the target table. (See also
2020-04-21 23:14:18 +02:00
<xref linkend="sql-createforeigntable"/>.) For each user-defined
row-level trigger that exists in the target table, a corresponding one
is created in the attached table.
Allow a partitioned table to have a default partition.
Any tuples that don't route to any other partition will route to the
default partition.
Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, and Robert
Haas, with review and testing at various stages by (at least) Rushabh
Lathia, Keith Fiske, Amit Langote, Amul Sul, Rajkumar Raghuanshi, Sven
Kunze, Kyotaro Horiguchi, Thom Brown, Rafia Sabih, and Dilip Kumar.
Discussion: http://postgr.es/m/CAH2L28tbN4SYyhS7YV1YBWcitkqbhSWfQCy0G=apRcC_PEO-bg@mail.gmail.com
Discussion: http://postgr.es/m/CAOG9ApEYj34fWMcvBMBQ-YtqR9fTdXhdN82QEKG0SVZ6zeL1xg@mail.gmail.com
2017-09-08 23:28:04 +02:00
</para>
<para>
A partition using <literal>FOR VALUES</literal> uses same syntax for
2017-10-09 04:00:57 +02:00
<replaceable class="parameter">partition_bound_spec</replaceable> as
Improve <xref> vs. <command> formatting in the documentation
SQL commands are generally marked up as <command>, except when a link
to a reference page is used using <xref>. But the latter doesn't
create monospace markup, so this looks strange especially when a
paragraph contains a mix of links and non-links.
We considered putting <command> in the <refentrytitle> on the target
side, but that creates some formatting side effects elsewhere.
Generally, it seems safer to solve this on the link source side.
We can't put the <xref> inside the <command>; the DTD doesn't allow
this. DocBook 5 would allow the <command> to have the linkend
attribute itself, but we are not there yet.
So to solve this for now, convert the <xref>s to <link> plus
<command>. This gives the correct look and also gives some more
flexibility what we can put into the link text (e.g., subcommands or
other clauses). In the future, these could then be converted to
DocBook 5 style.
I haven't converted absolutely all xrefs to SQL command reference
pages, only those where we care about the appearance of the link text
or where it was otherwise appropriate to make the appearance match a
bit better. Also in some cases, the links where repetitive, so in
those cases the links where just removed and replaced by a plain
<command>. In cases where we just want the link and don't
specifically care about the generated link text (typically phrased
"for further information see <xref ...>") the xref is kept.
Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://www.postgresql.org/message-id/flat/87o8pco34z.fsf@wibble.ilmari.org
2020-10-03 16:16:51 +02:00
<link linkend="sql-createtable"><command>CREATE TABLE</command></link>. The partition bound specification
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
must correspond to the partitioning strategy and partition key of the
target table. The table to be attached must have all the same columns
as the target table and no more; moreover, the column types must also
match. Also, it must have all the <literal>NOT NULL</literal> and
<literal>CHECK</literal> constraints of the target table. Currently
<literal>FOREIGN KEY</literal> constraints are not considered.
2018-02-19 20:59:37 +01:00
<literal>UNIQUE</literal> and <literal>PRIMARY KEY</literal> constraints
from the parent table will be created in the partition, if they don't
already exist.
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
If any of the <literal>CHECK</literal> constraints of the table being
2020-09-10 08:50:19 +02:00
attached are marked <literal>NO INHERIT</literal>, the command will fail;
2019-11-05 02:17:33 +01:00
such constraints must be recreated without the
<literal>NO INHERIT</literal> clause.
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</para>
<para>
2017-03-09 19:09:48 +01:00
If the new partition is a regular table, a full table scan is performed
2019-11-05 02:17:33 +01:00
to check that existing rows in the table do not violate the partition
constraint. It is possible to avoid this scan by adding a valid
<literal>CHECK</literal> constraint to the table that allows only
rows satisfying the desired partition constraint before running this
command. The <literal>CHECK</literal> constraint will be used to
determine that the table need not be scanned to validate the partition
constraint. This does not work, however, if any of the partition keys
is an expression and the partition does not accept
<literal>NULL</literal> values. If attaching a list partition that will
2023-01-03 08:26:14 +01:00
not accept <literal>NULL</literal> values, also add a
2019-11-05 02:17:33 +01:00
<literal>NOT NULL</literal> constraint to the partition key column,
unless it's an expression.
2017-03-09 19:09:48 +01:00
</para>
<para>
If the new partition is a foreign table, nothing is done to verify
that all the rows in the foreign table obey the partition constraint.
2017-11-23 15:39:47 +01:00
(See the discussion in <xref linkend="sql-createforeigntable"/> about
2017-03-09 19:09:48 +01:00
constraints on the foreign table.)
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</para>
Allow a partitioned table to have a default partition.
Any tuples that don't route to any other partition will route to the
default partition.
Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, and Robert
Haas, with review and testing at various stages by (at least) Rushabh
Lathia, Keith Fiske, Amit Langote, Amul Sul, Rajkumar Raghuanshi, Sven
Kunze, Kyotaro Horiguchi, Thom Brown, Rafia Sabih, and Dilip Kumar.
Discussion: http://postgr.es/m/CAH2L28tbN4SYyhS7YV1YBWcitkqbhSWfQCy0G=apRcC_PEO-bg@mail.gmail.com
Discussion: http://postgr.es/m/CAOG9ApEYj34fWMcvBMBQ-YtqR9fTdXhdN82QEKG0SVZ6zeL1xg@mail.gmail.com
2017-09-08 23:28:04 +02:00
<para>
When a table has a default partition, defining a new partition changes
the partition constraint for the default partition. The default
partition can't contain any rows that would need to be moved to the new
partition, and will be scanned to verify that none are present. This
scan, like the scan of the new partition, can be avoided if an
appropriate <literal>CHECK</literal> constraint is present. Also like
the scan of the new partition, it is always skipped when the default
partition is a foreign table.
</para>
2019-11-05 02:32:38 +01:00
<para>
Attaching a partition acquires a
<literal>SHARE UPDATE EXCLUSIVE</literal> lock on the parent table,
2021-07-28 05:02:37 +02:00
in addition to the <literal>ACCESS EXCLUSIVE</literal> locks on the table
being attached and on the default partition (if any).
</para>
<para>
Further locks must also be held on all sub-partitions if the table being
attached is itself a partitioned table. Likewise if the default
partition is itself a partitioned table. The locking of the
sub-partitions can be avoided by adding a <literal>CHECK</literal>
constraint as described in
<xref linkend="ddl-partitioning-declarative-maintenance"/>.
2019-11-05 02:32:38 +01:00
</para>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</listitem>
</varlistentry>
2021-05-06 22:42:30 +02:00
<varlistentry id="sql-altertable-detach-partition">
ALTER TABLE ... DETACH PARTITION ... CONCURRENTLY
Allow a partition be detached from its partitioned table without
blocking concurrent queries, by running in two transactions and only
requiring ShareUpdateExclusive in the partitioned table.
Because it runs in two transactions, it cannot be used in a transaction
block. This is the main reason to use dedicated syntax: so that users
can choose to use the original mode if they need it. But also, it
doesn't work when a default partition exists (because an exclusive lock
would still need to be obtained on it, in order to change its partition
constraint.)
In case the second transaction is cancelled or a crash occurs, there's
ALTER TABLE .. DETACH PARTITION .. FINALIZE, which executes the final
steps.
The main trick to make this work is the addition of column
pg_inherits.inhdetachpending, initially false; can only be set true in
the first part of this command. Once that is committed, concurrent
transactions that use a PartitionDirectory will include or ignore
partitions so marked: in optimizer they are ignored if the row is marked
committed for the snapshot; in executor they are always included. As a
result, and because of the way PartitionDirectory caches partition
descriptors, queries that were planned before the detach will see the
rows in the detached partition and queries that are planned after the
detach, won't.
A CHECK constraint is created that duplicates the partition constraint.
This is probably not strictly necessary, and some users will prefer to
remove it afterwards, but if the partition is re-attached to a
partitioned table, the constraint needn't be rechecked.
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Amit Langote <amitlangote09@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/20200803234854.GA24158@alvherre.pgsql
2021-03-25 22:00:28 +01:00
<term><literal>DETACH PARTITION <replaceable class="parameter">partition_name</replaceable> [ CONCURRENTLY | FINALIZE ]</literal></term>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<listitem>
<para>
2020-04-21 23:14:18 +02:00
This form detaches the specified partition of the target table. The detached
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
partition continues to exist as a standalone table, but no longer has any
Local partitioned indexes
When CREATE INDEX is run on a partitioned table, create catalog entries
for an index on the partitioned table (which is just a placeholder since
the table proper has no data of its own), and recurse to create actual
indexes on the existing partitions; create them in future partitions
also.
As a convenience gadget, if the new index definition matches some
existing index in partitions, these are picked up and used instead of
creating new ones. Whichever way these indexes come about, they become
attached to the index on the parent table and are dropped alongside it,
and cannot be dropped on isolation unless they are detached first.
To support pg_dump'ing these indexes, add commands
CREATE INDEX ON ONLY <table>
(which creates the index on the parent partitioned table, without
recursing) and
ALTER INDEX ATTACH PARTITION
(which is used after the indexes have been created individually on each
partition, to attach them to the parent index). These reconstruct prior
database state exactly.
Reviewed-by: (in alphabetical order) Peter Eisentraut, Robert Haas, Amit
Langote, Jesper Pedersen, Simon Riggs, David Rowley
Discussion: https://postgr.es/m/20171113170646.gzweigyrgg6pwsg4@alvherre.pgsql
2018-01-19 15:49:22 +01:00
ties to the table from which it was detached. Any indexes that were
2020-04-21 23:14:18 +02:00
attached to the target table's indexes are detached. Any triggers that
were created as clones of those in the target table are removed.
2021-03-25 20:30:22 +01:00
<literal>SHARE</literal> lock is obtained on any tables that reference
this partitioned table in foreign key constraints.
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</para>
ALTER TABLE ... DETACH PARTITION ... CONCURRENTLY
Allow a partition be detached from its partitioned table without
blocking concurrent queries, by running in two transactions and only
requiring ShareUpdateExclusive in the partitioned table.
Because it runs in two transactions, it cannot be used in a transaction
block. This is the main reason to use dedicated syntax: so that users
can choose to use the original mode if they need it. But also, it
doesn't work when a default partition exists (because an exclusive lock
would still need to be obtained on it, in order to change its partition
constraint.)
In case the second transaction is cancelled or a crash occurs, there's
ALTER TABLE .. DETACH PARTITION .. FINALIZE, which executes the final
steps.
The main trick to make this work is the addition of column
pg_inherits.inhdetachpending, initially false; can only be set true in
the first part of this command. Once that is committed, concurrent
transactions that use a PartitionDirectory will include or ignore
partitions so marked: in optimizer they are ignored if the row is marked
committed for the snapshot; in executor they are always included. As a
result, and because of the way PartitionDirectory caches partition
descriptors, queries that were planned before the detach will see the
rows in the detached partition and queries that are planned after the
detach, won't.
A CHECK constraint is created that duplicates the partition constraint.
This is probably not strictly necessary, and some users will prefer to
remove it afterwards, but if the partition is re-attached to a
partitioned table, the constraint needn't be rechecked.
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Amit Langote <amitlangote09@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/20200803234854.GA24158@alvherre.pgsql
2021-03-25 22:00:28 +01:00
<para>
If <literal>CONCURRENTLY</literal> is specified, it runs using a reduced
lock level to avoid blocking other sessions that might be accessing the
partitioned table. In this mode, two transactions are used internally.
During the first transaction, a <literal>SHARE UPDATE EXCLUSIVE</literal>
lock is taken on both parent table and partition, and the partition is
marked as undergoing detach; at that point, the transaction is committed
and all other transactions using the partitioned table are waited for.
Once all those transactions have completed, the second transaction
acquires <literal>SHARE UPDATE EXCLUSIVE</literal> on the partitioned
table and <literal>ACCESS EXCLUSIVE</literal> on the partition,
and the detach process completes. A <literal>CHECK</literal> constraint
that duplicates the partition constraint is added to the partition.
<literal>CONCURRENTLY</literal> cannot be run in a transaction block and
is not allowed if the partitioned table contains a default partition.
</para>
<para>
If <literal>FINALIZE</literal> is specified, a previous
2021-07-16 10:35:38 +02:00
<literal>DETACH CONCURRENTLY</literal> invocation that was canceled or
ALTER TABLE ... DETACH PARTITION ... CONCURRENTLY
Allow a partition be detached from its partitioned table without
blocking concurrent queries, by running in two transactions and only
requiring ShareUpdateExclusive in the partitioned table.
Because it runs in two transactions, it cannot be used in a transaction
block. This is the main reason to use dedicated syntax: so that users
can choose to use the original mode if they need it. But also, it
doesn't work when a default partition exists (because an exclusive lock
would still need to be obtained on it, in order to change its partition
constraint.)
In case the second transaction is cancelled or a crash occurs, there's
ALTER TABLE .. DETACH PARTITION .. FINALIZE, which executes the final
steps.
The main trick to make this work is the addition of column
pg_inherits.inhdetachpending, initially false; can only be set true in
the first part of this command. Once that is committed, concurrent
transactions that use a PartitionDirectory will include or ignore
partitions so marked: in optimizer they are ignored if the row is marked
committed for the snapshot; in executor they are always included. As a
result, and because of the way PartitionDirectory caches partition
descriptors, queries that were planned before the detach will see the
rows in the detached partition and queries that are planned after the
detach, won't.
A CHECK constraint is created that duplicates the partition constraint.
This is probably not strictly necessary, and some users will prefer to
remove it afterwards, but if the partition is re-attached to a
partitioned table, the constraint needn't be rechecked.
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Amit Langote <amitlangote09@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/20200803234854.GA24158@alvherre.pgsql
2021-03-25 22:00:28 +01:00
interrupted is completed.
2021-04-28 21:44:35 +02:00
At most one partition in a partitioned table can be pending detach at
a time.
ALTER TABLE ... DETACH PARTITION ... CONCURRENTLY
Allow a partition be detached from its partitioned table without
blocking concurrent queries, by running in two transactions and only
requiring ShareUpdateExclusive in the partitioned table.
Because it runs in two transactions, it cannot be used in a transaction
block. This is the main reason to use dedicated syntax: so that users
can choose to use the original mode if they need it. But also, it
doesn't work when a default partition exists (because an exclusive lock
would still need to be obtained on it, in order to change its partition
constraint.)
In case the second transaction is cancelled or a crash occurs, there's
ALTER TABLE .. DETACH PARTITION .. FINALIZE, which executes the final
steps.
The main trick to make this work is the addition of column
pg_inherits.inhdetachpending, initially false; can only be set true in
the first part of this command. Once that is committed, concurrent
transactions that use a PartitionDirectory will include or ignore
partitions so marked: in optimizer they are ignored if the row is marked
committed for the snapshot; in executor they are always included. As a
result, and because of the way PartitionDirectory caches partition
descriptors, queries that were planned before the detach will see the
rows in the detached partition and queries that are planned after the
detach, won't.
A CHECK constraint is created that duplicates the partition constraint.
This is probably not strictly necessary, and some users will prefer to
remove it afterwards, but if the partition is re-attached to a
partitioned table, the constraint needn't be rechecked.
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reviewed-by: Amit Langote <amitlangote09@gmail.com>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/20200803234854.GA24158@alvherre.pgsql
2021-03-25 22:00:28 +01:00
</para>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</listitem>
</varlistentry>
2024-04-06 23:58:09 +02:00
<varlistentry id="sql-altertable-split-partition">
<term><literal>SPLIT PARTITION <replaceable class="parameter">partition_name</replaceable> INTO (PARTITION <replaceable class="parameter">partition_name1</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }, PARTITION <replaceable class="parameter">partition_name2</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } [, ...])</literal></term>
<listitem>
<para>
This form splits a single partition of the target table. Hash-partitioning
is not supported. Bounds of new partitions should not overlap with new and
existing partitions (except <replaceable class="parameter">partition_name</replaceable>).
If the split partition is a DEFAULT partition, one of the new partitions must be DEFAULT.
In case one of the new partitions or one of existing partitions is DEFAULT,
new partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable>, ... can have spaces
between partitions bounds. If the partitioned table does not have a DEFAULT
partition, the DEFAULT partition can be defined as one of the new partitions.
</para>
<para>
In case new partitions do not contain a DEFAULT partition and the partitioned table
does not have a DEFAULT partition, the following must be true: sum bounds of
new partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable>, ... should be
equal to bound of split partition <replaceable class="parameter">partition_name</replaceable>.
One of the new partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable>, ... can have
the same name as split partition <replaceable class="parameter">partition_name</replaceable>
(this is suitable in case of splitting a DEFAULT partition: we split it, but after
splitting we have a partition with the same name).
Only simple, non-partitioned partition can be split.
</para>
<note>
<para>
This command acquires an <literal>ACCESS EXCLUSIVE</literal> lock.
This is a significant limitation, which limits the usage of this
command with large partitioned tables under a high load.
</para>
</note>
</listitem>
</varlistentry>
2024-04-06 23:57:22 +02:00
<varlistentry id="sql-altertable-merge-partitions">
<term><literal>MERGE PARTITIONS (<replaceable class="parameter">partition_name1</replaceable>, <replaceable class="parameter">partition_name2</replaceable> [, ...]) INTO <replaceable class="parameter">partition_name</replaceable></literal></term>
<listitem>
<para>
This form merges several partitions into the one partition of the target table.
Hash-partitioning is not supported. If DEFAULT partition is not in the
list of partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable> [, ...]:
<itemizedlist>
<listitem>
<para>
For range-partitioned tables is necessary that the ranges
of the partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable> [, ...] can
be merged into one range without spaces and overlaps (otherwise an error
will be generated). The combined range will be the range for the partition
<replaceable class="parameter">partition_name</replaceable>.
</para>
</listitem>
<listitem>
<para>
For list-partitioned tables the values lists of all partitions
<replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable> [, ...] are
combined and form a list of values of partition
<replaceable class="parameter">partition_name</replaceable>.
</para>
</listitem>
</itemizedlist>
If DEFAULT partition is in the list of partitions <replaceable class="parameter">partition_name1</replaceable>,
<replaceable class="parameter">partition_name2</replaceable> [, ...]:
<itemizedlist>
<listitem>
<para>
The partition <replaceable class="parameter">partition_name</replaceable>
will be the DEFAULT partition.
</para>
</listitem>
<listitem>
<para>
For range- and list-partitioned tables the ranges and lists of values
of the merged partitions can be any.
</para>
</listitem>
</itemizedlist>
The new partition <replaceable class="parameter">partition_name</replaceable>
can have the same name as one of the merged partitions. Only simple,
non-partitioned partitions can be merged.
</para>
<note>
<para>
This command acquires an <literal>ACCESS EXCLUSIVE</literal> lock.
This is a significant limitation, which limits the usage of this
command with large partitioned tables under a high load.
</para>
</note>
</listitem>
</varlistentry>
2002-04-23 04:07:16 +02:00
</variablelist>
2003-04-15 15:25:08 +02:00
</para>
2002-04-23 04:07:16 +02:00
2004-05-05 06:48:48 +02:00
<para>
2016-12-21 21:03:32 +01:00
All the forms of ALTER TABLE that act on a single table, except
<literal>RENAME</literal>, <literal>SET SCHEMA</literal>,
2024-04-06 23:57:22 +02:00
<literal>ATTACH PARTITION</literal>, <literal>DETACH PARTITION</literal>,
2024-04-06 23:58:09 +02:00
<literal>SPLIT PARTITION</literal>, and <literal>MERGE PARTITIONS</literal>
can be combined into
2016-12-21 21:03:32 +01:00
a list of multiple alterations to be applied together. For example, it
2004-05-05 06:48:48 +02:00
is possible to add several columns and/or alter the type of several
columns in a single command. This is particularly useful with large
tables, since only one pass over the table need be made.
</para>
1999-07-06 19:16:42 +02:00
<para>
2017-10-09 03:44:17 +02:00
You must own the table to use <command>ALTER TABLE</command>.
2014-08-22 01:06:17 +02:00
To change the schema or tablespace of a table, you must also have
<literal>CREATE</literal> privilege on the new schema or tablespace.
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
To add the table as a new child of a parent table, you must own the parent
table as well. Also, to attach a table as a new partition of the table,
you must own the table being attached.
2023-01-16 16:35:29 +01:00
To alter the owner, you must be able to <literal>SET ROLE</literal> to the
new owning role, and that role must have <literal>CREATE</literal>
privilege on the table's schema.
(These restrictions enforce that altering the owner
2005-08-24 19:24:19 +02:00
doesn't do anything you couldn't do by dropping and recreating the table.
However, a superuser can alter ownership of any table anyway.)
2011-12-19 23:05:19 +01:00
To add a column or alter a column type or use the <literal>OF</literal>
clause, you must also have <literal>USAGE</literal> privilege on the data
type.
1999-07-06 19:16:42 +02:00
</para>
2003-04-15 15:25:08 +02:00
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-if-exists">
2015-04-24 19:22:18 +02:00
<term><literal>IF EXISTS</literal></term>
<listitem>
<para>
Do not throw an error if the table does not exist. A notice is issued
in this case.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-name">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">name</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2012-09-17 20:59:31 +02:00
The name (optionally schema-qualified) of an existing table to
2017-10-09 03:44:17 +02:00
alter. If <literal>ONLY</literal> is specified before the table name, only
that table is altered. If <literal>ONLY</literal> is not specified, the table
2012-09-17 20:59:31 +02:00
and all its descendant tables (if any) are altered. Optionally,
2017-10-09 03:44:17 +02:00
<literal>*</literal> can be specified after the table name to explicitly
2012-09-17 20:59:31 +02:00
indicate that descendant tables are included.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-column-name">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">column_name</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2005-01-04 01:39:53 +01:00
Name of a new or existing column.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-new-column-name">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">new_column_name</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2005-01-04 01:39:53 +01:00
New name for an existing column.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-new-name">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">new_name</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2005-01-04 01:39:53 +01:00
New name for the table.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-data-type">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">data_type</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2005-01-04 01:39:53 +01:00
Data type of the new column, or new data type for an existing
column.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-table-constraint">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">table_constraint</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2005-01-04 01:39:53 +01:00
New table constraint for the table.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-constraint-name">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">constraint_name</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2014-04-14 16:52:07 +02:00
Name of a new or existing constraint.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-cascade">
2004-07-12 01:13:58 +02:00
<term><literal>CASCADE</literal></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2004-07-12 01:13:58 +02:00
Automatically drop objects that depend on the dropped column
2016-08-13 00:45:18 +02:00
or constraint (for example, views referencing the column),
and in turn all objects that depend on those objects
2017-11-23 15:39:47 +01:00
(see <xref linkend="ddl-depend"/>).
2004-07-12 01:13:58 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-restrict">
2004-07-12 01:13:58 +02:00
<term><literal>RESTRICT</literal></term>
<listitem>
<para>
Refuse to drop the column or constraint if there are any dependent
2005-01-04 01:39:53 +01:00
objects. This is the default behavior.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-trigger-name">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">trigger_name</replaceable></term>
2005-08-24 19:24:19 +02:00
<listitem>
<para>
Name of a single trigger to disable or enable.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-all">
2005-08-24 19:24:19 +02:00
<term><literal>ALL</literal></term>
<listitem>
<para>
Disable or enable all triggers belonging to the table.
2010-06-09 19:48:10 +02:00
(This requires superuser privilege if any of the triggers are
2023-03-04 19:32:35 +01:00
internally generated constraint triggers, such as those that are used
2010-06-09 19:48:10 +02:00
to implement foreign key constraints or deferrable uniqueness and
exclusion constraints.)
2005-08-24 19:24:19 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-user">
2005-08-24 19:24:19 +02:00
<term><literal>USER</literal></term>
<listitem>
<para>
Disable or enable all triggers belonging to the table except for
2023-03-04 19:32:35 +01:00
internally generated constraint triggers, such as those that are used
2010-06-09 19:48:10 +02:00
to implement foreign key constraints or deferrable uniqueness and
exclusion constraints.
2005-08-24 19:24:19 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-index-name">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">index_name</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2014-04-28 16:10:51 +02:00
The name of an existing index.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-storage-parameter">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">storage_parameter</replaceable></term>
2006-07-04 20:07:24 +02:00
<listitem>
<para>
The name of a table storage parameter.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-value">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">value</replaceable></term>
2006-07-04 20:07:24 +02:00
<listitem>
<para>
The new value for a table storage parameter.
This might be a number or a word depending on the parameter.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-parent-table">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">parent_table</replaceable></term>
2006-07-04 20:07:24 +02:00
<listitem>
<para>
A parent table to associate or de-associate with this table.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-new-owner">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">new_owner</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2005-01-04 01:39:53 +01:00
The user name of the new owner of the table.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-new-access-method">
2021-07-28 03:10:44 +02:00
<term><replaceable class="parameter">new_access_method</replaceable></term>
<listitem>
<para>
The name of the access method to which the table will be converted.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-new-tablespace">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">new_tablespace</replaceable></term>
2005-08-01 18:11:14 +02:00
<listitem>
<para>
The name of the tablespace to which the table will be moved.
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-new-schema">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">new_schema</replaceable></term>
2003-04-15 15:25:08 +02:00
<listitem>
<para>
2005-08-01 18:11:14 +02:00
The name of the schema to which the table will be moved.
2003-04-15 15:25:08 +02:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-partition-name">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">partition_name</replaceable></term>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<listitem>
<para>
2024-04-06 23:57:22 +02:00
The name of the table to attach as a new partition or to detach from this table,
2024-04-06 23:58:09 +02:00
or the name of split partition, or the name of the new merged partition.
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</para>
</listitem>
</varlistentry>
2023-01-09 21:08:24 +01:00
<varlistentry id="sql-altertable-parms-partition-bound-spec">
2017-10-09 04:00:57 +02:00
<term><replaceable class="parameter">partition_bound_spec</replaceable></term>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<listitem>
<para>
The partition bound specification for a new partition. Refer to
2017-11-23 15:39:47 +01:00
<xref linkend="sql-createtable"/> for more details on the syntax of the same.
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</para>
</listitem>
</varlistentry>
2003-04-15 15:25:08 +02:00
</variablelist>
</refsect1>
Doc: fix "Unresolved ID reference" warnings, clean up man page cross-refs.
Use xreflabel attributes instead of endterm attributes to control the
appearance of links to subsections of SQL command reference pages.
This is simpler, it matches what we do elsewhere (e.g. for GUC variables),
and it doesn't draw "Unresolved ID reference" warnings from the PDF
toolchain.
Fix some places where the text was absolutely dependent on an <xref>
rendering exactly so, by using a <link> around the required text
instead. At least one of those spots had already been turned into
bad grammar by subsequent changes, and the whole idea is just too
fragile for my taste. <xref> does NOT have fixed output, don't write
as if it does.
Consistently include a page-level link in cross-man-page references,
because otherwise they are useless/nonsensical in man-page output.
Likewise, be consistent about mentioning "below" or "above" in same-page
references; we were doing that in about 90% of the cases, but now it's
100%.
Also get rid of another nonfunctional-in-PDF idea, of making
cross-references to functions by sticking ID tags on <row> constructs.
We can put the IDs on <indexterm>s instead --- which is probably not any
more sensible in abstract terms, but it works where the other doesn't.
(There is talk of attaching cross-reference IDs to most or all of
the docs' function descriptions, but for now I just fixed the two
that exist.)
Discussion: https://postgr.es/m/14480.1589154358@sss.pgh.pa.us
2020-05-11 20:15:49 +02:00
<refsect1 id="sql-altertable-notes" xreflabel="Notes">
<title>Notes</title>
1999-07-06 19:16:42 +02:00
<para>
2003-04-15 15:25:08 +02:00
The key word <literal>COLUMN</literal> is noise and can be omitted.
1999-07-06 19:16:42 +02:00
</para>
1998-05-13 07:34:00 +02:00
1999-07-22 17:09:15 +02:00
<para>
2018-03-28 02:13:52 +02:00
When a column is added with <literal>ADD COLUMN</literal> and a
non-volatile <literal>DEFAULT</literal> is specified, the default is
evaluated at the time of the statement and the result stored in the
table's metadata. That value will be used for the column for all existing
rows. If no <literal>DEFAULT</literal> is specified, NULL is used. In
neither case is a rewrite of the table required.
2004-05-05 06:48:48 +02:00
</para>
<para>
2018-03-28 02:13:52 +02:00
Adding a column with a volatile <literal>DEFAULT</literal> or
changing the type of an existing column will require the entire table and
its indexes to be rewritten. As an exception, when changing the type of an
existing column, if the <literal>USING</literal> clause does not change
the column contents and the old type is either binary coercible to the new
type or an unconstrained domain over the new type, a table rewrite is not
2022-04-01 14:48:44 +02:00
needed. However, indexes must always be rebuilt unless the system can
verify that the new index would be logically equivalent to the existing
2023-01-03 08:26:14 +01:00
one. For example, if the collation for a column has been changed, an index
2022-04-01 14:48:44 +02:00
rebuild is always required because the new sort order might be different.
However, in the absence of a collation change, a column can be changed
from <type>text</type> to <type>varchar</type> (or vice versa) without
rebuilding the indexes because these data types sort identically.
2018-12-07 20:50:46 +01:00
Table and/or index rebuilds may take a
2018-03-28 02:13:52 +02:00
significant amount of time for a large table; and will temporarily require
as much as double the disk space.
2004-05-05 06:48:48 +02:00
</para>
<para>
2017-10-09 03:44:17 +02:00
Adding a <literal>CHECK</literal> or <literal>NOT NULL</literal> constraint requires
2015-08-15 19:30:16 +02:00
scanning the table to verify that existing rows meet the constraint,
but does not require a table rewrite.
2004-05-05 06:48:48 +02:00
</para>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<para>
Similarly, when attaching a new partition it may be scanned to verify that
existing rows meet the partition constraint.
</para>
2004-05-05 06:48:48 +02:00
<para>
The main reason for providing the option to specify multiple changes
2017-10-09 03:44:17 +02:00
in a single <command>ALTER TABLE</command> is that multiple table scans or
2004-05-05 06:48:48 +02:00
rewrites can thereby be combined into a single pass over the table.
1999-07-22 17:09:15 +02:00
</para>
2002-08-02 20:15:10 +02:00
<para>
2018-12-07 22:40:58 +01:00
Scanning a large table to verify a new foreign key or check constraint
can take a long time, and other updates to the table are locked out
until the <command>ALTER TABLE ADD CONSTRAINT</command> command is
committed. The main purpose of the <literal>NOT VALID</literal>
constraint option is to reduce the impact of adding a constraint on
concurrent updates. With <literal>NOT VALID</literal>,
the <command>ADD CONSTRAINT</command> command does not scan the table
and can be committed immediately. After that, a <literal>VALIDATE
CONSTRAINT</literal> command can be issued to verify that existing rows
satisfy the constraint. The validation step does not need to lock out
concurrent updates, since it knows that other transactions will be
enforcing the constraint for rows that they insert or update; only
pre-existing rows need to be checked. Hence, validation acquires only
a <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the table being
altered. (If the constraint is a foreign key then a <literal>ROW
SHARE</literal> lock is also required on the table referenced by the
constraint.) In addition to improving concurrency, it can be useful to
use <literal>NOT VALID</literal> and <literal>VALIDATE
CONSTRAINT</literal> in cases where the table is known to contain
pre-existing violations. Once the constraint is in place, no new
violations can be inserted, and the existing problems can be corrected
at leisure until <literal>VALIDATE CONSTRAINT</literal> finally
succeeds.
</para>
<para>
2003-04-15 15:25:08 +02:00
The <literal>DROP COLUMN</literal> form does not physically remove
2002-08-02 20:15:10 +02:00
the column, but simply makes it invisible to SQL operations. Subsequent
2004-05-27 05:30:11 +02:00
insert and update operations in the table will store a null value for the
column. Thus, dropping a column is quick but it will not immediately
2009-02-11 22:11:16 +01:00
reduce the on-disk size of your table, as the space occupied
2002-08-02 20:15:10 +02:00
by the dropped column is not reclaimed. The space will be
2018-12-07 20:50:46 +01:00
reclaimed over time as existing rows are updated.
2004-05-27 05:30:11 +02:00
</para>
<para>
2015-08-15 19:30:16 +02:00
To force immediate reclamation of space occupied by a dropped column,
2017-10-09 03:44:17 +02:00
you can execute one of the forms of <command>ALTER TABLE</command> that
2015-08-15 19:30:16 +02:00
performs a rewrite of the whole table. This results in reconstructing
each row with the dropped column replaced by a null value.
</para>
<para>
2017-10-09 03:44:17 +02:00
The rewriting forms of <command>ALTER TABLE</command> are not MVCC-safe.
2015-08-15 19:30:16 +02:00
After a table rewrite, the table will appear empty to concurrent
transactions, if they are using a snapshot taken before the rewrite
2017-11-23 15:39:47 +01:00
occurred. See <xref linkend="mvcc-caveats"/> for more details.
2002-08-02 20:15:10 +02:00
</para>
2004-10-22 19:20:05 +02:00
<para>
2017-10-09 03:44:17 +02:00
The <literal>USING</literal> option of <literal>SET DATA TYPE</literal> can actually
2004-10-22 19:20:05 +02:00
specify any expression involving the old values of the row; that is, it
can refer to other columns as well as the one being converted. This allows
2017-10-09 03:44:17 +02:00
very general conversions to be done with the <literal>SET DATA TYPE</literal>
2004-10-22 19:20:05 +02:00
syntax. Because of this flexibility, the <literal>USING</literal>
expression is not applied to the column's default value (if any); the
result might not be a constant expression as required for a default.
This means that when there is no implicit or assignment cast from old to
2017-10-09 03:44:17 +02:00
new type, <literal>SET DATA TYPE</literal> might fail to convert the default even
2004-10-22 19:20:05 +02:00
though a <literal>USING</literal> clause is supplied. In such cases,
2017-10-09 03:44:17 +02:00
drop the default with <literal>DROP DEFAULT</literal>, perform the <literal>ALTER
TYPE</literal>, and then use <literal>SET DEFAULT</literal> to add a suitable new
2005-01-04 01:39:53 +01:00
default. Similar considerations apply to indexes and constraints involving
the column.
2004-10-22 19:20:05 +02:00
</para>
2002-10-20 00:51:45 +02:00
<para>
2004-05-05 06:48:48 +02:00
If a table has any descendant tables, it is not permitted to add,
2016-09-15 23:24:54 +02:00
rename, or change the type of a column in the parent table without doing
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
the same to the descendants. This ensures that the descendants always
have columns matching the parent. Similarly, a <literal>CHECK</literal>
constraint cannot be renamed in the parent without also renaming it in
all descendants, so that <literal>CHECK</literal> constraints also match
between the parent and its descendants. (That restriction does not apply
to index-based constraints, however.)
2016-12-23 17:53:35 +01:00
Also, because selecting from the parent also selects from its descendants,
2016-09-15 23:24:54 +02:00
a constraint on the parent cannot be marked valid unless it is also marked
2016-12-23 17:53:35 +01:00
valid for those descendants. In all of these cases, <command>ALTER TABLE
2016-12-17 18:00:00 +01:00
ONLY</command> will be rejected.
2002-10-20 00:51:45 +02:00
</para>
<para>
2003-02-19 05:06:28 +01:00
A recursive <literal>DROP COLUMN</literal> operation will remove a
descendant table's column only if the descendant does not inherit
that column from any other parents and never had an independent
definition of the column. A nonrecursive <literal>DROP
COLUMN</literal> (i.e., <command>ALTER TABLE ONLY ... DROP
COLUMN</command>) never removes any descendant columns, but
instead marks them as independently defined rather than inherited.
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
A nonrecursive <literal>DROP COLUMN</literal> command will fail for a
partitioned table, because all partitions of a table must have the same
columns as the partitioning root.
2002-10-20 00:51:45 +02:00
</para>
2005-08-24 19:24:19 +02:00
<para>
2017-04-06 14:33:16 +02:00
The actions for identity columns (<literal>ADD
GENERATED</literal>, <literal>SET</literal> etc., <literal>DROP
IDENTITY</literal>), as well as the actions
2023-03-04 19:32:35 +01:00
<literal>CLUSTER</literal>, <literal>OWNER</literal>,
2017-10-09 03:44:17 +02:00
and <literal>TABLESPACE</literal> never recurse to descendant tables;
that is, they always act as though <literal>ONLY</literal> were specified.
2023-03-04 19:32:35 +01:00
Actions affecting trigger states recurse to partitions of partitioned
tables (unless <literal>ONLY</literal> is specified), but never to
traditional-inheritance descendants.
2017-10-09 03:44:17 +02:00
Adding a constraint recurses only for <literal>CHECK</literal> constraints
that are not marked <literal>NO INHERIT</literal>.
2005-08-24 19:24:19 +02:00
</para>
1999-07-22 17:09:15 +02:00
<para>
2003-04-15 15:25:08 +02:00
Changing any part of a system catalog table is not permitted.
1999-07-06 19:16:42 +02:00
</para>
1998-05-13 07:34:00 +02:00
1999-07-06 19:16:42 +02:00
<para>
2017-11-23 15:39:47 +01:00
Refer to <xref linkend="sql-createtable"/> for a further description of valid
parameters. <xref linkend="ddl"/> has further information on
2003-01-19 01:13:31 +01:00
inheritance.
1999-07-06 19:16:42 +02:00
</para>
</refsect1>
1998-05-13 07:34:00 +02:00
2003-04-15 15:25:08 +02:00
<refsect1>
<title>Examples</title>
1999-07-06 19:16:42 +02:00
<para>
2002-01-20 23:19:57 +01:00
To add a column of type <type>varchar</type> to a table:
2003-04-15 15:25:08 +02:00
<programlisting>
ALTER TABLE distributors ADD COLUMN address varchar(30);
</programlisting>
Clarify behavior of adding and altering a column in same ALTER command.
The behavior of something like
ALTER TABLE transactions
ADD COLUMN status varchar(30) DEFAULT 'old',
ALTER COLUMN status SET default 'current';
is to fill existing table rows with 'old', not 'current'. That's
intentional and desirable for a couple of reasons:
* It makes the behavior the same whether you merge the sub-commands
into one ALTER command or give them separately;
* If we applied the new default while filling the table, there would
be no way to get the existing behavior in one SQL command.
The same reasoning applies in cases that add a column and then
manipulate its GENERATED/IDENTITY status in a second sub-command,
since the generation expression is really just a kind of default.
However, that wasn't very obvious (at least not to me; earlier in
the referenced discussion thread I'd thought it was a bug to be
fixed). And it certainly wasn't documented.
Hence, add documentation, code comments, and a test case to clarify
that this behavior is all intentional.
In passing, adjust ATExecAddColumn's defaults-related relkind check
so that it matches up exactly with ATRewriteTables, instead of being
effectively (though not literally) the negated inverse condition.
The reasoning can be explained a lot more concisely that way, too
(not to mention that the comment now matches the code, which it
did not before).
Discussion: https://postgr.es/m/10365.1558909428@sss.pgh.pa.us
2020-01-21 22:17:21 +01:00
That will cause all existing rows in the table to be filled with null
values for the new column.
</para>
<para>
To add a column with a non-null default:
<programlisting>
ALTER TABLE measurements
ADD COLUMN mtime timestamp with time zone DEFAULT now();
</programlisting>
Existing rows will be filled with the current time as the value of the
new column, and then new rows will receive the time of their insertion.
</para>
<para>
To add a column and fill it with a value different from the default to
be used later:
<programlisting>
ALTER TABLE transactions
ADD COLUMN status varchar(30) DEFAULT 'old',
ALTER COLUMN status SET default 'current';
</programlisting>
Existing rows will be filled with <literal>old</literal>, but then
the default for subsequent commands will be <literal>current</literal>.
The effects are the same as if the two sub-commands had been issued
in separate <command>ALTER TABLE</command> commands.
1999-07-06 19:16:42 +02:00
</para>
1998-05-13 07:34:00 +02:00
2002-08-02 20:15:10 +02:00
<para>
To drop a column from a table:
2003-04-15 15:25:08 +02:00
<programlisting>
2002-08-02 20:15:10 +02:00
ALTER TABLE distributors DROP COLUMN address RESTRICT;
2003-04-15 15:25:08 +02:00
</programlisting>
2002-08-02 20:15:10 +02:00
</para>
2004-05-05 06:48:48 +02:00
<para>
To change the types of two existing columns in one operation:
<programlisting>
ALTER TABLE distributors
ALTER COLUMN address TYPE varchar(80),
ALTER COLUMN name TYPE varchar(100);
</programlisting>
</para>
2005-01-14 02:16:52 +01:00
<para>
2015-09-11 03:22:21 +02:00
To change an integer column containing Unix timestamps to <type>timestamp
2005-01-14 02:16:52 +01:00
with time zone</type> via a <literal>USING</literal> clause:
<programlisting>
ALTER TABLE foo
2008-10-21 10:38:16 +02:00
ALTER COLUMN foo_timestamp SET DATA TYPE timestamp with time zone
2005-01-14 02:16:52 +01:00
USING
timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';
</programlisting>
</para>
2006-08-03 22:57:06 +02:00
<para>
The same, when the column has a default expression that won't automatically
2006-10-23 20:10:32 +02:00
cast to the new data type:
2006-08-03 22:57:06 +02:00
<programlisting>
ALTER TABLE foo
ALTER COLUMN foo_timestamp DROP DEFAULT,
ALTER COLUMN foo_timestamp TYPE timestamp with time zone
USING
timestamp with time zone 'epoch' + foo_timestamp * interval '1 second',
ALTER COLUMN foo_timestamp SET DEFAULT now();
</programlisting>
</para>
1999-07-06 19:16:42 +02:00
<para>
1998-05-13 07:34:00 +02:00
To rename an existing column:
2003-04-15 15:25:08 +02:00
<programlisting>
1999-07-06 19:16:42 +02:00
ALTER TABLE distributors RENAME COLUMN address TO city;
2003-04-15 15:25:08 +02:00
</programlisting>
1999-07-06 19:16:42 +02:00
</para>
1998-05-13 07:34:00 +02:00
1999-07-06 19:16:42 +02:00
<para>
1998-05-13 07:34:00 +02:00
To rename an existing table:
2003-04-15 15:25:08 +02:00
<programlisting>
1999-07-06 19:16:42 +02:00
ALTER TABLE distributors RENAME TO suppliers;
2003-04-15 15:25:08 +02:00
</programlisting>
1999-07-06 19:16:42 +02:00
</para>
2002-04-01 06:35:40 +02:00
2012-03-10 19:19:13 +01:00
<para>
To rename an existing constraint:
<programlisting>
ALTER TABLE distributors RENAME CONSTRAINT zipchk TO zip_check;
</programlisting>
</para>
2002-04-01 06:35:40 +02:00
<para>
2003-04-15 15:25:08 +02:00
To add a not-null constraint to a column:
<programlisting>
2002-04-01 06:35:40 +02:00
ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
2003-04-15 15:25:08 +02:00
</programlisting>
To remove a not-null constraint from a column:
<programlisting>
2002-04-01 06:35:40 +02:00
ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
2003-04-15 15:25:08 +02:00
</programlisting>
2002-04-01 06:35:40 +02:00
</para>
2000-04-11 16:43:54 +02:00
2009-02-11 22:11:16 +01:00
<para>
2008-05-10 01:32:05 +02:00
To add a check constraint to a table and all its children:
2003-04-15 15:25:08 +02:00
<programlisting>
2001-09-12 04:13:25 +02:00
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
2003-04-15 15:25:08 +02:00
</programlisting>
2001-05-09 15:27:15 +02:00
</para>
2011-12-05 19:10:18 +01:00
<para>
To add a check constraint only to a table and not to its children:
<programlisting>
2012-07-24 21:49:54 +02:00
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5) NO INHERIT;
2011-12-05 19:10:18 +01:00
</programlisting>
(The check constraint will not be inherited by future children, either.)
</para>
2009-02-11 22:11:16 +01:00
<para>
2001-05-30 15:01:08 +02:00
To remove a check constraint from a table and all its children:
2003-04-15 15:25:08 +02:00
<programlisting>
2002-07-12 20:43:19 +02:00
ALTER TABLE distributors DROP CONSTRAINT zipchk;
2003-04-15 15:25:08 +02:00
</programlisting>
2001-05-30 15:01:08 +02:00
</para>
2009-02-11 22:11:16 +01:00
<para>
2012-09-17 20:59:31 +02:00
To remove a check constraint from one table only:
2008-05-10 01:32:05 +02:00
<programlisting>
ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;
</programlisting>
(The check constraint remains in place for any child tables.)
</para>
2009-02-11 22:11:16 +01:00
<para>
2000-04-11 16:43:54 +02:00
To add a foreign key constraint to a table:
2003-04-15 15:25:08 +02:00
<programlisting>
2011-09-10 15:24:05 +02:00
ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address);
2014-04-06 17:13:43 +02:00
</programlisting>
</para>
<para>
To add a foreign key constraint to a table with the least impact on other work:
<programlisting>
ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address) NOT VALID;
ALTER TABLE distributors VALIDATE CONSTRAINT distfk;
2003-04-15 15:25:08 +02:00
</programlisting>
2000-04-11 16:43:54 +02:00
</para>
2001-09-07 23:57:53 +02:00
2009-02-11 22:11:16 +01:00
<para>
2002-01-20 23:19:57 +01:00
To add a (multicolumn) unique constraint to a table:
2003-04-15 15:25:08 +02:00
<programlisting>
2001-09-12 04:13:25 +02:00
ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);
2003-04-15 15:25:08 +02:00
</programlisting>
2002-02-17 12:50:09 +01:00
</para>
2009-02-11 22:11:16 +01:00
<para>
2002-02-17 12:50:09 +01:00
To add an automatically named primary key constraint to a table, noting
that a table can only ever have one primary key:
2003-04-15 15:25:08 +02:00
<programlisting>
2002-02-17 12:50:09 +01:00
ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
2003-04-15 15:25:08 +02:00
</programlisting>
2001-09-07 23:57:53 +02:00
</para>
2004-07-12 01:13:58 +02:00
2009-02-11 22:11:16 +01:00
<para>
2005-08-01 18:11:14 +02:00
To move a table to a different tablespace:
2004-07-12 01:13:58 +02:00
<programlisting>
ALTER TABLE distributors SET TABLESPACE fasttablespace;
2005-08-01 18:11:14 +02:00
</programlisting>
</para>
2009-02-11 22:11:16 +01:00
<para>
2005-08-01 18:11:14 +02:00
To move a table to a different schema:
<programlisting>
ALTER TABLE myschema.distributors SET SCHEMA yourschema;
2004-07-12 01:13:58 +02:00
</programlisting>
</para>
2011-01-25 21:42:03 +01:00
<para>
To recreate a primary key constraint, without blocking updates while the
index is rebuilt:
<programlisting>
2011-01-26 14:35:01 +01:00
CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id);
2011-01-25 21:42:03 +01:00
ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;
2011-08-07 09:49:45 +02:00
</programlisting></para>
2011-01-25 21:42:03 +01:00
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<para>
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
To attach a partition to a range-partitioned table:
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<programlisting>
ALTER TABLE measurement
ATTACH PARTITION measurement_y2016m07 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
</programlisting></para>
<para>
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
To attach a partition to a list-partitioned table:
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<programlisting>
ALTER TABLE cities
2016-12-13 14:18:00 +01:00
ATTACH PARTITION cities_ab FOR VALUES IN ('a', 'b');
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
</programlisting></para>
Allow a partitioned table to have a default partition.
Any tuples that don't route to any other partition will route to the
default partition.
Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, and Robert
Haas, with review and testing at various stages by (at least) Rushabh
Lathia, Keith Fiske, Amit Langote, Amul Sul, Rajkumar Raghuanshi, Sven
Kunze, Kyotaro Horiguchi, Thom Brown, Rafia Sabih, and Dilip Kumar.
Discussion: http://postgr.es/m/CAH2L28tbN4SYyhS7YV1YBWcitkqbhSWfQCy0G=apRcC_PEO-bg@mail.gmail.com
Discussion: http://postgr.es/m/CAOG9ApEYj34fWMcvBMBQ-YtqR9fTdXhdN82QEKG0SVZ6zeL1xg@mail.gmail.com
2017-09-08 23:28:04 +02:00
<para>
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
To attach a partition to a hash-partitioned table:
Allow a partitioned table to have a default partition.
Any tuples that don't route to any other partition will route to the
default partition.
Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, and Robert
Haas, with review and testing at various stages by (at least) Rushabh
Lathia, Keith Fiske, Amit Langote, Amul Sul, Rajkumar Raghuanshi, Sven
Kunze, Kyotaro Horiguchi, Thom Brown, Rafia Sabih, and Dilip Kumar.
Discussion: http://postgr.es/m/CAH2L28tbN4SYyhS7YV1YBWcitkqbhSWfQCy0G=apRcC_PEO-bg@mail.gmail.com
Discussion: http://postgr.es/m/CAOG9ApEYj34fWMcvBMBQ-YtqR9fTdXhdN82QEKG0SVZ6zeL1xg@mail.gmail.com
2017-09-08 23:28:04 +02:00
<programlisting>
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
ALTER TABLE orders
ATTACH PARTITION orders_p4 FOR VALUES WITH (MODULUS 4, REMAINDER 3);
Allow a partitioned table to have a default partition.
Any tuples that don't route to any other partition will route to the
default partition.
Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, and Robert
Haas, with review and testing at various stages by (at least) Rushabh
Lathia, Keith Fiske, Amit Langote, Amul Sul, Rajkumar Raghuanshi, Sven
Kunze, Kyotaro Horiguchi, Thom Brown, Rafia Sabih, and Dilip Kumar.
Discussion: http://postgr.es/m/CAH2L28tbN4SYyhS7YV1YBWcitkqbhSWfQCy0G=apRcC_PEO-bg@mail.gmail.com
Discussion: http://postgr.es/m/CAOG9ApEYj34fWMcvBMBQ-YtqR9fTdXhdN82QEKG0SVZ6zeL1xg@mail.gmail.com
2017-09-08 23:28:04 +02:00
</programlisting></para>
Add hash partitioning.
Hash partitioning is useful when you want to partition a growing data
set evenly. This can be useful to keep table sizes reasonable, which
makes maintenance operations such as VACUUM faster, or to enable
partition-wise join.
At present, we still depend on constraint exclusion for partitioning
pruning, and the shape of the partition constraints for hash
partitioning is such that that doesn't work. Work is underway to fix
that, which should both improve performance and make partitioning
pruning work with hash partitioning.
Amul Sul, reviewed and tested by Dilip Kumar, Ashutosh Bapat, Yugo
Nagata, Rajkumar Raghuwanshi, Jesper Pedersen, and by me. A few
final tweaks also by me.
Discussion: http://postgr.es/m/CAAJ_b96fhpJAP=ALbETmeLk1Uni_GFZD938zgenhF49qgDTjaQ@mail.gmail.com
2017-11-10 00:07:25 +01:00
<para>
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
To attach a default partition to a partitioned table:
Add hash partitioning.
Hash partitioning is useful when you want to partition a growing data
set evenly. This can be useful to keep table sizes reasonable, which
makes maintenance operations such as VACUUM faster, or to enable
partition-wise join.
At present, we still depend on constraint exclusion for partitioning
pruning, and the shape of the partition constraints for hash
partitioning is such that that doesn't work. Work is underway to fix
that, which should both improve performance and make partitioning
pruning work with hash partitioning.
Amul Sul, reviewed and tested by Dilip Kumar, Ashutosh Bapat, Yugo
Nagata, Rajkumar Raghuwanshi, Jesper Pedersen, and by me. A few
final tweaks also by me.
Discussion: http://postgr.es/m/CAAJ_b96fhpJAP=ALbETmeLk1Uni_GFZD938zgenhF49qgDTjaQ@mail.gmail.com
2017-11-10 00:07:25 +01:00
<programlisting>
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
ALTER TABLE cities
ATTACH PARTITION cities_partdef DEFAULT;
Add hash partitioning.
Hash partitioning is useful when you want to partition a growing data
set evenly. This can be useful to keep table sizes reasonable, which
makes maintenance operations such as VACUUM faster, or to enable
partition-wise join.
At present, we still depend on constraint exclusion for partitioning
pruning, and the shape of the partition constraints for hash
partitioning is such that that doesn't work. Work is underway to fix
that, which should both improve performance and make partitioning
pruning work with hash partitioning.
Amul Sul, reviewed and tested by Dilip Kumar, Ashutosh Bapat, Yugo
Nagata, Rajkumar Raghuwanshi, Jesper Pedersen, and by me. A few
final tweaks also by me.
Discussion: http://postgr.es/m/CAAJ_b96fhpJAP=ALbETmeLk1Uni_GFZD938zgenhF49qgDTjaQ@mail.gmail.com
2017-11-10 00:07:25 +01:00
</programlisting></para>
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<para>
Fully enforce uniqueness of constraint names.
It's been true for a long time that we expect names of table and domain
constraints to be unique among the constraints of that table or domain.
However, the enforcement of that has been pretty haphazard, and it missed
some corner cases such as creating a CHECK constraint and then an index
constraint of the same name (as per recent report from André Hänsel).
Also, due to the lack of an actual unique index enforcing this, duplicates
could be created through race conditions.
Moreover, the code that searches pg_constraint has been quite inconsistent
about how to handle duplicate names if one did occur: some places checked
and threw errors if there was more than one match, while others just
processed the first match they came to.
To fix, create a unique index on (conrelid, contypid, conname). Since
either conrelid or contypid is zero, this will separately enforce
uniqueness of constraint names among constraints of any one table and any
one domain. (If we ever implement SQL assertions, and put them into this
catalog, more thought might be needed. But it'd be at least as reasonable
to put them into a new catalog; having overloaded this one catalog with
two kinds of constraints was a mistake already IMO.) This index can replace
the existing non-unique index on conrelid, though we need to keep the one
on contypid for query performance reasons.
Having done that, we can simplify the logic in various places that either
coped with duplicates or neglected to, as well as potentially improve
lookup performance when searching for a constraint by name.
Also, as per our usual practice, install a preliminary check so that you
get something more friendly than a unique-index violation report in the
case complained of by André. And teach ChooseIndexName to avoid choosing
autogenerated names that would draw such a failure.
While it's not possible to make such a change in the back branches,
it doesn't seem quite too late to put this into v11, so do so.
Discussion: https://postgr.es/m/0c1001d4428f$0942b430$1bc81c90$@webkr.de
2018-09-04 19:45:35 +02:00
To detach a partition from a partitioned table:
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
<programlisting>
2017-06-12 07:49:25 +02:00
ALTER TABLE measurement
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
DETACH PARTITION measurement_y2015m12;
</programlisting></para>
2024-04-06 23:58:09 +02:00
<para>
To split a single partition of the range-partitioned table:
<programlisting>
ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2023 INTO
(PARTITION sales_feb2023 FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'),
PARTITION sales_mar2023 FOR VALUES FROM ('2023-03-01') TO ('2023-04-01'),
PARTITION sales_apr2023 FOR VALUES FROM ('2023-04-01') TO ('2023-05-01'));
</programlisting></para>
<para>
To split a single partition of the list-partitioned table:
<programlisting>
ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
(PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
</programlisting></para>
2024-04-06 23:57:22 +02:00
<para>
To merge several partitions into one partition of the target table:
<programlisting>
ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central)
INTO sales_all;
</programlisting></para>
1999-07-06 19:16:42 +02:00
</refsect1>
1998-05-13 07:34:00 +02:00
2003-04-15 15:25:08 +02:00
<refsect1>
<title>Compatibility</title>
1998-09-16 16:43:12 +02:00
2003-04-15 15:25:08 +02:00
<para>
Catalog not-null constraints
We now create contype='n' pg_constraint rows for not-null constraints.
We propagate these constraints to other tables during operations such as
adding inheritance relationships, creating and attaching partitions and
creating tables LIKE other tables. We also spawn not-null constraints
for inheritance child tables when their parents have primary keys.
These related constraints mostly follow the well-known rules of
conislocal and coninhcount that we have for CHECK constraints, with some
adaptations: for example, as opposed to CHECK constraints, we don't
match not-null ones by name when descending a hierarchy to alter it,
instead matching by column name that they apply to. This means we don't
require the constraint names to be identical across a hierarchy.
For now, we omit them for system catalogs. Maybe this is worth
reconsidering. We don't support NOT VALID nor DEFERRABLE clauses
either; these can be added as separate features later (this patch is
already large and complicated enough.)
psql shows these constraints in \d+.
pg_dump requires some ad-hoc hacks, particularly when dumping a primary
key. We now create one "throwaway" not-null constraint for each column
in the PK together with the CREATE TABLE command, and once the PK is
created, all those throwaway constraints are removed. This avoids
having to check each tuple for nullness when the dump restores the
primary key creation.
pg_upgrading from an older release requires a somewhat brittle procedure
to create a constraint state that matches what would be created if the
database were being created fresh in Postgres 17. I have tested all the
scenarios I could think of, and it works correctly as far as I can tell,
but I could have neglected weird cases.
This patch has been very long in the making. The first patch was
written by Bernd Helmle in 2010 to add a new pg_constraint.contype value
('n'), which I (Álvaro) then hijacked in 2011 and 2012, until that one
was killed by the realization that we ought to use contype='c' instead:
manufactured CHECK constraints. However, later SQL standard
development, as well as nonobvious emergent properties of that design
(mostly, failure to distinguish them from "normal" CHECK constraints as
well as the performance implication of having to test the CHECK
expression) led us to reconsider this choice, so now the current
implementation uses contype='n' again. During Postgres 16 this had
already been introduced by commit e056c557aef4, but there were some
problems mainly with the pg_upgrade procedure that couldn't be fixed in
reasonable time, so it was reverted.
In 2016 Vitaly Burovoy also worked on this feature[1] but found no
consensus for his proposed approach, which was claimed to be closer to
the letter of the standard, requiring an additional pg_attribute column
to track the OID of the not-null constraint for that column.
[1] https://postgr.es/m/CAKOSWNkN6HSyatuys8xZxzRCR-KL1OkHS5-b9qd9bf1Rad3PLA@mail.gmail.com
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Author: Bernd Helmle <mailings@oopsware.de>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
2023-08-25 13:31:24 +02:00
The forms <literal>ADD [COLUMN]</literal>,
2017-10-09 03:44:17 +02:00
<literal>DROP [COLUMN]</literal>, <literal>DROP IDENTITY</literal>, <literal>RESTART</literal>,
<literal>SET DEFAULT</literal>, <literal>SET DATA TYPE</literal> (without <literal>USING</literal>),
2017-04-06 14:33:16 +02:00
<literal>SET GENERATED</literal>, and <literal>SET <replaceable>sequence_option</replaceable></literal>
Catalog not-null constraints
We now create contype='n' pg_constraint rows for not-null constraints.
We propagate these constraints to other tables during operations such as
adding inheritance relationships, creating and attaching partitions and
creating tables LIKE other tables. We also spawn not-null constraints
for inheritance child tables when their parents have primary keys.
These related constraints mostly follow the well-known rules of
conislocal and coninhcount that we have for CHECK constraints, with some
adaptations: for example, as opposed to CHECK constraints, we don't
match not-null ones by name when descending a hierarchy to alter it,
instead matching by column name that they apply to. This means we don't
require the constraint names to be identical across a hierarchy.
For now, we omit them for system catalogs. Maybe this is worth
reconsidering. We don't support NOT VALID nor DEFERRABLE clauses
either; these can be added as separate features later (this patch is
already large and complicated enough.)
psql shows these constraints in \d+.
pg_dump requires some ad-hoc hacks, particularly when dumping a primary
key. We now create one "throwaway" not-null constraint for each column
in the PK together with the CREATE TABLE command, and once the PK is
created, all those throwaway constraints are removed. This avoids
having to check each tuple for nullness when the dump restores the
primary key creation.
pg_upgrading from an older release requires a somewhat brittle procedure
to create a constraint state that matches what would be created if the
database were being created fresh in Postgres 17. I have tested all the
scenarios I could think of, and it works correctly as far as I can tell,
but I could have neglected weird cases.
This patch has been very long in the making. The first patch was
written by Bernd Helmle in 2010 to add a new pg_constraint.contype value
('n'), which I (Álvaro) then hijacked in 2011 and 2012, until that one
was killed by the realization that we ought to use contype='c' instead:
manufactured CHECK constraints. However, later SQL standard
development, as well as nonobvious emergent properties of that design
(mostly, failure to distinguish them from "normal" CHECK constraints as
well as the performance implication of having to test the CHECK
expression) led us to reconsider this choice, so now the current
implementation uses contype='n' again. During Postgres 16 this had
already been introduced by commit e056c557aef4, but there were some
problems mainly with the pg_upgrade procedure that couldn't be fixed in
reasonable time, so it was reverted.
In 2016 Vitaly Burovoy also worked on this feature[1] but found no
consensus for his proposed approach, which was claimed to be closer to
the letter of the standard, requiring an additional pg_attribute column
to track the OID of the not-null constraint for that column.
[1] https://postgr.es/m/CAKOSWNkN6HSyatuys8xZxzRCR-KL1OkHS5-b9qd9bf1Rad3PLA@mail.gmail.com
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Author: Bernd Helmle <mailings@oopsware.de>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com>
2023-08-25 13:31:24 +02:00
conform with the SQL standard.
The form <literal>ADD <replaceable>table_constraint</replaceable></literal>
conforms with the SQL standard when the <literal>USING INDEX</literal> and
<literal>NOT VALID</literal> clauses are omitted and the constraint type is
one of <literal>CHECK</literal>, <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>,
or <literal>REFERENCES</literal>.
The other forms are
2003-04-15 15:25:08 +02:00
<productname>PostgreSQL</productname> extensions of the SQL standard.
2004-05-05 06:48:48 +02:00
Also, the ability to specify more than one manipulation in a single
2017-10-09 03:44:17 +02:00
<command>ALTER TABLE</command> command is an extension.
2003-04-15 15:25:08 +02:00
</para>
<para>
2017-10-09 03:44:17 +02:00
<command>ALTER TABLE DROP COLUMN</command> can be used to drop the only
2003-04-15 15:25:08 +02:00
column of a table, leaving a zero-column table. This is an
extension of SQL, which disallows zero-column tables.
</para>
1999-07-06 19:16:42 +02:00
</refsect1>
2011-01-25 21:42:03 +01:00
<refsect1>
<title>See Also</title>
<simplelist type="inline">
2017-11-23 15:39:47 +01:00
<member><xref linkend="sql-createtable"/></member>
2011-01-25 21:42:03 +01:00
</simplelist>
</refsect1>
1999-07-06 19:16:42 +02:00
</refentry>