Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: AfterQuery using safer right trim while clearing from clause's j… #7153

Merged
merged 1 commit into from
Aug 22, 2024
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
2 changes: 1 addition & 1 deletion callbacks/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func AfterQuery(db *gorm.DB) {
// clear the joins after query because preload need it
if v, ok := db.Statement.Clauses["FROM"].Expression.(clause.From); ok {
fromClause := db.Statement.Clauses["FROM"]
fromClause.Expression = clause.From{Tables: v.Tables, Joins: v.Joins[:len(v.Joins)-len(db.Statement.Joins)]} // keep the original From Joins
fromClause.Expression = clause.From{Tables: v.Tables, Joins: utils.RTrimSlice(v.Joins, len(db.Statement.Joins))} // keep the original From Joins
db.Statement.Clauses["FROM"] = fromClause
}
if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && db.Statement.Schema.AfterFind && db.RowsAffected > 0 {
Expand Down
11 changes: 11 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,14 @@
func JoinNestedRelationNames(relationNames []string) string {
return strings.Join(relationNames, nestedRelationSplit)
}

// RTrimSlice Right trims the given slice by given length
func RTrimSlice[T any](v []T, trimLen int) []T {
if trimLen >= len(v) { // trimLen greater than slice len means fully sliced
return v[:0]
}
if trimLen < 0 { // negative trimLen is ignored
return v[:]

Check failure on line 176 in utils/utils.go

View workflow job for this annotation

GitHub Actions / runner / golangci-lint

[golangci] reported by reviewdog 🐶 unslice: could simplify v[:] to v (gocritic) Raw Output: utils/utils.go:176:10: unslice: could simplify v[:] to v (gocritic) return v[:] ^
}
return v[:len(v)-trimLen]
}
61 changes: 61 additions & 0 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,64 @@ func TestToString(t *testing.T) {
})
}
}

func TestRTrimSlice(t *testing.T) {
tests := []struct {
name string
input []int
trimLen int
expected []int
}{
{
name: "Trim two elements from end",
input: []int{1, 2, 3, 4, 5},
trimLen: 2,
expected: []int{1, 2, 3},
},
{
name: "Trim entire slice",
input: []int{1, 2, 3},
trimLen: 3,
expected: []int{},
},
{
name: "Trim length greater than slice length",
input: []int{1, 2, 3},
trimLen: 5,
expected: []int{},
},
{
name: "Zero trim length",
input: []int{1, 2, 3},
trimLen: 0,
expected: []int{1, 2, 3},
},
{
name: "Trim one element from end",
input: []int{1, 2, 3},
trimLen: 1,
expected: []int{1, 2},
},
{
name: "Empty slice",
input: []int{},
trimLen: 2,
expected: []int{},
},
{
name: "Negative trim length (should be treated as zero)",
input: []int{1, 2, 3},
trimLen: -1,
expected: []int{1, 2, 3},
},
}

for _, testcase := range tests {
t.Run(testcase.name, func(t *testing.T) {
result := RTrimSlice(testcase.input, testcase.trimLen)
if !AssertEqual(result, testcase.expected) {
t.Errorf("RTrimSlice(%v, %d) = %v; want %v", testcase.input, testcase.trimLen, result, testcase.expected)
}
})
}
}
Loading