Skip to content

Commit 0daaf17

Browse files
bhowmik-abhijeetAbhijeet Bhowmik
and
Abhijeet Bhowmik
authored
fix: AfterQuery using safer right trim while clearing from clause's join added as part of #7027 (#7153)
Co-authored-by: Abhijeet Bhowmik <[email protected]>
1 parent 0dbfda5 commit 0daaf17

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

callbacks/query.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ func AfterQuery(db *gorm.DB) {
288288
// clear the joins after query because preload need it
289289
if v, ok := db.Statement.Clauses["FROM"].Expression.(clause.From); ok {
290290
fromClause := db.Statement.Clauses["FROM"]
291-
fromClause.Expression = clause.From{Tables: v.Tables, Joins: v.Joins[:len(v.Joins)-len(db.Statement.Joins)]} // keep the original From Joins
291+
fromClause.Expression = clause.From{Tables: v.Tables, Joins: utils.RTrimSlice(v.Joins, len(db.Statement.Joins))} // keep the original From Joins
292292
db.Statement.Clauses["FROM"] = fromClause
293293
}
294294
if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && db.Statement.Schema.AfterFind && db.RowsAffected > 0 {

utils/utils.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,14 @@ func SplitNestedRelationName(name string) []string {
166166
func JoinNestedRelationNames(relationNames []string) string {
167167
return strings.Join(relationNames, nestedRelationSplit)
168168
}
169+
170+
// RTrimSlice Right trims the given slice by given length
171+
func RTrimSlice[T any](v []T, trimLen int) []T {
172+
if trimLen >= len(v) { // trimLen greater than slice len means fully sliced
173+
return v[:0]
174+
}
175+
if trimLen < 0 { // negative trimLen is ignored
176+
return v[:]
177+
}
178+
return v[:len(v)-trimLen]
179+
}

utils/utils_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,64 @@ func TestToString(t *testing.T) {
138138
})
139139
}
140140
}
141+
142+
func TestRTrimSlice(t *testing.T) {
143+
tests := []struct {
144+
name string
145+
input []int
146+
trimLen int
147+
expected []int
148+
}{
149+
{
150+
name: "Trim two elements from end",
151+
input: []int{1, 2, 3, 4, 5},
152+
trimLen: 2,
153+
expected: []int{1, 2, 3},
154+
},
155+
{
156+
name: "Trim entire slice",
157+
input: []int{1, 2, 3},
158+
trimLen: 3,
159+
expected: []int{},
160+
},
161+
{
162+
name: "Trim length greater than slice length",
163+
input: []int{1, 2, 3},
164+
trimLen: 5,
165+
expected: []int{},
166+
},
167+
{
168+
name: "Zero trim length",
169+
input: []int{1, 2, 3},
170+
trimLen: 0,
171+
expected: []int{1, 2, 3},
172+
},
173+
{
174+
name: "Trim one element from end",
175+
input: []int{1, 2, 3},
176+
trimLen: 1,
177+
expected: []int{1, 2},
178+
},
179+
{
180+
name: "Empty slice",
181+
input: []int{},
182+
trimLen: 2,
183+
expected: []int{},
184+
},
185+
{
186+
name: "Negative trim length (should be treated as zero)",
187+
input: []int{1, 2, 3},
188+
trimLen: -1,
189+
expected: []int{1, 2, 3},
190+
},
191+
}
192+
193+
for _, testcase := range tests {
194+
t.Run(testcase.name, func(t *testing.T) {
195+
result := RTrimSlice(testcase.input, testcase.trimLen)
196+
if !AssertEqual(result, testcase.expected) {
197+
t.Errorf("RTrimSlice(%v, %d) = %v; want %v", testcase.input, testcase.trimLen, result, testcase.expected)
198+
}
199+
})
200+
}
201+
}

0 commit comments

Comments
 (0)