diff --git a/internal/diff/constraint.go b/internal/diff/constraint.go index df1d06a1..614522f1 100644 --- a/internal/diff/constraint.go +++ b/internal/diff/constraint.go @@ -56,6 +56,9 @@ func generateConstraintSQL(constraint *ir.Constraint, targetSchema string, quali ir.QuoteIdentifier(constraint.Name), strings.Join(cols, ", "), qualifiedRefTable, strings.Join(refCols, ", ")) + if constraint.MatchFull { + stmt += " MATCH FULL" + } // Only add ON UPDATE/DELETE if they are not the default "NO ACTION" if constraint.UpdateRule != "" && constraint.UpdateRule != "NO ACTION" { stmt += fmt.Sprintf(" ON UPDATE %s", constraint.UpdateRule) @@ -189,6 +192,9 @@ func constraintsEqual(old, new *ir.Constraint) bool { if old.UpdateRule != new.UpdateRule { return false } + if old.MatchFull != new.MatchFull { + return false + } if old.Deferrable != new.Deferrable { return false } diff --git a/internal/diff/table.go b/internal/diff/table.go index c9fc2e6d..466d0dc5 100644 --- a/internal/diff/table.go +++ b/internal/diff/table.go @@ -2225,6 +2225,10 @@ func generateForeignKeyClauseMode(constraint *ir.Constraint, targetSchema string } } + if constraint.MatchFull { + clause += " MATCH FULL" + } + // Add referential actions if constraint.UpdateRule != "" && constraint.UpdateRule != "NO ACTION" { clause += fmt.Sprintf(" ON UPDATE %s", constraint.UpdateRule) diff --git a/internal/plan/rewrite.go b/internal/plan/rewrite.go index 2c261172..88ccf52c 100644 --- a/internal/plan/rewrite.go +++ b/internal/plan/rewrite.go @@ -316,6 +316,10 @@ func generateForeignKeyRewrite(constraint *ir.Constraint) []RewriteStep { refTableName, joinStrings(refColumnNames, ", ")) + if constraint.MatchFull { + fkClause += " MATCH FULL" + } + // Add ON UPDATE/DELETE clauses if specified (in correct order) if constraint.UpdateRule != "" && constraint.UpdateRule != "NO ACTION" { fkClause += fmt.Sprintf(" ON UPDATE %s", constraint.UpdateRule) diff --git a/ir/inspector.go b/ir/inspector.go index 7ccd0f0d..3082dec5 100644 --- a/ir/inspector.go +++ b/ir/inspector.go @@ -639,6 +639,7 @@ func (i *Inspector) buildConstraints(ctx context.Context, schema *IR, targetSche if updateRule := i.safeInterfaceToString(constraint.UpdateRule); updateRule != "" && updateRule != "" { c.UpdateRule = updateRule } + c.MatchFull = constraint.MatchFull.Bool } // Handle check constraints diff --git a/ir/ir.go b/ir/ir.go index ea3c8dc6..4c46b354 100644 --- a/ir/ir.go +++ b/ir/ir.go @@ -262,6 +262,7 @@ type Constraint struct { DeleteRule string `json:"delete_rule,omitempty"` DeleteSetColumns []string `json:"delete_set_columns,omitempty"` // PG15+: column list of ON DELETE SET NULL/SET DEFAULT (confdelsetcols) UpdateRule string `json:"update_rule,omitempty"` + MatchFull bool `json:"match_full,omitempty"` // FOREIGN KEY ... MATCH FULL (confmatchtype = 'f') Deferrable bool `json:"deferrable,omitempty"` InitiallyDeferred bool `json:"initially_deferred,omitempty"` IsValid bool `json:"is_valid,omitempty"` diff --git a/ir/queries/queries.sql b/ir/queries/queries.sql index 7b97e7c3..f098cb2f 100644 --- a/ir/queries/queries.sql +++ b/ir/queries/queries.sql @@ -424,6 +424,8 @@ SELECT c.convalidated AS is_valid, COALESCE((to_jsonb(c) ->> 'conperiod')::boolean, false) AS is_period, c.connoinherit AS no_inherit, + -- MATCH FULL (pg_constraint.confmatchtype = 'f'); only foreign keys can set it. + (c.confmatchtype = 'f') AS match_full, -- ON DELETE SET NULL/SET DEFAULT (column list), PG15+ (pg_constraint.confdelsetcols). -- Rendered as a JSON array of column names so it survives the per-column row fan-out -- and stays a single scalar on PG14 (where the attribute does not exist). Issue #589. @@ -1418,6 +1420,8 @@ SELECT -- pg_index.indnullsnotdistinct is PG15+. Use to_jsonb so the column reference -- doesn't fail to plan on PG14 (where the attribute does not exist on pg_index). COALESCE((to_jsonb(i) ->> 'indnullsnotdistinct')::boolean, false) AS nulls_not_distinct, + -- MATCH FULL (pg_constraint.confmatchtype = 'f'); only foreign keys can set it. + (c.confmatchtype = 'f') AS match_full, -- ON DELETE SET NULL/SET DEFAULT (column list), PG15+ (pg_constraint.confdelsetcols). -- Rendered as a JSON array of column names so it survives the per-column row fan-out -- and stays a single scalar on PG14 (where the attribute does not exist). Issue #589. diff --git a/ir/queries/queries.sql.go b/ir/queries/queries.sql.go index 48d076d5..8f05d7b0 100644 --- a/ir/queries/queries.sql.go +++ b/ir/queries/queries.sql.go @@ -1062,6 +1062,8 @@ SELECT c.convalidated AS is_valid, COALESCE((to_jsonb(c) ->> 'conperiod')::boolean, false) AS is_period, c.connoinherit AS no_inherit, + -- MATCH FULL (pg_constraint.confmatchtype = 'f'); only foreign keys can set it. + (c.confmatchtype = 'f') AS match_full, -- ON DELETE SET NULL/SET DEFAULT (column list), PG15+ (pg_constraint.confdelsetcols). -- Rendered as a JSON array of column names so it survives the per-column row fan-out -- and stays a single scalar on PG14 (where the attribute does not exist). Issue #589. @@ -1132,6 +1134,7 @@ type GetConstraintsRow struct { IsValid bool `db:"is_valid" json:"is_valid"` IsPeriod sql.NullBool `db:"is_period" json:"is_period"` NoInherit bool `db:"no_inherit" json:"no_inherit"` + MatchFull sql.NullBool `db:"match_full" json:"match_full"` DeleteSetColumns sql.NullString `db:"delete_set_columns" json:"delete_set_columns"` } @@ -1165,6 +1168,7 @@ func (q *Queries) GetConstraints(ctx context.Context) ([]GetConstraintsRow, erro &i.IsValid, &i.IsPeriod, &i.NoInherit, + &i.MatchFull, &i.DeleteSetColumns, ); err != nil { return nil, err @@ -1233,6 +1237,8 @@ SELECT -- pg_index.indnullsnotdistinct is PG15+. Use to_jsonb so the column reference -- doesn't fail to plan on PG14 (where the attribute does not exist on pg_index). COALESCE((to_jsonb(i) ->> 'indnullsnotdistinct')::boolean, false) AS nulls_not_distinct, + -- MATCH FULL (pg_constraint.confmatchtype = 'f'); only foreign keys can set it. + (c.confmatchtype = 'f') AS match_full, -- ON DELETE SET NULL/SET DEFAULT (column list), PG15+ (pg_constraint.confdelsetcols). -- Rendered as a JSON array of column names so it survives the per-column row fan-out -- and stays a single scalar on PG14 (where the attribute does not exist). Issue #589. @@ -1304,6 +1310,7 @@ type GetConstraintsForSchemaRow struct { IsPeriod sql.NullBool `db:"is_period" json:"is_period"` NoInherit bool `db:"no_inherit" json:"no_inherit"` NullsNotDistinct sql.NullBool `db:"nulls_not_distinct" json:"nulls_not_distinct"` + MatchFull sql.NullBool `db:"match_full" json:"match_full"` DeleteSetColumns sql.NullString `db:"delete_set_columns" json:"delete_set_columns"` } @@ -1339,6 +1346,7 @@ func (q *Queries) GetConstraintsForSchema(ctx context.Context, dollar_1 sql.Null &i.IsPeriod, &i.NoInherit, &i.NullsNotDistinct, + &i.MatchFull, &i.DeleteSetColumns, ); err != nil { return nil, err diff --git a/testdata/diff/create_table/add_fk/diff.sql b/testdata/diff/create_table/add_fk/diff.sql index 2f2a2026..65171e6c 100644 --- a/testdata/diff/create_table/add_fk/diff.sql +++ b/testdata/diff/create_table/add_fk/diff.sql @@ -33,6 +33,14 @@ ADD CONSTRAINT products_category_code_fkey FOREIGN KEY (category_code) REFERENCE ALTER TABLE projects ADD CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id); +ALTER TABLE returns DROP CONSTRAINT returns_region_id_warehouse_id_fkey; + +ALTER TABLE returns +ADD CONSTRAINT returns_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES warehouses (region_id, warehouse_id) MATCH FULL; + +ALTER TABLE shipments +ADD CONSTRAINT shipments_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES warehouses (region_id, warehouse_id) MATCH FULL; + ALTER TABLE tasks ADD CONSTRAINT tasks_org_id_owner_member_id_fkey FOREIGN KEY (org_id, owner_member_id) REFERENCES members (org_id, id) ON DELETE SET DEFAULT (owner_member_id); diff --git a/testdata/diff/create_table/add_fk/new.sql b/testdata/diff/create_table/add_fk/new.sql index 71e5ab5b..f1410265 100644 --- a/testdata/diff/create_table/add_fk/new.sql +++ b/testdata/diff/create_table/add_fk/new.sql @@ -150,6 +150,31 @@ CREATE TABLE public.notes ( CONSTRAINT notes_org_id_author_member_id_fkey FOREIGN KEY (org_id, author_member_id) REFERENCES public.members(org_id, id) ON DELETE SET NULL (author_member_id) ); +-- FK with MATCH FULL case: added on a new constraint +CREATE TABLE public.warehouses ( + region_id integer NOT NULL, + warehouse_id integer NOT NULL, + CONSTRAINT warehouses_pkey PRIMARY KEY (region_id, warehouse_id) +); + +CREATE TABLE public.shipments ( + id integer NOT NULL, + region_id integer, + warehouse_id integer, + CONSTRAINT shipments_pkey PRIMARY KEY (id), + CONSTRAINT shipments_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES public.warehouses(region_id, warehouse_id) MATCH FULL +); + +-- Existing FK that is simple: the desired state adds MATCH FULL, so the +-- constraint must be recreated (the match type must be compared). +CREATE TABLE public.returns ( + id integer NOT NULL, + region_id integer, + warehouse_id integer, + CONSTRAINT returns_pkey PRIMARY KEY (id), + CONSTRAINT returns_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES public.warehouses(region_id, warehouse_id) MATCH FULL +); + -- Temporal FK case (PG18+) CREATE TABLE public.price_history ( product_id integer NOT NULL, diff --git a/testdata/diff/create_table/add_fk/old.sql b/testdata/diff/create_table/add_fk/old.sql index 6132e13d..b01fd3c9 100644 --- a/testdata/diff/create_table/add_fk/old.sql +++ b/testdata/diff/create_table/add_fk/old.sql @@ -138,6 +138,30 @@ CREATE TABLE public.notes ( CONSTRAINT notes_org_id_author_member_id_fkey FOREIGN KEY (org_id, author_member_id) REFERENCES public.members(org_id, id) ON DELETE SET NULL ); +-- FK with MATCH FULL case: added on a new constraint +CREATE TABLE public.warehouses ( + region_id integer NOT NULL, + warehouse_id integer NOT NULL, + CONSTRAINT warehouses_pkey PRIMARY KEY (region_id, warehouse_id) +); + +CREATE TABLE public.shipments ( + id integer NOT NULL, + region_id integer, + warehouse_id integer, + CONSTRAINT shipments_pkey PRIMARY KEY (id) +); + +-- Existing FK that is simple: the desired state adds MATCH FULL, so the +-- constraint must be recreated (the match type must be compared). +CREATE TABLE public.returns ( + id integer NOT NULL, + region_id integer, + warehouse_id integer, + CONSTRAINT returns_pkey PRIMARY KEY (id), + CONSTRAINT returns_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES public.warehouses(region_id, warehouse_id) +); + -- Temporal FK case (PG18+) CREATE TABLE public.price_history ( product_id integer NOT NULL, diff --git a/testdata/diff/create_table/add_fk/plan.json b/testdata/diff/create_table/add_fk/plan.json index f3f4aa08..553db8aa 100644 --- a/testdata/diff/create_table/add_fk/plan.json +++ b/testdata/diff/create_table/add_fk/plan.json @@ -3,7 +3,7 @@ "pgschema_version": "1.13.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "d362a1d307cacbda3523c26227836ff883ea2839ece7b16eec4eb53c5d6959d6" + "hash": "24701480f5a3206f0530e8cce038066c4b550ffcd8c097e683d15e12b2441726" }, "groups": [ { @@ -232,6 +232,52 @@ } ] }, + { + "steps": [ + { + "sql": "ALTER TABLE returns DROP CONSTRAINT returns_region_id_warehouse_id_fkey;", + "type": "table.constraint", + "operation": "drop", + "path": "public.returns.returns_region_id_warehouse_id_fkey" + }, + { + "sql": "ALTER TABLE returns\nADD CONSTRAINT returns_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES warehouses (region_id, warehouse_id) MATCH FULL NOT VALID;", + "type": "table.constraint", + "operation": "create", + "path": "public.returns.returns_region_id_warehouse_id_fkey" + } + ] + }, + { + "steps": [ + { + "sql": "ALTER TABLE returns VALIDATE CONSTRAINT returns_region_id_warehouse_id_fkey;", + "type": "table.constraint", + "operation": "create", + "path": "public.returns.returns_region_id_warehouse_id_fkey" + } + ] + }, + { + "steps": [ + { + "sql": "ALTER TABLE shipments\nADD CONSTRAINT shipments_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES warehouses (region_id, warehouse_id) MATCH FULL NOT VALID;", + "type": "table.constraint", + "operation": "create", + "path": "public.shipments.shipments_region_id_warehouse_id_fkey" + } + ] + }, + { + "steps": [ + { + "sql": "ALTER TABLE shipments VALIDATE CONSTRAINT shipments_region_id_warehouse_id_fkey;", + "type": "table.constraint", + "operation": "create", + "path": "public.shipments.shipments_region_id_warehouse_id_fkey" + } + ] + }, { "steps": [ { diff --git a/testdata/diff/create_table/add_fk/plan.sql b/testdata/diff/create_table/add_fk/plan.sql index 74b1dddc..25ad9b5b 100644 --- a/testdata/diff/create_table/add_fk/plan.sql +++ b/testdata/diff/create_table/add_fk/plan.sql @@ -55,6 +55,18 @@ ADD CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) RE ALTER TABLE projects VALIDATE CONSTRAINT projects_tenant_id_org_id_fkey; +ALTER TABLE returns DROP CONSTRAINT returns_region_id_warehouse_id_fkey; + +ALTER TABLE returns +ADD CONSTRAINT returns_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES warehouses (region_id, warehouse_id) MATCH FULL NOT VALID; + +ALTER TABLE returns VALIDATE CONSTRAINT returns_region_id_warehouse_id_fkey; + +ALTER TABLE shipments +ADD CONSTRAINT shipments_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES warehouses (region_id, warehouse_id) MATCH FULL NOT VALID; + +ALTER TABLE shipments VALIDATE CONSTRAINT shipments_region_id_warehouse_id_fkey; + ALTER TABLE tasks ADD CONSTRAINT tasks_org_id_owner_member_id_fkey FOREIGN KEY (org_id, owner_member_id) REFERENCES members (org_id, id) ON DELETE SET DEFAULT (owner_member_id) NOT VALID; diff --git a/testdata/diff/create_table/add_fk/plan.txt b/testdata/diff/create_table/add_fk/plan.txt index 692bc4d3..e7aae0d3 100644 --- a/testdata/diff/create_table/add_fk/plan.txt +++ b/testdata/diff/create_table/add_fk/plan.txt @@ -1,7 +1,7 @@ -Plan: 12 to modify. +Plan: 14 to modify. Summary by type: - tables: 12 to modify + tables: 14 to modify Tables: ~ audit_log @@ -25,6 +25,11 @@ Tables: + products_category_code_fkey (constraint) ~ projects + projects_tenant_id_org_id_fkey (constraint) + ~ returns + - returns_region_id_warehouse_id_fkey (constraint) + + returns_region_id_warehouse_id_fkey (constraint) + ~ shipments + + shipments_region_id_warehouse_id_fkey (constraint) ~ tasks + tasks_org_id_owner_member_id_fkey (constraint) ~ teams @@ -115,22 +120,38 @@ ADD CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) RE ALTER TABLE projects VALIDATE CONSTRAINT projects_tenant_id_org_id_fkey; -- Transaction Group #23 +ALTER TABLE returns DROP CONSTRAINT returns_region_id_warehouse_id_fkey; + +ALTER TABLE returns +ADD CONSTRAINT returns_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES warehouses (region_id, warehouse_id) MATCH FULL NOT VALID; + +-- Transaction Group #24 +ALTER TABLE returns VALIDATE CONSTRAINT returns_region_id_warehouse_id_fkey; + +-- Transaction Group #25 +ALTER TABLE shipments +ADD CONSTRAINT shipments_region_id_warehouse_id_fkey FOREIGN KEY (region_id, warehouse_id) REFERENCES warehouses (region_id, warehouse_id) MATCH FULL NOT VALID; + +-- Transaction Group #26 +ALTER TABLE shipments VALIDATE CONSTRAINT shipments_region_id_warehouse_id_fkey; + +-- Transaction Group #27 ALTER TABLE tasks ADD CONSTRAINT tasks_org_id_owner_member_id_fkey FOREIGN KEY (org_id, owner_member_id) REFERENCES members (org_id, id) ON DELETE SET DEFAULT (owner_member_id) NOT VALID; --- Transaction Group #24 +-- Transaction Group #28 ALTER TABLE tasks VALIDATE CONSTRAINT tasks_org_id_owner_member_id_fkey; --- Transaction Group #25 +-- Transaction Group #29 ALTER TABLE teams ADD CONSTRAINT teams_manager_id_fkey FOREIGN KEY (manager_id) REFERENCES managers (id) ON DELETE SET NULL NOT VALID; --- Transaction Group #26 +-- Transaction Group #30 ALTER TABLE teams VALIDATE CONSTRAINT teams_manager_id_fkey; --- Transaction Group #27 +-- Transaction Group #31 ALTER TABLE user_profiles ADD CONSTRAINT user_profiles_user_id_fkey FOREIGN KEY (user_id) REFERENCES users (id) DEFERRABLE INITIALLY DEFERRED NOT VALID; --- Transaction Group #28 +-- Transaction Group #32 ALTER TABLE user_profiles VALIDATE CONSTRAINT user_profiles_user_id_fkey; diff --git a/testdata/diff/create_table/add_table_composite_keys/diff.sql b/testdata/diff/create_table/add_table_composite_keys/diff.sql index b6e096ef..eb762117 100644 --- a/testdata/diff/create_table/add_table_composite_keys/diff.sql +++ b/testdata/diff/create_table/add_table_composite_keys/diff.sql @@ -16,5 +16,5 @@ CREATE TABLE IF NOT EXISTS projects ( description text, CONSTRAINT projects_pkey PRIMARY KEY (tenant_id, org_id, project_id), CONSTRAINT projects_project_name_tenant_id_project_id_key UNIQUE (project_name, tenant_id, project_id), - CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id) + CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id) MATCH FULL ); diff --git a/testdata/diff/create_table/add_table_composite_keys/new.sql b/testdata/diff/create_table/add_table_composite_keys/new.sql index b5ec83ef..d2ee1f06 100644 --- a/testdata/diff/create_table/add_table_composite_keys/new.sql +++ b/testdata/diff/create_table/add_table_composite_keys/new.sql @@ -15,6 +15,6 @@ CREATE TABLE public.projects ( project_code text NOT NULL, description text, PRIMARY KEY (tenant_id, org_id, project_id), - FOREIGN KEY (tenant_id, org_id) REFERENCES public.organizations(tenant_id, org_id), + FOREIGN KEY (tenant_id, org_id) REFERENCES public.organizations(tenant_id, org_id) MATCH FULL, UNIQUE (project_name, tenant_id, project_id) ); \ No newline at end of file diff --git a/testdata/diff/create_table/add_table_composite_keys/plan.json b/testdata/diff/create_table/add_table_composite_keys/plan.json index 6dc0a088..1fbc5974 100644 --- a/testdata/diff/create_table/add_table_composite_keys/plan.json +++ b/testdata/diff/create_table/add_table_composite_keys/plan.json @@ -15,7 +15,7 @@ "path": "public.organizations" }, { - "sql": "CREATE TABLE IF NOT EXISTS projects (\n tenant_id integer,\n org_id integer,\n project_id integer,\n project_name text NOT NULL,\n project_code text NOT NULL,\n description text,\n CONSTRAINT projects_pkey PRIMARY KEY (tenant_id, org_id, project_id),\n CONSTRAINT projects_project_name_tenant_id_project_id_key UNIQUE (project_name, tenant_id, project_id),\n CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id)\n);", + "sql": "CREATE TABLE IF NOT EXISTS projects (\n tenant_id integer,\n org_id integer,\n project_id integer,\n project_name text NOT NULL,\n project_code text NOT NULL,\n description text,\n CONSTRAINT projects_pkey PRIMARY KEY (tenant_id, org_id, project_id),\n CONSTRAINT projects_project_name_tenant_id_project_id_key UNIQUE (project_name, tenant_id, project_id),\n CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id) MATCH FULL\n);", "type": "table", "operation": "create", "path": "public.projects" diff --git a/testdata/diff/create_table/add_table_composite_keys/plan.sql b/testdata/diff/create_table/add_table_composite_keys/plan.sql index b6e096ef..eb762117 100644 --- a/testdata/diff/create_table/add_table_composite_keys/plan.sql +++ b/testdata/diff/create_table/add_table_composite_keys/plan.sql @@ -16,5 +16,5 @@ CREATE TABLE IF NOT EXISTS projects ( description text, CONSTRAINT projects_pkey PRIMARY KEY (tenant_id, org_id, project_id), CONSTRAINT projects_project_name_tenant_id_project_id_key UNIQUE (project_name, tenant_id, project_id), - CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id) + CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id) MATCH FULL ); diff --git a/testdata/diff/create_table/add_table_composite_keys/plan.txt b/testdata/diff/create_table/add_table_composite_keys/plan.txt index f7c86fd2..96e37014 100644 --- a/testdata/diff/create_table/add_table_composite_keys/plan.txt +++ b/testdata/diff/create_table/add_table_composite_keys/plan.txt @@ -28,5 +28,5 @@ CREATE TABLE IF NOT EXISTS projects ( description text, CONSTRAINT projects_pkey PRIMARY KEY (tenant_id, org_id, project_id), CONSTRAINT projects_project_name_tenant_id_project_id_key UNIQUE (project_name, tenant_id, project_id), - CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id) + CONSTRAINT projects_tenant_id_org_id_fkey FOREIGN KEY (tenant_id, org_id) REFERENCES organizations (tenant_id, org_id) MATCH FULL );