@@ -100,6 +100,121 @@ func TestGenerateConstraintSQL_WithQuoting(t *testing.T) {
100100 }
101101}
102102
103+ func TestGenerateConstraintSQL_TemporalConstraints (t * testing.T ) {
104+ tests := []struct {
105+ name string
106+ constraint * ir.Constraint
107+ want string
108+ }{
109+ {
110+ name : "PRIMARY KEY WITHOUT OVERLAPS" ,
111+ constraint : & ir.Constraint {
112+ Name : "pk_temporal" ,
113+ Type : ir .ConstraintTypePrimaryKey ,
114+ Columns : []* ir.ConstraintColumn {
115+ {Name : "id" , Position : 1 },
116+ {Name : "valid_period" , Position : 2 },
117+ },
118+ WithoutOverlaps : true ,
119+ },
120+ want : `CONSTRAINT pk_temporal PRIMARY KEY (id, valid_period WITHOUT OVERLAPS)` ,
121+ },
122+ {
123+ name : "UNIQUE WITHOUT OVERLAPS" ,
124+ constraint : & ir.Constraint {
125+ Name : "uq_temporal" ,
126+ Type : ir .ConstraintTypeUnique ,
127+ Columns : []* ir.ConstraintColumn {
128+ {Name : "tenant_id" , Position : 1 },
129+ {Name : "valid_period" , Position : 2 },
130+ },
131+ WithoutOverlaps : true ,
132+ },
133+ want : `CONSTRAINT uq_temporal UNIQUE (tenant_id, valid_period WITHOUT OVERLAPS)` ,
134+ },
135+ {
136+ name : "FOREIGN KEY with PERIOD" ,
137+ constraint : & ir.Constraint {
138+ Name : "fk_temporal" ,
139+ Type : ir .ConstraintTypeForeignKey ,
140+ Columns : []* ir.ConstraintColumn {
141+ {Name : "parent_id" , Position : 1 },
142+ {Name : "valid_period" , Position : 2 },
143+ },
144+ ReferencedSchema : "public" ,
145+ ReferencedTable : "parent" ,
146+ ReferencedColumns : []* ir.ConstraintColumn {
147+ {Name : "id" , Position : 1 },
148+ {Name : "valid_period" , Position : 2 },
149+ },
150+ WithoutOverlaps : true ,
151+ IsValid : true ,
152+ },
153+ want : `CONSTRAINT fk_temporal FOREIGN KEY (parent_id, PERIOD valid_period) REFERENCES parent (id, PERIOD valid_period)` ,
154+ },
155+ {
156+ name : "PRIMARY KEY without WithoutOverlaps remains unchanged" ,
157+ constraint : & ir.Constraint {
158+ Name : "pk_normal" ,
159+ Type : ir .ConstraintTypePrimaryKey ,
160+ Columns : []* ir.ConstraintColumn {
161+ {Name : "id" , Position : 1 },
162+ },
163+ WithoutOverlaps : false ,
164+ },
165+ want : `CONSTRAINT pk_normal PRIMARY KEY (id)` ,
166+ },
167+ }
168+
169+ for _ , tt := range tests {
170+ t .Run (tt .name , func (t * testing.T ) {
171+ got := generateConstraintSQL (tt .constraint , "public" )
172+ if got != tt .want {
173+ t .Errorf ("generateConstraintSQL() = %q, want %q" , got , tt .want )
174+ }
175+ })
176+ }
177+ }
178+
179+ func TestConstraintsEqual_WithoutOverlaps (t * testing.T ) {
180+ base := & ir.Constraint {
181+ Name : "pk_temporal" ,
182+ Type : ir .ConstraintTypePrimaryKey ,
183+ Columns : []* ir.ConstraintColumn {
184+ {Name : "id" , Position : 1 },
185+ {Name : "valid_period" , Position : 2 },
186+ },
187+ WithoutOverlaps : true ,
188+ }
189+
190+ same := & ir.Constraint {
191+ Name : "pk_temporal" ,
192+ Type : ir .ConstraintTypePrimaryKey ,
193+ Columns : []* ir.ConstraintColumn {
194+ {Name : "id" , Position : 1 },
195+ {Name : "valid_period" , Position : 2 },
196+ },
197+ WithoutOverlaps : true ,
198+ }
199+
200+ different := & ir.Constraint {
201+ Name : "pk_temporal" ,
202+ Type : ir .ConstraintTypePrimaryKey ,
203+ Columns : []* ir.ConstraintColumn {
204+ {Name : "id" , Position : 1 },
205+ {Name : "valid_period" , Position : 2 },
206+ },
207+ WithoutOverlaps : false ,
208+ }
209+
210+ if ! constraintsEqual (base , same ) {
211+ t .Error ("constraintsEqual() should return true for identical temporal constraints" )
212+ }
213+ if constraintsEqual (base , different ) {
214+ t .Error ("constraintsEqual() should return false when WithoutOverlaps differs" )
215+ }
216+ }
217+
103218func TestCheckConstraintQuoting (t * testing.T ) {
104219 tests := []struct {
105220 name string
0 commit comments