From 4cf705177c85e9c4ea73afa9834cd86a1c631e01 Mon Sep 17 00:00:00 2001 From: Yexiang Zhang Date: Mon, 29 Nov 2021 15:53:53 +0800 Subject: [PATCH 1/2] topsql: fix nil pointer panic in stmtctx (#30181) --- sessionctx/stmtctx/stmtctx.go | 39 +++++++---------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/sessionctx/stmtctx/stmtctx.go b/sessionctx/stmtctx/stmtctx.go index bdf93278a59d5..100dbb79bee3f 100644 --- a/sessionctx/stmtctx/stmtctx.go +++ b/sessionctx/stmtctx/stmtctx.go @@ -173,12 +173,7 @@ type StatementContext struct { // stmtCache is used to store some statement-related values. stmtCache map[StmtCacheKey]interface{} - // resourceGroupTagWithRow cache for the current statement resource group tag (with `Row` label). - resourceGroupTagWithRow atomic.Value - // resourceGroupTagWithIndex cache for the current statement resource group tag (with `Index` label). - resourceGroupTagWithIndex atomic.Value - // resourceGroupTagWithUnknown cache for the current statement resource group tag (with `Unknown` label). - resourceGroupTagWithUnknown atomic.Value + // Map to store all CTE storages of current SQL. // Will clean up at the end of the execution. CTEStorageMap interface{} @@ -287,6 +282,9 @@ func (sc *StatementContext) GetPlanDigest() (normalized string, planDigest *pars // GetResourceGroupTagger returns the implementation of tikvrpc.ResourceGroupTagger related to self. func (sc *StatementContext) GetResourceGroupTagger() tikvrpc.ResourceGroupTagger { return func(req *tikvrpc.Request) { + if req == nil { + return + } req.ResourceGroupTag = sc.GetResourceGroupTagByLabel( resourcegrouptag.GetResourceGroupLabelByKey(resourcegrouptag.GetFirstKeyFromRequest(req))) } @@ -294,37 +292,14 @@ func (sc *StatementContext) GetResourceGroupTagger() tikvrpc.ResourceGroupTagger // GetResourceGroupTagByLabel gets the resource group of the statement based on the label. func (sc *StatementContext) GetResourceGroupTagByLabel(label tipb.ResourceGroupTagLabel) []byte { - switch label { - case tipb.ResourceGroupTagLabel_ResourceGroupTagLabelRow: - v := sc.resourceGroupTagWithRow.Load() - if v != nil { - return v.([]byte) - } - case tipb.ResourceGroupTagLabel_ResourceGroupTagLabelIndex: - v := sc.resourceGroupTagWithIndex.Load() - if v != nil { - return v.([]byte) - } - case tipb.ResourceGroupTagLabel_ResourceGroupTagLabelUnknown: - v := sc.resourceGroupTagWithUnknown.Load() - if v != nil { - return v.([]byte) - } + if sc == nil { + return nil } normalized, sqlDigest := sc.SQLDigest() if len(normalized) == 0 { return nil } - newTag := resourcegrouptag.EncodeResourceGroupTag(sqlDigest, sc.planDigest, label) - switch label { - case tipb.ResourceGroupTagLabel_ResourceGroupTagLabelRow: - sc.resourceGroupTagWithRow.Store(newTag) - case tipb.ResourceGroupTagLabel_ResourceGroupTagLabelIndex: - sc.resourceGroupTagWithIndex.Store(newTag) - case tipb.ResourceGroupTagLabel_ResourceGroupTagLabelUnknown: - sc.resourceGroupTagWithUnknown.Store(newTag) - } - return newTag + return resourcegrouptag.EncodeResourceGroupTag(sqlDigest, sc.planDigest, label) } // SetPlanDigest sets the normalized plan and plan digest. From 352811dfc4eeded86f26432477e5fad01b3cf181 Mon Sep 17 00:00:00 2001 From: wjHuang Date: Mon, 29 Nov 2021 16:29:52 +0800 Subject: [PATCH 2/2] types: fix wrong str_to_date() microseconds with leading zeros are not converted correctly (#30122) --- expression/builtin_time_test.go | 1 + types/time.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/expression/builtin_time_test.go b/expression/builtin_time_test.go index 686079402c664..7e41e0c8c549d 100644 --- a/expression/builtin_time_test.go +++ b/expression/builtin_time_test.go @@ -1451,6 +1451,7 @@ func TestStrToDate(t *testing.T) { {"15-01-2001 1:59:58.", "%d-%m-%Y %H:%i:%s.%f", true, types.KindMysqlTime, time.Date(2001, 1, 15, 1, 59, 58, 000000000, time.Local)}, {"15-01-2001 1:9:8.999", "%d-%m-%Y %H:%i:%s.%f", true, types.KindMysqlTime, time.Date(2001, 1, 15, 1, 9, 8, 999000000, time.Local)}, {"15-01-2001 1:9:8.999", "%d-%m-%Y %H:%i:%S.%f", true, types.KindMysqlTime, time.Date(2001, 1, 15, 1, 9, 8, 999000000, time.Local)}, + {"2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f", true, types.KindMysqlTime, time.Date(2003, 1, 2, 10, 11, 12, 1200000, time.Local)}, {"2003-01-02 10:11:12 PM", "%Y-%m-%d %H:%i:%S %p", false, types.KindMysqlTime, time.Time{}}, {"10:20:10AM", "%H:%i:%S%p", false, types.KindMysqlTime, time.Time{}}, // test %@(skip alpha), %#(skip number), %.(skip punct) diff --git a/types/time.go b/types/time.go index 161ea708e66d8..51378719e01e8 100644 --- a/types/time.go +++ b/types/time.go @@ -3192,7 +3192,7 @@ func microSeconds(t *CoreTime, input string, ctx map[string]int) (string, bool) t.setMicrosecond(0) return input, true } - for v > 0 && v*10 < 1000000 { + for i := step; i < 6; i++ { v *= 10 } t.setMicrosecond(uint32(v))