Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time zone error while using WithAll() #2980

Closed
exqlnet opened this issue Sep 22, 2023 · 2 comments
Closed

time zone error while using WithAll() #2980

exqlnet opened this issue Sep 22, 2023 · 2 comments
Labels
bug It is confirmed a bug, but don't worry, we'll handle it. done This issue is done, which may be release in next version.

Comments

@exqlnet
Copy link

exqlnet commented Sep 22, 2023

1. What version of Go and system type/arch are you using?

go1.21.0 darwin/arm64

2. What version of GoFrame are you using?

v2.5.4

3. Can this issue be re-produced with the latest release?

yes

4. What did you do?

init MySQL data

-- auto-generated definition
create table post
(
    id         bigint auto_increment primary key,
    content    text null,
    user_id    bigint null,
    created_at datetime default (now()) null,
    updated_at datetime default (now()) null,
    deleted_at datetime null
);


create table user
(
    id         bigint auto_increment primary key,
    username   varchar(255) null,
    created_at datetime default (now()) null,
    updated_at datetime default (now()) null,
    deleted_at datetime null
);

insert into user (id, username, created_at, updated_at, deleted_at)
values (1, 'user1', '2023-09-22 12:00:00', '2023-09-22 12:00:00', null);

insert into post (id, content, user_id, created_at, updated_at, deleted_at)
VALUES (1, 'hello', 1, '2023-09-22 12:00:00', '2023-09-22 12:00:00', null);

reproduce logic

// hack/withall.go
package main

import (
	"context"
	"gdb-withall-bug/internal/dao"
	_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
	"log"
)
func main() {
	ctx := context.Background()
	post, err := dao.Post.Get(ctx, 1)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("%v is not equals to %v", post.CreatedAt.Unix(), post.User.CreatedAt.Unix())
}
// internal/model/entity/post_with_user.go
package entity

import "github.com/gogf/gf/v2/frame/g"

type PostWithUser struct {
	g.Meta `orm:"table:post"`

	Post

	User User `json:"user" orm:"with:id=userId"`
}
// internal/dao/post.go
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================

package dao

import (
	"context"
	"gdb-withall-bug/internal/dao/internal"
	"gdb-withall-bug/internal/model/entity"
)

// internalPostDao is internal type for wrapping internal DAO implements.
type internalPostDao = *internal.PostDao

// postDao is the data access object for table post.
// You can define custom methods on it to extend its functionality as you wish.
type postDao struct {
	internalPostDao
}

var (
	// Post is globally public accessible object for table post operations.
	Post = postDao{
		internal.NewPostDao(),
	}
)

// Fill with you ideas below.

func (d postDao) Get(ctx context.Context, id int64) (entity.PostWithUser, error) {
	var data entity.PostWithUser
	err := d.Ctx(ctx).WithAll().Where(d.Columns().Id, id).Scan(&data)
	return data, err
}

You can also clone this repository and run it locally. https://github.com/exqlnet/gdb-withall-bug

  1. Run hack/init.sql in local/test MySQL server.
  2. Configure MySQL connection in hack/config.yaml.
  3. go run hack/withall.go

I have read the instruction here: https://goframe.org/pages/viewpage.action?pageId=3672072. It does not mention the time zone used for querying and unmarshaling data, but after my testing, it should be consistent with the parameter passing. And it has little to do with this issue.

5. What did you expect to see?

The two unix timestamp should be the same. More specifically, it should print the following content.

2023/09/22 15:24:25 1695384000 is not equals to 1695384000

6. What did you see instead?

2023/09/22 15:24:25 1695355200 is not equals to 1695384000
@oldme-git
Copy link
Member

oldme-git commented Sep 24, 2023

I can't reproduce your question.

@exqlnet
Copy link
Author

exqlnet commented Sep 24, 2023

I can't reproduce your question.

Try to change loc param in MySQL dsn continuously. It should print the two same unix seconds.

More specifically, the problem is that time fields of the embedded struct Post in PostWithUser are always using Local time zone, which are not consistent with User in PostWithUser or other common cases, no matter which loc you set. The time is received from the MySQL server and parsed in the wrong time zone.

If you set loc to Local, the problem may not be reproduced.

Here is a screenshot displaying the inconsistence in debug window:

screenshot-20230925-010240

oldme-git added a commit to oldme-git/gf that referenced this issue Sep 28, 2023
@gqcn gqcn added the bug It is confirmed a bug, but don't worry, we'll handle it. label Oct 7, 2023
oldme-git added a commit to oldme-git/gf that referenced this issue Oct 9, 2023
gqcn pushed a commit that referenced this issue Oct 11, 2023
@gqcn gqcn added the done This issue is done, which may be release in next version. label Oct 19, 2023
@gqcn gqcn closed this as completed Oct 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug It is confirmed a bug, but don't worry, we'll handle it. done This issue is done, which may be release in next version.
Projects
None yet
Development

No branches or pull requests

3 participants