gf icon indicating copy to clipboard operation
gf copied to clipboard

Bug caused by combining ORM's List method and garray

Open xiucaiwu opened this issue 1 year ago • 6 comments

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,已报名

xiucaiwu avatar May 27 '24 02:05 xiucaiwu

你的所有代码我拿过来测试的结果却是user_id:2,live_id:266,报名了

lyonzhi avatar May 27 '24 08:05 lyonzhi

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.

Issues-translate-bot avatar May 27 '24 08:05 Issues-translate-bot

你的所有代码我拿过来测试的结果却是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}}

按理说不应该存放内存地址的

xiucaiwu avatar Jun 03 '24 03:06 xiucaiwu

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.

Issues-translate-bot avatar Jun 03 '24 03:06 Issues-translate-bot

@xiucaiwu 你好,请提供最小可运行代码,以便于复现和定位。

gqcn avatar Sep 23 '24 09:09 gqcn

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.

Issues-translate-bot avatar Sep 23 '24 09:09 Issues-translate-bot

操作系统: 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]比较就不会是相等了

xiucaiwu avatar Nov 14 '24 10:11 xiucaiwu

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

Issues-translate-bot avatar Nov 14 '24 10:11 Issues-translate-bot

经测试,2.7.0-2.8.3的测试结果都是直接存放的值,并没有存放地址

wln32 avatar Mar 11 '25 04:03 wln32

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.

Issues-translate-bot avatar Mar 11 '25 04:03 Issues-translate-bot