From f2256f10a1d328fb924ca79cde76e77641398573 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sun, 10 Sep 2023 10:26:57 +0300 Subject: [PATCH] fix: alloc when mounting (#891) --- internal/util.go | 24 ++++++++++++++++++++++++ model_table_struct.go | 3 ++- schema/field.go | 5 +++-- schema/reflect.go | 24 ------------------------ 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/internal/util.go b/internal/util.go index 641309725..66b92b3c5 100644 --- a/internal/util.go +++ b/internal/util.go @@ -55,3 +55,27 @@ func Unwrap(err error) error { } return u.Unwrap() } + +func FieldByIndexAlloc(v reflect.Value, index []int) reflect.Value { + if len(index) == 1 { + return v.Field(index[0]) + } + + for i, idx := range index { + if i > 0 { + v = indirectNil(v) + } + v = v.Field(idx) + } + return v +} + +func indirectNil(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + return v +} diff --git a/model_table_struct.go b/model_table_struct.go index fadc9284c..65e076d23 100644 --- a/model_table_struct.go +++ b/model_table_struct.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/uptrace/bun/internal" "github.com/uptrace/bun/schema" ) @@ -234,7 +235,7 @@ func (m *structTableModel) parentIndex() []int { } func (m *structTableModel) mount(host reflect.Value) { - m.strct = host.FieldByIndex(m.rel.Field.Index) + m.strct = internal.FieldByIndexAlloc(host, m.rel.Field.Index) m.structInited = false } diff --git a/schema/field.go b/schema/field.go index 283a3b992..a3b086054 100644 --- a/schema/field.go +++ b/schema/field.go @@ -5,6 +5,7 @@ import ( "reflect" "github.com/uptrace/bun/dialect" + "github.com/uptrace/bun/internal" "github.com/uptrace/bun/internal/tagparser" ) @@ -50,7 +51,7 @@ func (f *Field) Clone() *Field { } func (f *Field) Value(strct reflect.Value) reflect.Value { - return fieldByIndexAlloc(strct, f.Index) + return internal.FieldByIndexAlloc(strct, f.Index) } func (f *Field) HasNilValue(v reflect.Value) bool { @@ -117,7 +118,7 @@ func (f *Field) ScanValue(strct reflect.Value, src interface{}) error { return nil } - fv := fieldByIndexAlloc(strct, f.Index) + fv := internal.FieldByIndexAlloc(strct, f.Index) return f.ScanWithCheck(fv, src) } diff --git a/schema/reflect.go b/schema/reflect.go index f13826a6c..89be8eeb6 100644 --- a/schema/reflect.go +++ b/schema/reflect.go @@ -46,27 +46,3 @@ func fieldByIndex(v reflect.Value, index []int) (_ reflect.Value, ok bool) { } return v, true } - -func fieldByIndexAlloc(v reflect.Value, index []int) reflect.Value { - if len(index) == 1 { - return v.Field(index[0]) - } - - for i, idx := range index { - if i > 0 { - v = indirectNil(v) - } - v = v.Field(idx) - } - return v -} - -func indirectNil(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - v = v.Elem() - } - return v -}