[code notes] implementation of creating partition table
SQL
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
data text
) PARTITION BY RANGE (logdate);
CREATE TABLE p1 PARTITION OF measurement
FOR VALUES FROM ('2020-01-01') TO ('2020-02-01');
Semantic Struct
CreateStmt *n = makeNode(CreateStmt);
n->relation = $4; /* `p1` here */
n->inhRelations = list_make1($7); /* `measurement` here */
n->partbound = $9; /* ('2020-01-01') TO ('2020-02-01') */
/* other attributes are not important */
Execution
DDL statements are handled by function ProcessUtilitySlow
. For T_CreateStmt
:
- run the parse analysis through
transformCreateStmt
- After transforming, the create table statment could have three types:
- CreateStmt
- CreateForeignTableStmt
- TableLikeClause
we are focusing onCreateStmt
.
- Create the table itself by function
DefineRelation
- record a ddl_command_end event
- parse and validate reloptions for the toast table
- check and create toast table
DefineRelation
- Look up the namespace in which we are supposed to create the relation, check we have permission to create there, lock it against concurrent drop, and mark stmt->relation as RELPERSISTENCE_TEMP if a temporary namespace is selected.
- record the list of OIDs of the parents and lock the parents
- Select tablespace to use
- Check permissions except when using database's default
- In all cases disallow placing user relations in pg_global
- Identify user ID that will own the table
- Parse and validate reloptions, if any.
- Look up inheritance ancestors and generate relation schema, including inherited attributes.
- Create a tuple descriptor from the relation schema.
- Find columns with default values and prepare for insertion of the defaults.
- If the statement hasn't specified an access method, but we're defining a type of relation that needs one, use the default.
- Create the relation by function
heap_create_with_catalog
. - make the newly created relation visible by function
CommandCounterIncrement
- Now add any newly specified column default and generation expressions to the new relation.
- Make
column generation expressions
visible for use by partitioning. - lock default partition table with
AccessExclusiveLock
if exists. Here's the reason. - Transform the bound values by function
transformPartitionBound
- Check first that the new partition's bound is valid and does not overlap with any of existing partitions of the parent.
- If the default partition exists, checks if there exists a row in the default partition that would properly belong to the new partition being added. If it finds one, it throws an error.
- store the partition bound in the pg_class entry
- Updates the system catalogs with proper inheritance information.
- If we're creating a partition, create now all the indexes, triggers, FKs defined in the parent.
- indexes are created by
DefineIndex
, triggers are cloned byCloneRowTriggersToPartition
, foreign keys ared cloned byCloneForeignKeyConstraints
- Now add any newly specified CHECK constraints to the new relation by
AddRelationNewConstraints
- Finally, merge the not-null constraints that are declared directly with those that come from parent relations
posted on 2024-03-26 00:33 winter-loo 阅读(10) 评论(0) 编辑 收藏 举报