From ec6a822cfa782c744415d5b47341ae969b0852c4 Mon Sep 17 00:00:00 2001 From: zhexuany Date: Fri, 7 Sep 2018 12:42:48 +0800 Subject: [PATCH] get tz name from zoneinfo --- executor/distsql.go | 16 +++++++++++++++- executor/distsql_test.go | 6 ++++++ store/mockstore/mocktikv/cop_handler_dag.go | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/executor/distsql.go b/executor/distsql.go index b16c04aad1901..e1f8c11a937ef 100644 --- a/executor/distsql.go +++ b/executor/distsql.go @@ -117,6 +117,16 @@ func closeAll(objs ...Closeable) error { return errors.Trace(err) } +func getTZNameFromFileName(path string) (string, error) { + // phase1 only support read /etc/localtime which is a softlink to zoneinfo file + substr := "share/zoneinfo" + if strings.Contains(path, substr) { + idx := strings.Index(path, substr) + return string(path[idx+len(substr)+1:]), nil + } + return "", errors.New("only support softlink has share/zoneinfo as a suffix" + path) +} + // zone returns the current timezone name and timezone offset in seconds. // In compatible with MySQL, we change `Local` to `System`. // TODO: Golang team plan to return system timezone name intead of @@ -127,7 +137,11 @@ func zone(sctx sessionctx.Context) (string, int64) { var name string name = loc.String() if name == "Local" { - name = "System" + path, err := filepath.EvalSymlinks("/etc/localtime") + if err != nil { + return "Sysytem", int64(offset) + } + return getTZNameFromFileName(path), int64(offset) } return name, int64(offset) diff --git a/executor/distsql_test.go b/executor/distsql_test.go index 070c10233e1be..15edf80a586a4 100644 --- a/executor/distsql_test.go +++ b/executor/distsql_test.go @@ -207,3 +207,9 @@ func (s *testSuite) TestUniqueKeyNullValueSelect(c *C) { res = tk.MustQuery("select * from t where id is null;") res.Check(testkit.Rows(" a", " b", " c")) } + +func (s *testSuite) TestgetTZNameFromFileName(c *C) { + tz, err := getTZNameFromFileName("/user/share/zoneinfo/Asia/Shanghai") + c.Assert(err, IsNil) + c.Assert(tz, Equals, "Asia/Shanghai") +} diff --git a/store/mockstore/mocktikv/cop_handler_dag.go b/store/mockstore/mocktikv/cop_handler_dag.go index 456e1feb057b2..450694703573d 100644 --- a/store/mockstore/mocktikv/cop_handler_dag.go +++ b/store/mockstore/mocktikv/cop_handler_dag.go @@ -17,6 +17,7 @@ import ( "bytes" "fmt" "io" + "strings" "sync" "time" @@ -41,6 +42,7 @@ import ( "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/metadata" + "path/filepath" ) var dummySlice = make([]byte, 0) @@ -164,13 +166,26 @@ func (h *rpcHandler) buildDAGExecutor(req *coprocessor.Request) (*dagContext, ex return ctx, e, dagReq, err } +func getTZNameFromFileName(path string) (string, error) { + // phase1 only support read /etc/localtime which is a softlink to zoneinfo file + substr := "share/zoneinfo" + if strings.Contains(path, substr) { + idx := strings.Index(path, substr) + return string(path[idx+len(substr)+1:]), nil + } + return "", errors.New("only support softlink has share/zoneinfo as a suffix" + path) +} + // constructTimeZone constructs timezone by name first. When the timezone name // is set, the daylight saving problem must be considered. Otherwise the // timezone offset in seconds east of UTC is used to constructed the timezone. func constructTimeZone(name string, offset int) (*time.Location, error) { if name != "" { + // no need to care about case since name is retreved + // from go std library call return LocCache.getLoc(name) } + return time.FixedZone("", offset), nil }