Bug caused by combining ORM's List method and garray
Go version
1.20.3
GoFrame version
2.7.1
Can this bug be reproduced with the latest release?
Option Yes
What did you do?
collection(报名表单)表数据,其中target_id存放的是直播id
| id | target_id |
|---|---|
| 1 | 266 |
collection_user(用户报名记录)表数据
| id | collection_id | user_id |
|---|---|---|
| 1 | 1 | 2 |
测试代码
func TestGarray1(t *testing.T) {
var (
ctx = context.TODO()
liveIds = []int{266}
)
configNode := gdb.ConfigNode{
Type: "mysql",
Link: "mysql:root:root@tcp(127.0.0.1:3306)/edusassvc?loc=Local",
Charset: "utf8mb4",
Debug: true,
}
gdb.AddConfigNode("default", configNode)
//查看用户报名表中当前用户是否已经报名了
liveHaveSignUp, _ := dao.Collection.Ctx(ctx).Fields("c.target_id, cu.collection_id").As("c").
InnerJoin(dao.CollectionUser.Table(), "cu", "c.id = cu.collection_id").
Where("cu.user_id", 2).
WhereIn("c.Id", []int{1}).
All()
_liveHaveSignUp := liveHaveSignUp.List()
fmt.Printf("_liveHaveSignUp:%#v\n", _liveHaveSignUp)
//已经报名的直播id数组
havedSignUpLiveIds := gutil.ListItemValuesUnique(_liveHaveSignUp, "target_id")
fmt.Printf("havedSignUpLiveIds:%#v\n", havedSignUpLiveIds)
havedSignUpLiveIdArr := garray.NewFrom(havedSignUpLiveIds)
fmt.Printf("havedSignUpLiveIdArr:%#v\n", havedSignUpLiveIdArr)
if havedSignUpLiveIdArr.Contains(liveIds[0]) {
fmt.Printf("user_id:%d,live_id:%d,报名了\n", 2, liveIds[0])
} else {
fmt.Printf("user_id:%d,live_id:%d,未报名\n", 2, liveIds[0])
}
}
如果把ORM的All()改为Scan,则结果是我想要的
What did you see happen?
$ go test garray_test.go --run TestGarray1 -v
=== RUN TestGarray1
2024-05-27 10:29:53.346 [DEBU] {380cc95e9437d317783a87287d7f7e7c} [ 3 ms] [default] [edusassvc] [rows:65 ] SHOW TABLES
2024-05-27 10:29:53.347 [DEBU] {f8d2f65e9437d317793a8728dbe4abb7} [ 1 ms] [default] [edusassvc] [rows:13 ] SHOW FULL COLUMNS FROM `collection`
2024-05-27 10:29:53.348 [DEBU] {7863135f9437d3177a3a87280528f3d1} [ 0 ms] [default] [edusassvc] [rows:9 ] SHOW FULL COLUMNS FROM `collection_user`
2024-05-27 10:29:53.349 [DEBU] {94c7155f9437d3177b3a87289d4485c0} [ 1 ms] [default] [edusassvc] [rows:1 ] SELECT c.target_id,cu.collection_id FROM `collection` AS c INNER JOIN `collection_user` AS `cu` ON (c.id = cu.collection_id) WHERE ((`cu`.`user_id`=2) AND (c.
Id IN (1))) AND `c`.`deleted_at` IS NULL AND `cu`.`deleted_at` IS NULL
_liveHaveSignUp:[]map[string]interface {}{map[string]interface {}{"collection_id":1, "target_id":0x10a}}
havedSignUpLiveIds:[]interface {}{0x10a}
havedSignUpLiveIdArr:&garray.Array{mu:rwmutex.RWMutex{mutex:(*sync.RWMutex)(nil)}, array:[]interface {}{0x10a}}
user_id:2,live_id:266,未报名
--- PASS: TestGarray1 (0.01s)
PASS
ok command-line-arguments 3.409s
What did you expect to see?
user_id:2,live_id:266,已报名
你的所有代码我拿过来测试的结果却是user_id:2,live_id:266,报名了。
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
I took all your codes and tested them, but the result was user_id: 2, live_id: 266, registered.
你的所有代码我拿过来测试的结果却是
user_id:2,live_id:266,报名了。
我的orm和gf都是2.7.1的
require (
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.1
github.com/gogf/gf/v2 v2.7.1
)
而且我发现打印_liveHaveSignUp的结果中target_id存放的是内存地址,但是collection_id却不是
_liveHaveSignUp:[]map[string]interface {}{map[string]interface {}{"collection_id":1, "target_id":0x10a}}
按理说不应该存放内存地址的
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
I took all your codes and tested them, but the result was
user_id: 2, live_id: 266, registered. My orm and gf are both 2.7.1
require (
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.1
github.com/gogf/gf/v2 v2.7.1
)
And I found that the target_id in the result of printing _liveHaveSignUp is the memory address, but the collection_id is not.
_liveHaveSignUp:[]map[string]interface {}{map[string]interface {}{"collection_id":1, "target_id":0x10a}}
Logically speaking, memory addresses should not be stored.
@xiucaiwu 你好,请提供最小可运行代码,以便于复现和定位。
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
@xiucaiwu Hello, please provide the minimum runnable code to facilitate reproduction and location.
操作系统: Win10 gf版本: 2.7.1 go版本:1.20.3 表结构和数据
DROP TABLE IF EXISTS `collection`;
CREATE TABLE `collection` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`target_id` int(11) DEFAULT NULL,
`created_at` datetime(0) DEFAULT NULL,
`updated_at` datetime(0) DEFAULT NULL,
`deleted_at` datetime(0) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of collection
-- ----------------------------
INSERT INTO `collection` VALUES (1, '第一届厨神报名大赛', 1, '2024-11-14 18:04:22', '2024-11-14 18:04:22', NULL);
DROP TABLE IF EXISTS `collection_user`;
CREATE TABLE `collection_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`collection_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`created_at` datetime(0) DEFAULT NULL,
`updated_at` datetime(0) DEFAULT NULL,
`deleted_at` datetime(0) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of collection_user
-- ----------------------------
INSERT INTO `collection_user` VALUES (1, 1, 2, '2024-11-14 18:03:07', '2024-11-14 18:03:07', NULL);
最小测试代码
package main
import (
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
"context"
"fmt"
"gf-demo-test/repository2/dao"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/util/gutil"
)
func main() {
var (
ctx = context.TODO()
liveIds = []int{1}
)
configNode := gdb.ConfigNode{
Type: "mysql",
Link: "mysql:root:root@tcp(127.0.0.1:3306)/edusassvc?loc=Local",
Charset: "utf8mb4",
Debug: true,
}
gdb.AddConfigNode("default", configNode)
//查看用户报名表中当前用户是否已经报名了
liveHaveSignUp, _ := dao.Collection.Ctx(ctx).Fields("c.target_id, cu.collection_id").As("c").
InnerJoin(dao.CollectionUser.Table(), "cu", "c.id = cu.collection_id").
Where("cu.user_id", 2).
WhereIn("c.Id", []int{1}).
All()
_liveHaveSignUp := liveHaveSignUp.List()
fmt.Printf("_liveHaveSignUp:%#v\n", _liveHaveSignUp)
//已经报名的直播id数组
havedSignUpLiveIds := gutil.ListItemValuesUnique(_liveHaveSignUp, "target_id")
fmt.Printf("havedSignUpLiveIds:%#v\n", havedSignUpLiveIds)
havedSignUpLiveIdArr := garray.NewFrom(havedSignUpLiveIds)
fmt.Printf("havedSignUpLiveIdArr:%#v\n", havedSignUpLiveIdArr)
if havedSignUpLiveIdArr.Contains(liveIds[0]) {
fmt.Printf("user_id:%d,live_id:%d,报名了\n", 2, liveIds[0])
} else {
fmt.Printf("user_id:%d,live_id:%d,未报名\n", 2, liveIds[0])
}
}
运行输出:
2024-11-14 18:18:54.933 [DEBU] {8485dda769ce071893e1a63f3241b84d} [ 3 ms] [default] [edusassvc] [rows:93 ] SHOW TABLES
2024-11-14 18:18:54.937 [DEBU] {501739a869ce071894e1a63f625f5aa9} [ 1 ms] [default] [edusassvc] [rows:13 ] SHOW FULL COLUMNS FROM `collection`
2024-11-14 18:18:54.939 [DEBU] {089b57a869ce071895e1a63f0fb90a9a} [ 1 ms] [default] [edusassvc] [rows:9 ] SHOW FULL COLUMNS FROM `collection_user`
2024-11-14 18:18:54.940 [DEBU] {101a76a869ce071896e1a63f38f545d9} [ 0 ms] [default] [edusassvc] [rows:1 ] SELECT c.target_id,cu.collection_id FROM `collection` AS c INNER JOIN `collection_user` AS `cu` ON (c.id = cu.collection_id) WHERE ((`cu`.`user_id`=2) AND (c.Id IN (1))) AND `c`.`deleted_at` IS NULL AND `cu`.`deleted_at` IS NULL
_liveHaveSignUp:[]map[string]interface {}{map[string]interface {}{"collection_id":1, "target_id":0x10a}}
havedSignUpLiveIds:[]interface {}{0x10a}
havedSignUpLiveIdArr:&garray.Array{mu:rwmutex.RWMutex{mutex:(*sync.RWMutex)(nil)}, array:[]interface {}{0x10a}}
user_id:2,live_id:1,未报名
从输出中看到 "target_id":0x10a 存的是地址,所以和liveIds[0]比较就不会是相等了
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
DROP TABLE IF EXISTS `collection`;
CREATE TABLE `collection` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`target_id` int(11) DEFAULT NULL,
`created_at` datetime(0) DEFAULT NULL,
`updated_at` datetime(0) DEFAULT NULL,
`deleted_at` datetime(0) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of collection
-- ----------------------------
INSERT INTO `collection` VALUES (1, '第一届厨神报名大赛', 1, '2024-11-14 18:04:22', '2024-11-14 18:04:22', NULL);
DROP TABLE IF EXISTS `collection_user`;
CREATE TABLE `collection_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`collection_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`created_at` datetime(0) DEFAULT NULL,
`updated_at` datetime(0) DEFAULT NULL,
`deleted_at` datetime(0) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of collection_user
-- ----------------------------
INSERT INTO `collection_user` VALUES (1, 1, 2, '2024-11-14 18:03:07', '2024-11-14 18:03:07', NULL);
经测试,2.7.0-2.8.3的测试结果都是直接存放的值,并没有存放地址
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
After testing, the test results of 2.7.0-2.8.3 are all directly stored values and do not have storage addresses.