Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions ir/inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,15 +550,15 @@ func (i *Inspector) buildConstraints(ctx context.Context, schema *IR, targetSche

// Add referenced column only if it doesn't exist
if !refColumnExists {
// Get the foreign ordinal position for proper ordering
refPosition := position // Default fallback to source position
if constraint.ForeignOrdinalPosition.Valid {
refPosition = int(constraint.ForeignOrdinalPosition.Int32)
}

// Use the local column's constraint position for the referenced column.
// The local and referenced columns are paired together in the FK definition,
// so they must have the same position to maintain correct ordering.
// Note: ForeignOrdinalPosition from the query is fa.attnum (column position
// in the foreign table's definition), which is wrong - we need the constraint
// array position, which is the same as the local column's position.
refConstraintCol := &ConstraintColumn{
Name: refColumnName,
Position: refPosition, // Use foreign ordinal position for referenced column
Position: position, // Use local column's constraint position
}
c.ReferencedColumns = append(c.ReferencedColumns, refConstraintCol)
}
Expand Down
2 changes: 2 additions & 0 deletions testdata/diff/create_table/composite_fk_column_order/diff.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE order_items
ADD CONSTRAINT fk_order_items_order FOREIGN KEY (customer_id, order_id) REFERENCES orders (customer_id, order_id);
22 changes: 22 additions & 0 deletions testdata/diff/create_table/composite_fk_column_order/new.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- Test case: Composite FK where FK column order differs from table column order
-- This tests that constraint column ordering is preserved independently of table column order

-- Referenced table with composite primary key
CREATE TABLE public.orders (
order_id integer NOT NULL,
customer_id integer NOT NULL,
name varchar(255) NOT NULL,
CONSTRAINT orders_pkey PRIMARY KEY (customer_id, order_id)
);

-- Referencing table where columns are defined in OPPOSITE order from how FK references them
CREATE TABLE public.order_items (
id serial PRIMARY KEY,
-- Table defines columns in this order: order_id first (lower attnum), then customer_id (higher attnum)
order_id integer NOT NULL,
customer_id integer NOT NULL,
quantity integer NOT NULL,
-- FK references columns in DIFFERENT order than table definition
-- customer_id is listed first in FK, but has higher attnum in table
CONSTRAINT fk_order_items_order FOREIGN KEY (customer_id, order_id) REFERENCES public.orders(customer_id, order_id)
);
19 changes: 19 additions & 0 deletions testdata/diff/create_table/composite_fk_column_order/old.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-- Test case: Composite FK where FK column order differs from table column order
-- This tests that constraint column ordering is preserved independently of table column order

-- Referenced table with composite primary key
CREATE TABLE public.orders (
order_id integer NOT NULL,
customer_id integer NOT NULL,
name varchar(255) NOT NULL,
CONSTRAINT orders_pkey PRIMARY KEY (customer_id, order_id)
);

-- Referencing table where columns are defined in OPPOSITE order from how FK references them
CREATE TABLE public.order_items (
id serial PRIMARY KEY,
-- Table defines columns in this order: order_id first (lower attnum), then customer_id (higher attnum)
order_id integer NOT NULL,
customer_id integer NOT NULL,
quantity integer NOT NULL
);
26 changes: 26 additions & 0 deletions testdata/diff/create_table/composite_fk_column_order/plan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": "1.0.0",
"pgschema_version": "1.6.1",
"created_at": "1970-01-01T00:00:00Z",
"source_fingerprint": {
"hash": "1948e0ca8413d527d01353e9a8b4f4581198c99a5b994959bda5e05beb462153"
},
"groups": [
{
"steps": [
{
"sql": "ALTER TABLE order_items\nADD CONSTRAINT fk_order_items_order FOREIGN KEY (customer_id, order_id) REFERENCES orders (customer_id, order_id) NOT VALID;",
"type": "table.constraint",
"operation": "create",
"path": "public.order_items.fk_order_items_order"
},
{
"sql": "ALTER TABLE order_items VALIDATE CONSTRAINT fk_order_items_order;",
"type": "table.constraint",
"operation": "create",
"path": "public.order_items.fk_order_items_order"
}
]
}
]
}
4 changes: 4 additions & 0 deletions testdata/diff/create_table/composite_fk_column_order/plan.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE order_items
ADD CONSTRAINT fk_order_items_order FOREIGN KEY (customer_id, order_id) REFERENCES orders (customer_id, order_id) NOT VALID;

ALTER TABLE order_items VALIDATE CONSTRAINT fk_order_items_order;
16 changes: 16 additions & 0 deletions testdata/diff/create_table/composite_fk_column_order/plan.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Plan: 1 to modify.

Summary by type:
tables: 1 to modify

Tables:
~ order_items
+ fk_order_items_order (constraint)

DDL to be executed:
--------------------------------------------------

ALTER TABLE order_items
ADD CONSTRAINT fk_order_items_order FOREIGN KEY (customer_id, order_id) REFERENCES orders (customer_id, order_id) NOT VALID;

ALTER TABLE order_items VALIDATE CONSTRAINT fk_order_items_order;
Loading