diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 97ef618..ce02af9 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -214,6 +214,16 @@
+ pg_partition
+ information about partitions, including partition boundary
+
+
+
+ pg_partitioned_rel
+ information about partitioned tables, including the partition key
+
+
+ pg_pltemplatetemplate data for procedural languages
@@ -4629,6 +4639,161 @@
+
+ pg_partition
+
+
+ pg_partition
+
+
+
+ The catalog pg_partition stores
+ information about partitions of partitioned tables.
+
+
+
+ pg_partition> Columns
+
+
+
+
+ Name
+ Type
+ References
+ Description
+
+
+
+
+
+
+ partrelid
+ oid
+ pg_class.oid
+ The OID of the pg_class> entry for this partition
+
+
+
+ partparent
+ oid
+ pg_class.oid
+ The OID of the partitioned table this partition is part of
+
+
+
+ partlistvals
+ anyarray
+
+ For partitions of a list partitioned table, list of values assigned to this partition
+
+
+
+ partrangemaxs
+ anyarray
+
+ For partitions of a range partitioned table, array of maximum values per partition key column
+
+
+
+
+
+
+
+
+
+ pg_partitioned_rel
+
+
+ pg_partitioned_rel
+
+
+
+ The catalog pg_partitioned stores
+ information about partition key of partitioned tables.
+
+
+
+ pg_partitioned_rel> Columns
+
+
+
+
+ Name
+ Type
+ References
+ Description
+
+
+
+
+
+
+ partrelid
+ oid
+ pg_class.oid
+ The OID of the pg_class> entry for this partitioned table
+
+
+
+ partstrat
+ char
+
+
+ Partitioning strategy (method); l> = list partitioned table,
+ r> = range partitioned table
+
+
+
+
+ partnatts
+ int2
+
+ The number of columns in partition key
+
+
+
+ partkey
+ int2vector
+ pg_attribute.attnum
+
+ This is an array of partnatts values that
+ correspond to table columns used as partition key. For example, a value
+ of 1 3 would mean that the first and the third table
+ columns make up the partition key. A zero in this array indicates that the
+ corresponding partition key column is an expression over the table columns,
+ rather than a simple column reference.
+
+
+
+
+ partclass
+ oidvector
+ pg_opclass.oid
+
+ For each column in the partition key, this contains the OID of
+ the operator class to use. See
+ pg_opclass for details.
+
+
+
+
+ partexprs
+ pg_node_tree
+
+
+ Expression trees (in nodeToString()
+ representation) for partition key columns that are not simple column
+ references. This is a list with one element for each zero
+ entry in partkey>. Null if all partition key columns
+ are simple references.
+
+
+
+
+
+
+
+ pg_pltemplate
diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index aca40f5..07b3000 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -77,12 +77,23 @@ ALTER TABLE ALL IN TABLESPACE name
NOT OF
OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING }
+ ATTACH PARTITION partition_name FOR VALUES { list_partition_values | range_partition_values } USING [ TABLE ] table_name
+ DETACH PARTITION partition_name [ USING [ TABLE ] table_name ]
and table_constraint_using_index is:
[ CONSTRAINT constraint_name ]
{ UNIQUE | PRIMARY KEY } USING INDEX index_name
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+and list_partition_values is:
+
+[ IN ] ( { expression } [, ...] )
+
+and range_partition_values is:
+
+LESS THAN ( { expression } [, ...] )
+
@@ -704,6 +715,32 @@ ALTER TABLE ALL IN TABLESPACE name
+
+ ATTACH PARTITION partition_name FOR VALUES { list_partition_values | range_partition_values } USING [ TABLE ] table_name
+
+
+ This form attaches a table as partition of the target table (presumably
+ partitioned.) To be attached as a partition, the source table must
+ already contain all the same columns as the parent. The columns must
+ have matching data types, and if they have NOT NULL
+ constraints in the target table then they must also have
+ NOT NULL constraints in the source table. The table is renamed
+ to the specified partition name. [Note: this command is currently
+ unimplemented.]
+
+
+
+
+
+ DETACH PARTITION partition_name [ USING [ TABLE ] table_name ]
+
+
+ This form detaches a partition from the target table (presumably
+ partitioned.) The resulting table can optionally have a different
+ name after being detached.
+
+
+
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index a2d0b0c..2fa7bc8 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -28,6 +28,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
[, ... ]
] )
[ INHERITS ( parent_table [, ... ] ) ]
+[ PARTITION BY {RANGE | LIST} ON ( { column_name | ( expression ) } [ opclass ] [, ...] )]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]
@@ -42,6 +43,13 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
+ PARTITION OF table_name
+ FOR VALUES { list_partition_values | range_partition_values }
+[ WITH ( storage_parameter [= value] [, ... ] ) ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE tablespace_name ]
+
where column_constraint is:
[ CONSTRAINT constraint_name ]
@@ -70,6 +78,14 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
{ INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | ALL }
+and list_partition_values is:
+
+[ IN ] ( { expression } [, ...] )
+
+and range_partition_values is:
+
+LESS THAN ( { expression } [, ...] )
+
index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:
[ WITH ( storage_parameter [= value] [, ... ] ) ]
@@ -230,6 +246,40 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
+ PARTITION OF table_name FOR VALUES { list_partition_values | range_partition_values }
+
+
+ Creates the table as a partition of the
+ specified partitioned table.
+
+
+
+ When a table is created as partition, the data types of the
+ columns, constraints are determined by the underlying partitioned
+ table and are not specified by the CREATE TABLE
+ command nor can they be added or altered after the fact using
+ ALTER TABLE. But the CREATE TABLE command
+ command can specify table storage parameters and tablespace for the
+ partition (and can be altered after the fact). The
+ FOR VALUES specification describes partition bounds,
+ that is, either a list of values or of maximum values of partition
+ key columns for list partitions and range partitions, respectively.
+
+
+
+ Care must be taken to specify correct values for the bounds.
+ Specifying bounds such that new partition overlaps with some existing
+ partition results in error. Rules for whether such overlaps occurs
+ are different based on the partitioning method used. For list
+ bounds, make sure that the new partition's list of values does
+ not contain any values already present in some existing partition's
+ list. For range bounds, make sure that the new partition's rangemax
+ value is greater than the last existing partition's rangemax.
+
+
+
+
+ column_name
@@ -314,6 +364,32 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
+ PARTITION BY {RANGE | LIST} ON ( { column_name | ( expression ) } [ opclass ] [, ...] )
+
+
+ The optional PARTITION BY> clause specifies a list
+ of columns (or expressions) to use as the partition key of table.
+ Currently, LIST> and RANGE> can be specified
+ as the partitioning method. Such a table (hereafter referred to as
+ partitioned table) is divided into sub-tables called partitions which
+ are created after the fact.
+
+
+
+ Scanning a partitioned table results in scanning its partitions
+ and appending the results. Rows inserted into a partitioned table
+ are mapped to and stored in a partition based on values of partition
+ key columns unless an appropriate partition has not been defined yet.
+
+
+
+ There are currently a number of limitations on constraints that
+ can be defined on partitioned tables as detailed elsewhere.
+
+
+
+
+ LIKE source_table [ like_option ... ]
@@ -498,6 +574,10 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
primary key constraint defined for the table. (Otherwise it
would just be the same constraint listed twice.)
+
+
+ UNIQUE constraints are not supported on partitioned tables at the moment.
+
@@ -526,6 +606,10 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
different from other sets of columns named by any unique
constraint defined for the same table.
+
+
+ Primary key constraints are not supported on partitioned tables at the moment.
+
@@ -576,6 +660,10 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
exclusion constraint on a subset of the table; internally this creates a
partial index. Note that parentheses are required around the predicate.
+
+
+ Exclusion constraints are not supported on partitioned tables at the moment.
+
@@ -699,6 +787,10 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
associated with the foreign key constraint can be performed more
efficiently.
+
+
+ Partitioned tables cannot use the REFERENCES clause at the moment.
+
@@ -1119,7 +1211,9 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
Unique constraints and primary keys are not inherited in the
current implementation. This makes the combination of
- inheritance and unique constraints rather dysfunctional.
+ inheritance and unique constraints rather dysfunctional. As
+ noted before, they cannot be used with partitioned tables
+ either.
@@ -1341,6 +1435,76 @@ CREATE TABLE employees OF employee_type (
salary WITH OPTIONS DEFAULT 1000
);
+
+
+ Create a range partitioned table and partitions:
+
+CREATE TABLE employee (
+ name text,
+ age int NOT NULL
+)
+PARTITION BY RANGE ON (age);
+
+CREATE TABLE employees_less_than_30
+ PARTITION OF employee
+ FOR VALUES LESS THAN (30)
+ WITH (fillfactor=70)
+ TABLESPACE diskvol1;
+
+CREATE TABLE employees_between_30_and_40
+ PARTITION OF employee
+ FOR VALUES LESS THAN (40)
+ WITH (fillfactor=70)
+ TABLESPACE diskvol2;
+
+
+
+ Create a list partitioned table and partitions:
+
+CREATE TABLE store (
+ id int,
+ city text NOT NULL
+)
+PARTITION BY LIST ON (city);
+
+CREATE TABLE store_east
+ PARTITION OF store
+ FOR VALUES IN ('New York', 'Boston');
+
+CREATE TABLE store_west
+ PARTITION OF store
+ FOR VALUES ('San Fransisco', 'Seattle');
+
+
+
+ Create a multi-column range partitioned table and partitions:
+
+CREATE TABLE sales (
+ tos timestamp NOT NULL,
+ item text
+)
+PARTITION BY RANGE ON (extract(year from tos), extract(month from tos));
+
+CREATE TABLE sales_before_2015
+ PARTITION OF sales
+ FOR VALUES LESS THAN (2015, 1);
+
+CREATE TABLE sales_2015_q1
+ PARTITION OF sales
+ FOR VALUES LESS THAN (2015, 4);
+
+CREATE TABLE sales_2015_q2
+ PARTITION OF sales
+ FOR VALUES LESS THAN (2015, 7);
+
+CREATE TABLE sales_2015_q3
+ PARTITION OF sales
+ FOR VALUES LESS THAN (2015, 10);
+
+CREATE TABLE sales_2015_q4
+ PARTITION OF sales
+ FOR VALUES LESS THAN (2016, 1);
+
@@ -1511,6 +1675,16 @@ CREATE TABLE employees OF employee_type (
effect can be had using the OID feature.
+
+
+ Partitioned Tables
+
+
+ PARTITION BY and PARTITION OF (including
+ FOR VALUES) are PostgreSQL
+ extensions.
+
+