Go 1.22 goes somewhat toward addressing the issue using reflect
MethodByName disabling linker deadcode elimination (DCE) and the
resultant large increase in binary size because the linker cannot
prune unused code because it might be reached via reflection.
Go Issue golang/go#62257 reduces the number of incidences of this
problem by leveraging a compiler assist to avoid marking functions
containing calls to MethodByName as ReflectMethods as long as the
arguments are constants.
An analysis of Uber Technologies code base however shows that a number
of transitive imports still contain calls to MethodByName with a
variable argument, including GORM.
In the case of GORM, the solution we are proposing is because the
number of possible methods is finite, we will "unroll" this. This
demonstrably shows that GORM is not longer a problem for DCE.
Before
```
% go version
go version devel go1.22-2f3458a8ce Sat Sep 16 16:26:48 2023 -0700 darwin/arm64
% go test ./... -ldflags=-dumpdep 2> >(grep -i -e '->.*<reflectmethod>')
gorm.io/gorm.(*Statement).BuildCondition -> gorm.io/gorm/schema.ParseWithSpecialTableName <ReflectMethod>
type:reflect.Value <UsedInIface> -> reflect.(*Value).Method <ReflectMethod>
type:reflect.Value <UsedInIface> -> reflect.(*Value).MethodByName <ReflectMethod>
ok gorm.io/gorm (cached)
ok gorm.io/gorm/callbacks (cached)
gorm.io/gorm/clause_test.BenchmarkComplexSelect -> gorm.io/gorm/schema.ParseWithSpecialTableName <ReflectMethod>
type:reflect.Value <UsedInIface> -> reflect.(*Value).Method <ReflectMethod>
type:reflect.Value <UsedInIface> -> reflect.(*Value).MethodByName <ReflectMethod>
? gorm.io/gorm/migrator [no test files]
ok gorm.io/gorm/clause (cached)
ok gorm.io/gorm/logger (cached)
gorm.io/gorm/schema_test.TestAdvancedDataTypeValuerAndSetter -> gorm.io/gorm/schema.ParseWithSpecialTableName <ReflectMethod>
type:reflect.Value <UsedInIface> -> reflect.(*Value).Method <ReflectMethod>
type:reflect.Value <UsedInIface> -> reflect.(*Value).MethodByName <ReflectMethod>
? gorm.io/gorm/utils/tests [no test files]
ok gorm.io/gorm/schema (cached)
ok gorm.io/gorm/utils (cached)
```
After
```
%go version
go version devel go1.22-2f3458a8ce Sat Sep 16 16:26:48 2023 -0700 darwin/arm64
%go test ./... -ldflags=-dumpdep 2> >(grep -i -e '->.*<reflectmethod>')
ok gorm.io/gorm (cached)
ok gorm.io/gorm/callbacks (cached)
? gorm.io/gorm/migrator [no test files]
? gorm.io/gorm/utils/tests [no test files]
ok gorm.io/gorm/clause (cached)
ok gorm.io/gorm/logger (cached)
ok gorm.io/gorm/schema (cached)
ok gorm.io/gorm/utils (cached)
```
* Fix#4930 workaround for databases that support auto-increment in composite primary key.
* Add test for composite key with auto-increment.
* schema.go: use field.AutoIncrement instead of field.TagSettings["AUTOINCREMENT"], add test to check autoincrement:false
create_test.go: remove unused code: drop table CompositeKeyProduct
---------
Co-authored-by: Jinzhu <wosmvp@gmail.com>
* Refactor ParseWithSchemaTable method and improve test.
* Fix schema.ParseWithSchemaTable method for only use schemaTable in migrator and improve test.
* Rename `schemaTable` to `specialTableName` for clearly argument.
* optimize gormSourceDir replace
* fmt.Errorf adjust and Optimize for-break
* strings trim
* feat: avoid using the same name field and if..else optimization adjustment
* optimization callbacks/create.go Create func if...else logic
* fix: callbacks/create.go Create func
* fix FileWithLineNum func and add gormSourceDir unit test
* remove debug print and utils_filenum_test.go
* Fix schema initialization paths
The initialized channel was only closed if the schema's cacheStore did not contain the embeddedCacheKey and there were no errors parsing relations. If the key existed or an error occurred, it would not be closed. This could leave other goroutines waiting for synchronization that will never occur.
Additionally, the other code paths that wait for initialization to complete did not return the possible error.
* Unnest common schema initialization
This makes the common code path less deeply nested and the flow control easier to follow.