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');
構文解析構造
CreateStmt *node = makeNode(CreateStmt);
node->relation = $4; /* ここでは `p1` */
node->inhRelations = list_make1($7); /* ここでは `measurement` */
node->partbound = $9; /* ('2020-01-01') TO ('2020-02-01') */
/* その他の属性は関係ない */
実行処理
DDL文は関数 ProcessUtilitySlow によって処理されます。 T_CreateStmt の場合:
- パース解析を
transformCreateStmtを通じて実行 - 変換後、作成ステートメントには3つのタイプがあります:
- CreateStmt
- CreateForeignTableStmt
- TableLikeClause
この中で CreateStmt に焦点を当てます。
- 関数
DefineRelationを使用してテーブルを作成 - ddl_command_end イベントを記録
- toast テーブルの reloptions を解析・検証
- toast テーブルの存在確認と作成
DefineRelation
- 関係を作成する名前空間を検索し、権限を確認し、同時に削除操作からロックし、一時的な名前空間が選択された場合は stmt->relation を RELPERSISTENCE_TEMP としてマーク
- 親テーブルの OID リストを記録し、親テーブルをロック
- 使用するテーブルスペースを選択
- データベースのデフォルトを使用しない限り、権限をチェック
- すべての場合で、ユーザー関係を pg_global に配置することを禁止
- テーブルの所有者となるユーザIDを特定
- 再オプションの解析と検証(存在する場合)
- 継承祖先を検索し、継承属性を含む関係スキーマを生成
- 関係スキーマからタプル記述子を作成
- デフォルト値を持つ列を特定し、デフォルト挿入の準備を行う
- アクセスメソッドが指定されていないが、関係タイプに必要な場合はデフォルトを使用
- 関数
heap_create_with_catalogを使用して関係を作成 - 関数
CommandCounterIncrementを使用して新規関係を可視化 - 新しい列のデフォルトおよび生成式を新規関係に追加
- パーティショニングのために「列生成式」を可視化
- 既存のデフォルトパーティションが存在する場合、
AccessExclusiveLockでロックします。その理由は以下の通りです。 - 関数
transformPartitionBoundを使用して境界値を変換 - 新しいパーティションの境界が有効であり、親パーティションとの重複がないことを確認
- デフォルトパーティションが存在する場合、既存の行が新しく追加されるパーティションに属すべきかどうかを確認。該当する行があればエラーを発生
- パーティション境界を pg_class エントリに保存
- システムカタログを適切な継承情報で更新
- パーティションを作成する場合、親で定義されたインデックス、トリガー、外部キーをすべて作成
インデックスは DefineIndex で作成され、トリガーは CloneRowTriggersToPartition で複製され、外部キーは CloneForeignKeyConstraints で複製されます。
- 新しい CHECK 制約を
AddRelationNewConstraintsで新規関係に追加 - 最後に、直接宣言された NOT NULL 制約と親関係から継承された NOT NULL 制約をマージ