From 91e0d2719a5a20b3208cea0232e2dbcb452d6c23 Mon Sep 17 00:00:00 2001 From: j2gg0s Date: Tue, 14 Jan 2025 11:11:50 +0800 Subject: [PATCH] feat: downgrade to use the field in has-many-relation Even if driver.Valuer is implemented, we will still directly use the field if the returned value is not suitable as a map key. Close #1107 --- model_table_has_many.go | 18 +++++++++++++----- model_table_m2m.go | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/model_table_has_many.go b/model_table_has_many.go index f7ace5740..c7bdee98a 100644 --- a/model_table_has_many.go +++ b/model_table_has_many.go @@ -94,7 +94,7 @@ func (m *hasManyModel) Scan(src interface{}) error { for i, f := range m.rel.JoinPKs { if f.Name == column { - m.structKey[i] = indirectFieldValue(field.Value(m.strct)) + m.structKey[i] = indirectAsKey(field.Value(m.strct)) break } } @@ -144,19 +144,27 @@ func baseValues(model TableModel, fields []*schema.Field) map[internal.MapKey][] func modelKey(key []interface{}, strct reflect.Value, fields []*schema.Field) []interface{} { for _, f := range fields { - key = append(key, indirectFieldValue(f.Value(strct))) + key = append(key, indirectAsKey(f.Value(strct))) } return key } -// indirectFieldValue return the field value dereferencing the pointer if necessary. +// indirectAsKey return the field value dereferencing the pointer if necessary. // The value is then used as a map key. -func indirectFieldValue(field reflect.Value) interface{} { +func indirectAsKey(field reflect.Value) interface{} { if field.Kind() != reflect.Ptr { i := field.Interface() if valuer, ok := i.(driver.Valuer); ok { if v, err := valuer.Value(); err == nil { - return v + switch reflect.TypeOf(v).Kind() { + case reflect.Array, reflect.Chan, reflect.Func, + reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: + // NOTE #1107, these types cannot be used as map key, + // let us use original logic. + return i + default: + return v + } } } return i diff --git a/model_table_m2m.go b/model_table_m2m.go index df072fbdf..1a6b1b46a 100644 --- a/model_table_m2m.go +++ b/model_table_m2m.go @@ -103,7 +103,7 @@ func (m *m2mModel) scanM2MColumn(column string, src interface{}) error { if err := field.Scan(dest, src); err != nil { return err } - m.structKey = append(m.structKey, indirectFieldValue(dest)) + m.structKey = append(m.structKey, indirectAsKey(dest)) break } }