Fix stack overflow for embedded self-referred associations, close #3269

This commit is contained in:
Jinzhu 2020-08-17 12:02:41 +08:00
parent 2faff25dfb
commit 6834c25cec
4 changed files with 42 additions and 11 deletions

View File

@ -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 {

View File

@ -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
}

View File

@ -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)

View File

@ -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)
}
}