Skip to content

Commit f2cb598

Browse files
authored
Merge branch 'release-3.0' into automated-cherry-pick-of-pingcap#12173-upstream-release-3.0
2 parents 8096263 + 268d5ae commit f2cb598

29 files changed

+951
-185
lines changed

config/config.go

+13-11
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,11 @@ type Log struct {
104104
// File log config.
105105
File logutil.FileLogConfig `toml:"file" json:"file"`
106106

107-
SlowQueryFile string `toml:"slow-query-file" json:"slow-query-file"`
108-
SlowThreshold uint64 `toml:"slow-threshold" json:"slow-threshold"`
109-
ExpensiveThreshold uint `toml:"expensive-threshold" json:"expensive-threshold"`
110-
QueryLogMaxLen uint64 `toml:"query-log-max-len" json:"query-log-max-len"`
107+
SlowQueryFile string `toml:"slow-query-file" json:"slow-query-file"`
108+
SlowThreshold uint64 `toml:"slow-threshold" json:"slow-threshold"`
109+
ExpensiveThreshold uint `toml:"expensive-threshold" json:"expensive-threshold"`
110+
QueryLogMaxLen uint64 `toml:"query-log-max-len" json:"query-log-max-len"`
111+
RecordPlanInSlowLog uint32 `toml:"record-plan-in-slow-log" json:"record-plan-in-slow-log"`
111112
}
112113

113114
// Security is the security section of the config.
@@ -341,13 +342,14 @@ var defaultConf = Config{
341342
},
342343
LowerCaseTableNames: 2,
343344
Log: Log{
344-
Level: "info",
345-
Format: "text",
346-
File: logutil.NewFileLogConfig(true, logutil.DefaultLogMaxSize),
347-
SlowQueryFile: "tidb-slow.log",
348-
SlowThreshold: logutil.DefaultSlowThreshold,
349-
ExpensiveThreshold: 10000,
350-
QueryLogMaxLen: logutil.DefaultQueryLogMaxLen,
345+
Level: "info",
346+
Format: "text",
347+
File: logutil.NewFileLogConfig(true, logutil.DefaultLogMaxSize),
348+
SlowQueryFile: "tidb-slow.log",
349+
SlowThreshold: logutil.DefaultSlowThreshold,
350+
ExpensiveThreshold: 10000,
351+
QueryLogMaxLen: logutil.DefaultQueryLogMaxLen,
352+
RecordPlanInSlowLog: logutil.DefaultRecordPlanInSlowLog,
351353
},
352354
Status: Status{
353355
ReportStatus: true,

config/config.toml.example

+4
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ slow-query-file = "tidb-slow.log"
7373
# Queries with execution time greater than this value will be logged. (Milliseconds)
7474
slow-threshold = 300
7575

76+
# record-plan-in-slow-log is used to enable record query plan in slow log.
77+
# 0 is disable. 1 is enable.
78+
record-plan-in-slow-log = 1
79+
7680
# Queries with internal result greater than this value will be logged.
7781
expensive-threshold = 10000
7882

executor/adapter.go

+30
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ func (a *ExecStmt) LogSlowQuery(txnTS uint64, succ bool, hasMoreResults bool) {
687687
ExecDetail: execDetail,
688688
MemMax: memMax,
689689
Succ: succ,
690+
Plan: getPlanTree(a.Plan),
690691
Prepared: a.isPreparedStmt,
691692
HasMoreResults: hasMoreResults,
692693
}
@@ -722,6 +723,35 @@ func (a *ExecStmt) LogSlowQuery(txnTS uint64, succ bool, hasMoreResults bool) {
722723
}
723724
}
724725

726+
// getPlanTree will try to get the select plan tree if the plan is select or the select plan of delete/update/insert statement.
727+
func getPlanTree(p plannercore.Plan) string {
728+
cfg := config.GetGlobalConfig()
729+
if atomic.LoadUint32(&cfg.Log.RecordPlanInSlowLog) == 0 {
730+
return ""
731+
}
732+
var selectPlan plannercore.PhysicalPlan
733+
if physicalPlan, ok := p.(plannercore.PhysicalPlan); ok {
734+
selectPlan = physicalPlan
735+
} else {
736+
switch x := p.(type) {
737+
case *plannercore.Delete:
738+
selectPlan = x.SelectPlan
739+
case *plannercore.Update:
740+
selectPlan = x.SelectPlan
741+
case *plannercore.Insert:
742+
selectPlan = x.SelectPlan
743+
}
744+
}
745+
if selectPlan == nil {
746+
return ""
747+
}
748+
planTree := plannercore.EncodePlan(selectPlan)
749+
if len(planTree) == 0 {
750+
return planTree
751+
}
752+
return variable.SlowLogPlanPrefix + planTree + variable.SlowLogPlanSuffix
753+
}
754+
725755
// SummaryStmt collects statements for performance_schema.events_statements_summary_by_digest
726756
func (a *ExecStmt) SummaryStmt() {
727757
sessVars := a.Ctx.GetSessionVars()

executor/set_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,11 @@ func (s *testSuite2) TestSetVar(c *C) {
381381

382382
tk.MustExec("set @@tidb_expensive_query_time_threshold=70")
383383
tk.MustQuery("select @@tidb_expensive_query_time_threshold;").Check(testkit.Rows("70"))
384+
385+
tk.MustExec("set @@tidb_record_plan_in_slow_log = 1")
386+
tk.MustQuery("select @@tidb_record_plan_in_slow_log;").Check(testkit.Rows("1"))
387+
tk.MustExec("set @@tidb_record_plan_in_slow_log = 0")
388+
tk.MustQuery("select @@tidb_record_plan_in_slow_log;").Check(testkit.Rows("0"))
384389
}
385390

386391
func (s *testSuite2) TestSetCharset(c *C) {

expression/builtin.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,6 @@ var funcs = map[string]functionClass{
415415
ast.Year: &yearFunctionClass{baseFunctionClass{ast.Year, 1, 1}},
416416
ast.YearWeek: &yearWeekFunctionClass{baseFunctionClass{ast.YearWeek, 1, 2}},
417417
ast.LastDay: &lastDayFunctionClass{baseFunctionClass{ast.LastDay, 1, 1}},
418-
ast.TiDBParseTso: &tidbParseTsoFunctionClass{baseFunctionClass{ast.TiDBParseTso, 1, 1}},
419418

420419
// string functions
421420
ast.ASCII: &asciiFunctionClass{baseFunctionClass{ast.ASCII, 1, 1}},
@@ -486,9 +485,6 @@ var funcs = map[string]functionClass{
486485
ast.RowCount: &rowCountFunctionClass{baseFunctionClass{ast.RowCount, 0, 0}},
487486
ast.SessionUser: &userFunctionClass{baseFunctionClass{ast.SessionUser, 0, 0}},
488487
ast.SystemUser: &userFunctionClass{baseFunctionClass{ast.SystemUser, 0, 0}},
489-
// This function is used to show tidb-server version info.
490-
ast.TiDBVersion: &tidbVersionFunctionClass{baseFunctionClass{ast.TiDBVersion, 0, 0}},
491-
ast.TiDBIsDDLOwner: &tidbIsDDLOwnerFunctionClass{baseFunctionClass{ast.TiDBIsDDLOwner, 0, 0}},
492488

493489
// control functions
494490
ast.If: &ifFunctionClass{baseFunctionClass{ast.If, 3, 3}},
@@ -600,4 +596,11 @@ var funcs = map[string]functionClass{
600596
ast.JSONDepth: &jsonDepthFunctionClass{baseFunctionClass{ast.JSONDepth, 1, 1}},
601597
ast.JSONKeys: &jsonKeysFunctionClass{baseFunctionClass{ast.JSONKeys, 1, 2}},
602598
ast.JSONLength: &jsonLengthFunctionClass{baseFunctionClass{ast.JSONLength, 1, 2}},
599+
600+
// TiDB internal function.
601+
// This function is used to show tidb-server version info.
602+
ast.TiDBVersion: &tidbVersionFunctionClass{baseFunctionClass{ast.TiDBVersion, 0, 0}},
603+
ast.TiDBIsDDLOwner: &tidbIsDDLOwnerFunctionClass{baseFunctionClass{ast.TiDBIsDDLOwner, 0, 0}},
604+
ast.TiDBParseTso: &tidbParseTsoFunctionClass{baseFunctionClass{ast.TiDBParseTso, 1, 1}},
605+
ast.TiDBDecodePlan: &tidbDecodePlanFunctionClass{baseFunctionClass{ast.TiDBDecodePlan, 1, 1}},
603606
}

expression/builtin_info.go

+34
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/pingcap/tidb/sessionctx"
2626
"github.com/pingcap/tidb/types"
2727
"github.com/pingcap/tidb/util/chunk"
28+
"github.com/pingcap/tidb/util/plancodec"
2829
"github.com/pingcap/tidb/util/printer"
2930
)
3031

@@ -44,6 +45,7 @@ var (
4445
_ functionClass = &rowCountFunctionClass{}
4546
_ functionClass = &tidbVersionFunctionClass{}
4647
_ functionClass = &tidbIsDDLOwnerFunctionClass{}
48+
_ functionClass = &tidbDecodePlanFunctionClass{}
4749
)
4850

4951
var (
@@ -589,3 +591,35 @@ func (b *builtinRowCountSig) evalInt(_ chunk.Row) (res int64, isNull bool, err e
589591
res = int64(b.ctx.GetSessionVars().StmtCtx.PrevAffectedRows)
590592
return res, false, nil
591593
}
594+
595+
type tidbDecodePlanFunctionClass struct {
596+
baseFunctionClass
597+
}
598+
599+
func (c *tidbDecodePlanFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
600+
if err := c.verifyArgs(args); err != nil {
601+
return nil, err
602+
}
603+
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETString)
604+
sig := &builtinTiDBDecodePlanSig{bf}
605+
return sig, nil
606+
}
607+
608+
type builtinTiDBDecodePlanSig struct {
609+
baseBuiltinFunc
610+
}
611+
612+
func (b *builtinTiDBDecodePlanSig) Clone() builtinFunc {
613+
newSig := &builtinTiDBDecodePlanSig{}
614+
newSig.cloneFrom(&b.baseBuiltinFunc)
615+
return newSig
616+
}
617+
618+
func (b *builtinTiDBDecodePlanSig) evalString(row chunk.Row) (string, bool, error) {
619+
planString, isNull, err := b.args[0].EvalString(b.ctx, row)
620+
if isNull || err != nil {
621+
return "", isNull, err
622+
}
623+
planTree, err := plancodec.DecodePlan(planString)
624+
return planTree, false, err
625+
}

expression/integration_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -4010,6 +4010,25 @@ func (s *testIntegrationSuite) testTiDBIsOwnerFunc(c *C) {
40104010
result.Check(testkit.Rows(fmt.Sprintf("%v", ret)))
40114011
}
40124012

4013+
func (s *testIntegrationSuite) TestTiDBDecodePlanFunc(c *C) {
4014+
tk := testkit.NewTestKit(c, s.store)
4015+
defer s.cleanEnv(c)
4016+
tk.MustQuery("select tidb_decode_plan('')").Check(testkit.Rows(""))
4017+
tk.MustQuery("select tidb_decode_plan('7APIMAk1XzEzCTAJMQlmdW5jczpjb3VudCgxKQoxCTE3XzE0CTAJMAlpbm5lciBqb2luLCBp" +
4018+
"AQyQOlRhYmxlUmVhZGVyXzIxLCBlcXVhbDpbZXEoQ29sdW1uIzEsIA0KCDkpIBkXADIVFywxMCldCjIJMzJfMTgFZXhkYXRhOlNlbGVjdGlvbl" +
4019+
"8xNwozCTFfMTcJMQkwCWx0HVlATlVMTCksIG5vdChpc251bGwVHAApUhcAUDIpKQo0CTEwXzE2CTEJMTAwMDAJdAHB2Dp0MSwgcmFuZ2U6Wy1p" +
4020+
"bmYsK2luZl0sIGtlZXAgb3JkZXI6ZmFsc2UsIHN0YXRzOnBzZXVkbwoFtgAyAZcEMAk6tgAEMjAFtgQyMDq2AAg5LCBmtgAAMFa3AAA5FbcAO" +
4021+
"T63AAAyzrcA')").Check(testkit.Rows("" +
4022+
"\tStreamAgg_13 \troot\t1 \tfuncs:count(1)\n" +
4023+
"\t└─HashLeftJoin_14 \troot\t0 \tinner join, inner:TableReader_21, equal:[eq(Column#1, Column#9) eq(Column#2, Column#10)]\n" +
4024+
"\t ├─TableReader_18 \troot\t0 \tdata:Selection_17\n" +
4025+
"\t │ └─Selection_17 \tcop \t0 \tlt(Column#1, NULL), not(isnull(Column#1)), not(isnull(Column#2))\n" +
4026+
"\t │ └─TableScan_16\tcop \t10000\ttable:t1, range:[-inf,+inf], keep order:false, stats:pseudo\n" +
4027+
"\t └─TableReader_21 \troot\t0 \tdata:Selection_20\n" +
4028+
"\t └─Selection_20 \tcop \t0 \tlt(Column#9, NULL), not(isnull(Column#10)), not(isnull(Column#9))\n" +
4029+
"\t └─TableScan_19\tcop \t10000\ttable:t2, range:[-inf,+inf], keep order:false, stats:pseudo"))
4030+
}
4031+
40134032
func newStoreWithBootstrap() (kv.Storage, *domain.Domain, error) {
40144033
store, err := mockstore.NewMockTikvStore()
40154034
if err != nil {

go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ require (
1818
github.com/go-sql-driver/mysql v0.0.0-20170715192408-3955978caca4
1919
github.com/gogo/protobuf v1.2.0
2020
github.com/golang/protobuf v1.2.0
21-
github.com/golang/snappy v0.0.1 // indirect
21+
github.com/golang/snappy v0.0.1
2222
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c
2323
github.com/google/uuid v1.1.1
2424
github.com/gorilla/context v1.1.1 // indirect
@@ -42,7 +42,7 @@ require (
4242
github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e
4343
github.com/pingcap/kvproto v0.0.0-20190918085321-44e3817e1f18
4444
github.com/pingcap/log v0.0.0-20190715063458-479153f07ebd
45-
github.com/pingcap/parser v0.0.0-20190910041007-2a177b291004
45+
github.com/pingcap/parser v0.0.0-20191018040038-555b97093a2a
4646
github.com/pingcap/pd v1.1.0-beta.0.20190912093418-dc03c839debd
4747
github.com/pingcap/tidb-tools v2.1.3-0.20190321065848-1e8b48f5c168+incompatible
4848
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ github.com/pingcap/kvproto v0.0.0-20190918085321-44e3817e1f18 h1:5vQV8S/8B9nE+I+
161161
github.com/pingcap/kvproto v0.0.0-20190918085321-44e3817e1f18/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY=
162162
github.com/pingcap/log v0.0.0-20190715063458-479153f07ebd h1:hWDol43WY5PGhsh3+8794bFHY1bPrmu6bTalpssCrGg=
163163
github.com/pingcap/log v0.0.0-20190715063458-479153f07ebd/go.mod h1:WpHUKhNZ18v116SvGrmjkA9CBhYmuUTKL+p8JC9ANEw=
164-
github.com/pingcap/parser v0.0.0-20190910041007-2a177b291004 h1:LaA55frHvXh8vTYcQj0xNsQiiPb8iU/JcU8cc2HA9Jg=
165-
github.com/pingcap/parser v0.0.0-20190910041007-2a177b291004/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
164+
github.com/pingcap/parser v0.0.0-20191018040038-555b97093a2a h1:PMjYrxWKdVUlJ77+9YHbYVciDQCyqZ/noS9nIni76KQ=
165+
github.com/pingcap/parser v0.0.0-20191018040038-555b97093a2a/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
166166
github.com/pingcap/pd v1.1.0-beta.0.20190912093418-dc03c839debd h1:bKj6hodu/ro78B0oN2yicdGn0t4yd9XjnyoW95qmWic=
167167
github.com/pingcap/pd v1.1.0-beta.0.20190912093418-dc03c839debd/go.mod h1:I7TEby5BHTYIxgHszfsOJSBsk8b2Qt8QrSIgdv5n5QQ=
168168
github.com/pingcap/tidb-tools v2.1.3-0.20190321065848-1e8b48f5c168+incompatible h1:MkWCxgZpJBgY2f4HtwWMMFzSBb3+JPzeJgF3VrXE/bU=

infoschema/slow_log.go

+20
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/pingcap/tidb/util/execdetails"
3131
"github.com/pingcap/tidb/util/hack"
3232
"github.com/pingcap/tidb/util/logutil"
33+
"github.com/pingcap/tidb/util/plancodec"
3334
"go.uber.org/zap"
3435
)
3536

@@ -61,6 +62,7 @@ var slowQueryCols = []columnInfo{
6162
{variable.SlowLogCopWaitAddr, mysql.TypeVarchar, 64, 0, nil, nil},
6263
{variable.SlowLogMemMax, mysql.TypeLonglong, 20, 0, nil, nil},
6364
{variable.SlowLogSucc, mysql.TypeTiny, 1, 0, nil, nil},
65+
{variable.SlowLogPlan, mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
6466
{variable.SlowLogPrevStmt, mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
6567
{variable.SlowLogQuerySQLStr, mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
6668
}
@@ -205,6 +207,7 @@ type slowQueryTuple struct {
205207
sql string
206208
isInternal bool
207209
succ bool
210+
plan string
208211
}
209212

210213
func (st *slowQueryTuple) setFieldValue(tz *time.Location, field, value string) error {
@@ -274,6 +277,8 @@ func (st *slowQueryTuple) setFieldValue(tz *time.Location, field, value string)
274277
st.memMax, err = strconv.ParseInt(value, 10, 64)
275278
case variable.SlowLogSucc:
276279
st.succ, err = strconv.ParseBool(value)
280+
case variable.SlowLogPlan:
281+
st.plan = value
277282
case variable.SlowLogQuerySQLStr:
278283
st.sql = value
279284
}
@@ -320,11 +325,26 @@ func (st *slowQueryTuple) convertToDatumRow() []types.Datum {
320325
} else {
321326
record = append(record, types.NewIntDatum(0))
322327
}
328+
record = append(record, types.NewStringDatum(parsePlan(st.plan)))
323329
record = append(record, types.NewStringDatum(st.prevStmt))
324330
record = append(record, types.NewStringDatum(st.sql))
325331
return record
326332
}
327333

334+
func parsePlan(planString string) string {
335+
if len(planString) <= len(variable.SlowLogPlanPrefix)+len(variable.SlowLogPlanSuffix) {
336+
return planString
337+
}
338+
planString = planString[len(variable.SlowLogPlanPrefix) : len(planString)-len(variable.SlowLogPlanSuffix)]
339+
decodePlanString, err := plancodec.DecodePlan(planString)
340+
if err == nil {
341+
planString = decodePlanString
342+
} else {
343+
logutil.Logger(context.Background()).Error("decode plan in slow log failed", zap.String("plan", planString), zap.Error(err))
344+
}
345+
return planString
346+
}
347+
328348
// ParseTime exports for testing.
329349
func ParseTime(s string) (time.Time, error) {
330350
t, err := time.Parse(logutil.SlowLogTimeFormat, s)

infoschema/slow_log_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ select * from t;`)
5555
}
5656
recordString += str
5757
}
58-
expectRecordString := "2019-04-28 15:24:04.309074,405888132465033227,,,0,0.216905,0.021,0,0,1,637,0,,,1,42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772,t1:1,t2:2,0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,0,update t set i = 1;,select * from t;"
58+
expectRecordString := "2019-04-28 15:24:04.309074,405888132465033227,,,0,0.216905,0.021,0,0,1,637,0,,,1,42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772,t1:1,t2:2,0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,0,,update t set i = 1;,select * from t;"
5959
c.Assert(expectRecordString, Equals, recordString)
6060

6161
// fix sql contain '# ' bug

infoschema/tables_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ func (s *testTableSuite) TestSlowQuery(c *C) {
458458
# Cop_wait_avg: 0.05 Cop_wait_p90: 0.6 Cop_wait_max: 0.8 Cop_wait_addr: 0.0.0.0:20160
459459
# Mem_max: 70724
460460
# Succ: true
461+
# Plan: abcd
461462
# Prev_stmt: update t set i = 2;
462463
select * from t_slim;`))
463464
c.Assert(f.Sync(), IsNil)
@@ -467,10 +468,10 @@ select * from t_slim;`))
467468
tk.MustExec("set time_zone = '+08:00';")
468469
re := tk.MustQuery("select * from information_schema.slow_query")
469470
re.Check(testutil.RowsWithSep("|",
470-
"2019-02-12 19:33:56.571953|406315658548871171|root|127.0.0.1|6|4.895492|0.161|0.101|0.092|1|100001|100000|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|1|update t set i = 2;|select * from t_slim;"))
471+
"2019-02-12 19:33:56.571953|406315658548871171|root|127.0.0.1|6|4.895492|0.161|0.101|0.092|1|100001|100000|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|1|abcd|update t set i = 2;|select * from t_slim;"))
471472
tk.MustExec("set time_zone = '+00:00';")
472473
re = tk.MustQuery("select * from information_schema.slow_query")
473-
re.Check(testutil.RowsWithSep("|", "2019-02-12 11:33:56.571953|406315658548871171|root|127.0.0.1|6|4.895492|0.161|0.101|0.092|1|100001|100000|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|1|update t set i = 2;|select * from t_slim;"))
474+
re.Check(testutil.RowsWithSep("|", "2019-02-12 11:33:56.571953|406315658548871171|root|127.0.0.1|6|4.895492|0.161|0.101|0.092|1|100001|100000|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|1|abcd|update t set i = 2;|select * from t_slim;"))
474475

475476
// Test for long query.
476477
_, err = f.Write([]byte(`

0 commit comments

Comments
 (0)