fix(common): skip bun relation fields when building valid columns
Tests / Integration Tests (push) Skipped
Build , Vet Test, and Lint / Build (push) Successful in 1m58s
Tests / Unit Tests (push) Successful in 2m26s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 2m55s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 2m57s
Build , Vet Test, and Lint / Lint Code (push) Successful in 3m19s
Tests / Race Detector (push) Successful in 5m34s

Fields tagged rel:, join: or m2m: were registered as columns (e.g. rel:has-many),
which broke the 'all' filter expansion with invalid SQL.
This commit is contained in:
Hein
2026-10-12 16:30:32 +02:00
parent 5dbe187915
commit 82f82b998f
2 changed files with 43 additions and 0 deletions
+17
View File
@@ -49,6 +49,11 @@ func (v *ColumnValidator) buildValidColumns() {
continue
}
// Relation fields are not columns
if isBunRelationTag(field.Tag.Get("bun")) {
continue
}
// Get column name from bun, gorm, or json tag
columnName := v.getColumnName(field)
if columnName != "" && columnName != "-" {
@@ -57,6 +62,18 @@ func (v *ColumnValidator) buildValidColumns() {
}
}
// isBunRelationTag reports whether a bun tag describes a relation (rel:, join:, m2m:)
// rather than a database column.
func isBunRelationTag(tag string) bool {
for _, part := range strings.Split(tag, ",") {
part = strings.TrimSpace(part)
if strings.HasPrefix(part, "rel:") || strings.HasPrefix(part, "join:") || strings.HasPrefix(part, "m2m:") {
return true
}
}
return false
}
// getColumnName extracts the column name from a struct field's tags
// Supports both Bun and GORM tags
func (v *ColumnValidator) getColumnName(field reflect.StructField) string {
+26
View File
@@ -545,3 +545,29 @@ func TestFilterRequestOptions_PreloadColumnsParentModelFallback(t *testing.T) {
t.Errorf("Expected preload column 'id', got '%s'", cols[0])
}
}
type relationTestModel struct {
ID int64 `bun:"id,pk"`
Name string `bun:"name"`
Children []*relationTestKid `bun:"rel:has-many,join:id=parent_id"`
Parent *relationTestKid `bun:"rel:has-one,join:parent_id=id"`
Tags []*relationTestKid `bun:"m2m:model_tags,join:Model=Tag"`
}
type relationTestKid struct{}
func TestNewColumnValidator_SkipsRelationFields(t *testing.T) {
cols := NewColumnValidator(relationTestModel{}).GetValidColumns()
set := map[string]bool{}
for _, c := range cols {
set[c] = true
}
if !set["id"] || !set["name"] {
t.Errorf("expected id and name columns, got %v", cols)
}
for _, bad := range []string{"rel:has-many", "rel:has-one", "m2m:model_tags", "children", "parent", "tags"} {
if set[bad] {
t.Errorf("relation %q must not be a valid column (got %v)", bad, cols)
}
}
}