diff --git a/cmd/dump/dump_integration_test.go b/cmd/dump/dump_integration_test.go index f4501ec4..201b5821 100644 --- a/cmd/dump/dump_integration_test.go +++ b/cmd/dump/dump_integration_test.go @@ -11,6 +11,7 @@ import ( "context" "fmt" "os" + "regexp" "strings" "testing" @@ -651,8 +652,13 @@ func runTenantSchemaTest(t *testing.T, testDataDir string) { } } -// normalizeSchemaOutput removes version-specific lines for comparison. -// This allows comparing dumps across different PostgreSQL versions. +// tzOffsetRe matches timezone offsets (e.g. -08, +00, +05:30) at the end of +// quoted timestamp literals inside partition bound expressions. pg_get_expr +// returns machine-local offsets, so we normalize them for cross-platform comparison. +var tzOffsetRe = regexp.MustCompile(`(\d{2}:\d{2}:\d{2})[-+]\d{2}(:\d{2})?`) + +// normalizeSchemaOutput removes version-specific lines and normalizes +// timezone offsets in partition bounds for cross-platform comparison. func normalizeSchemaOutput(output string) string { lines := strings.Split(output, "\n") var normalizedLines []string @@ -663,6 +669,9 @@ func normalizeSchemaOutput(output string) string { strings.Contains(line, "-- Dumped from database version") { continue } + if strings.Contains(line, "PARTITION OF") || strings.Contains(line, "FOR VALUES") { + line = tzOffsetRe.ReplaceAllString(line, "${1}+00") + } normalizedLines = append(normalizedLines, line) } diff --git a/cmd/plan/plan.go b/cmd/plan/plan.go index 7f824187..1628c312 100644 --- a/cmd/plan/plan.go +++ b/cmd/plan/plan.go @@ -487,6 +487,14 @@ func normalizeSchemaNames(irData *ir.IR, fromSchema, toSchema string) { } } + // Normalize partition parent schema reference and bound expression + if table.PartitionOfSchema == fromSchema { + table.PartitionOfSchema = toSchema + } + if table.PartitionBound != "" { + table.PartitionBound = stripQualifiers(replaceString(table.PartitionBound)) + } + // Normalize schema references in LIKE clauses for i := range table.LikeClauses { if table.LikeClauses[i].SourceSchema == fromSchema { diff --git a/internal/diff/table.go b/internal/diff/table.go index 0fc9910a..acc7f2a0 100644 --- a/internal/diff/table.go +++ b/internal/diff/table.go @@ -764,6 +764,52 @@ func generateTableSQL(table *ir.Table, targetSchema string, qualifySchema bool, // forced qualification is on). tableName := ir.QualifyEntityNameWithQuotesMode(table.Schema, table.Name, targetSchema, qualifySchema) + // Partition children: emit PARTITION OF instead of standalone CREATE TABLE. + // Columns and inherited constraints come from the parent automatically; + // only child-specific constraints (conparentid = 0) remain in the IR. + if table.PartitionOf != "" && table.PartitionBound != "" { + parentSchema := table.PartitionOfSchema + if parentSchema == "" { + parentSchema = table.Schema + } + parentName := ir.QualifyEntityNameWithQuotesMode(parentSchema, table.PartitionOf, targetSchema, qualifySchema) + + // Include child-specific constraints in the PARTITION OF statement. + inlineConstraints := getInlineConstraintsForTable(table) + var constraintParts []string + var deferred []*deferredConstraint + currentKey := fmt.Sprintf("%s.%s", table.Schema, table.Name) + for _, constraint := range inlineConstraints { + if suppressedInlineFKs[constraintPathKey(constraint)] { + continue + } + if shouldDeferConstraint(table, constraint, currentKey, createdTables, existingTables) { + deferred = append(deferred, &deferredConstraint{ + table: table, + constraint: constraint, + }) + continue + } + if def := generateConstraintSQL(constraint, targetSchema, qualifySchema); def != "" { + constraintParts = append(constraintParts, fmt.Sprintf(" %s", def)) + } + } + + createPrefix := "CREATE TABLE IF NOT EXISTS" + if table.Unlogged { + createPrefix = "CREATE UNLOGGED TABLE IF NOT EXISTS" + } + + var sql string + if len(constraintParts) > 0 { + sql = fmt.Sprintf("%s %s PARTITION OF %s (\n%s\n) %s;", + createPrefix, tableName, parentName, strings.Join(constraintParts, ",\n"), table.PartitionBound) + } else { + sql = fmt.Sprintf("%s %s PARTITION OF %s %s;", createPrefix, tableName, parentName, table.PartitionBound) + } + return sql, deferred + } + var parts []string createPrefix := "CREATE TABLE IF NOT EXISTS" if table.Unlogged { diff --git a/internal/diff/topological.go b/internal/diff/topological.go index 3602b5f0..50c1b335 100644 --- a/internal/diff/topological.go +++ b/internal/diff/topological.go @@ -34,7 +34,21 @@ func topologicallySortTables(tables []*ir.Table) []*ir.Table { } // Build edges: if tableA has a foreign key to tableB, add edge tableB -> tableA + // Also: if tableA is a partition child of tableB, add edge tableB -> tableA for keyA, tableA := range tableMap { + // Partition parent → child dependency + if tableA.PartitionOf != "" { + parentSchema := tableA.PartitionOfSchema + if parentSchema == "" { + parentSchema = tableA.Schema + } + keyB := parentSchema + "." + tableA.PartitionOf + if _, exists := tableMap[keyB]; exists && keyA != keyB { + adjList[keyB] = append(adjList[keyB], keyA) + inDegree[keyA]++ + } + } + for _, constraint := range tableA.Constraints { if constraint.Type == ir.ConstraintTypeForeignKey && constraint.ReferencedTable != "" { // Build referenced table key diff --git a/internal/postgres/embedded.go b/internal/postgres/embedded.go index 11e5e585..90c8ea4b 100644 --- a/internal/postgres/embedded.go +++ b/internal/postgres/embedded.go @@ -106,6 +106,7 @@ func StartEmbeddedPostgres(config *EmbeddedPostgresConfig) (*EmbeddedPostgres, e "log_statement": "none", // Don't log SQL statements "log_min_duration_statement": "-1", // Don't log slow queries "unix_socket_directories": runtimePath, // Use a directory that is guaranteed to exist + "timezone": "UTC", // Ensure platform-independent output for pg_get_expr }) // Create and start PostgreSQL instance diff --git a/ir/inspector.go b/ir/inspector.go index be5c33e3..3fd09c69 100644 --- a/ir/inspector.go +++ b/ir/inspector.go @@ -673,6 +673,7 @@ func requiresPositionSorting(constraintType ConstraintType) bool { } // buildPartitionMapping builds a mapping from partition table names to their parent's partition keys +// and populates partition child metadata (PartitionOf, PartitionOfSchema, PartitionBound) on child tables. func (i *Inspector) buildPartitionMapping(ctx context.Context, schema *IR, targetSchema string) map[string]string { partitionMapping := make(map[string]string) @@ -683,6 +684,8 @@ func (i *Inspector) buildPartitionMapping(ctx context.Context, schema *IR, targe return partitionMapping } + dbSchema := schema.getOrCreateSchema(targetSchema) + for _, child := range partitionChildren { // Only process children in the target schema if child.ChildSchema != targetSchema { @@ -692,8 +695,16 @@ func (i *Inspector) buildPartitionMapping(ctx context.Context, schema *IR, targe childTable := child.ChildTable parentTable := child.ParentTable + // Set partition child metadata on the child table + if childTableInfo, exists := dbSchema.Tables[childTable]; exists { + childTableInfo.PartitionOf = parentTable + childTableInfo.PartitionOfSchema = child.ParentSchema + if child.PartitionBound.Valid { + childTableInfo.PartitionBound = child.PartitionBound.String + } + } + // Find the parent table's partition key - dbSchema := schema.getOrCreateSchema(targetSchema) if parentTableInfo, exists := dbSchema.Tables[parentTable]; exists && parentTableInfo.IsPartitioned { partitionMapping[childTable] = parentTableInfo.PartitionKey } diff --git a/ir/ir.go b/ir/ir.go index 46490298..8d03c040 100644 --- a/ir/ir.go +++ b/ir/ir.go @@ -62,6 +62,9 @@ type Table struct { IsPartitioned bool `json:"is_partitioned"` PartitionStrategy string `json:"partition_strategy,omitempty"` // RANGE, LIST, HASH PartitionKey string `json:"partition_key,omitempty"` // Column(s) used for partitioning + PartitionOf string `json:"partition_of,omitempty"` // Parent table name (partition children) + PartitionOfSchema string `json:"partition_of_schema,omitempty"` // Parent table schema (partition children) + PartitionBound string `json:"partition_bound,omitempty"` // Partition bound expression (e.g. "FOR VALUES IN (1, 2)" or "DEFAULT") LikeClauses []LikeClause `json:"like_clauses,omitempty"` // LIKE clauses in CREATE TABLE Unlogged bool `json:"unlogged,omitempty"` // True for UNLOGGED tables } diff --git a/ir/queries/queries.sql b/ir/queries/queries.sql index b69cdafd..6c5f5111 100644 --- a/ir/queries/queries.sql +++ b/ir/queries/queries.sql @@ -368,10 +368,11 @@ LEFT JOIN LATERAL ( WHERE n.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast') AND n.nspname NOT LIKE 'pg_temp_%' AND n.nspname NOT LIKE 'pg_toast_temp_%' - -- Skip internal per-partition FK rows (conparentid != 0) that PostgreSQL - -- creates when a FK references a partitioned table. pg_dump omits these; - -- only the top-level FK (conparentid = 0) is a real, dumpable constraint. - AND (c.contype <> 'f' OR c.conparentid = 0) + -- Skip inherited per-partition constraint copies (conparentid != 0) that + -- PostgreSQL auto-creates on partition children. pg_dump omits these; + -- only root constraints (conparentid = 0) and child-specific constraints + -- are dumpable. PARTITION OF auto-creates the inherited copies. + AND c.conparentid = 0 ORDER BY n.nspname, cl.relname, c.contype, c.conname, a.attnum; -- GetIndexes retrieves all indexes including regular and unique indexes created with CREATE INDEX @@ -1031,10 +1032,11 @@ LEFT JOIN LATERAL ( CASE WHEN c.contype = 'x' THEN pg_get_constraintdef(c.oid, true) ELSE NULL END AS exclusion_definition ) cd ON true WHERE n.nspname = $1 - -- Skip internal per-partition FK rows (conparentid != 0) that PostgreSQL - -- creates when a FK references a partitioned table. pg_dump omits these; - -- only the top-level FK (conparentid = 0) is a real, dumpable constraint. - AND (c.contype <> 'f' OR c.conparentid = 0) + -- Skip inherited per-partition constraint copies (conparentid != 0) that + -- PostgreSQL auto-creates on partition children. pg_dump omits these; + -- only root constraints (conparentid = 0) and child-specific constraints + -- are dumpable. PARTITION OF auto-creates the inherited copies. + AND c.conparentid = 0 ORDER BY n.nspname, cl.relname, c.contype, c.conname, a.attnum; -- GetSequencesForSchema retrieves all sequences for a specific schema diff --git a/ir/queries/queries.sql.go b/ir/queries/queries.sql.go index 9424eaf7..aa34f520 100644 --- a/ir/queries/queries.sql.go +++ b/ir/queries/queries.sql.go @@ -904,10 +904,11 @@ LEFT JOIN LATERAL ( WHERE n.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast') AND n.nspname NOT LIKE 'pg_temp_%' AND n.nspname NOT LIKE 'pg_toast_temp_%' - -- Skip internal per-partition FK rows (conparentid != 0) that PostgreSQL - -- creates when a FK references a partitioned table. pg_dump omits these; - -- only the top-level FK (conparentid = 0) is a real, dumpable constraint. - AND (c.contype <> 'f' OR c.conparentid = 0) + -- Skip inherited per-partition constraint copies (conparentid != 0) that + -- PostgreSQL auto-creates on partition children. pg_dump omits these; + -- only root constraints (conparentid = 0) and child-specific constraints + -- are dumpable. PARTITION OF auto-creates the inherited copies. + AND c.conparentid = 0 ORDER BY n.nspname, cl.relname, c.contype, c.conname, a.attnum ` @@ -1041,10 +1042,11 @@ LEFT JOIN LATERAL ( CASE WHEN c.contype = 'x' THEN pg_get_constraintdef(c.oid, true) ELSE NULL END AS exclusion_definition ) cd ON true WHERE n.nspname = $1 - -- Skip internal per-partition FK rows (conparentid != 0) that PostgreSQL - -- creates when a FK references a partitioned table. pg_dump omits these; - -- only the top-level FK (conparentid = 0) is a real, dumpable constraint. - AND (c.contype <> 'f' OR c.conparentid = 0) + -- Skip inherited per-partition constraint copies (conparentid != 0) that + -- PostgreSQL auto-creates on partition children. pg_dump omits these; + -- only root constraints (conparentid = 0) and child-specific constraints + -- are dumpable. PARTITION OF auto-creates the inherited copies. + AND c.conparentid = 0 ORDER BY n.nspname, cl.relname, c.contype, c.conname, a.attnum ` diff --git a/testdata/diff/create_table/issue_495_partition_constraint_convergence/plan.json b/testdata/diff/create_table/issue_495_partition_constraint_convergence/plan.json index e67dc6bd..5fdff888 100644 --- a/testdata/diff/create_table/issue_495_partition_constraint_convergence/plan.json +++ b/testdata/diff/create_table/issue_495_partition_constraint_convergence/plan.json @@ -3,7 +3,7 @@ "pgschema_version": "1.11.1", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "b52a7d3e192793cd8af86dbf6b990056fa88b14303a29a10bb55048423a811c0" + "hash": "e4ddb6f43ac5b7a34cb423cb508c9912218b7d05931422dbbb0019d897c80892" }, "groups": null } diff --git a/testdata/diff/create_table/issue_496_partition_of_create_path/diff.sql b/testdata/diff/create_table/issue_496_partition_of_create_path/diff.sql new file mode 100644 index 00000000..4e37c183 --- /dev/null +++ b/testdata/diff/create_table/issue_496_partition_of_create_path/diff.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS events ( + id bigint NOT NULL, + region text NOT NULL, + payload text +) PARTITION BY LIST (region); + +CREATE TABLE IF NOT EXISTS events_eu PARTITION OF events FOR VALUES IN ('eu'); + +CREATE TABLE IF NOT EXISTS events_other PARTITION OF events DEFAULT; + +CREATE TABLE IF NOT EXISTS events_us PARTITION OF events FOR VALUES IN ('us'); diff --git a/testdata/diff/create_table/issue_496_partition_of_create_path/new.sql b/testdata/diff/create_table/issue_496_partition_of_create_path/new.sql new file mode 100644 index 00000000..1a09a3c7 --- /dev/null +++ b/testdata/diff/create_table/issue_496_partition_of_create_path/new.sql @@ -0,0 +1,9 @@ +CREATE TABLE public.events ( + id bigint NOT NULL, + region text NOT NULL, + payload text +) PARTITION BY LIST (region); + +CREATE TABLE public.events_us PARTITION OF public.events FOR VALUES IN ('us'); +CREATE TABLE public.events_eu PARTITION OF public.events FOR VALUES IN ('eu'); +CREATE TABLE public.events_other PARTITION OF public.events DEFAULT; diff --git a/testdata/diff/create_table/issue_496_partition_of_create_path/old.sql b/testdata/diff/create_table/issue_496_partition_of_create_path/old.sql new file mode 100644 index 00000000..03d7e9ae --- /dev/null +++ b/testdata/diff/create_table/issue_496_partition_of_create_path/old.sql @@ -0,0 +1 @@ +-- Empty schema diff --git a/testdata/diff/create_table/issue_496_partition_of_create_path/plan.json b/testdata/diff/create_table/issue_496_partition_of_create_path/plan.json new file mode 100644 index 00000000..79cacde7 --- /dev/null +++ b/testdata/diff/create_table/issue_496_partition_of_create_path/plan.json @@ -0,0 +1,38 @@ +{ + "version": "1.0.0", + "pgschema_version": "1.11.1", + "created_at": "1970-01-01T00:00:00Z", + "source_fingerprint": { + "hash": "965b1131737c955e24c7f827c55bd78e4cb49a75adfd04229e0ba297376f5085" + }, + "groups": [ + { + "steps": [ + { + "sql": "CREATE TABLE IF NOT EXISTS events (\n id bigint NOT NULL,\n region text NOT NULL,\n payload text\n) PARTITION BY LIST (region);", + "type": "table", + "operation": "create", + "path": "public.events" + }, + { + "sql": "CREATE TABLE IF NOT EXISTS events_eu PARTITION OF events FOR VALUES IN ('eu');", + "type": "table", + "operation": "create", + "path": "public.events_eu" + }, + { + "sql": "CREATE TABLE IF NOT EXISTS events_other PARTITION OF events DEFAULT;", + "type": "table", + "operation": "create", + "path": "public.events_other" + }, + { + "sql": "CREATE TABLE IF NOT EXISTS events_us PARTITION OF events FOR VALUES IN ('us');", + "type": "table", + "operation": "create", + "path": "public.events_us" + } + ] + } + ] +} diff --git a/testdata/diff/create_table/issue_496_partition_of_create_path/plan.sql b/testdata/diff/create_table/issue_496_partition_of_create_path/plan.sql new file mode 100644 index 00000000..4e37c183 --- /dev/null +++ b/testdata/diff/create_table/issue_496_partition_of_create_path/plan.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS events ( + id bigint NOT NULL, + region text NOT NULL, + payload text +) PARTITION BY LIST (region); + +CREATE TABLE IF NOT EXISTS events_eu PARTITION OF events FOR VALUES IN ('eu'); + +CREATE TABLE IF NOT EXISTS events_other PARTITION OF events DEFAULT; + +CREATE TABLE IF NOT EXISTS events_us PARTITION OF events FOR VALUES IN ('us'); diff --git a/testdata/diff/create_table/issue_496_partition_of_create_path/plan.txt b/testdata/diff/create_table/issue_496_partition_of_create_path/plan.txt new file mode 100644 index 00000000..0d1060f2 --- /dev/null +++ b/testdata/diff/create_table/issue_496_partition_of_create_path/plan.txt @@ -0,0 +1,25 @@ +Plan: 4 to add. + +Summary by type: + tables: 4 to add + +Tables: + + events + + events_eu + + events_other + + events_us + +DDL to be executed: +-------------------------------------------------- + +CREATE TABLE IF NOT EXISTS events ( + id bigint NOT NULL, + region text NOT NULL, + payload text +) PARTITION BY LIST (region); + +CREATE TABLE IF NOT EXISTS events_eu PARTITION OF events FOR VALUES IN ('eu'); + +CREATE TABLE IF NOT EXISTS events_other PARTITION OF events DEFAULT; + +CREATE TABLE IF NOT EXISTS events_us PARTITION OF events FOR VALUES IN ('us'); diff --git a/testdata/diff/online/issue_418_partitioned_parent_index/plan.json b/testdata/diff/online/issue_418_partitioned_parent_index/plan.json index 353d6daf..f2be595c 100644 --- a/testdata/diff/online/issue_418_partitioned_parent_index/plan.json +++ b/testdata/diff/online/issue_418_partitioned_parent_index/plan.json @@ -3,7 +3,7 @@ "pgschema_version": "1.11.1", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "78af5157bfb48369c44c1028df6929fa7b3966b23a288d78ab8cd45a3953dd7d" + "hash": "758267339ede8175e5b0a3c63d4a525550fa89d5ba42ae71486edbe75dc5cab3" }, "groups": [ { diff --git a/testdata/dump/issue_409_partitioned_fk/pgschema.sql b/testdata/dump/issue_409_partitioned_fk/pgschema.sql index 3dca6bb1..d8299eea 100644 --- a/testdata/dump/issue_409_partitioned_fk/pgschema.sql +++ b/testdata/dump/issue_409_partitioned_fk/pgschema.sql @@ -30,19 +30,11 @@ CREATE TABLE IF NOT EXISTS event ( -- Name: session_2026_01; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS session_2026_01 ( - id bigint, - started_at timestamptz, - CONSTRAINT session_2026_01_pkey PRIMARY KEY (started_at, id) -); +CREATE TABLE IF NOT EXISTS session_2026_01 PARTITION OF session FOR VALUES FROM ('2026-01-01 00:00:00+00') TO ('2026-02-01 00:00:00+00'); -- -- Name: session_2026_02; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS session_2026_02 ( - id bigint, - started_at timestamptz, - CONSTRAINT session_2026_02_pkey PRIMARY KEY (started_at, id) -); +CREATE TABLE IF NOT EXISTS session_2026_02 PARTITION OF session FOR VALUES FROM ('2026-02-01 00:00:00+00') TO ('2026-03-01 00:00:00+00'); diff --git a/testdata/dump/issue_472_partition_clone_trigger/pgschema.sql b/testdata/dump/issue_472_partition_clone_trigger/pgschema.sql index 830a6697..29bd7178 100644 --- a/testdata/dump/issue_472_partition_clone_trigger/pgschema.sql +++ b/testdata/dump/issue_472_partition_clone_trigger/pgschema.sql @@ -21,12 +21,7 @@ CREATE TABLE IF NOT EXISTS ledger ( -- Name: ledger_2026_06; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS ledger_2026_06 ( - id uuid, - amount bigint NOT NULL, - ts timestamptz, - CONSTRAINT ledger_2026_06_pkey PRIMARY KEY (ts, id) -); +CREATE TABLE IF NOT EXISTS ledger_2026_06 PARTITION OF ledger FOR VALUES FROM ('2026-06-01 00:00:00+00') TO ('2026-07-01 00:00:00+00'); -- -- Name: tg_noop(); Type: FUNCTION; Schema: -; Owner: - diff --git a/testdata/dump/sakila/pgschema.sql b/testdata/dump/sakila/pgschema.sql index 094d476d..8e6695a0 100644 --- a/testdata/dump/sakila/pgschema.sql +++ b/testdata/dump/sakila/pgschema.sql @@ -3,7 +3,7 @@ -- -- Dumped from database version PostgreSQL 18.0 --- Dumped by pgschema version 1.6.1 +-- Dumped by pgschema version 1.11.1 -- @@ -350,18 +350,11 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_unq_rental_rental_date_inventory_id_custom -- Name: payment_p2022_01; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS payment_p2022_01 ( - payment_id SERIAL, - customer_id integer NOT NULL, - staff_id integer NOT NULL, - rental_id integer NOT NULL, - amount numeric(5,2) NOT NULL, - payment_date timestamptz, - CONSTRAINT payment_p2022_01_pkey PRIMARY KEY (payment_date, payment_id), +CREATE TABLE IF NOT EXISTS payment_p2022_01 PARTITION OF payment ( CONSTRAINT payment_p2022_01_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customer (customer_id), CONSTRAINT payment_p2022_01_rental_id_fkey FOREIGN KEY (rental_id) REFERENCES rental (rental_id), CONSTRAINT payment_p2022_01_staff_id_fkey FOREIGN KEY (staff_id) REFERENCES staff (staff_id) -); +) FOR VALUES FROM ('2022-01-01 00:00:00+00') TO ('2022-02-01 00:00:00+00'); -- -- Name: idx_fk_payment_p2022_01_customer_id; Type: INDEX; Schema: -; Owner: - @@ -385,18 +378,11 @@ CREATE INDEX IF NOT EXISTS payment_p2022_01_customer_id_idx ON payment_p2022_01 -- Name: payment_p2022_02; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS payment_p2022_02 ( - payment_id SERIAL, - customer_id integer NOT NULL, - staff_id integer NOT NULL, - rental_id integer NOT NULL, - amount numeric(5,2) NOT NULL, - payment_date timestamptz, - CONSTRAINT payment_p2022_02_pkey PRIMARY KEY (payment_date, payment_id), +CREATE TABLE IF NOT EXISTS payment_p2022_02 PARTITION OF payment ( CONSTRAINT payment_p2022_02_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customer (customer_id), CONSTRAINT payment_p2022_02_rental_id_fkey FOREIGN KEY (rental_id) REFERENCES rental (rental_id), CONSTRAINT payment_p2022_02_staff_id_fkey FOREIGN KEY (staff_id) REFERENCES staff (staff_id) -); +) FOR VALUES FROM ('2022-02-01 00:00:00+00') TO ('2022-03-01 00:00:00+00'); -- -- Name: idx_fk_payment_p2022_02_customer_id; Type: INDEX; Schema: -; Owner: - @@ -420,18 +406,11 @@ CREATE INDEX IF NOT EXISTS payment_p2022_02_customer_id_idx ON payment_p2022_02 -- Name: payment_p2022_03; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS payment_p2022_03 ( - payment_id SERIAL, - customer_id integer NOT NULL, - staff_id integer NOT NULL, - rental_id integer NOT NULL, - amount numeric(5,2) NOT NULL, - payment_date timestamptz, - CONSTRAINT payment_p2022_03_pkey PRIMARY KEY (payment_date, payment_id), +CREATE TABLE IF NOT EXISTS payment_p2022_03 PARTITION OF payment ( CONSTRAINT payment_p2022_03_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customer (customer_id), CONSTRAINT payment_p2022_03_rental_id_fkey FOREIGN KEY (rental_id) REFERENCES rental (rental_id), CONSTRAINT payment_p2022_03_staff_id_fkey FOREIGN KEY (staff_id) REFERENCES staff (staff_id) -); +) FOR VALUES FROM ('2022-03-01 00:00:00+00') TO ('2022-04-01 00:00:00+00'); -- -- Name: idx_fk_payment_p2022_03_customer_id; Type: INDEX; Schema: -; Owner: - @@ -455,18 +434,11 @@ CREATE INDEX IF NOT EXISTS payment_p2022_03_customer_id_idx ON payment_p2022_03 -- Name: payment_p2022_04; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS payment_p2022_04 ( - payment_id SERIAL, - customer_id integer NOT NULL, - staff_id integer NOT NULL, - rental_id integer NOT NULL, - amount numeric(5,2) NOT NULL, - payment_date timestamptz, - CONSTRAINT payment_p2022_04_pkey PRIMARY KEY (payment_date, payment_id), +CREATE TABLE IF NOT EXISTS payment_p2022_04 PARTITION OF payment ( CONSTRAINT payment_p2022_04_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customer (customer_id), CONSTRAINT payment_p2022_04_rental_id_fkey FOREIGN KEY (rental_id) REFERENCES rental (rental_id), CONSTRAINT payment_p2022_04_staff_id_fkey FOREIGN KEY (staff_id) REFERENCES staff (staff_id) -); +) FOR VALUES FROM ('2022-04-01 00:00:00+00') TO ('2022-05-01 00:00:00+00'); -- -- Name: idx_fk_payment_p2022_04_customer_id; Type: INDEX; Schema: -; Owner: - @@ -490,18 +462,11 @@ CREATE INDEX IF NOT EXISTS payment_p2022_04_customer_id_idx ON payment_p2022_04 -- Name: payment_p2022_05; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS payment_p2022_05 ( - payment_id SERIAL, - customer_id integer NOT NULL, - staff_id integer NOT NULL, - rental_id integer NOT NULL, - amount numeric(5,2) NOT NULL, - payment_date timestamptz, - CONSTRAINT payment_p2022_05_pkey PRIMARY KEY (payment_date, payment_id), +CREATE TABLE IF NOT EXISTS payment_p2022_05 PARTITION OF payment ( CONSTRAINT payment_p2022_05_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customer (customer_id), CONSTRAINT payment_p2022_05_rental_id_fkey FOREIGN KEY (rental_id) REFERENCES rental (rental_id), CONSTRAINT payment_p2022_05_staff_id_fkey FOREIGN KEY (staff_id) REFERENCES staff (staff_id) -); +) FOR VALUES FROM ('2022-05-01 00:00:00+00') TO ('2022-06-01 00:00:00+00'); -- -- Name: idx_fk_payment_p2022_05_customer_id; Type: INDEX; Schema: -; Owner: - @@ -525,18 +490,11 @@ CREATE INDEX IF NOT EXISTS payment_p2022_05_customer_id_idx ON payment_p2022_05 -- Name: payment_p2022_06; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS payment_p2022_06 ( - payment_id SERIAL, - customer_id integer NOT NULL, - staff_id integer NOT NULL, - rental_id integer NOT NULL, - amount numeric(5,2) NOT NULL, - payment_date timestamptz, - CONSTRAINT payment_p2022_06_pkey PRIMARY KEY (payment_date, payment_id), +CREATE TABLE IF NOT EXISTS payment_p2022_06 PARTITION OF payment ( CONSTRAINT payment_p2022_06_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customer (customer_id), CONSTRAINT payment_p2022_06_rental_id_fkey FOREIGN KEY (rental_id) REFERENCES rental (rental_id), CONSTRAINT payment_p2022_06_staff_id_fkey FOREIGN KEY (staff_id) REFERENCES staff (staff_id) -); +) FOR VALUES FROM ('2022-06-01 00:00:00+00') TO ('2022-07-01 00:00:00+00'); -- -- Name: idx_fk_payment_p2022_06_customer_id; Type: INDEX; Schema: -; Owner: - @@ -560,18 +518,11 @@ CREATE INDEX IF NOT EXISTS payment_p2022_06_customer_id_idx ON payment_p2022_06 -- Name: payment_p2022_07; Type: TABLE; Schema: -; Owner: - -- -CREATE TABLE IF NOT EXISTS payment_p2022_07 ( - payment_id SERIAL, - customer_id integer NOT NULL, - staff_id integer NOT NULL, - rental_id integer NOT NULL, - amount numeric(5,2) NOT NULL, - payment_date timestamptz, - CONSTRAINT payment_p2022_07_pkey PRIMARY KEY (payment_date, payment_id), +CREATE TABLE IF NOT EXISTS payment_p2022_07 PARTITION OF payment ( CONSTRAINT payment_p2022_07_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES customer (customer_id), CONSTRAINT payment_p2022_07_rental_id_fkey FOREIGN KEY (rental_id) REFERENCES rental (rental_id), CONSTRAINT payment_p2022_07_staff_id_fkey FOREIGN KEY (staff_id) REFERENCES staff (staff_id) -); +) FOR VALUES FROM ('2022-07-01 00:00:00+00') TO ('2022-08-01 00:00:00+00'); -- -- Name: idx_fk_payment_p2022_07_customer_id; Type: INDEX; Schema: -; Owner: -