Skip to content

Commit 13c7c1b

Browse files
committed
Merge branch 'get_tz_name_from_zoneinfo' of github.com:zhexuany/tidb into get_tz_name_from_zoneinfo
2 parents 8ba623f + 085dc79 commit 13c7c1b

25 files changed

+460
-50
lines changed

distsql/distsql.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package distsql
1616
import (
1717
"github.com/juju/errors"
1818
"github.com/pingcap/tidb/kv"
19+
"github.com/pingcap/tidb/metrics"
1920
"github.com/pingcap/tidb/sessionctx"
2021
"github.com/pingcap/tidb/statistics"
2122
"github.com/pingcap/tidb/types"
@@ -54,6 +55,10 @@ func Select(ctx context.Context, sctx sessionctx.Context, kvReq *kv.Request, fie
5455
}, nil
5556
}
5657

58+
label := metrics.LblGeneral
59+
if sctx.GetSessionVars().InRestrictedSQL {
60+
label = metrics.LblInternal
61+
}
5762
return &selectResult{
5863
label: "dag",
5964
resp: resp,
@@ -63,21 +68,28 @@ func Select(ctx context.Context, sctx sessionctx.Context, kvReq *kv.Request, fie
6368
fieldTypes: fieldTypes,
6469
ctx: sctx,
6570
feedback: fb,
71+
sqlType: label,
6672
}, nil
6773
}
6874

6975
// Analyze do a analyze request.
70-
func Analyze(ctx context.Context, client kv.Client, kvReq *kv.Request, vars *kv.Variables) (SelectResult, error) {
76+
func Analyze(ctx context.Context, client kv.Client, kvReq *kv.Request, vars *kv.Variables,
77+
isRestrict bool) (SelectResult, error) {
7178
resp := client.Send(ctx, kvReq, vars)
7279
if resp == nil {
7380
return nil, errors.New("client returns nil response")
7481
}
82+
label := metrics.LblGeneral
83+
if isRestrict {
84+
label = metrics.LblInternal
85+
}
7586
result := &selectResult{
7687
label: "analyze",
7788
resp: resp,
7889
results: make(chan resultWithErr, kvReq.Concurrency),
7990
closed: make(chan struct{}),
8091
feedback: statistics.NewQueryFeedback(0, nil, 0, false),
92+
sqlType: label,
8193
}
8294
return result, nil
8395
}
@@ -94,6 +106,7 @@ func Checksum(ctx context.Context, client kv.Client, kvReq *kv.Request, vars *kv
94106
results: make(chan resultWithErr, kvReq.Concurrency),
95107
closed: make(chan struct{}),
96108
feedback: statistics.NewQueryFeedback(0, nil, 0, false),
109+
sqlType: metrics.LblGeneral,
97110
}
98111
return result, nil
99112
}

distsql/distsql_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ func (s *testSuite) TestSelectNormal(c *C) {
6464
result, ok := response.(*selectResult)
6565
c.Assert(ok, IsTrue)
6666
c.Assert(result.label, Equals, "dag")
67+
c.Assert(result.sqlType, Equals, "general")
6768
c.Assert(result.rowLen, Equals, len(colTypes))
6869

6970
response.Fetch(context.TODO())
@@ -143,12 +144,13 @@ func (s *testSuite) TestAnalyze(c *C) {
143144
Build()
144145
c.Assert(err, IsNil)
145146

146-
response, err := Analyze(context.TODO(), s.sctx.GetClient(), request, kv.DefaultVars)
147+
response, err := Analyze(context.TODO(), s.sctx.GetClient(), request, kv.DefaultVars, true)
147148
c.Assert(err, IsNil)
148149

149150
result, ok := response.(*selectResult)
150151
c.Assert(ok, IsTrue)
151152
c.Assert(result.label, Equals, "analyze")
153+
c.Assert(result.sqlType, Equals, "internal")
152154

153155
response.Fetch(context.TODO())
154156

distsql/select_result.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type selectResult struct {
6767

6868
feedback *statistics.QueryFeedback
6969
partialCount int64 // number of partial results.
70+
sqlType string
7071
}
7172

7273
func (r *selectResult) Fetch(ctx context.Context) {
@@ -78,7 +79,7 @@ func (r *selectResult) fetch(ctx context.Context) {
7879
defer func() {
7980
close(r.results)
8081
duration := time.Since(startTime)
81-
metrics.DistSQLQueryHistgram.WithLabelValues(r.label).Observe(duration.Seconds())
82+
metrics.DistSQLQueryHistgram.WithLabelValues(r.label, r.sqlType).Observe(duration.Seconds())
8283
}()
8384
for {
8485
resultSubset, err := r.resp.Next(ctx)

executor/adapter.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -354,15 +354,19 @@ func (a *ExecStmt) logSlowQuery(txnTS uint64, succ bool) {
354354
if len(sessVars.StmtCtx.IndexIDs) > 0 {
355355
indexIDs = strings.Replace(fmt.Sprintf("index_ids:%v ", a.Ctx.GetSessionVars().StmtCtx.IndexIDs), " ", ",", -1)
356356
}
357-
user := a.Ctx.GetSessionVars().User
357+
user := sessVars.User
358+
var internal string
359+
if sessVars.InRestrictedSQL {
360+
internal = "[INTERNAL] "
361+
}
358362
if costTime < threshold {
359363
logutil.SlowQueryLogger.Debugf(
360-
"[QUERY] cost_time:%v %s succ:%v con:%v user:%s txn_start_ts:%v database:%v %v%vsql:%v",
361-
costTime, sessVars.StmtCtx.GetExecDetails(), succ, connID, user, txnTS, currentDB, tableIDs, indexIDs, sql)
364+
"[QUERY] %vcost_time:%v %s succ:%v con:%v user:%s txn_start_ts:%v database:%v %v%vsql:%v",
365+
internal, costTime, sessVars.StmtCtx.GetExecDetails(), succ, connID, user, txnTS, currentDB, tableIDs, indexIDs, sql)
362366
} else {
363367
logutil.SlowQueryLogger.Warnf(
364-
"[SLOW_QUERY] cost_time:%v %s succ:%v con:%v user:%s txn_start_ts:%v database:%v %v%vsql:%v",
365-
costTime, sessVars.StmtCtx.GetExecDetails(), succ, connID, user, txnTS, currentDB, tableIDs, indexIDs, sql)
368+
"[SLOW_QUERY] %vcost_time:%v %s succ:%v con:%v user:%s txn_start_ts:%v database:%v %v%vsql:%v",
369+
internal, costTime, sessVars.StmtCtx.GetExecDetails(), succ, connID, user, txnTS, currentDB, tableIDs, indexIDs, sql)
366370
}
367371
}
368372

executor/analyze.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func (e *AnalyzeIndexExec) open() error {
176176
SetConcurrency(e.concurrency).
177177
Build()
178178
ctx := context.TODO()
179-
e.result, err = distsql.Analyze(ctx, e.ctx.GetClient(), kvReq, e.ctx.GetSessionVars().KVVars)
179+
e.result, err = distsql.Analyze(ctx, e.ctx.GetClient(), kvReq, e.ctx.GetSessionVars().KVVars, e.ctx.GetSessionVars().InRestrictedSQL)
180180
if err != nil {
181181
return errors.Trace(err)
182182
}
@@ -295,7 +295,7 @@ func (e *AnalyzeColumnsExec) buildResp(ranges []*ranger.Range) (distsql.SelectRe
295295
return nil, errors.Trace(err)
296296
}
297297
ctx := context.TODO()
298-
result, err := distsql.Analyze(ctx, e.ctx.GetClient(), kvReq, e.ctx.GetSessionVars().KVVars)
298+
result, err := distsql.Analyze(ctx, e.ctx.GetClient(), kvReq, e.ctx.GetSessionVars().KVVars, e.ctx.GetSessionVars().InRestrictedSQL)
299299
if err != nil {
300300
return nil, errors.Trace(err)
301301
}

expression/builtin.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -572,14 +572,15 @@ var funcs = map[string]functionClass{
572572
ast.ValidatePasswordStrength: &validatePasswordStrengthFunctionClass{baseFunctionClass{ast.ValidatePasswordStrength, 1, 1}},
573573

574574
// json functions
575-
ast.JSONType: &jsonTypeFunctionClass{baseFunctionClass{ast.JSONType, 1, 1}},
576-
ast.JSONExtract: &jsonExtractFunctionClass{baseFunctionClass{ast.JSONExtract, 2, -1}},
577-
ast.JSONUnquote: &jsonUnquoteFunctionClass{baseFunctionClass{ast.JSONUnquote, 1, 1}},
578-
ast.JSONSet: &jsonSetFunctionClass{baseFunctionClass{ast.JSONSet, 3, -1}},
579-
ast.JSONInsert: &jsonInsertFunctionClass{baseFunctionClass{ast.JSONInsert, 3, -1}},
580-
ast.JSONReplace: &jsonReplaceFunctionClass{baseFunctionClass{ast.JSONReplace, 3, -1}},
581-
ast.JSONRemove: &jsonRemoveFunctionClass{baseFunctionClass{ast.JSONRemove, 2, -1}},
582-
ast.JSONMerge: &jsonMergeFunctionClass{baseFunctionClass{ast.JSONMerge, 2, -1}},
583-
ast.JSONObject: &jsonObjectFunctionClass{baseFunctionClass{ast.JSONObject, 0, -1}},
584-
ast.JSONArray: &jsonArrayFunctionClass{baseFunctionClass{ast.JSONArray, 0, -1}},
575+
ast.JSONType: &jsonTypeFunctionClass{baseFunctionClass{ast.JSONType, 1, 1}},
576+
ast.JSONExtract: &jsonExtractFunctionClass{baseFunctionClass{ast.JSONExtract, 2, -1}},
577+
ast.JSONUnquote: &jsonUnquoteFunctionClass{baseFunctionClass{ast.JSONUnquote, 1, 1}},
578+
ast.JSONSet: &jsonSetFunctionClass{baseFunctionClass{ast.JSONSet, 3, -1}},
579+
ast.JSONInsert: &jsonInsertFunctionClass{baseFunctionClass{ast.JSONInsert, 3, -1}},
580+
ast.JSONReplace: &jsonReplaceFunctionClass{baseFunctionClass{ast.JSONReplace, 3, -1}},
581+
ast.JSONRemove: &jsonRemoveFunctionClass{baseFunctionClass{ast.JSONRemove, 2, -1}},
582+
ast.JSONMerge: &jsonMergeFunctionClass{baseFunctionClass{ast.JSONMerge, 2, -1}},
583+
ast.JSONObject: &jsonObjectFunctionClass{baseFunctionClass{ast.JSONObject, 0, -1}},
584+
ast.JSONArray: &jsonArrayFunctionClass{baseFunctionClass{ast.JSONArray, 0, -1}},
585+
ast.JSONContains: &jsonContainsFunctionClass{baseFunctionClass{ast.JSONContains, 2, 3}},
585586
}

expression/builtin_cast.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ func (b *builtinCastDecimalAsTimeSig) evalTime(row chunk.Row) (res types.Time, i
968968
return res, isNull, errors.Trace(err)
969969
}
970970
sc := b.ctx.GetSessionVars().StmtCtx
971-
res, err = types.ParseTime(sc, string(val.ToString()), b.tp.Tp, b.tp.Decimal)
971+
res, err = types.ParseTimeFromFloatString(sc, string(val.ToString()), b.tp.Tp, b.tp.Decimal)
972972
if err != nil {
973973
return res, false, errors.Trace(err)
974974
}

expression/builtin_json.go

+66
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ var (
3535
_ functionClass = &jsonMergeFunctionClass{}
3636
_ functionClass = &jsonObjectFunctionClass{}
3737
_ functionClass = &jsonArrayFunctionClass{}
38+
_ functionClass = &jsonContainsFunctionClass{}
3839

3940
// Type of JSON value.
4041
_ builtinFunc = &builtinJSONTypeSig{}
@@ -56,6 +57,8 @@ var (
5657
_ builtinFunc = &builtinJSONRemoveSig{}
5758
// Merge JSON documents, preserving duplicate keys.
5859
_ builtinFunc = &builtinJSONMergeSig{}
60+
// Check JSON document contains specific target.
61+
_ builtinFunc = &builtinJSONContainsSig{}
5962
)
6063

6164
type jsonTypeFunctionClass struct {
@@ -548,3 +551,66 @@ func jsonModify(ctx sessionctx.Context, args []Expression, row chunk.Row, mt jso
548551
}
549552
return res, false, nil
550553
}
554+
555+
type jsonContainsFunctionClass struct {
556+
baseFunctionClass
557+
}
558+
559+
type builtinJSONContainsSig struct {
560+
baseBuiltinFunc
561+
}
562+
563+
func (b *builtinJSONContainsSig) Clone() builtinFunc {
564+
newSig := &builtinJSONContainsSig{}
565+
newSig.cloneFrom(&b.baseBuiltinFunc)
566+
return newSig
567+
}
568+
569+
func (c *jsonContainsFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
570+
if err := c.verifyArgs(args); err != nil {
571+
return nil, errors.Trace(err)
572+
}
573+
argTps := []types.EvalType{types.ETJson, types.ETJson}
574+
if len(args) == 3 {
575+
argTps = append(argTps, types.ETString)
576+
}
577+
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, argTps...)
578+
sig := &builtinJSONContainsSig{bf}
579+
sig.setPbCode(tipb.ScalarFuncSig_JsonContainsSig)
580+
return sig, nil
581+
}
582+
583+
func (b *builtinJSONContainsSig) evalInt(row chunk.Row) (res int64, isNull bool, err error) {
584+
obj, isNull, err := b.args[0].EvalJSON(b.ctx, row)
585+
if isNull || err != nil {
586+
return res, isNull, errors.Trace(err)
587+
}
588+
target, isNull, err := b.args[1].EvalJSON(b.ctx, row)
589+
if isNull || err != nil {
590+
return res, isNull, errors.Trace(err)
591+
}
592+
var pathExpr json.PathExpression
593+
if len(b.args) == 3 {
594+
path, isNull, err := b.args[2].EvalString(b.ctx, row)
595+
if isNull || err != nil {
596+
return res, isNull, errors.Trace(err)
597+
}
598+
pathExpr, err = json.ParseJSONPathExpr(path)
599+
if err != nil {
600+
return res, true, errors.Trace(err)
601+
}
602+
if pathExpr.ContainsAnyAsterisk() {
603+
return res, true, json.ErrInvalidJSONPathWildcard
604+
}
605+
var exists bool
606+
obj, exists = obj.Extract([]json.PathExpression{pathExpr})
607+
if !exists {
608+
return res, true, nil
609+
}
610+
}
611+
612+
if json.ContainsBinary(obj, target) {
613+
return 1, false, nil
614+
}
615+
return 0, false, nil
616+
}

expression/builtin_json_test.go

+64-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ func (s *testEvaluatorSuite) TestJSONObject(c *C) {
259259
}
260260
}
261261

262-
func (s *testEvaluatorSuite) TestJSONORemove(c *C) {
262+
func (s *testEvaluatorSuite) TestJSONRemove(c *C) {
263263
defer testleak.AfterTest(c)()
264264
fc := funcs[ast.JSONRemove]
265265
tbl := []struct {
@@ -308,3 +308,66 @@ func (s *testEvaluatorSuite) TestJSONORemove(c *C) {
308308
}
309309
}
310310
}
311+
312+
func (s *testEvaluatorSuite) TestJSONContains(c *C) {
313+
defer testleak.AfterTest(c)()
314+
fc := funcs[ast.JSONContains]
315+
tbl := []struct {
316+
input []interface{}
317+
expected interface{}
318+
success bool
319+
}{
320+
// Tests nil arguments
321+
{[]interface{}{nil, `1`, "$.c"}, nil, true},
322+
{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, nil, "$.a[3]"}, nil, true},
323+
{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, nil}, nil, true},
324+
// Tests with path expression
325+
{[]interface{}{`[1,2,[1,[5,[3]]]]`, `[1,3]`, "$[2]"}, 1, true},
326+
{[]interface{}{`[1,2,[1,[5,{"a":[2,3]}]]]`, `[1,{"a":[3]}]`, "$[2]"}, 1, true},
327+
{[]interface{}{`[{"a":1}]`, `{"a":1}`, "$"}, 1, true},
328+
{[]interface{}{`[{"a":1,"b":2}]`, `{"a":1,"b":2}`, "$"}, 1, true},
329+
{[]interface{}{`[{"a":{"a":1},"b":2}]`, `{"a":1}`, "$.a"}, 0, true},
330+
// Tests without path expression
331+
{[]interface{}{`{}`, `{}`}, 1, true},
332+
{[]interface{}{`{"a":1}`, `{}`}, 1, true},
333+
{[]interface{}{`{"a":1}`, `1`}, 0, true},
334+
{[]interface{}{`{"a":[1]}`, `[1]`}, 0, true},
335+
{[]interface{}{`{"b":2, "c":3}`, `{"c":3}`}, 1, true},
336+
{[]interface{}{`1`, `1`}, 1, true},
337+
{[]interface{}{`[1]`, `1`}, 1, true},
338+
{[]interface{}{`[1,2]`, `[1]`}, 1, true},
339+
{[]interface{}{`[1,2]`, `[1,3]`}, 0, true},
340+
{[]interface{}{`[1,2]`, `["1"]`}, 0, true},
341+
{[]interface{}{`[1,2,[1,3]]`, `[1,3]`}, 1, true},
342+
{[]interface{}{`[1,2,[1,[5,[3]]]]`, `[1,3]`}, 1, true},
343+
{[]interface{}{`[1,2,[1,[5,{"a":[2,3]}]]]`, `[1,{"a":[3]}]`}, 1, true},
344+
{[]interface{}{`[{"a":1}]`, `{"a":1}`}, 1, true},
345+
{[]interface{}{`[{"a":1,"b":2}]`, `{"a":1}`}, 1, true},
346+
{[]interface{}{`[{"a":{"a":1},"b":2}]`, `{"a":1}`}, 0, true},
347+
// Tests path expression contains any asterisk
348+
{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.*"}, nil, false},
349+
{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$[*]"}, nil, false},
350+
{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$**.a"}, nil, false},
351+
// Tests path expression does not identify a section of the target document
352+
{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.c"}, nil, true},
353+
{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.a[3]"}, nil, true},
354+
{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.a[2].b"}, nil, true},
355+
}
356+
for _, t := range tbl {
357+
args := types.MakeDatums(t.input...)
358+
f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
359+
c.Assert(err, IsNil)
360+
d, err := evalBuiltinFunc(f, chunk.Row{})
361+
362+
if t.success {
363+
c.Assert(err, IsNil)
364+
if t.expected == nil {
365+
c.Assert(d.IsNull(), IsTrue)
366+
} else {
367+
c.Assert(d.GetInt64(), Equals, int64(t.expected.(int)))
368+
}
369+
} else {
370+
c.Assert(err, NotNil)
371+
}
372+
}
373+
}

expression/builtin_time.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,10 @@ func (b *builtinMonthSig) evalInt(row chunk.Row) (int64, bool, error) {
993993
}
994994

995995
if date.IsZero() {
996-
return 0, true, errors.Trace(handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenByArgs(date.String())))
996+
if b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode() {
997+
return 0, true, errors.Trace(handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenByArgs(date.String())))
998+
}
999+
return 0, false, nil
9971000
}
9981001

9991002
return int64(date.Time.Month()), false, nil
@@ -1030,9 +1033,9 @@ func (b *builtinMonthNameSig) evalString(row chunk.Row) (string, bool, error) {
10301033
return "", true, errors.Trace(handleInvalidTimeError(b.ctx, err))
10311034
}
10321035
mon := arg.Time.Month()
1033-
if arg.IsZero() || mon < 0 || mon > len(types.MonthNames) {
1036+
if (arg.IsZero() && b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode()) || mon < 0 || mon > len(types.MonthNames) {
10341037
return "", true, errors.Trace(handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenByArgs(arg.String())))
1035-
} else if mon == 0 {
1038+
} else if mon == 0 || arg.IsZero() {
10361039
return "", true, nil
10371040
}
10381041
return types.MonthNames[mon-1], false, nil
@@ -1111,7 +1114,10 @@ func (b *builtinDayOfMonthSig) evalInt(row chunk.Row) (int64, bool, error) {
11111114
return 0, true, errors.Trace(handleInvalidTimeError(b.ctx, err))
11121115
}
11131116
if arg.IsZero() {
1114-
return 0, true, errors.Trace(handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenByArgs(arg.String())))
1117+
if b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode() {
1118+
return 0, true, errors.Trace(handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenByArgs(arg.String())))
1119+
}
1120+
return 0, false, nil
11151121
}
11161122
return int64(arg.Time.Day()), false, nil
11171123
}
@@ -1393,9 +1399,11 @@ func (b *builtinYearSig) evalInt(row chunk.Row) (int64, bool, error) {
13931399
}
13941400

13951401
if date.IsZero() {
1396-
return 0, true, errors.Trace(handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenByArgs(date.String())))
1402+
if b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode() {
1403+
return 0, true, errors.Trace(handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenByArgs(date.String())))
1404+
}
1405+
return 0, false, nil
13971406
}
1398-
13991407
return int64(date.Time.Year()), false, nil
14001408
}
14011409

0 commit comments

Comments
 (0)