mirror of https://github.com/go-gorm/gorm.git
Fix stack overflow for embedded self-referred associations, close #3269
This commit is contained in:
parent
2faff25dfb
commit
6834c25cec
|
@ -317,7 +317,13 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
|||
field.Creatable = false
|
||||
field.Updatable = false
|
||||
field.Readable = false
|
||||
if field.EmbeddedSchema, err = Parse(fieldValue.Interface(), &sync.Map{}, schema.namer); err != nil {
|
||||
|
||||
cacheStore := schema.cacheStore
|
||||
if _, embedded := schema.cacheStore.Load("embedded_cache_store"); !embedded {
|
||||
cacheStore = &sync.Map{}
|
||||
cacheStore.Store("embedded_cache_store", true)
|
||||
}
|
||||
if field.EmbeddedSchema, err = Parse(fieldValue.Interface(), cacheStore, schema.namer); err != nil {
|
||||
schema.err = err
|
||||
}
|
||||
for _, ef := range field.EmbeddedSchema.Fields {
|
||||
|
|
|
@ -39,3 +39,25 @@ type AdvancedDataTypeUser struct {
|
|||
Active mybool
|
||||
Admin *mybool
|
||||
}
|
||||
|
||||
type BaseModel struct {
|
||||
ID uint `gorm:"primarykey"`
|
||||
CreatedAt time.Time
|
||||
CreatedBy *int
|
||||
Created *VersionUser `gorm:"foreignKey:CreatedBy"`
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
}
|
||||
|
||||
type VersionModel struct {
|
||||
BaseModel
|
||||
Version int
|
||||
CompanyID int
|
||||
}
|
||||
|
||||
type VersionUser struct {
|
||||
VersionModel
|
||||
Name string
|
||||
Age uint
|
||||
Birthday *time.Time
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/jinzhu/inflection"
|
||||
"gorm.io/gorm/clause"
|
||||
|
@ -67,17 +66,15 @@ func (schema *Schema) parseRelation(field *Field) {
|
|||
}
|
||||
)
|
||||
|
||||
cacheStore := schema.cacheStore
|
||||
if field.OwnerSchema != nil {
|
||||
if relation.FieldSchema, err = Parse(fieldValue, &sync.Map{}, schema.namer); err != nil {
|
||||
cacheStore = field.OwnerSchema.cacheStore
|
||||
}
|
||||
|
||||
if relation.FieldSchema, err = Parse(fieldValue, cacheStore, schema.namer); err != nil {
|
||||
schema.err = err
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if relation.FieldSchema, err = Parse(fieldValue, schema.cacheStore, schema.namer); err != nil {
|
||||
schema.err = err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if polymorphic := field.TagSettings["POLYMORPHIC"]; polymorphic != "" {
|
||||
schema.buildPolymorphicRelation(relation, field, polymorphic)
|
||||
|
|
|
@ -160,3 +160,9 @@ func TestCustomizeTableName(t *testing.T) {
|
|||
t.Errorf("Failed to customize table with TableName method")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNestedModel(t *testing.T) {
|
||||
if _, err := schema.Parse(&VersionUser{}, &sync.Map{}, schema.NamingStrategy{}); err != nil {
|
||||
t.Fatalf("failed to parse nested user, got error %v", err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue