session.Insert(&[]interface{}) panic "reflect: call of reflect.Value.FieldByName on ptr Value" #1503

Closed
opened 2020-01-05 15:30:49 +00:00 by joelBai · 2 comments
Contributor

ver: golang v1.13, xorm v0.7.2, core v0.6.2,涉及代码与主分支基本一致.

尝试使用session.Insert()插入[]interface{}会报reflect: call of reflect.Value.FieldByName on ptr Value.

能否添加对[]interface{}{ptr, ...}批量插入的支持?

转为用例就是能够跑通下面的用例(搬运自master分支session_insert_test.go):

func TestInsertMulti2(t *testing.T) {
	assert.NoError(t, prepareEngine())

	assertSync(t, new(Userinfo))

	// 原本是[]UserInfo{},改为[]interface{}后,正常运行
	users := []interface{}{
		UserInfo{Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
		UserInfo{Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
		UserInfo{Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
		UserInfo{Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
	}
	cnt, err := testEngine.Insert(&users)
	if err != nil {
		t.Error(err)
		panic(err)
	}
	assert.EqualValues(t, len(users), cnt)

	// 原本是[]*UserInfo{},改为[]interface{}后,报错<<<<<<<<
	users2 := []interface{}{
		&Userinfo{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
		&Userinfo{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
		&Userinfo{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()},
		&Userinfo{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()},
	}

	cnt, err = testEngine.Insert(&users2)
	assert.NoError(t, err)
	assert.EqualValues(t, len(users2), cnt)
}

附报错堆栈和设想方案gitea:

--- FAIL: TestInsertMulti2 (0.01s)
panic: reflect: call of reflect.Value.FieldByName on ptr Value [recovered]
        panic: reflect: call of reflect.Value.FieldByName on ptr Value

goroutine 35 [running]:
testing.tRunner.func1(0xc00034a100)
        /go/src/testing/testing.go:874 +0x3aa
panic(0xba1140, 0xc000338b00)
        /go/src/runtime/panic.go:679 +0x1c0
reflect.flag.mustBe(...)
        /go/src/reflect/value.go:208
reflect.Value.FieldByName(0xb5d160, 0xc000342460, 0x16, 0xb49b1d, 0x3, 0xc000342460, 0xc0003310d0, 0x1)
        /go/src/reflect/value.go:890 +0x1f4
github.com/go-xorm/core.(*Column).ValueOfV(0xc00034cdd0, 0xc000091630, 0xc000342460, 0x0, 0x0)
        /golib/pkg/mod/github.com/go-xorm/core@v0.6.2/column.go:144 +0x185
github.com/go-xorm/xorm.(*Session).innerInsertMulti(0xc000091960, 0xb554a0, 0xc0003389e0, 0x4, 0xc0003389e0, 0x197)
        /golib/pkg/mod/github.com/go-xorm/xorm@v0.7.2/session_insert.go:151 +0x63f
github.com/go-xorm/xorm.(*Session).Insert(0xc000091960, 0xc000331090, 0x1, 0x1, 0x0, 0x0, 0x0)
        /golib/pkg/mod/github.com/go-xorm/xorm@v0.7.2/session_insert.go:67 +0x55a
github.com/go-xorm/xorm.(*Engine).Insert(0xc0002d6000, 0xc000331090, 0x1, 0x1, 0x0, 0x0, 0x0)
        /golib/pkg/mod/github.com/go-xorm/xorm@v0.7.2/engine.go:1389 +0x11b
github.com/go-xorm/xorm.TestInsertMulti2(0xc00034a100)
        /golib/pkg/mod/github.com/go-xorm/xorm@v0.7.2/session_insert_test.go:569 +0xa3e
testing.tRunner(0xc00034a100, 0xc827f8)
        /go/src/testing/testing.go:909 +0xd0
created by testing.(*T).Run
        /go/src/testing/testing.go:960 +0x357
exit status 2
FAIL    github.com/go-xorm/xorm 0.948s

ver: `golang v1.13, xorm v0.7.2, core v0.6.2`,涉及代码与主分支基本一致. 尝试使用`session.Insert()`插入`[]interface{}`会报`reflect: call of reflect.Value.FieldByName on ptr Value`. - [报错位置gitea](https://gitea.com/xorm/core/src/tag/v0.6.2/column.go#L144) - [调用位置gitea](https://gitea.com/xorm/xorm/src/tag/v0.7.2/session_insert.go#L141). 能否添加对`[]interface{}{ptr, ...}`批量插入的支持? 转为用例就是能够跑通下面的用例(搬运自`master`分支`session_insert_test.go`): ``` func TestInsertMulti2(t *testing.T) { assert.NoError(t, prepareEngine()) assertSync(t, new(Userinfo)) // 原本是[]UserInfo{},改为[]interface{}后,正常运行 users := []interface{}{ UserInfo{Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()}, UserInfo{Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()}, UserInfo{Username: "xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()}, UserInfo{Username: "xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()}, } cnt, err := testEngine.Insert(&users) if err != nil { t.Error(err) panic(err) } assert.EqualValues(t, len(users), cnt) // 原本是[]*UserInfo{},改为[]interface{}后,报错<<<<<<<< users2 := []interface{}{ &Userinfo{Username: "1xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()}, &Userinfo{Username: "1xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()}, &Userinfo{Username: "1xlw11", Departname: "dev", Alias: "lunny2", Created: time.Now()}, &Userinfo{Username: "1xlw22", Departname: "dev", Alias: "lunny3", Created: time.Now()}, } cnt, err = testEngine.Insert(&users2) assert.NoError(t, err) assert.EqualValues(t, len(users2), cnt) } ``` 附报错堆栈和[设想方案gitea](https://gitea.com/joelBai/xorm/commit/2dc43f5f619ab3b10b033bdd09d115723307b3ca): ``` --- FAIL: TestInsertMulti2 (0.01s) panic: reflect: call of reflect.Value.FieldByName on ptr Value [recovered] panic: reflect: call of reflect.Value.FieldByName on ptr Value goroutine 35 [running]: testing.tRunner.func1(0xc00034a100) /go/src/testing/testing.go:874 +0x3aa panic(0xba1140, 0xc000338b00) /go/src/runtime/panic.go:679 +0x1c0 reflect.flag.mustBe(...) /go/src/reflect/value.go:208 reflect.Value.FieldByName(0xb5d160, 0xc000342460, 0x16, 0xb49b1d, 0x3, 0xc000342460, 0xc0003310d0, 0x1) /go/src/reflect/value.go:890 +0x1f4 github.com/go-xorm/core.(*Column).ValueOfV(0xc00034cdd0, 0xc000091630, 0xc000342460, 0x0, 0x0) /golib/pkg/mod/github.com/go-xorm/core@v0.6.2/column.go:144 +0x185 github.com/go-xorm/xorm.(*Session).innerInsertMulti(0xc000091960, 0xb554a0, 0xc0003389e0, 0x4, 0xc0003389e0, 0x197) /golib/pkg/mod/github.com/go-xorm/xorm@v0.7.2/session_insert.go:151 +0x63f github.com/go-xorm/xorm.(*Session).Insert(0xc000091960, 0xc000331090, 0x1, 0x1, 0x0, 0x0, 0x0) /golib/pkg/mod/github.com/go-xorm/xorm@v0.7.2/session_insert.go:67 +0x55a github.com/go-xorm/xorm.(*Engine).Insert(0xc0002d6000, 0xc000331090, 0x1, 0x1, 0x0, 0x0, 0x0) /golib/pkg/mod/github.com/go-xorm/xorm@v0.7.2/engine.go:1389 +0x11b github.com/go-xorm/xorm.TestInsertMulti2(0xc00034a100) /golib/pkg/mod/github.com/go-xorm/xorm@v0.7.2/session_insert_test.go:569 +0xa3e testing.tRunner(0xc00034a100, 0xc827f8) /go/src/testing/testing.go:909 +0xd0 created by testing.(*T).Run /go/src/testing/testing.go:960 +0x357 exit status 2 FAIL github.com/go-xorm/xorm 0.948s ```
Owner

Please send a PR with tests.

Please send a PR with tests.
Author
Contributor

please check up pr1504

please check up [pr1504](https://gitea.com/xorm/xorm/pulls/1504)
lunny added the
kind
enhancement
label 2020-02-29 09:10:18 +00:00
lunny added this to the 1.1.1 milestone 2020-03-10 02:29:48 +00:00
lunny modified the milestone from 1.1.1 to 1.0.0 2020-03-12 12:05:15 +00:00
lunny closed this issue 2020-03-12 12:05:45 +00:00
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: xorm/xorm#1503
No description provided.