mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03: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.
This commit is contained in:
@@ -45,6 +45,35 @@ typedef struct LockInfoData
|
||||
|
||||
typedef LockInfoData *LockInfo;
|
||||
|
||||
/*
|
||||
* Information about the partition key of a relation
|
||||
*/
|
||||
typedef struct PartitionKeyData
|
||||
{
|
||||
char strategy; /* partitioning strategy */
|
||||
int16 partnatts; /* number of columns in the partition key */
|
||||
AttrNumber *partattrs; /* attribute numbers of columns in the
|
||||
* partition key */
|
||||
List *partexprs; /* list of expressions in the partitioning
|
||||
* key, or NIL */
|
||||
|
||||
Oid *partopfamily; /* OIDs of operator families */
|
||||
Oid *partopcintype; /* OIDs of opclass declared input data types */
|
||||
FmgrInfo *partsupfunc; /* lookup info for support funcs */
|
||||
|
||||
/* Partitioning collation per attribute */
|
||||
Oid *partcollation;
|
||||
|
||||
/* Type information per attribute */
|
||||
Oid *parttypid;
|
||||
int32 *parttypmod;
|
||||
int16 *parttyplen;
|
||||
bool *parttypbyval;
|
||||
char *parttypalign;
|
||||
Oid *parttypcoll;
|
||||
} PartitionKeyData;
|
||||
|
||||
typedef struct PartitionKeyData *PartitionKey;
|
||||
|
||||
/*
|
||||
* Here are the contents of a relation cache entry.
|
||||
@@ -94,6 +123,12 @@ typedef struct RelationData
|
||||
List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */
|
||||
bool rd_fkeyvalid; /* true if list has been computed */
|
||||
|
||||
MemoryContext rd_partkeycxt; /* private memory cxt for the below */
|
||||
struct PartitionKeyData *rd_partkey; /* partition key, or NULL */
|
||||
MemoryContext rd_pdcxt; /* private context for partdesc */
|
||||
struct PartitionDescData *rd_partdesc; /* partitions, or NULL */
|
||||
List *rd_partcheck; /* partition CHECK quals */
|
||||
|
||||
/* data managed by RelationGetIndexList: */
|
||||
List *rd_indexlist; /* list of OIDs of indexes on relation */
|
||||
Oid rd_oidindex; /* OID of unique index on OID, if any */
|
||||
@@ -534,6 +569,60 @@ typedef struct ViewOptions
|
||||
RelationNeedsWAL(relation) && \
|
||||
!IsCatalogRelation(relation))
|
||||
|
||||
/*
|
||||
* RelationGetPartitionKey
|
||||
* Returns the PartitionKey of a relation
|
||||
*/
|
||||
#define RelationGetPartitionKey(relation) ((relation)->rd_partkey)
|
||||
|
||||
/*
|
||||
* PartitionKey inquiry functions
|
||||
*/
|
||||
static inline int
|
||||
get_partition_strategy(PartitionKey key)
|
||||
{
|
||||
return key->strategy;
|
||||
}
|
||||
|
||||
static inline int
|
||||
get_partition_natts(PartitionKey key)
|
||||
{
|
||||
return key->partnatts;
|
||||
}
|
||||
|
||||
static inline List *
|
||||
get_partition_exprs(PartitionKey key)
|
||||
{
|
||||
return key->partexprs;
|
||||
}
|
||||
|
||||
/*
|
||||
* PartitionKey inquiry functions - one column
|
||||
*/
|
||||
static inline int16
|
||||
get_partition_col_attnum(PartitionKey key, int col)
|
||||
{
|
||||
return key->partattrs[col];
|
||||
}
|
||||
|
||||
static inline Oid
|
||||
get_partition_col_typid(PartitionKey key, int col)
|
||||
{
|
||||
return key->parttypid[col];
|
||||
}
|
||||
|
||||
static inline int32
|
||||
get_partition_col_typmod(PartitionKey key, int col)
|
||||
{
|
||||
return key->parttypmod[col];
|
||||
}
|
||||
|
||||
/*
|
||||
* RelationGetPartitionDesc
|
||||
* Returns partition descriptor for a relation.
|
||||
*/
|
||||
#define RelationGetPartitionDesc(relation) ((relation)->rd_partdesc)
|
||||
|
||||
/* routines in utils/cache/relcache.c */
|
||||
extern void RelationIncrementReferenceCount(Relation rel);
|
||||
extern void RelationDecrementReferenceCount(Relation rel);
|
||||
|
Reference in New Issue
Block a user