提交 a1c7d035 编写于 作者: martianzhang's avatar martianzhang

fix issue #235 & update vendor

上级 7944a57e
...@@ -35,7 +35,7 @@ SOAR(SQL Optimizer And Rewriter) 是一个对 SQL 进行优化和改写的自动 ...@@ -35,7 +35,7 @@ SOAR(SQL Optimizer And Rewriter) 是一个对 SQL 进行优化和改写的自动
## 交流与反馈 ## 交流与反馈
* 欢迎通过 Github Issues 提交问题报告与建议 * 欢迎通过 Github Issues 提交问题报告与建议
* QQ 群:779359816(满) 758940447(新 * QQ 群:779359816(未满) 758940447(已满
* [Gitter](https://gitter.im/xiaomi-dba/soar) 推荐 * [Gitter](https://gitter.im/xiaomi-dba/soar) 推荐
![xiaomi_sa](https://raw.githubusercontent.com/XiaoMi/soar/master/doc/images/xiaomi_sa.png) ![xiaomi_sa](https://raw.githubusercontent.com/XiaoMi/soar/master/doc/images/xiaomi_sa.png)
......
...@@ -1827,7 +1827,7 @@ func (q *Query4Audit) RuleIndexAttributeOrder() Rule { ...@@ -1827,7 +1827,7 @@ func (q *Query4Audit) RuleIndexAttributeOrder() Rule {
for _, tiStmt := range q.TiStmt { for _, tiStmt := range q.TiStmt {
switch node := tiStmt.(type) { switch node := tiStmt.(type) {
case *tidb.CreateIndexStmt: case *tidb.CreateIndexStmt:
if len(node.IndexColNames) > 1 { if len(node.IndexPartSpecifications) > 1 {
rule = HeuristicRules["KEY.004"] rule = HeuristicRules["KEY.004"]
break break
} }
...@@ -2808,7 +2808,7 @@ func (q *Query4Audit) RuleTooManyKeyParts() Rule { ...@@ -2808,7 +2808,7 @@ func (q *Query4Audit) RuleTooManyKeyParts() Rule {
return HeuristicRules["KEY.006"] return HeuristicRules["KEY.006"]
} }
if constraint.Refer != nil && len(constraint.Refer.IndexColNames) > common.Config.MaxIdxColsCount { if constraint.Refer != nil && len(constraint.Refer.IndexPartSpecifications) > common.Config.MaxIdxColsCount {
return HeuristicRules["KEY.006"] return HeuristicRules["KEY.006"]
} }
} }
...@@ -2823,7 +2823,7 @@ func (q *Query4Audit) RuleTooManyKeyParts() Rule { ...@@ -2823,7 +2823,7 @@ func (q *Query4Audit) RuleTooManyKeyParts() Rule {
} }
if spec.Constraint.Refer != nil { if spec.Constraint.Refer != nil {
if len(spec.Constraint.Refer.IndexColNames) > common.Config.MaxIdxColsCount { if len(spec.Constraint.Refer.IndexPartSpecifications) > common.Config.MaxIdxColsCount {
return HeuristicRules["KEY.006"] return HeuristicRules["KEY.006"]
} }
} }
......
...@@ -62,7 +62,7 @@ func NewQuery4Audit(sql string, options ...string) (*Query4Audit, error) { ...@@ -62,7 +62,7 @@ func NewQuery4Audit(sql string, options ...string) (*Query4Audit, error) {
} }
// TODO: charset, collation // TODO: charset, collation
// tdib parser 语法解析 // tidb parser 语法解析
q.TiStmt, err = ast.TiParse(sql, charset, collation) q.TiStmt, err = ast.TiParse(sql, charset, collation)
return q, err return q, err
} }
......
...@@ -69,3 +69,18 @@ func TestIsIgnoreRule(t *testing.T) { ...@@ -69,3 +69,18 @@ func TestIsIgnoreRule(t *testing.T) {
} }
common.Log.Debug("Exiting function: %s", common.GetFunctionName()) common.Log.Debug("Exiting function: %s", common.GetFunctionName())
} }
func TestNewQuery4Audit(t *testing.T) {
common.Log.Debug("Entering function: %s", common.GetFunctionName())
sqls := []string{
`SELECT CONVERT("abc" using gbk)`,
`SET NAMES gbk`,
}
for _, sql := range sqls {
_, err := NewQuery4Audit(sql)
if err != nil {
t.Errorf("SQL: %s, Error: %s", sql, err.Error())
}
}
common.Log.Debug("Exiting function: %s", common.GetFunctionName())
}
...@@ -38,6 +38,14 @@ func TiParse(sql, charset, collation string) ([]ast.StmtNode, error) { ...@@ -38,6 +38,14 @@ func TiParse(sql, charset, collation string) ([]ast.StmtNode, error) {
p := parser.New() p := parser.New()
sql = removeIncompatibleWords(sql) sql = removeIncompatibleWords(sql)
stmt, warn, err := p.Parse(sql, charset, collation) stmt, warn, err := p.Parse(sql, charset, collation)
if err != nil {
// issue: https://github.com/XiaoMi/soar/issues/235
// TODO: bypass charset error, pingcap/parser not support so much charsets
if strings.Contains(err.Error(), "Unknown character set") {
err = nil
}
}
// TODO: bypass warning info // TODO: bypass warning info
for _, w := range warn { for _, w := range warn {
common.Log.Warn(w.Error()) common.Log.Warn(w.Error())
......
.PHONY: all parser clean .PHONY: all parser clean
ARCH:="`uname -s`" all: fmt parser
MAC:="Darwin"
LINUX:="Linux"
all: parser.go fmt test: fmt parser
test: parser.go fmt
sh test.sh sh test.sh
parser.go: parser.y parser: parser.go hintparser.go
make parser
parser: bin/goyacc
bin/goyacc -o /dev/null parser.y
bin/goyacc -o parser.go parser.y 2>&1 | egrep "(shift|reduce)/reduce" | awk '{print} END {if (NR > 0) {print "Find conflict in parser.y. Please check y.output for more information."; exit 1;}}'
rm -f y.output
@if [ $(ARCH) = $(LINUX) ]; \ %arser.go: prefix = $(@:parser.go=)
then \ %arser.go: %arser.y bin/goyacc
sed -i -e 's|//line.*||' -e 's/yyEofCode/yyEOFCode/' parser.go; \ @echo "bin/goyacc -o $@ -p yy$(prefix) -t $(prefix)Parser $<"
elif [ $(ARCH) = $(MAC) ]; \ @bin/goyacc -o $@ -p yy$(prefix) -t $(prefix)Parser $< || ( rm -f $@ && echo 'Please check y.output for more information' && exit 1 )
then \ @rm -f y.output
/usr/bin/sed -i "" 's|//line.*||' parser.go; \
/usr/bin/sed -i "" 's/yyEofCode/yyEOFCode/' parser.go; \
fi
@awk 'BEGIN{print "// Code generated by goyacc DO NOT EDIT."} {print $0}' parser.go > tmp_parser.go && mv tmp_parser.go parser.go; %arser_golden.y: %arser.y
@bin/goyacc -fmt -fmtout $@ $<
@(git diff --no-index --exit-code $< $@ && rm $@) || (mv $@ $< && >&2 echo "formatted $<" && exit 1)
bin/goyacc: goyacc/main.go bin/goyacc: goyacc/main.go goyacc/format_yacc.go
GO111MODULE=on go build -o bin/goyacc goyacc/main.go GO111MODULE=on go build -o bin/goyacc goyacc/main.go goyacc/format_yacc.go
fmt: fmt: bin/goyacc parser_golden.y hintparser_golden.y
@echo "gofmt (simplify)" @echo "gofmt (simplify)"
@gofmt -s -l -w . 2>&1 | awk '{print} END{if(NR>0) {exit 1}}' @gofmt -s -l -w . 2>&1 | awk '{print} END{if(NR>0) {exit 1}}'
clean: clean:
go clean -i ./... go clean -i ./...
rm -rf *.out rm -rf *.out
rm parser.go rm -f parser.go hintparser.go
...@@ -7,6 +7,33 @@ TiDB SQL Parser ...@@ -7,6 +7,33 @@ TiDB SQL Parser
## How to use it ## How to use it
```go
import (
"fmt"
"github.com/pingcap/parser"
_ "github.com/pingcap/tidb/types/parser_driver"
)
// This example show how to parse a text sql into ast.
func example() {
// 0. make sure import parser_driver implemented by TiDB(user also can implement own driver by self).
// and add `import _ "github.com/pingcap/tidb/types/parser_driver"` in the head of file.
// 1. Create a parser. The parser is NOT goroutine safe and should
// not be shared among multiple goroutines. However, parser is also
// heavy, so each goroutine should reuse its own local instance if
// possible.
p := parser.New()
// 2. Parse a text SQL into AST([]ast.StmtNode).
stmtNodes, _, err := p.Parse("select * from tbl where id = 1", "", "")
// 3. Use AST to do cool things.
fmt.Println(stmtNodes[0], err)
}
```
See [https://godoc.org/github.com/pingcap/parser](https://godoc.org/github.com/pingcap/parser) See [https://godoc.org/github.com/pingcap/parser](https://godoc.org/github.com/pingcap/parser)
## How to update parser for TiDB ## How to update parser for TiDB
......
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package ast
import (
. "github.com/pingcap/parser/format"
)
var _ StmtNode = &IndexAdviseStmt{}
// IndexAdviseStmt is used to advise indexes
type IndexAdviseStmt struct {
stmtNode
IsLocal bool
Path string
MaxMinutes uint64
MaxIndexNum *MaxIndexNumClause
LinesInfo *LinesClause
}
// Restore implements Node Accept interface.
func (n *IndexAdviseStmt) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord("INDEX ADVISE ")
if n.IsLocal {
ctx.WriteKeyWord("LOCAL ")
}
ctx.WriteKeyWord("INFILE ")
ctx.WriteString(n.Path)
if n.MaxMinutes != UnspecifiedSize {
ctx.WriteKeyWord(" MAX_MINUTES ")
ctx.WritePlainf("%d", n.MaxMinutes)
}
if n.MaxIndexNum != nil {
n.MaxIndexNum.Restore(ctx)
}
n.LinesInfo.Restore(ctx)
return nil
}
// Accept implements Node Accept interface.
func (n *IndexAdviseStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*IndexAdviseStmt)
return v.Leave(n)
}
// MaxIndexNumClause represents 'maximum number of indexes' clause in index advise statement.
type MaxIndexNumClause struct {
PerTable uint64
PerDB uint64
}
// Restore for max index num clause
func (n *MaxIndexNumClause) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord(" MAX_IDXNUM")
if n.PerTable != UnspecifiedSize {
ctx.WriteKeyWord(" PER_TABLE ")
ctx.WritePlainf("%d", n.PerTable)
}
if n.PerDB != UnspecifiedSize {
ctx.WriteKeyWord(" PER_DB ")
ctx.WritePlainf("%d", n.PerDB)
}
return nil
}
...@@ -29,9 +29,11 @@ var ( ...@@ -29,9 +29,11 @@ var (
_ DDLNode = &CreateIndexStmt{} _ DDLNode = &CreateIndexStmt{}
_ DDLNode = &CreateTableStmt{} _ DDLNode = &CreateTableStmt{}
_ DDLNode = &CreateViewStmt{} _ DDLNode = &CreateViewStmt{}
_ DDLNode = &CreateSequenceStmt{}
_ DDLNode = &DropDatabaseStmt{} _ DDLNode = &DropDatabaseStmt{}
_ DDLNode = &DropIndexStmt{} _ DDLNode = &DropIndexStmt{}
_ DDLNode = &DropTableStmt{} _ DDLNode = &DropTableStmt{}
_ DDLNode = &DropSequenceStmt{}
_ DDLNode = &RenameTableStmt{} _ DDLNode = &RenameTableStmt{}
_ DDLNode = &TruncateTableStmt{} _ DDLNode = &TruncateTableStmt{}
_ DDLNode = &RepairTableStmt{} _ DDLNode = &RepairTableStmt{}
...@@ -41,7 +43,7 @@ var ( ...@@ -41,7 +43,7 @@ var (
_ Node = &ColumnOption{} _ Node = &ColumnOption{}
_ Node = &ColumnPosition{} _ Node = &ColumnPosition{}
_ Node = &Constraint{} _ Node = &Constraint{}
_ Node = &IndexColName{} _ Node = &IndexPartSpecification{}
_ Node = &ReferenceDef{} _ Node = &ReferenceDef{}
) )
...@@ -192,18 +194,27 @@ func (n *DropDatabaseStmt) Accept(v Visitor) (Node, bool) { ...@@ -192,18 +194,27 @@ func (n *DropDatabaseStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(n) return v.Leave(n)
} }
// IndexColName is used for parsing index column name from SQL. // IndexPartSpecifications is used for parsing index column name or index expression from SQL.
type IndexColName struct { type IndexPartSpecification struct {
node node
Column *ColumnName Column *ColumnName
Length int Length int
Expr ExprNode
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *IndexColName) Restore(ctx *RestoreCtx) error { func (n *IndexPartSpecification) Restore(ctx *RestoreCtx) error {
if n.Expr != nil {
ctx.WritePlain("(")
if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing IndexPartSpecifications")
}
ctx.WritePlain(")")
return nil
}
if err := n.Column.Restore(ctx); err != nil { if err := n.Column.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing IndexColName") return errors.Annotate(err, "An error occurred while splicing IndexPartSpecifications")
} }
if n.Length > 0 { if n.Length > 0 {
ctx.WritePlainf("(%d)", n.Length) ctx.WritePlainf("(%d)", n.Length)
...@@ -212,12 +223,20 @@ func (n *IndexColName) Restore(ctx *RestoreCtx) error { ...@@ -212,12 +223,20 @@ func (n *IndexColName) Restore(ctx *RestoreCtx) error {
} }
// Accept implements Node Accept interface. // Accept implements Node Accept interface.
func (n *IndexColName) Accept(v Visitor) (Node, bool) { func (n *IndexPartSpecification) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n) newNode, skipChildren := v.Enter(n)
if skipChildren { if skipChildren {
return v.Leave(newNode) return v.Leave(newNode)
} }
n = newNode.(*IndexColName) n = newNode.(*IndexPartSpecification)
if n.Expr != nil {
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
node, ok := n.Column.Accept(v) node, ok := n.Column.Accept(v)
if !ok { if !ok {
return n, false return n, false
...@@ -242,11 +261,11 @@ const ( ...@@ -242,11 +261,11 @@ const (
type ReferenceDef struct { type ReferenceDef struct {
node node
Table *TableName Table *TableName
IndexColNames []*IndexColName IndexPartSpecifications []*IndexPartSpecification
OnDelete *OnDeleteOpt OnDelete *OnDeleteOpt
OnUpdate *OnUpdateOpt OnUpdate *OnUpdateOpt
Match MatchType Match MatchType
} }
// Restore implements Node interface. // Restore implements Node interface.
...@@ -258,14 +277,14 @@ func (n *ReferenceDef) Restore(ctx *RestoreCtx) error { ...@@ -258,14 +277,14 @@ func (n *ReferenceDef) Restore(ctx *RestoreCtx) error {
} }
} }
if n.IndexColNames != nil { if n.IndexPartSpecifications != nil {
ctx.WritePlain("(") ctx.WritePlain("(")
for i, indexColNames := range n.IndexColNames { for i, indexColNames := range n.IndexPartSpecifications {
if i > 0 { if i > 0 {
ctx.WritePlain(", ") ctx.WritePlain(", ")
} }
if err := indexColNames.Restore(ctx); err != nil { if err := indexColNames.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while splicing IndexColNames: [%v]", i) return errors.Annotatef(err, "An error occurred while splicing IndexPartSpecifications: [%v]", i)
} }
} }
ctx.WritePlain(")") ctx.WritePlain(")")
...@@ -309,12 +328,12 @@ func (n *ReferenceDef) Accept(v Visitor) (Node, bool) { ...@@ -309,12 +328,12 @@ func (n *ReferenceDef) Accept(v Visitor) (Node, bool) {
return n, false return n, false
} }
n.Table = node.(*TableName) n.Table = node.(*TableName)
for i, val := range n.IndexColNames { for i, val := range n.IndexPartSpecifications {
node, ok = val.Accept(v) node, ok = val.Accept(v)
if !ok { if !ok {
return n, false return n, false
} }
n.IndexColNames[i] = node.(*IndexColName) n.IndexPartSpecifications[i] = node.(*IndexPartSpecification)
} }
onDelete, ok := n.OnDelete.Accept(v) onDelete, ok := n.OnDelete.Accept(v)
if !ok { if !ok {
...@@ -430,6 +449,7 @@ const ( ...@@ -430,6 +449,7 @@ const (
ColumnOptionCheck ColumnOptionCheck
ColumnOptionColumnFormat ColumnOptionColumnFormat
ColumnOptionStorage ColumnOptionStorage
ColumnOptionAutoRandom
) )
var ( var (
...@@ -452,8 +472,9 @@ type ColumnOption struct { ...@@ -452,8 +472,9 @@ type ColumnOption struct {
// Stored is only for ColumnOptionGenerated, default is false. // Stored is only for ColumnOptionGenerated, default is false.
Stored bool Stored bool
// Refer is used for foreign key. // Refer is used for foreign key.
Refer *ReferenceDef Refer *ReferenceDef
StrValue string StrValue string
AutoRandomBitLength int
// Enforced is only for Check, default is true. // Enforced is only for Check, default is true.
Enforced bool Enforced bool
} }
...@@ -530,6 +551,11 @@ func (n *ColumnOption) Restore(ctx *RestoreCtx) error { ...@@ -530,6 +551,11 @@ func (n *ColumnOption) Restore(ctx *RestoreCtx) error {
case ColumnOptionStorage: case ColumnOptionStorage:
ctx.WriteKeyWord("STORAGE ") ctx.WriteKeyWord("STORAGE ")
ctx.WriteKeyWord(n.StrValue) ctx.WriteKeyWord(n.StrValue)
case ColumnOptionAutoRandom:
ctx.WriteKeyWord("AUTO_RANDOM")
if n.AutoRandomBitLength != types.UnspecifiedLength {
ctx.WritePlainf("(%d)", n.AutoRandomBitLength)
}
default: default:
return errors.New("An error occurred while splicing ColumnOption") return errors.New("An error occurred while splicing ColumnOption")
} }
...@@ -667,7 +693,7 @@ type Constraint struct { ...@@ -667,7 +693,7 @@ type Constraint struct {
Tp ConstraintType Tp ConstraintType
Name string Name string
Keys []*IndexColName // Used for PRIMARY KEY, UNIQUE, ...... Keys []*IndexPartSpecification // Used for PRIMARY KEY, UNIQUE, ......
Refer *ReferenceDef // Used for foreign key. Refer *ReferenceDef // Used for foreign key.
...@@ -778,7 +804,7 @@ func (n *Constraint) Accept(v Visitor) (Node, bool) { ...@@ -778,7 +804,7 @@ func (n *Constraint) Accept(v Visitor) (Node, bool) {
if !ok { if !ok {
return n, false return n, false
} }
n.Keys[i] = node.(*IndexColName) n.Keys[i] = node.(*IndexPartSpecification)
} }
if n.Refer != nil { if n.Refer != nil {
node, ok := n.Refer.Accept(v) node, ok := n.Refer.Accept(v)
...@@ -1064,6 +1090,54 @@ func (n *DropTableStmt) Accept(v Visitor) (Node, bool) { ...@@ -1064,6 +1090,54 @@ func (n *DropTableStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(n) return v.Leave(n)
} }
// DropSequenceStmt is a statement to drop a Sequence.
type DropSequenceStmt struct {
ddlNode
IfExists bool
Sequences []*TableName
IsTemporary bool
}
// Restore implements Node interface.
func (n *DropSequenceStmt) Restore(ctx *RestoreCtx) error {
if n.IsTemporary {
ctx.WriteKeyWord("DROP TEMPORARY SEQUENCE ")
} else {
ctx.WriteKeyWord("DROP SEQUENCE ")
}
if n.IfExists {
ctx.WriteKeyWord("IF EXISTS ")
}
for i, sequence := range n.Sequences {
if i != 0 {
ctx.WritePlain(", ")
}
if err := sequence.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore DropSequenceStmt.Sequences[%d]", i)
}
}
return nil
}
// Accept implements Node Accept interface.
func (n *DropSequenceStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DropSequenceStmt)
for i, val := range n.Sequences {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Sequences[i] = node.(*TableName)
}
return v.Leave(n)
}
// RenameTableStmt is a statement to rename a table. // RenameTableStmt is a statement to rename a table.
// See http://dev.mysql.com/doc/refman/5.7/en/rename-table.html // See http://dev.mysql.com/doc/refman/5.7/en/rename-table.html
type RenameTableStmt struct { type RenameTableStmt struct {
...@@ -1252,6 +1326,65 @@ func (n *CreateViewStmt) Accept(v Visitor) (Node, bool) { ...@@ -1252,6 +1326,65 @@ func (n *CreateViewStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(n) return v.Leave(n)
} }
// CreateSequenceStmt is a statement to create a Sequence.
type CreateSequenceStmt struct {
ddlNode
// TODO : support or replace if need : care for it will conflict on temporaryOpt.
OrReplace bool
IsTemporary bool
IfNotExists bool
Name *TableName
SeqOptions []*SequenceOption
TblOptions []*TableOption
}
// Restore implements Node interface.
func (n *CreateSequenceStmt) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord("CREATE ")
if n.OrReplace {
ctx.WriteKeyWord("OR REPLACE ")
}
if n.IsTemporary {
ctx.WriteKeyWord("TEMPORARY ")
}
ctx.WriteKeyWord("SEQUENCE ")
if n.IfNotExists {
ctx.WriteKeyWord("IF NOT EXISTS ")
}
if err := n.Name.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while create CreateSequenceStmt.Name")
}
for i, option := range n.SeqOptions {
ctx.WritePlain(" ")
if err := option.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while splicing CreateSequenceStmt SequenceOption: [%v]", i)
}
}
for i, option := range n.TblOptions {
ctx.WritePlain(" ")
if err := option.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while splicing CreateSequenceStmt TableOption: [%v]", i)
}
}
return nil
}
// Accept implements Node Accept interface.
func (n *CreateSequenceStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*CreateSequenceStmt)
node, ok := n.Name.Accept(v)
if !ok {
return n, false
}
n.Name = node.(*TableName)
return v.Leave(n)
}
// IndexLockAndAlgorithm stores the algorithm option and the lock option. // IndexLockAndAlgorithm stores the algorithm option and the lock option.
type IndexLockAndAlgorithm struct { type IndexLockAndAlgorithm struct {
node node
...@@ -1311,12 +1444,12 @@ type CreateIndexStmt struct { ...@@ -1311,12 +1444,12 @@ type CreateIndexStmt struct {
// see https://mariadb.com/kb/en/library/create-index/ // see https://mariadb.com/kb/en/library/create-index/
IfNotExists bool IfNotExists bool
IndexName string IndexName string
Table *TableName Table *TableName
IndexColNames []*IndexColName IndexPartSpecifications []*IndexPartSpecification
IndexOption *IndexOption IndexOption *IndexOption
KeyType IndexKeyType KeyType IndexKeyType
LockAlg *IndexLockAndAlgorithm LockAlg *IndexLockAndAlgorithm
} }
// Restore implements Node interface. // Restore implements Node interface.
...@@ -1341,12 +1474,12 @@ func (n *CreateIndexStmt) Restore(ctx *RestoreCtx) error { ...@@ -1341,12 +1474,12 @@ func (n *CreateIndexStmt) Restore(ctx *RestoreCtx) error {
} }
ctx.WritePlain(" (") ctx.WritePlain(" (")
for i, indexColName := range n.IndexColNames { for i, indexColName := range n.IndexPartSpecifications {
if i != 0 { if i != 0 {
ctx.WritePlain(", ") ctx.WritePlain(", ")
} }
if err := indexColName.Restore(ctx); err != nil { if err := indexColName.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore CreateIndexStmt.IndexColNames: [%v]", i) return errors.Annotatef(err, "An error occurred while restore CreateIndexStmt.IndexPartSpecifications: [%v]", i)
} }
} }
ctx.WritePlain(")") ctx.WritePlain(")")
...@@ -1380,12 +1513,12 @@ func (n *CreateIndexStmt) Accept(v Visitor) (Node, bool) { ...@@ -1380,12 +1513,12 @@ func (n *CreateIndexStmt) Accept(v Visitor) (Node, bool) {
return n, false return n, false
} }
n.Table = node.(*TableName) n.Table = node.(*TableName)
for i, val := range n.IndexColNames { for i, val := range n.IndexPartSpecifications {
node, ok = val.Accept(v) node, ok = val.Accept(v)
if !ok { if !ok {
return n, false return n, false
} }
n.IndexColNames[i] = node.(*IndexColName) n.IndexPartSpecifications[i] = node.(*IndexPartSpecification)
} }
if n.IndexOption != nil { if n.IndexOption != nil {
node, ok := n.IndexOption.Accept(v) node, ok := n.IndexOption.Accept(v)
...@@ -1670,6 +1803,11 @@ const ( ...@@ -1670,6 +1803,11 @@ const (
OnDuplicateKeyHandlingReplace OnDuplicateKeyHandlingReplace
) )
const (
TableOptionCharsetWithoutConvertTo uint64 = 0
TableOptionCharsetWithConvertTo uint64 = 1
)
// TableOption is used for parsing table option from SQL. // TableOption is used for parsing table option from SQL.
type TableOption struct { type TableOption struct {
Tp TableOptionType Tp TableOptionType
...@@ -1690,9 +1828,20 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { ...@@ -1690,9 +1828,20 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error {
ctx.WritePlain("''") ctx.WritePlain("''")
} }
case TableOptionCharset: case TableOptionCharset:
ctx.WriteKeyWord("DEFAULT CHARACTER SET ") if n.UintValue == TableOptionCharsetWithConvertTo {
ctx.WritePlain("= ") ctx.WriteKeyWord("CONVERT TO ")
ctx.WriteKeyWord(n.StrValue) } else {
ctx.WriteKeyWord("DEFAULT ")
}
ctx.WriteKeyWord("CHARACTER SET ")
if n.UintValue == TableOptionCharsetWithoutConvertTo {
ctx.WriteKeyWord("= ")
}
if n.Default {
ctx.WriteKeyWord("DEFAULT")
} else {
ctx.WriteKeyWord(n.StrValue)
}
case TableOptionCollate: case TableOptionCollate:
ctx.WriteKeyWord("DEFAULT COLLATE ") ctx.WriteKeyWord("DEFAULT COLLATE ")
ctx.WritePlain("= ") ctx.WritePlain("= ")
...@@ -1864,6 +2013,69 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error { ...@@ -1864,6 +2013,69 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error {
return nil return nil
} }
// SequenceOptionType is the type for SequenceOption
type SequenceOptionType int
// SequenceOption types.
const (
SequenceOptionNone SequenceOptionType = iota
SequenceOptionIncrementBy
SequenceStartWith
SequenceNoMinValue
SequenceMinValue
SequenceNoMaxValue
SequenceMaxValue
SequenceNoCache
SequenceCache
SequenceNoCycle
SequenceCycle
SequenceNoOrder
SequenceOrder
)
// SequenceOption is used for parsing sequence option from SQL.
type SequenceOption struct {
Tp SequenceOptionType
IntValue int64
}
func (n *SequenceOption) Restore(ctx *RestoreCtx) error {
switch n.Tp {
case SequenceOptionIncrementBy:
ctx.WriteKeyWord("INCREMENT BY ")
ctx.WritePlainf("%d", n.IntValue)
case SequenceStartWith:
ctx.WriteKeyWord("START WITH ")
ctx.WritePlainf("%d", n.IntValue)
case SequenceNoMinValue:
ctx.WriteKeyWord("NO MINVALUE")
case SequenceMinValue:
ctx.WriteKeyWord("MINVALUE ")
ctx.WritePlainf("%d", n.IntValue)
case SequenceNoMaxValue:
ctx.WriteKeyWord("NO MAXVALUE")
case SequenceMaxValue:
ctx.WriteKeyWord("MAXVALUE ")
ctx.WritePlainf("%d", n.IntValue)
case SequenceNoCache:
ctx.WriteKeyWord("NOCACHE")
case SequenceCache:
ctx.WriteKeyWord("CACHE ")
ctx.WritePlainf("%d", n.IntValue)
case SequenceNoCycle:
ctx.WriteKeyWord("NOCYCLE")
case SequenceCycle:
ctx.WriteKeyWord("CYCLE")
case SequenceNoOrder:
ctx.WriteKeyWord("NOORDER")
case SequenceOrder:
ctx.WriteKeyWord("ORDER")
default:
return errors.Errorf("invalid SequenceOption: %d", n.Tp)
}
return nil
}
// ColumnPositionType is the type for ColumnPosition. // ColumnPositionType is the type for ColumnPosition.
type ColumnPositionType int type ColumnPositionType int
...@@ -2106,13 +2318,23 @@ func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error { ...@@ -2106,13 +2318,23 @@ func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error {
} }
case AlterTableOption: case AlterTableOption:
switch { switch {
case len(n.Options) == 2 && case len(n.Options) == 2 && n.Options[0].Tp == TableOptionCharset && n.Options[1].Tp == TableOptionCollate:
n.Options[0].Tp == TableOptionCharset && if n.Options[0].UintValue == TableOptionCharsetWithConvertTo {
n.Options[1].Tp == TableOptionCollate: ctx.WriteKeyWord("CONVERT TO ")
ctx.WriteKeyWord("CONVERT TO CHARACTER SET ") }
ctx.WriteKeyWord(n.Options[0].StrValue) ctx.WriteKeyWord("CHARACTER SET ")
if n.Options[0].Default {
ctx.WriteKeyWord("DEFAULT")
} else {
ctx.WriteKeyWord(n.Options[0].StrValue)
}
ctx.WriteKeyWord(" COLLATE ") ctx.WriteKeyWord(" COLLATE ")
ctx.WriteKeyWord(n.Options[1].StrValue) ctx.WriteKeyWord(n.Options[1].StrValue)
case n.Options[0].Tp == TableOptionCharset && n.Options[0].Default:
if n.Options[0].UintValue == TableOptionCharsetWithConvertTo {
ctx.WriteKeyWord("CONVERT TO ")
}
ctx.WriteKeyWord("CHARACTER SET DEFAULT")
default: default:
for i, opt := range n.Options { for i, opt := range n.Options {
if i != 0 { if i != 0 {
...@@ -3162,3 +3384,47 @@ func (n *RecoverTableStmt) Accept(v Visitor) (Node, bool) { ...@@ -3162,3 +3384,47 @@ func (n *RecoverTableStmt) Accept(v Visitor) (Node, bool) {
} }
return v.Leave(n) return v.Leave(n)
} }
// FlashBackTableStmt is a statement to restore a dropped/truncate table.
type FlashBackTableStmt struct {
ddlNode
Table *TableName
Timestamp ValueExpr
NewName string
}
// Restore implements Node interface.
func (n *FlashBackTableStmt) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord("FLASHBACK TABLE ")
if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing RecoverTableStmt Table")
}
ctx.WriteKeyWord(" UNTIL TIMESTAMP ")
if err := n.Timestamp.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing FlashBackTableStmt Table")
}
if len(n.NewName) > 0 {
ctx.WriteKeyWord(" TO ")
ctx.WriteName(n.NewName)
}
return nil
}
// Accept implements Node Accept interface.
func (n *FlashBackTableStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*FlashBackTableStmt)
if n.Table != nil {
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
}
return v.Leave(n)
}
...@@ -1842,6 +1842,7 @@ const ( ...@@ -1842,6 +1842,7 @@ const (
ShowCreateTable ShowCreateTable
ShowCreateView ShowCreateView
ShowCreateUser ShowCreateUser
ShowCreateSequence
ShowGrants ShowGrants
ShowTriggers ShowTriggers
ShowProcedureStatus ShowProcedureStatus
...@@ -1897,6 +1898,7 @@ type ShowStmt struct { ...@@ -1897,6 +1898,7 @@ type ShowStmt struct {
User *auth.UserIdentity // Used for show grants/create user. User *auth.UserIdentity // Used for show grants/create user.
Roles []*auth.RoleIdentity // Used for show grants .. using Roles []*auth.RoleIdentity // Used for show grants .. using
IfNotExists bool // Used for `show create database if not exists` IfNotExists bool // Used for `show create database if not exists`
Extended bool // Used for `show extended columns from ...`
// GlobalScope is used by `show variables` and `show bindings` // GlobalScope is used by `show variables` and `show bindings`
GlobalScope bool GlobalScope bool
...@@ -1962,6 +1964,11 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error { ...@@ -1962,6 +1964,11 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord("IF NOT EXISTS ") ctx.WriteKeyWord("IF NOT EXISTS ")
} }
ctx.WriteName(n.DBName) ctx.WriteName(n.DBName)
case ShowCreateSequence:
ctx.WriteKeyWord("CREATE SEQUENCE ")
if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore ShowStmt.SEQUENCE")
}
case ShowCreateUser: case ShowCreateUser:
ctx.WriteKeyWord("CREATE USER ") ctx.WriteKeyWord("CREATE USER ")
if err := n.User.Restore(ctx); err != nil { if err := n.User.Restore(ctx); err != nil {
...@@ -2085,6 +2092,9 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error { ...@@ -2085,6 +2092,9 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error {
return errors.Annotate(err, "An error occurred while resotre ShowStmt.Table") return errors.Annotate(err, "An error occurred while resotre ShowStmt.Table")
} // TODO: remember to check this case } // TODO: remember to check this case
case ShowColumns: // equivalent to SHOW FIELDS case ShowColumns: // equivalent to SHOW FIELDS
if n.Extended {
ctx.WriteKeyWord("EXTENDED ")
}
restoreOptFull() restoreOptFull()
ctx.WriteKeyWord("COLUMNS") ctx.WriteKeyWord("COLUMNS")
if n.Table != nil { if n.Table != nil {
...@@ -2608,3 +2618,39 @@ func (n *SplitOption) Restore(ctx *RestoreCtx) error { ...@@ -2608,3 +2618,39 @@ func (n *SplitOption) Restore(ctx *RestoreCtx) error {
} }
return nil return nil
} }
type FulltextSearchModifier int
const (
FulltextSearchModifierNaturalLanguageMode = 0
FulltextSearchModifierBooleanMode = 1
FulltextSearchModifierModeMask = 0xF
FulltextSearchModifierWithQueryExpansion = 1 << 4
)
func (m FulltextSearchModifier) IsBooleanMode() bool {
return m&FulltextSearchModifierModeMask == FulltextSearchModifierBooleanMode
}
func (m FulltextSearchModifier) IsNaturalLanguageMode() bool {
return m&FulltextSearchModifierModeMask == FulltextSearchModifierNaturalLanguageMode
}
func (m FulltextSearchModifier) WithQueryExpansion() bool {
return m&FulltextSearchModifierWithQueryExpansion == FulltextSearchModifierWithQueryExpansion
}
type TimestampBound struct {
Mode TimestampBoundMode
Timestamp ExprNode
}
type TimestampBoundMode int
const (
TimestampBoundStrong TimestampBoundMode = iota
TimestampBoundMaxStaleness
TimestampBoundExactStaleness
TimestampBoundReadTimestamp
TimestampBoundMinReadTimestamp
)
...@@ -45,6 +45,7 @@ var ( ...@@ -45,6 +45,7 @@ var (
_ ExprNode = &UnaryOperationExpr{} _ ExprNode = &UnaryOperationExpr{}
_ ExprNode = &ValuesExpr{} _ ExprNode = &ValuesExpr{}
_ ExprNode = &VariableExpr{} _ ExprNode = &VariableExpr{}
_ ExprNode = &MatchAgainst{}
_ Node = &ColumnName{} _ Node = &ColumnName{}
_ Node = &WhenClause{} _ Node = &WhenClause{}
...@@ -1273,3 +1274,83 @@ func (n *MaxValueExpr) Accept(v Visitor) (Node, bool) { ...@@ -1273,3 +1274,83 @@ func (n *MaxValueExpr) Accept(v Visitor) (Node, bool) {
} }
return v.Leave(n) return v.Leave(n)
} }
// MatchAgainst is the expression for matching against fulltext index.
type MatchAgainst struct {
exprNode
// ColumnNames are the columns to match.
ColumnNames []*ColumnName
// Against
Against ExprNode
// Modifier
Modifier FulltextSearchModifier
}
func (n *MatchAgainst) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord("MATCH")
ctx.WritePlain(" (")
for i, v := range n.ColumnNames {
if i != 0 {
ctx.WritePlain(",")
}
if err := v.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore MatchAgainst.ColumnNames[%d]", i)
}
}
ctx.WritePlain(") ")
ctx.WriteKeyWord("AGAINST")
ctx.WritePlain(" (")
if err := n.Against.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore MatchAgainst.Against")
}
if n.Modifier.IsBooleanMode() {
ctx.WritePlain(" IN BOOLEAN MODE")
if n.Modifier.WithQueryExpansion() {
return errors.New("BOOLEAN MODE doesn't support QUERY EXPANSION")
}
} else if n.Modifier.WithQueryExpansion() {
ctx.WritePlain(" WITH QUERY EXPANSION")
}
ctx.WritePlain(")")
return nil
}
func (n *MatchAgainst) Format(w io.Writer) {
fmt.Fprint(w, "MATCH(")
for i, v := range n.ColumnNames {
if i != 0 {
fmt.Fprintf(w, ",%s", v.String())
} else {
fmt.Fprint(w, v.String())
}
}
fmt.Fprint(w, ") AGAINST(")
n.Against.Format(w)
if n.Modifier.IsBooleanMode() {
fmt.Fprint(w, " IN BOOLEAN MODE")
} else if n.Modifier.WithQueryExpansion() {
fmt.Fprint(w, " WITH QUERY EXPANSION")
}
fmt.Fprint(w, ")")
}
func (n *MatchAgainst) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*MatchAgainst)
for i, colName := range n.ColumnNames {
newColName, ok := colName.Accept(v)
if !ok {
return n, false
}
n.ColumnNames[i] = newColName.(*ColumnName)
}
newAgainst, ok := n.Against.Accept(v)
if !ok {
return n, false
}
n.Against = newAgainst.(ExprNode)
return v.Leave(n)
}
...@@ -120,7 +120,7 @@ const ( ...@@ -120,7 +120,7 @@ const (
CurrentTimestamp = "current_timestamp" CurrentTimestamp = "current_timestamp"
Curtime = "curtime" Curtime = "curtime"
Date = "date" Date = "date"
DateLiteral = "dateliteral" DateLiteral = "'tidb`.(dateliteral"
DateAdd = "date_add" DateAdd = "date_add"
DateFormat = "date_format" DateFormat = "date_format"
DateSub = "date_sub" DateSub = "date_sub"
...@@ -154,12 +154,12 @@ const ( ...@@ -154,12 +154,12 @@ const (
SubTime = "subtime" SubTime = "subtime"
Sysdate = "sysdate" Sysdate = "sysdate"
Time = "time" Time = "time"
TimeLiteral = "timeliteral" TimeLiteral = "'tidb`.(timeliteral"
TimeFormat = "time_format" TimeFormat = "time_format"
TimeToSec = "time_to_sec" TimeToSec = "time_to_sec"
TimeDiff = "timediff" TimeDiff = "timediff"
Timestamp = "timestamp" Timestamp = "timestamp"
TimestampLiteral = "timestampliteral" TimestampLiteral = "'tidb`.(timestampliteral"
TimestampAdd = "timestampadd" TimestampAdd = "timestampadd"
TimestampDiff = "timestampdiff" TimestampDiff = "timestampdiff"
ToDays = "to_days" ToDays = "to_days"
...@@ -338,6 +338,23 @@ type FuncCallExpr struct { ...@@ -338,6 +338,23 @@ type FuncCallExpr struct {
// Restore implements Node interface. // Restore implements Node interface.
func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error { func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error {
var specialLiteral string
switch n.FnName.L {
case DateLiteral:
specialLiteral = "DATE "
case TimeLiteral:
specialLiteral = "TIME "
case TimestampLiteral:
specialLiteral = "TIMESTAMP "
}
if specialLiteral != "" {
ctx.WritePlain(specialLiteral)
if err := n.Args[0].Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore FuncCastExpr.Expr")
}
return nil
}
ctx.WriteKeyWord(n.FnName.O) ctx.WriteKeyWord(n.FnName.O)
ctx.WritePlain("(") ctx.WritePlain("(")
switch n.FnName.L { switch n.FnName.L {
......
...@@ -63,10 +63,11 @@ const ( ...@@ -63,10 +63,11 @@ const (
RepeatableRead = "REPEATABLE-READ" RepeatableRead = "REPEATABLE-READ"
// Valid formats for explain statement. // Valid formats for explain statement.
ExplainFormatROW = "row" ExplainFormatROW = "row"
ExplainFormatDOT = "dot" ExplainFormatDOT = "dot"
PumpType = "PUMP" ExplainFormatHint = "hint"
DrainerType = "DRAINER" PumpType = "PUMP"
DrainerType = "DRAINER"
) )
// Transaction mode constants. // Transaction mode constants.
...@@ -80,6 +81,7 @@ var ( ...@@ -80,6 +81,7 @@ var (
ExplainFormats = []string{ ExplainFormats = []string{
ExplainFormatROW, ExplainFormatROW,
ExplainFormatDOT, ExplainFormatDOT,
ExplainFormatHint,
} }
) )
...@@ -323,6 +325,7 @@ type Prepared struct { ...@@ -323,6 +325,7 @@ type Prepared struct {
SchemaVersion int64 SchemaVersion int64
UseCache bool UseCache bool
CachedPlan interface{} CachedPlan interface{}
CachedNames interface{}
} }
// ExecuteStmt is a statement to execute PreparedStmt. // ExecuteStmt is a statement to execute PreparedStmt.
...@@ -376,13 +379,37 @@ func (n *ExecuteStmt) Accept(v Visitor) (Node, bool) { ...@@ -376,13 +379,37 @@ func (n *ExecuteStmt) Accept(v Visitor) (Node, bool) {
// See https://dev.mysql.com/doc/refman/5.7/en/commit.html // See https://dev.mysql.com/doc/refman/5.7/en/commit.html
type BeginStmt struct { type BeginStmt struct {
stmtNode stmtNode
Mode string Mode string
ReadOnly bool
Bound *TimestampBound
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *BeginStmt) Restore(ctx *RestoreCtx) error { func (n *BeginStmt) Restore(ctx *RestoreCtx) error {
if n.Mode == "" { if n.Mode == "" {
ctx.WriteKeyWord("START TRANSACTION") if n.ReadOnly {
ctx.WriteKeyWord("START TRANSACTION READ ONLY")
if n.Bound != nil {
switch n.Bound.Mode {
case TimestampBoundStrong:
ctx.WriteKeyWord(" WITH TIMESTAMP BOUND STRONG")
case TimestampBoundMaxStaleness:
ctx.WriteKeyWord(" WITH TIMESTAMP BOUND MAX STALENESS ")
return n.Bound.Timestamp.Restore(ctx)
case TimestampBoundExactStaleness:
ctx.WriteKeyWord(" WITH TIMESTAMP BOUND EXACT STALENESS ")
return n.Bound.Timestamp.Restore(ctx)
case TimestampBoundReadTimestamp:
ctx.WriteKeyWord(" WITH TIMESTAMP BOUND READ TIMESTAMP ")
return n.Bound.Timestamp.Restore(ctx)
case TimestampBoundMinReadTimestamp:
ctx.WriteKeyWord(" WITH TIMESTAMP BOUND MIN READ TIMESTAMP ")
return n.Bound.Timestamp.Restore(ctx)
}
}
} else {
ctx.WriteKeyWord("START TRANSACTION")
}
} else { } else {
ctx.WriteKeyWord("BEGIN ") ctx.WriteKeyWord("BEGIN ")
ctx.WriteKeyWord(n.Mode) ctx.WriteKeyWord(n.Mode)
...@@ -397,6 +424,13 @@ func (n *BeginStmt) Accept(v Visitor) (Node, bool) { ...@@ -397,6 +424,13 @@ func (n *BeginStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(newNode) return v.Leave(newNode)
} }
n = newNode.(*BeginStmt) n = newNode.(*BeginStmt)
if n.Bound != nil && n.Bound.Timestamp != nil {
newTimestamp, ok := n.Bound.Timestamp.Accept(v)
if !ok {
return n, false
}
n.Bound.Timestamp = newTimestamp.(ExprNode)
}
return v.Leave(n) return v.Leave(n)
} }
...@@ -571,6 +605,20 @@ const ( ...@@ -571,6 +605,20 @@ const (
FlushPrivileges FlushPrivileges
FlushStatus FlushStatus
FlushTiDBPlugin FlushTiDBPlugin
FlushHosts
FlushLogs
)
// LogType is the log type used in FLUSH statement.
type LogType int8
const (
LogTypeDefault LogType = iota
LogTypeBinary
LogTypeEngine
LogTypeError
LogTypeGeneral
LogTypeSlow
) )
// FlushStmt is a statement to flush tables/privileges/optimizer costs and so on. // FlushStmt is a statement to flush tables/privileges/optimizer costs and so on.
...@@ -579,6 +627,7 @@ type FlushStmt struct { ...@@ -579,6 +627,7 @@ type FlushStmt struct {
Tp FlushStmtType // Privileges/Tables/... Tp FlushStmtType // Privileges/Tables/...
NoWriteToBinLog bool NoWriteToBinLog bool
LogType LogType
Tables []*TableName // For FlushTableStmt, if Tables is empty, it means flush all tables. Tables []*TableName // For FlushTableStmt, if Tables is empty, it means flush all tables.
ReadLock bool ReadLock bool
Plugins []string Plugins []string
...@@ -620,8 +669,27 @@ func (n *FlushStmt) Restore(ctx *RestoreCtx) error { ...@@ -620,8 +669,27 @@ func (n *FlushStmt) Restore(ctx *RestoreCtx) error {
} }
ctx.WritePlain(v) ctx.WritePlain(v)
} }
case FlushHosts:
ctx.WriteKeyWord("HOSTS")
case FlushLogs:
var logType string
switch n.LogType {
case LogTypeDefault:
logType = "LOGS"
case LogTypeBinary:
logType = "BINARY LOGS"
case LogTypeEngine:
logType = "ENGINE LOGS"
case LogTypeError:
logType = "ERROR LOGS"
case LogTypeGeneral:
logType = "GENERAL LOGS"
case LogTypeSlow:
logType = "SLOW LOGS"
}
ctx.WriteKeyWord(logType)
default: default:
return errors.New("Unsupported type of FlushTables") return errors.New("Unsupported type of FlushStmt")
} }
return nil return nil
} }
...@@ -979,12 +1047,12 @@ const ( ...@@ -979,12 +1047,12 @@ const (
Subject Subject
) )
type TslOption struct { type TLSOption struct {
Type int Type int
Value string Value string
} }
func (t *TslOption) Restore(ctx *RestoreCtx) error { func (t *TLSOption) Restore(ctx *RestoreCtx) error {
switch t.Type { switch t.Type {
case TslNone: case TslNone:
ctx.WriteKeyWord("NONE") ctx.WriteKeyWord("NONE")
...@@ -999,10 +1067,10 @@ func (t *TslOption) Restore(ctx *RestoreCtx) error { ...@@ -999,10 +1067,10 @@ func (t *TslOption) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord("ISSUER ") ctx.WriteKeyWord("ISSUER ")
ctx.WriteString(t.Value) ctx.WriteString(t.Value)
case Subject: case Subject:
ctx.WriteKeyWord("CIPHER") ctx.WriteKeyWord("SUBJECT ")
ctx.WriteString(t.Value) ctx.WriteString(t.Value)
default: default:
return errors.Errorf("Unsupported TslOption.Type %d", t.Type) return errors.Errorf("Unsupported TLSOption.Type %d", t.Type)
} }
return nil return nil
} }
...@@ -1080,7 +1148,7 @@ type CreateUserStmt struct { ...@@ -1080,7 +1148,7 @@ type CreateUserStmt struct {
IsCreateRole bool IsCreateRole bool
IfNotExists bool IfNotExists bool
Specs []*UserSpec Specs []*UserSpec
TslOptions []*TslOption TLSOptions []*TLSOption
ResourceOptions []*ResourceOption ResourceOptions []*ResourceOption
PasswordOrLockOptions []*PasswordOrLockOption PasswordOrLockOptions []*PasswordOrLockOption
} }
...@@ -1104,19 +1172,16 @@ func (n *CreateUserStmt) Restore(ctx *RestoreCtx) error { ...@@ -1104,19 +1172,16 @@ func (n *CreateUserStmt) Restore(ctx *RestoreCtx) error {
} }
} }
tslOptionLen := len(n.TslOptions) if len(n.TLSOptions) != 0 {
if tslOptionLen != 0 {
ctx.WriteKeyWord(" REQUIRE ") ctx.WriteKeyWord(" REQUIRE ")
} }
// Restore `tslOptions` reversely to keep order the same with original sql for i, option := range n.TLSOptions {
for i := tslOptionLen; i > 0; i-- { if i != 0 {
if i != tslOptionLen {
ctx.WriteKeyWord(" AND ") ctx.WriteKeyWord(" AND ")
} }
if err := n.TslOptions[i-1].Restore(ctx); err != nil { if err := option.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.TslOptions[%d]", i) return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.TLSOptions[%d]", i)
} }
} }
...@@ -1169,7 +1234,7 @@ type AlterUserStmt struct { ...@@ -1169,7 +1234,7 @@ type AlterUserStmt struct {
IfExists bool IfExists bool
CurrentAuth *AuthOption CurrentAuth *AuthOption
Specs []*UserSpec Specs []*UserSpec
TslOptions []*TslOption TLSOptions []*TLSOption
ResourceOptions []*ResourceOption ResourceOptions []*ResourceOption
PasswordOrLockOptions []*PasswordOrLockOption PasswordOrLockOptions []*PasswordOrLockOption
} }
...@@ -1196,19 +1261,16 @@ func (n *AlterUserStmt) Restore(ctx *RestoreCtx) error { ...@@ -1196,19 +1261,16 @@ func (n *AlterUserStmt) Restore(ctx *RestoreCtx) error {
} }
} }
tslOptionLen := len(n.TslOptions) if len(n.TLSOptions) != 0 {
if tslOptionLen != 0 {
ctx.WriteKeyWord(" REQUIRE ") ctx.WriteKeyWord(" REQUIRE ")
} }
// Restore `tslOptions` reversely to keep order the same with original sql for i, option := range n.TLSOptions {
for i := tslOptionLen; i > 0; i-- { if i != 0 {
if i != tslOptionLen {
ctx.WriteKeyWord(" AND ") ctx.WriteKeyWord(" AND ")
} }
if err := n.TslOptions[i-1].Restore(ctx); err != nil { if err := option.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.TslOptions[%d]", i) return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.TLSOptions[%d]", i)
} }
} }
...@@ -1346,10 +1408,27 @@ type DropBindingStmt struct { ...@@ -1346,10 +1408,27 @@ type DropBindingStmt struct {
GlobalScope bool GlobalScope bool
OriginSel StmtNode OriginSel StmtNode
HintedSel StmtNode
} }
func (n *DropBindingStmt) Restore(ctx *RestoreCtx) error { func (n *DropBindingStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") ctx.WriteKeyWord("DROP ")
if n.GlobalScope {
ctx.WriteKeyWord("GLOBAL ")
} else {
ctx.WriteKeyWord("SESSION ")
}
ctx.WriteKeyWord("BINDING FOR ")
if err := n.OriginSel.Restore(ctx); err != nil {
return errors.Trace(err)
}
if n.HintedSel != nil {
ctx.WriteKeyWord(" USING ")
if err := n.HintedSel.Restore(ctx); err != nil {
return errors.Trace(err)
}
}
return nil
} }
func (n *DropBindingStmt) Accept(v Visitor) (Node, bool) { func (n *DropBindingStmt) Accept(v Visitor) (Node, bool) {
...@@ -1363,6 +1442,13 @@ func (n *DropBindingStmt) Accept(v Visitor) (Node, bool) { ...@@ -1363,6 +1442,13 @@ func (n *DropBindingStmt) Accept(v Visitor) (Node, bool) {
return n, false return n, false
} }
n.OriginSel = selnode.(*SelectStmt) n.OriginSel = selnode.(*SelectStmt)
if n.HintedSel != nil {
selnode, ok = n.HintedSel.Accept(v)
if !ok {
return n, false
}
n.HintedSel = selnode.(*SelectStmt)
}
return v.Leave(n) return v.Leave(n)
} }
...@@ -1425,6 +1511,9 @@ const ( ...@@ -1425,6 +1511,9 @@ const (
AdminReloadOptRuleBlacklist AdminReloadOptRuleBlacklist
AdminPluginDisable AdminPluginDisable
AdminPluginEnable AdminPluginEnable
AdminFlushBindings
AdminCaptureBindings
AdminEvolveBindings
) )
// HandleRange represents a range where handle value >= Begin and < End. // HandleRange represents a range where handle value >= Begin and < End.
...@@ -1625,6 +1714,12 @@ func (n *AdminStmt) Restore(ctx *RestoreCtx) error { ...@@ -1625,6 +1714,12 @@ func (n *AdminStmt) Restore(ctx *RestoreCtx) error {
} }
ctx.WritePlain(v) ctx.WritePlain(v)
} }
case AdminFlushBindings:
ctx.WriteKeyWord("FLUSH BINDINGS")
case AdminCaptureBindings:
ctx.WriteKeyWord("CAPTURE BINDINGS")
case AdminEvolveBindings:
ctx.WriteKeyWord("EVOLVE BINDINGS")
default: default:
return errors.New("Unsupported AdminStmt type") return errors.New("Unsupported AdminStmt type")
} }
...@@ -1879,6 +1974,7 @@ type GrantStmt struct { ...@@ -1879,6 +1974,7 @@ type GrantStmt struct {
ObjectType ObjectTypeType ObjectType ObjectTypeType
Level *GrantLevel Level *GrantLevel
Users []*UserSpec Users []*UserSpec
TLSOptions []*TLSOption
WithGrant bool WithGrant bool
} }
...@@ -1914,6 +2010,19 @@ func (n *GrantStmt) Restore(ctx *RestoreCtx) error { ...@@ -1914,6 +2010,19 @@ func (n *GrantStmt) Restore(ctx *RestoreCtx) error {
return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i) return errors.Annotatef(err, "An error occurred while restore GrantStmt.Users[%d]", i)
} }
} }
if n.TLSOptions != nil {
if len(n.TLSOptions) != 0 {
ctx.WriteKeyWord(" REQUIRE ")
}
for i, option := range n.TLSOptions {
if i != 0 {
ctx.WriteKeyWord(" AND ")
}
if err := option.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore GrantStmt.TLSOptions[%d]", i)
}
}
}
if n.WithGrant { if n.WithGrant {
ctx.WriteKeyWord(" WITH GRANT OPTION") ctx.WriteKeyWord(" WITH GRANT OPTION")
} }
...@@ -2073,11 +2182,16 @@ type TableOptimizerHint struct { ...@@ -2073,11 +2182,16 @@ type TableOptimizerHint struct {
// HintTable is table in the hint. It may have query block info. // HintTable is table in the hint. It may have query block info.
type HintTable struct { type HintTable struct {
DBName model.CIStr
TableName model.CIStr TableName model.CIStr
QBName model.CIStr QBName model.CIStr
} }
func (ht *HintTable) Restore(ctx *RestoreCtx) { func (ht *HintTable) Restore(ctx *RestoreCtx) {
if ht.DBName.L != "" {
ctx.WriteName(ht.DBName.String())
ctx.WriteKeyWord(".")
}
ctx.WriteName(ht.TableName.String()) ctx.WriteName(ht.TableName.String())
if ht.QBName.L != "" { if ht.QBName.L != "" {
ctx.WriteKeyWord("@") ctx.WriteKeyWord("@")
......
...@@ -13,6 +13,13 @@ ...@@ -13,6 +13,13 @@
package ast package ast
import "math"
// UnspecifiedSize is unspecified size.
const (
UnspecifiedSize = math.MaxUint64
)
// IsReadOnly checks whether the input ast is readOnly. // IsReadOnly checks whether the input ast is readOnly.
func IsReadOnly(node Node) bool { func IsReadOnly(node Node) bool {
switch st := node.(type) { switch st := node.(type) {
......
...@@ -21,14 +21,9 @@ import ( ...@@ -21,14 +21,9 @@ import (
"github.com/pingcap/parser/terror" "github.com/pingcap/parser/terror"
) )
const (
codeCollationCharsetMismatch = terror.ErrCode(mysql.ErrCollationCharsetMismatch)
codeUnknownCollation = terror.ErrCode(mysql.ErrUnknownCollation)
)
var ( var (
ErrUnknownCollation = terror.ClassDDL.New(codeUnknownCollation, mysql.MySQLErrName[mysql.ErrUnknownCollation]) ErrUnknownCollation = terror.ClassDDL.New(mysql.ErrUnknownCollation, mysql.MySQLErrName[mysql.ErrUnknownCollation])
ErrCollationCharsetMismatch = terror.ClassDDL.New(codeCollationCharsetMismatch, mysql.MySQLErrName[mysql.ErrCollationCharsetMismatch]) ErrCollationCharsetMismatch = terror.ClassDDL.New(mysql.ErrCollationCharsetMismatch, mysql.MySQLErrName[mysql.ErrCollationCharsetMismatch])
) )
// Charset is a charset. // Charset is a charset.
......
...@@ -3,7 +3,7 @@ version: 2 ...@@ -3,7 +3,7 @@ version: 2
jobs: jobs:
build-ut: build-ut:
docker: docker:
- image: golang:1.11 - image: golang:1.13
working_directory: /go/src/github.com/pingcap/parser working_directory: /go/src/github.com/pingcap/parser
steps: steps:
- checkout - checkout
...@@ -24,22 +24,10 @@ jobs: ...@@ -24,22 +24,10 @@ jobs:
command: bash <(curl -s https://codecov.io/bash) command: bash <(curl -s https://codecov.io/bash)
build-integration: build-integration:
docker: docker:
- image: golang:1.11 - image: golang:1.13
working_directory: /go/src/github.com/pingcap/parser working_directory: /go/src/github.com/pingcap/parser
steps: steps:
- checkout - checkout
- run:
name: "Verify parser.go is up-to-date"
command: |
mv parser.go parser.go.committed
make parser
diff -u parser.go.committed parser.go
- run:
name: "Check code format"
command: make fmt
- run:
name: "Build"
command: make
- run: - run:
name: "Integration Test" name: "Integration Test"
command: | command: |
...@@ -48,10 +36,11 @@ jobs: ...@@ -48,10 +36,11 @@ jobs:
cd tidb cd tidb
rm go.sum rm go.sum
GO111MODULE=on go mod edit -replace github.com/pingcap/parser=github.com/${CIRCLE_PR_USERNAME:-$CIRCLE_PROJECT_USERNAME}/${CIRCLE_PR_REPONAME:-$CIRCLE_PROJECT_REPONAME}@$CIRCLE_SHA1 GO111MODULE=on go mod edit -replace github.com/pingcap/parser=github.com/${CIRCLE_PR_USERNAME:-$CIRCLE_PROJECT_USERNAME}/${CIRCLE_PR_REPONAME:-$CIRCLE_PROJECT_REPONAME}@$CIRCLE_SHA1
make gotest # use only 1 thread to minimize memory usage (we've only got 2 CPU + 4 GB on Circle CI).
make gotest P=1
workflows: workflows:
version: 2 version: 2
build_and_test: build_and_test:
jobs: jobs:
- build-ut - build-ut
- build-integration - build-integration
\ No newline at end of file
codecov:
require_ci_to_pass: no
notify:
wait_for_ci: no
coverage:
status:
project:
default:
threshold: 0.2
patch:
default:
target: 0% # trial operation
changes: no
comment:
layout: "header, diff"
behavior: default
require_changes: no
...@@ -18,9 +18,11 @@ import ( ...@@ -18,9 +18,11 @@ import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
hash2 "hash" hash2 "hash"
"reflect"
"strings" "strings"
"sync" "sync"
"unicode" "unicode"
"unsafe"
) )
// DigestHash generates the digest of statements. // DigestHash generates the digest of statements.
...@@ -28,6 +30,8 @@ import ( ...@@ -28,6 +30,8 @@ import (
// which removes general property of a statement but keeps specific property. // which removes general property of a statement but keeps specific property.
// //
// for example: both DigestHash('select 1') and DigestHash('select 2') => e1c71d1661ae46e09b7aaec1c390957f0d6260410df4e4bc71b9c8d681021471 // for example: both DigestHash('select 1') and DigestHash('select 2') => e1c71d1661ae46e09b7aaec1c390957f0d6260410df4e4bc71b9c8d681021471
//
// Deprecated: It is logically consistent with NormalizeDigest.
func DigestHash(sql string) (result string) { func DigestHash(sql string) (result string) {
d := digesterPool.Get().(*sqlDigester) d := digesterPool.Get().(*sqlDigester)
result = d.doDigest(sql) result = d.doDigest(sql)
...@@ -35,6 +39,20 @@ func DigestHash(sql string) (result string) { ...@@ -35,6 +39,20 @@ func DigestHash(sql string) (result string) {
return return
} }
// DigestNormalized generates the digest of a normalized sql.
// it will generate a hash on a normalized sql.
// Normalize + DigestNormalized equals to NormalizeDigest.
//
// for example: DigestNormalized('select ?')
// DigestNormalized should be called with a normalized SQL string (like 'select ?') generated by function Normalize.
// do not call with SQL which is not normalized, DigestNormalized('select 1') and DigestNormalized('select 2') is not the same
func DigestNormalized(normalized string) (result string) {
d := digesterPool.Get().(*sqlDigester)
result = d.doDigestNormalized(normalized)
digesterPool.Put(d)
return
}
// Normalize generates the normalized statements. // Normalize generates the normalized statements.
// it will get normalized form of statement text // it will get normalized form of statement text
// which removes general property of a statement but keeps specific property. // which removes general property of a statement but keeps specific property.
...@@ -47,7 +65,7 @@ func Normalize(sql string) (result string) { ...@@ -47,7 +65,7 @@ func Normalize(sql string) (result string) {
return return
} }
// NormalizeDigest combines Normalize and DigestHash into one method. // NormalizeDigest combines Normalize and DigestNormalized into one method.
func NormalizeDigest(sql string) (normalized, digest string) { func NormalizeDigest(sql string) (normalized, digest string) {
d := digesterPool.Get().(*sqlDigester) d := digesterPool.Get().(*sqlDigester)
normalized, digest = d.doNormalizeDigest(sql) normalized, digest = d.doNormalizeDigest(sql)
...@@ -72,6 +90,19 @@ type sqlDigester struct { ...@@ -72,6 +90,19 @@ type sqlDigester struct {
tokens tokenDeque tokens tokenDeque
} }
func (d *sqlDigester) doDigestNormalized(normalized string) (result string) {
hdr := *(*reflect.StringHeader)(unsafe.Pointer(&normalized))
b := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: hdr.Data,
Len: hdr.Len,
Cap: hdr.Len,
}))
d.hasher.Write(b)
result = fmt.Sprintf("%x", d.hasher.Sum(nil))
d.hasher.Reset()
return
}
func (d *sqlDigester) doDigest(sql string) (result string) { func (d *sqlDigester) doDigest(sql string) (result string) {
d.normalize(sql) d.normalize(sql)
d.hasher.Write(d.buffer.Bytes()) d.hasher.Write(d.buffer.Bytes())
...@@ -142,17 +173,7 @@ func (d *sqlDigester) normalize(sql string) { ...@@ -142,17 +173,7 @@ func (d *sqlDigester) normalize(sql string) {
func (d *sqlDigester) reduceOptimizerHint(tok *token) (reduced bool) { func (d *sqlDigester) reduceOptimizerHint(tok *token) (reduced bool) {
// ignore /*+..*/ // ignore /*+..*/
if tok.tok == hintBegin { if tok.tok == hintComment {
for {
tok, _, _ := d.lexer.scan()
if tok == 0 || (tok == unicode.ReplacementChar && d.lexer.r.eof()) {
break
}
if tok == hintEnd {
reduced = true
break
}
}
return return
} }
......
...@@ -7,10 +7,14 @@ require ( ...@@ -7,10 +7,14 @@ require (
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8 github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8
github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186 github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186
github.com/cznic/y v0.0.0-20170802143616-045f81c6662a github.com/cznic/y v0.0.0-20170802143616-045f81c6662a
github.com/golang/protobuf v1.3.2 // indirect
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8
github.com/pingcap/errors v0.11.4 github.com/pingcap/errors v0.11.4
github.com/pingcap/tidb v0.0.0-20190703092821-755875aacb5a github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330 github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330
github.com/sirupsen/logrus v1.3.0 github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237 // indirect
go.uber.org/zap v1.12.0
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2
) )
go 1.13
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/cznic/golex v0.0.0-20181122101858-9c343928389c h1:G8zTsaqyVfIHpgMFcGgdbhHSFhlNc77rAKkhVbQ9kQg=
github.com/cznic/golex v0.0.0-20181122101858-9c343928389c/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc=
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso=
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
github.com/cznic/parser v0.0.0-20160622100904-31edd927e5b1 h1:uWcWCkSP+E1w1z8r082miT+c+9vzg+5UdrgGCo15lMo=
github.com/cznic/parser v0.0.0-20160622100904-31edd927e5b1/go.mod h1:2B43mz36vGZNZEwkWi8ayRSSUXLfjL8OkbzwW4NcPMM=
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8 h1:LpMLYGyy67BoAFGda1NeOBQwqlv7nUXpm+rIVHGxZZ4=
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ=
github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186 h1:0rkFMAbn5KBKNpJyHQ6Prb95vIKanmAe62KxsrN+sqA=
github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
github.com/cznic/y v0.0.0-20170802143616-045f81c6662a h1:N2rDAvHuM46OGscJkGX4Dw4BBqZgg6mGNGLYs5utVVo=
github.com/cznic/y v0.0.0-20170802143616-045f81c6662a/go.mod h1:1rk5VM7oSnA4vjp+hrLQ3HWHa+Y4yPCa3/CsJrcNnvs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 h1:USx2/E1bX46VG32FIw034Au6seQ2fY9NEILmNh/UlQg=
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ=
github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9 h1:AJD9pZYm72vMgPcQDww9rkZ1DnWfl0pXV3BOWlkYIjA=
github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330 h1:rRMLMjIMFulCX9sGKZ1hoov/iROMsKyC8Snc02nSukw=
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237 h1:HQagqIiBmr8YXawX/le3+O26N+vPPC1PtjaF3mwnook=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.12.0 h1:dySoUQPFBGj6xwjmBzageVL8jGi8uxc6bEmJQjA06bw=
go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f h1:5ZfJxyXo8KyX8DgGXC5B7ILL8y51fci/qYz2B4j8iLY=
github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/blacktear23/go-proxyprotocol v0.0.0-20180807104634-af7a81e8dd0d/go.mod h1:VKt7CNAQxpFpSDz3sXyj9hY/GbVsQCr0sB3w59nE7lU=
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20171208011716-f6d7a1f6fbf3/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/bbolt v1.3.0 h1:HIgH5xUWXT914HCI671AxuTTqjj64UOFr7pHn48LUTI=
github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 h1:3jFq2xL4ZajGK4aZY8jz+DAF0FHjI51BXjjSwCzS1Dk=
github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cznic/golex v0.0.0-20181122101858-9c343928389c h1:G8zTsaqyVfIHpgMFcGgdbhHSFhlNc77rAKkhVbQ9kQg=
github.com/cznic/golex v0.0.0-20181122101858-9c343928389c/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc=
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso=
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
github.com/cznic/parser v0.0.0-20160622100904-31edd927e5b1 h1:uWcWCkSP+E1w1z8r082miT+c+9vzg+5UdrgGCo15lMo=
github.com/cznic/parser v0.0.0-20160622100904-31edd927e5b1/go.mod h1:2B43mz36vGZNZEwkWi8ayRSSUXLfjL8OkbzwW4NcPMM=
github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ=
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8 h1:LpMLYGyy67BoAFGda1NeOBQwqlv7nUXpm+rIVHGxZZ4=
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ=
github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186 h1:0rkFMAbn5KBKNpJyHQ6Prb95vIKanmAe62KxsrN+sqA=
github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
github.com/cznic/y v0.0.0-20170802143616-045f81c6662a h1:N2rDAvHuM46OGscJkGX4Dw4BBqZgg6mGNGLYs5utVVo=
github.com/cznic/y v0.0.0-20170802143616-045f81c6662a/go.mod h1:1rk5VM7oSnA4vjp+hrLQ3HWHa+Y4yPCa3/CsJrcNnvs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/etcd-io/gofail v0.0.0-20180808172546-51ce9a71510a h1:QNEenQIsGDEEfFNSnN+h6hE1OwnHqTg7Dl9gEk1Cko4=
github.com/etcd-io/gofail v0.0.0-20180808172546-51ce9a71510a/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-playground/overalls v0.0.0-20180201144345-22ec1a223b7c/go.mod h1:UqxAgEOt89sCiXlrc/ycnx00LVvUO/eS8tMUkWX4R7w=
github.com/go-sql-driver/mysql v0.0.0-20170715192408-3955978caca4/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/gogo/protobuf v0.0.0-20180717141946-636bf0302bc9/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff h1:kOkM9whyQYodu09SJ6W3NCsHG7crFaJILQ22Gozp3lg=
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v0.0.0-20180814211427-aa810b61a9c7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.4.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.5.1 h1:3scN4iuXkNOyP98jF55Lv8a9j1o/IwvnDIZ0LHJK1nk=
github.com/grpc-ecosystem/grpc-gateway v1.5.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio=
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.0.0/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe h1:W/GaMY0y69G4cFlmsC6B9sbuo2fP8OFP1ABjt4kPz+w=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/matttproud/golang_protobuf_extensions v1.0.0/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/montanaflynn/stats v0.0.0-20151014174947-eeaced052adb/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/montanaflynn/stats v0.0.0-20180911141734-db72e6cae808 h1:pmpDGKLw4n82EtrNiLqB+xSz/JQwFOaZuMALYUHwX5s=
github.com/montanaflynn/stats v0.0.0-20180911141734-db72e6cae808/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/myesui/uuid v1.0.0 h1:xCBmH4l5KuvLYc5L7AS7SZg9/jKdIFubM7OVoLqaQUI=
github.com/myesui/uuid v1.0.0/go.mod h1:2CDfNgU0LR8mIdO8vdWd8i9gWWxLlcoIGGpSNgafq84=
github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7 h1:7KAv7KMGTTqSmYZtNdcNTgsos+vFzULLwyElndwn+5c=
github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7/go.mod h1:iWMfgwqYW+e8n5lC/jjNEhwcjbRDpl5NT7n2h+4UNcI=
github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef h1:K0Fn+DoFqNqktdZtdV3bPQ/0cuYh2H4rkg0tytX/07k=
github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef/go.mod h1:7WjlapSfwQyo6LNmIvEWzsW1hbBQfpUO4JWnuQRmva8=
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pelletier/go-toml v1.3.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 h1:USx2/E1bX46VG32FIw034Au6seQ2fY9NEILmNh/UlQg=
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ=
github.com/pingcap/errcode v0.0.0-20180921232412-a1a7271709d9/go.mod h1:4b2X8xSqxIroj/IZ9MX/VGZhAwc11wB9wRIzHvz6SeM=
github.com/pingcap/errors v0.10.1/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.0 h1:DCJQB8jrHbQ1VVlMFIrbj2ApScNNotVmkSNplu2yUt4=
github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.1 h1:BXFZ6MdDd2U1uJUa2sRAWTmm+nieEzuyYM0R4aUTcC8=
github.com/pingcap/errors v0.11.1/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/failpoint v0.0.0-20190512135322-30cc7431d99c/go.mod h1:DNS3Qg7bEDhU6EXNHF+XSv/PGznQaMJ5FWvctpm6pQI=
github.com/pingcap/gofail v0.0.0-20181217135706-6a951c1e42c3 h1:04yuCf5NMvLU8rB2m4Qs3rynH7EYpMno3lHkewIOdMo=
github.com/pingcap/gofail v0.0.0-20181217135706-6a951c1e42c3/go.mod h1:DazNTg0PTldtpsQiT9I5tVJwV1onHMKBBgXzmJUlMns=
github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rGrobssy1nVy2VaVpNCuLpCbr+FEaTA8=
github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw=
github.com/pingcap/kvproto v0.0.0-20190215154024-7f2fc73ef562 h1:32oF1/8lVnBR2JVcCAnKPQATTOX0+ckRDFpjQk4Ngno=
github.com/pingcap/kvproto v0.0.0-20190215154024-7f2fc73ef562/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY=
github.com/pingcap/kvproto v0.0.0-20190516013202-4cf58ad90b6c/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY=
github.com/pingcap/kvproto v0.0.0-20190619024611-a4759dfe3753/go.mod h1:QMdbTAXCHzzygQzqcG9uVUgU2fKeSN1GmfMiykdSzzY=
github.com/pingcap/log v0.0.0-20190214045112-b37da76f67a7/go.mod h1:xsfkWVaFVV5B8e1K9seWfyJWFrIhbtUTAD8NV1Pq3+w=
github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596 h1:t2OQTpPJnrPDGlvA+3FwJptMTt6MEPdzK1Wt99oaefQ=
github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596/go.mod h1:WpHUKhNZ18v116SvGrmjkA9CBhYmuUTKL+p8JC9ANEw=
github.com/pingcap/parser v0.0.0-20190312024907-3f6280b08c8b/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
github.com/pingcap/parser v0.0.0-20190701123046-5768e68c1e65/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
github.com/pingcap/pd v0.0.0-20190617100349-293d4b5189bf/go.mod h1:3DlDlFT7EF64A1bmb/tulZb6wbPSagm5G4p1AlhaEDs=
github.com/pingcap/pd v2.1.0-rc.4+incompatible h1:/buwGk04aHO5odk/+O8ZOXGs4qkUjYTJ2UpCJXna8NE=
github.com/pingcap/pd v2.1.0-rc.4+incompatible/go.mod h1:nD3+EoYes4+aNNODO99ES59V83MZSI+dFbhyr667a0E=
github.com/pingcap/tidb v0.0.0-20190321025159-e8299209340c h1:n3i2K6zUzXZDe6imOtdOhWltuqCLFtmLropKwS6ljeI=
github.com/pingcap/tidb v0.0.0-20190321025159-e8299209340c/go.mod h1:FcgD4o1kq3YNk08MWtMRwNZXQJpM28bFdb/go9KpmEA=
github.com/pingcap/tidb v0.0.0-20190703092821-755875aacb5a h1:YfYdeUJC7LwGt2HYAWqtOuNAidYIg6uKPYWpNe+Px3s=
github.com/pingcap/tidb v0.0.0-20190703092821-755875aacb5a/go.mod h1:DU3S1YEJN8b1BookBt3g27hljItkONKZSJR+Bu/C/9g=
github.com/pingcap/tidb-tools v2.1.3-0.20190116051332-34c808eef588+incompatible h1:e9Gi/LP9181HT3gBfSOeSBA+5JfemuE4aEAhqNgoE4k=
github.com/pingcap/tidb-tools v2.1.3-0.20190116051332-34c808eef588+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tidb-tools v2.1.3-0.20190321065848-1e8b48f5c168+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tipb v0.0.0-20190107072121-abbec73437b7 h1:wnjdQRhybddDesBVBKyOLUPgDaOFdtqA92pduBgWvVQ=
github.com/pingcap/tipb v0.0.0-20190107072121-abbec73437b7/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI=
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330 h1:rRMLMjIMFulCX9sGKZ1hoov/iROMsKyC8Snc02nSukw=
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 h1:gGBSHPOU7g8YjTbhwn+lvFm2VDEhhA+PwDIlstkgSxE=
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.0 h1:tXuTFVHC03mW0D+Ua1Q2d1EAVqLTuggX50V0VLICCzY=
github.com/prometheus/client_golang v0.9.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 h1:Cto4X6SVMWRPBkJ/3YHn1iDGDGc/Z+sW+AEMKHMVvN4=
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20180612222113-7d6f385de8be/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446 h1:/NRJ5vAYoqz+7sG51ubIDHXeWO8DlTSrToPu6q11ziA=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/remyoudompheng/bigfft v0.0.0-20190512091148-babf20351dd7 h1:FUL3b97ZY2EPqg2NbXKuMHs5pXJB9hjj1fDHnF2vl28=
github.com/remyoudompheng/bigfft v0.0.0-20190512091148-babf20351dd7/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/sergi/go-diff v1.0.1-0.20180205163309-da645544ed44/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v2.18.10+incompatible h1:cy84jW6EVRPa5g9HAHrlbxMSIjBhDSX0OFYyMYminYs=
github.com/shirou/gopsutil v2.18.10+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/vfsgen v0.0.0-20181020040650-a97a25d856ca/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/struCoder/pidusage v0.1.2/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI=
github.com/syndtr/goleveldb v0.0.0-20180815032940-ae2bd5eed72d/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU=
github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU=
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc=
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk=
github.com/twinj/uuid v1.0.0/go.mod h1:mMgcE1RHFUFqe5AfiwlINXisXfDGro23fWdPUfOMjRY=
github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/uber/jaeger-client-go v2.15.0+incompatible h1:NP3qsSqNxh8VYr956ur1N/1C1PjvOJnJykCzcD5QHbk=
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v1.5.0 h1:OHbgr8l656Ub3Fw5k9SWnBfIEwvoHQ+W2y+Aa9D1Uyo=
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v0.0.0-20171019201919-bdcc60b419d1 h1:UvhxfNjNqlZ/x3cDyqxMhoiUpemd3zXkVQApN6bM/lg=
github.com/ugorji/go v0.0.0-20171019201919-bdcc60b419d1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
github.com/unrolled/render v0.0.0-20171102162132-65450fb6b2d3/go.mod h1:tu82oB5W2ykJRVioYsB+IQKcft7ryBr7w12qMBUPyXg=
github.com/unrolled/render v0.0.0-20180914162206-b9786414de4d h1:ggUgChAeyge4NZ4QUw6lhHsVymzwSDJOZcE0s2X8S20=
github.com/unrolled/render v0.0.0-20180914162206-b9786414de4d/go.mod h1:tu82oB5W2ykJRVioYsB+IQKcft7ryBr7w12qMBUPyXg=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/negroni v0.3.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18 h1:MPPkRncZLN9Kh4MEFmbnK4h3BD7AUmskWv2+EeZJCCs=
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yookoala/realpath v1.0.0/go.mod h1:gJJMA9wuX7AcqLy1+ffPatSCySA1FQ2S8Ya9AIoYBpE=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20190320044326-77d4b742cdbf/go.mod h1:KSGwdbiFchh5KIC9My2+ZVl5/3ANcwohw50dpPwa2cw=
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180608092829-8ac0e0d97ce4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190109145017-48ac38b7c8cb h1:1w588/yEchbPNpa9sEvOcMZYbWHedwJjg4VOAdDHWHk=
golang.org/x/sys v0.0.0-20190109145017-48ac38b7c8cb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190130214255-bb1329dc71a0 h1:iRpjPej1fPzmfoBhMFkp3HdqzF+ytPmAwiQhJGV0zGw=
golang.org/x/tools v0.0.0-20190130214255-bb1329dc71a0/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180608181217-32ee49c4dd80/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181004005441-af9cb2a35e7f/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190108161440-ae2f86662275 h1:9oFlwfEGIvmxXTcY53ygNyxIQtWciRHjrnUvZJCYXYU=
google.golang.org/genproto v0.0.0-20190108161440-ae2f86662275/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/grpc v0.0.0-20180607172857-7a6a684ca69e/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/gometalinter.v2 v2.0.12/go.mod h1:NDRytsqEZyolNuAgTzJkZMkSQM7FIKyzVzGhjB/qfYo=
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c/go.mod h1:3HH7i1SgMqlzxCcBmUHW657sD4Kvv9sC3HpL3YukzwA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M=
gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFYN9JcR6TxU=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4 h1:VO9oZbbkvTwqLimlQt15QNdOOBArT2dw/bvzsMZBiqQ=
sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=
// Code generated by goyacc DO NOT EDIT.
// Copyright 2020 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package parser
import __yyfmt__ "fmt"
import (
"math"
"strconv"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/model"
)
type yyhintSymType struct {
yys int
ident string
number uint64
hint *ast.TableOptimizerHint
hints []*ast.TableOptimizerHint
table ast.HintTable
}
type yyhintXError struct {
state, xsym int
}
const (
yyhintDefault = 57407
yyhintEOFCode = 57344
yyhintErrCode = 57345
hintAggToCop = 57376
hintBKA = 57354
hintBNL = 57356
hintDupsWeedOut = 57403
hintEnablePlanCache = 57377
hintFalse = 57399
hintFirstMatch = 57404
hintGB = 57402
hintHashAgg = 57378
hintHashJoin = 57358
hintIdentifier = 57347
hintIgnoreIndex = 57379
hintIndexMerge = 57362
hintInlHashJoin = 57380
hintInlJoin = 57381
hintInlMergeJoin = 57382
hintIntLit = 57346
hintJoinFixedOrder = 57350
hintJoinOrder = 57351
hintJoinPrefix = 57352
hintJoinSuffix = 57353
hintLooseScan = 57405
hintMB = 57401
hintMRR = 57364
hintMaterialization = 57406
hintMaxExecutionTime = 57372
hintMemoryQuota = 57383
hintMerge = 57360
hintNoBKA = 57355
hintNoBNL = 57357
hintNoHashJoin = 57359
hintNoICP = 57366
hintNoIndexMerge = 57363
hintNoMRR = 57365
hintNoMerge = 57361
hintNoRangeOptimization = 57367
hintNoSemijoin = 57371
hintNoSkipScan = 57369
hintNoSwapJoinInputs = 57384
hintOLAP = 57395
hintOLTP = 57396
hintQBName = 57375
hintQueryType = 57385
hintReadConsistentReplica = 57386
hintReadFromStorage = 57387
hintResourceGroup = 57374
hintSMJoin = 57388
hintSemijoin = 57370
hintSetVar = 57373
hintSingleAtIdentifier = 57348
hintSkipScan = 57368
hintStreamAgg = 57389
hintStringLit = 57349
hintSwapJoinInputs = 57390
hintTiFlash = 57398
hintTiKV = 57397
hintTrue = 57400
hintUseIndex = 57392
hintUseIndexMerge = 57391
hintUsePlanCache = 57393
hintUseToja = 57394
yyhintMaxDepth = 200
yyhintTabOfs = -154
)
var (
yyhintXLAT = map[int]int{
41: 0, // ')' (115x)
57376: 1, // hintAggToCop (105x)
57354: 2, // hintBKA (105x)
57356: 3, // hintBNL (105x)
57377: 4, // hintEnablePlanCache (105x)
57378: 5, // hintHashAgg (105x)
57358: 6, // hintHashJoin (105x)
57379: 7, // hintIgnoreIndex (105x)
57362: 8, // hintIndexMerge (105x)
57380: 9, // hintInlHashJoin (105x)
57381: 10, // hintInlJoin (105x)
57382: 11, // hintInlMergeJoin (105x)
57350: 12, // hintJoinFixedOrder (105x)
57351: 13, // hintJoinOrder (105x)
57352: 14, // hintJoinPrefix (105x)
57353: 15, // hintJoinSuffix (105x)
57372: 16, // hintMaxExecutionTime (105x)
57383: 17, // hintMemoryQuota (105x)
57360: 18, // hintMerge (105x)
57364: 19, // hintMRR (105x)
57355: 20, // hintNoBKA (105x)
57357: 21, // hintNoBNL (105x)
57359: 22, // hintNoHashJoin (105x)
57366: 23, // hintNoICP (105x)
57363: 24, // hintNoIndexMerge (105x)
57361: 25, // hintNoMerge (105x)
57365: 26, // hintNoMRR (105x)
57367: 27, // hintNoRangeOptimization (105x)
57371: 28, // hintNoSemijoin (105x)
57369: 29, // hintNoSkipScan (105x)
57384: 30, // hintNoSwapJoinInputs (105x)
57375: 31, // hintQBName (105x)
57385: 32, // hintQueryType (105x)
57386: 33, // hintReadConsistentReplica (105x)
57387: 34, // hintReadFromStorage (105x)
57374: 35, // hintResourceGroup (105x)
57370: 36, // hintSemijoin (105x)
57373: 37, // hintSetVar (105x)
57368: 38, // hintSkipScan (105x)
57388: 39, // hintSMJoin (105x)
57389: 40, // hintStreamAgg (105x)
57390: 41, // hintSwapJoinInputs (105x)
57392: 42, // hintUseIndex (105x)
57391: 43, // hintUseIndexMerge (105x)
57393: 44, // hintUsePlanCache (105x)
57394: 45, // hintUseToja (105x)
44: 46, // ',' (104x)
57403: 47, // hintDupsWeedOut (85x)
57404: 48, // hintFirstMatch (85x)
57405: 49, // hintLooseScan (85x)
57406: 50, // hintMaterialization (85x)
57398: 51, // hintTiFlash (85x)
57397: 52, // hintTiKV (85x)
57399: 53, // hintFalse (84x)
57395: 54, // hintOLAP (84x)
57396: 55, // hintOLTP (84x)
57400: 56, // hintTrue (84x)
57402: 57, // hintGB (83x)
57401: 58, // hintMB (83x)
57347: 59, // hintIdentifier (82x)
57348: 60, // hintSingleAtIdentifier (74x)
93: 61, // ']' (66x)
46: 62, // '.' (59x)
61: 63, // '=' (59x)
40: 64, // '(' (53x)
57344: 65, // $end (22x)
57425: 66, // QueryBlockOpt (16x)
57419: 67, // Identifier (11x)
57346: 68, // hintIntLit (6x)
57415: 69, // HintTable (4x)
57416: 70, // HintTableList (4x)
91: 71, // '[' (3x)
57408: 72, // BooleanHintName (2x)
57409: 73, // CommaOpt (2x)
57410: 74, // HintIndexList (2x)
57412: 75, // HintStorageType (2x)
57413: 76, // HintStorageTypeAndTable (2x)
57417: 77, // HintTableListOpt (2x)
57422: 78, // JoinOrderOptimizerHintName (2x)
57423: 79, // NullaryHintName (2x)
57427: 80, // StorageOptimizerHintOpt (2x)
57428: 81, // SubqueryOptimizerHintName (2x)
57431: 82, // SubqueryStrategy (2x)
57432: 83, // SupportedIndexLevelOptimizerHintName (2x)
57433: 84, // SupportedTableLevelOptimizerHintName (2x)
57434: 85, // TableOptimizerHintOpt (2x)
57436: 86, // UnsupportedIndexLevelOptimizerHintName (2x)
57437: 87, // UnsupportedTableLevelOptimizerHintName (2x)
57411: 88, // HintQueryType (1x)
57414: 89, // HintStorageTypeAndTableList (1x)
57349: 90, // hintStringLit (1x)
57418: 91, // HintTrueOrFalse (1x)
57420: 92, // IndexNameList (1x)
57421: 93, // IndexNameListOpt (1x)
57424: 94, // OptimizerHintList (1x)
57426: 95, // Start (1x)
57429: 96, // SubqueryStrategies (1x)
57430: 97, // SubqueryStrategiesOpt (1x)
57435: 98, // UnitOfBytes (1x)
57438: 99, // Value (1x)
57407: 100, // $default (0x)
57345: 101, // error (0x)
}
yyhintSymNames = []string{
"')'",
"hintAggToCop",
"hintBKA",
"hintBNL",
"hintEnablePlanCache",
"hintHashAgg",
"hintHashJoin",
"hintIgnoreIndex",
"hintIndexMerge",
"hintInlHashJoin",
"hintInlJoin",
"hintInlMergeJoin",
"hintJoinFixedOrder",
"hintJoinOrder",
"hintJoinPrefix",
"hintJoinSuffix",
"hintMaxExecutionTime",
"hintMemoryQuota",
"hintMerge",
"hintMRR",
"hintNoBKA",
"hintNoBNL",
"hintNoHashJoin",
"hintNoICP",
"hintNoIndexMerge",
"hintNoMerge",
"hintNoMRR",
"hintNoRangeOptimization",
"hintNoSemijoin",
"hintNoSkipScan",
"hintNoSwapJoinInputs",
"hintQBName",
"hintQueryType",
"hintReadConsistentReplica",
"hintReadFromStorage",
"hintResourceGroup",
"hintSemijoin",
"hintSetVar",
"hintSkipScan",
"hintSMJoin",
"hintStreamAgg",
"hintSwapJoinInputs",
"hintUseIndex",
"hintUseIndexMerge",
"hintUsePlanCache",
"hintUseToja",
"','",
"hintDupsWeedOut",
"hintFirstMatch",
"hintLooseScan",
"hintMaterialization",
"hintTiFlash",
"hintTiKV",
"hintFalse",
"hintOLAP",
"hintOLTP",
"hintTrue",
"hintGB",
"hintMB",
"hintIdentifier",
"hintSingleAtIdentifier",
"']'",
"'.'",
"'='",
"'('",
"$end",
"QueryBlockOpt",
"Identifier",
"hintIntLit",
"HintTable",
"HintTableList",
"'['",
"BooleanHintName",
"CommaOpt",
"HintIndexList",
"HintStorageType",
"HintStorageTypeAndTable",
"HintTableListOpt",
"JoinOrderOptimizerHintName",
"NullaryHintName",
"StorageOptimizerHintOpt",
"SubqueryOptimizerHintName",
"SubqueryStrategy",
"SupportedIndexLevelOptimizerHintName",
"SupportedTableLevelOptimizerHintName",
"TableOptimizerHintOpt",
"UnsupportedIndexLevelOptimizerHintName",
"UnsupportedTableLevelOptimizerHintName",
"HintQueryType",
"HintStorageTypeAndTableList",
"hintStringLit",
"HintTrueOrFalse",
"IndexNameList",
"IndexNameListOpt",
"OptimizerHintList",
"Start",
"SubqueryStrategies",
"SubqueryStrategiesOpt",
"UnitOfBytes",
"Value",
"$default",
"error",
}
yyhintReductions = []struct{ xsym, components int }{
{0, 1},
{95, 1},
{94, 1},
{94, 3},
{94, 1},
{94, 3},
{85, 4},
{85, 4},
{85, 4},
{85, 4},
{85, 4},
{85, 4},
{85, 5},
{85, 5},
{85, 6},
{85, 4},
{85, 4},
{85, 6},
{85, 5},
{85, 4},
{85, 5},
{80, 5},
{89, 1},
{89, 3},
{76, 4},
{66, 0},
{66, 1},
{73, 0},
{73, 1},
{77, 1},
{77, 1},
{70, 2},
{70, 3},
{69, 2},
{69, 4},
{74, 4},
{93, 0},
{93, 1},
{92, 1},
{92, 3},
{97, 0},
{97, 1},
{96, 1},
{96, 3},
{99, 1},
{99, 1},
{99, 1},
{98, 1},
{98, 1},
{91, 1},
{91, 1},
{78, 1},
{78, 1},
{78, 1},
{87, 1},
{87, 1},
{87, 1},
{87, 1},
{87, 1},
{87, 1},
{87, 1},
{84, 1},
{84, 1},
{84, 1},
{84, 1},
{84, 1},
{84, 1},
{84, 1},
{86, 1},
{86, 1},
{86, 1},
{86, 1},
{86, 1},
{86, 1},
{86, 1},
{83, 1},
{83, 1},
{83, 1},
{81, 1},
{81, 1},
{82, 1},
{82, 1},
{82, 1},
{82, 1},
{72, 1},
{72, 1},
{79, 1},
{79, 1},
{79, 1},
{79, 1},
{79, 1},
{79, 1},
{88, 1},
{88, 1},
{75, 1},
{75, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
{67, 1},
}
yyhintXErrors = map[yyhintXError]string{}
yyhintParseTab = [223][]uint16{
// 0
{1: 209, 178, 180, 205, 207, 191, 200, 192, 187, 186, 190, 159, 175, 176, 177, 166, 170, 183, 193, 179, 181, 182, 195, 210, 184, 194, 196, 203, 198, 189, 169, 173, 211, 174, 168, 202, 167, 197, 185, 208, 188, 199, 201, 206, 204, 72: 171, 78: 160, 172, 158, 165, 83: 164, 162, 157, 163, 161, 94: 156, 155},
{65: 154},
{1: 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 349, 65: 153, 73: 374},
{1: 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 65: 152},
{1: 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 65: 150},
// 5
{64: 371},
{64: 368},
{64: 365},
{64: 360},
{64: 357},
// 10
{64: 345},
{64: 333},
{64: 329},
{64: 321},
{64: 318},
// 15
{64: 315},
{64: 308},
{64: 302},
{64: 299},
{64: 293},
// 20
{64: 212},
{64: 103},
{64: 102},
{64: 101},
{64: 100},
// 25
{64: 99},
{64: 98},
{64: 97},
{64: 96},
{64: 95},
// 30
{64: 94},
{64: 93},
{64: 92},
{64: 91},
{64: 90},
// 35
{64: 89},
{64: 88},
{64: 87},
{64: 86},
{64: 85},
// 40
{64: 84},
{64: 83},
{64: 82},
{64: 81},
{64: 80},
// 45
{64: 79},
{64: 78},
{64: 77},
{64: 76},
{64: 75},
// 50
{64: 70},
{64: 69},
{64: 68},
{64: 67},
{64: 66},
// 55
{64: 65},
{64: 64},
{64: 63},
{51: 129, 129, 60: 214, 66: 213},
{51: 219, 218, 75: 217, 216, 89: 215},
// 60
{128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 61: 128, 68: 128},
{290, 46: 291},
{132, 46: 132},
{71: 220},
{71: 60},
// 65
{71: 59},
{1: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 47: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 214, 66: 222, 70: 221},
{46: 288, 61: 287},
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 224, 69: 223},
{123, 46: 123, 61: 123},
// 70
{129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 214, 129, 284, 66: 283},
{58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58},
{57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57},
{56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56},
{55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55},
// 75
{54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54},
{53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53},
{52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52},
{51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51},
{50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50},
// 80
{49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49},
{48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48},
{47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47},
{46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46},
{45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45},
// 85
{44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44},
{43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43},
{42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42},
{41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41},
{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40},
// 90
{39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39},
{38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38},
{37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37},
{36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36},
{35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35},
// 95
{34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34},
{33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33},
{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32},
{31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31},
{30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
// 100
{29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29},
{28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28},
{27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27},
{26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26},
{25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25},
// 105
{24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24},
{23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23},
{22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22},
{21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21},
{20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20},
// 110
{19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19},
{18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18},
{17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17},
{16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
{15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
// 115
{14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14},
{13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13},
{12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
{11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
// 120
{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9},
{8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
{7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7},
{6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6},
{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
// 125
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 61: 121},
// 130
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 285},
{129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 214, 129, 66: 286},
{120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 61: 120},
{130, 46: 130},
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 224, 69: 289},
// 135
{122, 46: 122, 61: 122},
{1: 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 65: 133},
{51: 219, 218, 75: 217, 292},
{131, 46: 131},
{54: 129, 129, 60: 214, 66: 294},
// 140
{54: 296, 297, 88: 295},
{298},
{62},
{61},
{1: 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 65: 134},
// 145
{129, 60: 214, 66: 300},
{301},
{1: 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 65: 135},
{53: 129, 56: 129, 60: 214, 66: 303},
{53: 306, 56: 305, 91: 304},
// 150
{307},
{105},
{104},
{1: 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 65: 136},
{60: 214, 66: 309, 68: 129},
// 155
{68: 310},
{57: 313, 312, 98: 311},
{314},
{107},
{106},
// 160
{1: 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 65: 137},
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 316},
{317},
{1: 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 65: 138},
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 319},
// 165
{320},
{1: 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 65: 139},
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 322},
{63: 323},
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 326, 327, 90: 325, 99: 324},
// 170
{328},
{110},
{109},
{108},
{1: 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 65: 140},
// 175
{60: 214, 66: 330, 68: 129},
{68: 331},
{332},
{1: 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 65: 141},
{129, 47: 129, 129, 129, 129, 60: 214, 66: 334},
// 180
{114, 47: 338, 339, 340, 341, 82: 337, 96: 336, 335},
{344},
{113, 46: 342},
{112, 46: 112},
{74, 46: 74},
// 185
{73, 46: 73},
{72, 46: 72},
{71, 46: 71},
{47: 338, 339, 340, 341, 82: 343},
{111, 46: 111},
// 190
{1: 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 65: 142},
{1: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 47: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 214, 66: 347, 74: 346},
{356},
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 224, 69: 348},
{127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 349, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 73: 350},
// 195
{126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 47: 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126},
{118, 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 353, 92: 352, 351},
{119},
{117, 46: 354},
{116, 46: 116},
// 200
{1: 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 355},
{115, 46: 115},
{1: 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 65: 143},
{1: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 47: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 214, 66: 347, 74: 358},
{359},
// 205
{1: 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 65: 144},
{129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 47: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 214, 66: 363, 70: 362, 77: 361},
{364},
{125, 46: 288},
{124, 252, 230, 232, 253, 254, 234, 255, 238, 256, 257, 258, 226, 227, 228, 229, 248, 259, 236, 240, 231, 233, 235, 242, 239, 237, 241, 243, 247, 245, 260, 251, 261, 262, 263, 250, 246, 249, 244, 264, 265, 266, 268, 267, 269, 270, 47: 279, 280, 281, 282, 274, 273, 275, 271, 272, 276, 278, 277, 225, 67: 224, 69: 223},
// 210
{1: 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 65: 145},
{129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 47: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 214, 66: 363, 70: 362, 77: 366},
{367},
{1: 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 65: 146},
{1: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 47: 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 214, 66: 222, 70: 369},
// 215
{370, 46: 288},
{1: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 65: 147},
{129, 60: 214, 66: 372},
{373},
{1: 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 65: 148},
// 220
{1: 209, 178, 180, 205, 207, 191, 200, 192, 187, 186, 190, 159, 175, 176, 177, 166, 170, 183, 193, 179, 181, 182, 195, 210, 184, 194, 196, 203, 198, 189, 169, 173, 211, 174, 168, 202, 167, 197, 185, 208, 188, 199, 201, 206, 204, 72: 171, 78: 160, 172, 376, 165, 83: 164, 162, 375, 163, 161},
{1: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 65: 151},
{1: 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 65: 149},
}
)
var yyhintDebug = 0
type yyhintLexer interface {
Lex(lval *yyhintSymType) int
Errorf(format string, a ...interface{}) error
AppendError(err error)
Errors() (warns []error, errs []error)
}
type yyhintLexerEx interface {
yyhintLexer
Reduced(rule, state int, lval *yyhintSymType) bool
}
func yyhintSymName(c int) (s string) {
x, ok := yyhintXLAT[c]
if ok {
return yyhintSymNames[x]
}
return __yyfmt__.Sprintf("%d", c)
}
func yyhintlex1(yylex yyhintLexer, lval *yyhintSymType) (n int) {
n = yylex.Lex(lval)
if n <= 0 {
n = yyhintEOFCode
}
if yyhintDebug >= 3 {
__yyfmt__.Printf("\nlex %s(%#x %d), lval: %+v\n", yyhintSymName(n), n, n, lval)
}
return n
}
func yyhintParse(yylex yyhintLexer, parser *hintParser) int {
const yyError = 101
yyEx, _ := yylex.(yyhintLexerEx)
var yyn int
parser.yylval = yyhintSymType{}
yyS := parser.cache
Nerrs := 0 /* number of errors */
Errflag := 0 /* error recovery flag */
yyerrok := func() {
if yyhintDebug >= 2 {
__yyfmt__.Printf("yyerrok()\n")
}
Errflag = 0
}
_ = yyerrok
yystate := 0
yychar := -1
var yyxchar int
var yyshift int
yyp := -1
goto yystack
ret0:
return 0
ret1:
return 1
yystack:
/* put a state and value onto the stack */
yyp++
if yyp+1 >= len(yyS) {
nyys := make([]yyhintSymType, len(yyS)*2)
copy(nyys, yyS)
yyS = nyys
parser.cache = yyS
}
parser.yyVAL = &yyS[yyp+1]
yyS[yyp].yys = yystate
yynewstate:
if yychar < 0 {
yychar = yyhintlex1(yylex, &parser.yylval)
var ok bool
if yyxchar, ok = yyhintXLAT[yychar]; !ok {
yyxchar = len(yyhintSymNames) // > tab width
}
}
if yyhintDebug >= 4 {
var a []int
for _, v := range yyS[:yyp+1] {
a = append(a, v.yys)
}
__yyfmt__.Printf("state stack %v\n", a)
}
row := yyhintParseTab[yystate]
yyn = 0
if yyxchar < len(row) {
if yyn = int(row[yyxchar]); yyn != 0 {
yyn += yyhintTabOfs
}
}
switch {
case yyn > 0: // shift
yychar = -1
*parser.yyVAL = parser.yylval
yystate = yyn
yyshift = yyn
if yyhintDebug >= 2 {
__yyfmt__.Printf("shift, and goto state %d\n", yystate)
}
if Errflag > 0 {
Errflag--
}
goto yystack
case yyn < 0: // reduce
case yystate == 1: // accept
if yyhintDebug >= 2 {
__yyfmt__.Println("accept")
}
goto ret0
}
if yyn == 0 {
/* error ... attempt to resume parsing */
switch Errflag {
case 0: /* brand new error */
if yyhintDebug >= 1 {
__yyfmt__.Printf("no action for %s in state %d\n", yyhintSymName(yychar), yystate)
}
msg, ok := yyhintXErrors[yyhintXError{yystate, yyxchar}]
if !ok {
msg, ok = yyhintXErrors[yyhintXError{yystate, -1}]
}
if !ok && yyshift != 0 {
msg, ok = yyhintXErrors[yyhintXError{yyshift, yyxchar}]
}
if !ok {
msg, ok = yyhintXErrors[yyhintXError{yyshift, -1}]
}
if !ok || msg == "" {
msg = "syntax error"
}
// ignore goyacc error message
yylex.AppendError(yylex.Errorf(""))
Nerrs++
fallthrough
case 1, 2: /* incompletely recovered error ... try again */
Errflag = 3
/* find a state where "error" is a legal shift action */
for yyp >= 0 {
row := yyhintParseTab[yyS[yyp].yys]
if yyError < len(row) {
yyn = int(row[yyError]) + yyhintTabOfs
if yyn > 0 { // hit
if yyhintDebug >= 2 {
__yyfmt__.Printf("error recovery found error shift in state %d\n", yyS[yyp].yys)
}
yystate = yyn /* simulate a shift of "error" */
goto yystack
}
}
/* the current p has no shift on "error", pop stack */
if yyhintDebug >= 2 {
__yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys)
}
yyp--
}
/* there is no state on the stack with an error shift ... abort */
if yyhintDebug >= 2 {
__yyfmt__.Printf("error recovery failed\n")
}
goto ret1
case 3: /* no shift yet; clobber input char */
if yyhintDebug >= 2 {
__yyfmt__.Printf("error recovery discards %s\n", yyhintSymName(yychar))
}
if yychar == yyhintEOFCode {
goto ret1
}
yychar = -1
goto yynewstate /* try again in the same state */
}
}
r := -yyn
x0 := yyhintReductions[r]
x, n := x0.xsym, x0.components
yypt := yyp
_ = yypt // guard against "declared and not used"
yyp -= n
if yyp+1 >= len(yyS) {
nyys := make([]yyhintSymType, len(yyS)*2)
copy(nyys, yyS)
yyS = nyys
parser.cache = yyS
}
parser.yyVAL = &yyS[yyp+1]
/* consult goto table to find next state */
exState := yystate
yystate = int(yyhintParseTab[yyS[yyp].yys][x]) + yyhintTabOfs
/* reduction by production r */
if yyhintDebug >= 2 {
__yyfmt__.Printf("reduce using rule %v (%s), and goto state %d\n", r, yyhintSymNames[x], yystate)
}
switch r {
case 1:
{
parser.result = yyS[yypt-0].hints
}
case 2:
{
if yyS[yypt-0].hint != nil {
parser.yyVAL.hints = []*ast.TableOptimizerHint{yyS[yypt-0].hint}
}
}
case 3:
{
if yyS[yypt-0].hint != nil {
parser.yyVAL.hints = append(yyS[yypt-2].hints, yyS[yypt-0].hint)
} else {
parser.yyVAL.hints = yyS[yypt-2].hints
}
}
case 4:
{
parser.yyVAL.hints = yyS[yypt-0].hints
}
case 5:
{
parser.yyVAL.hints = append(yyS[yypt-2].hints, yyS[yypt-0].hints...)
}
case 6:
{
parser.warnUnsupportedHint(yyS[yypt-3].ident)
parser.yyVAL.hint = nil
}
case 7:
{
parser.warnUnsupportedHint(yyS[yypt-3].ident)
parser.yyVAL.hint = nil
}
case 8:
{
parser.warnUnsupportedHint(yyS[yypt-3].ident)
parser.yyVAL.hint = nil
}
case 9:
{
h := yyS[yypt-1].hint
h.HintName = model.NewCIStr(yyS[yypt-3].ident)
parser.yyVAL.hint = h
}
case 10:
{
parser.warnUnsupportedHint(yyS[yypt-3].ident)
parser.yyVAL.hint = nil
}
case 11:
{
h := yyS[yypt-1].hint
h.HintName = model.NewCIStr(yyS[yypt-3].ident)
parser.yyVAL.hint = h
}
case 12:
{
parser.warnUnsupportedHint(yyS[yypt-4].ident)
parser.yyVAL.hint = nil
}
case 13:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-4].ident),
QBName: model.NewCIStr(yyS[yypt-2].ident),
MaxExecutionTime: yyS[yypt-1].number,
}
}
case 14:
{
parser.warnUnsupportedHint(yyS[yypt-5].ident)
parser.yyVAL.hint = nil
}
case 15:
{
parser.warnUnsupportedHint(yyS[yypt-3].ident)
parser.yyVAL.hint = nil
}
case 16:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-3].ident),
QBName: model.NewCIStr(yyS[yypt-1].ident),
}
}
case 17:
{
maxValue := uint64(math.MaxInt64) / yyS[yypt-1].number
if yyS[yypt-2].number <= maxValue {
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-5].ident),
MemoryQuota: int64(yyS[yypt-2].number * yyS[yypt-1].number),
QBName: model.NewCIStr(yyS[yypt-3].ident),
}
} else {
yylex.AppendError(ErrWarnMemoryQuotaOverflow.GenWithStackByArgs(math.MaxInt64))
parser.lastErrorAsWarn()
parser.yyVAL.hint = nil
}
}
case 18:
{
h := yyS[yypt-1].hint
h.HintName = model.NewCIStr(yyS[yypt-4].ident)
h.QBName = model.NewCIStr(yyS[yypt-2].ident)
parser.yyVAL.hint = h
}
case 19:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-3].ident),
QBName: model.NewCIStr(yyS[yypt-1].ident),
}
}
case 20:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-4].ident),
QBName: model.NewCIStr(yyS[yypt-2].ident),
QueryType: model.NewCIStr(yyS[yypt-1].ident),
}
}
case 21:
{
hs := yyS[yypt-1].hints
name := model.NewCIStr(yyS[yypt-4].ident)
qb := model.NewCIStr(yyS[yypt-2].ident)
for _, h := range hs {
h.HintName = name
h.QBName = qb
}
parser.yyVAL.hints = hs
}
case 22:
{
parser.yyVAL.hints = []*ast.TableOptimizerHint{yyS[yypt-0].hint}
}
case 23:
{
parser.yyVAL.hints = append(yyS[yypt-2].hints, yyS[yypt-0].hint)
}
case 24:
{
h := yyS[yypt-1].hint
h.StoreType = model.NewCIStr(yyS[yypt-3].ident)
parser.yyVAL.hint = h
}
case 25:
{
parser.yyVAL.ident = ""
}
case 30:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
QBName: model.NewCIStr(yyS[yypt-0].ident),
}
}
case 31:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
Tables: []ast.HintTable{yyS[yypt-0].table},
QBName: model.NewCIStr(yyS[yypt-1].ident),
}
}
case 32:
{
h := yyS[yypt-2].hint
h.Tables = append(h.Tables, yyS[yypt-0].table)
parser.yyVAL.hint = h
}
case 33:
{
parser.yyVAL.table = ast.HintTable{
TableName: model.NewCIStr(yyS[yypt-1].ident),
QBName: model.NewCIStr(yyS[yypt-0].ident),
}
}
case 34:
{
parser.yyVAL.table = ast.HintTable{
DBName: model.NewCIStr(yyS[yypt-3].ident),
TableName: model.NewCIStr(yyS[yypt-1].ident),
QBName: model.NewCIStr(yyS[yypt-0].ident),
}
}
case 35:
{
h := yyS[yypt-0].hint
h.Tables = []ast.HintTable{yyS[yypt-2].table}
h.QBName = model.NewCIStr(yyS[yypt-3].ident)
parser.yyVAL.hint = h
}
case 36:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{}
}
case 38:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
Indexes: []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)},
}
}
case 39:
{
h := yyS[yypt-2].hint
h.Indexes = append(h.Indexes, model.NewCIStr(yyS[yypt-0].ident))
parser.yyVAL.hint = h
}
case 46:
{
parser.yyVAL.ident = strconv.FormatUint(yyS[yypt-0].number, 10)
}
case 47:
{
parser.yyVAL.number = 1024 * 1024
}
case 48:
{
parser.yyVAL.number = 1024 * 1024 * 1024
}
case 49:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{HintFlag: true}
}
case 50:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{HintFlag: false}
}
}
if yyEx != nil && yyEx.Reduced(r, exState, parser.yyVAL) {
return -1
}
goto yystack /* stack new state and value */
}
%{
// Copyright 2020 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package parser
import (
"math"
"strconv"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/model"
)
%}
%union {
ident string
number uint64
hint *ast.TableOptimizerHint
hints []*ast.TableOptimizerHint
table ast.HintTable
}
%token <number>
/*yy:token "%d" */
hintIntLit "a 64-bit unsigned integer"
%token <ident>
/*yy:token "%c" */
hintIdentifier
/*yy:token "@%c" */
hintSingleAtIdentifier "identifier with single leading at"
/*yy:token "'%c'" */
hintStringLit
/* MySQL 8.0 hint names */
hintJoinFixedOrder "JOIN_FIXED_ORDER"
hintJoinOrder "JOIN_ORDER"
hintJoinPrefix "JOIN_PREFIX"
hintJoinSuffix "JOIN_SUFFIX"
hintBKA "BKA"
hintNoBKA "NO_BKA"
hintBNL "BNL"
hintNoBNL "NO_BNL"
hintHashJoin "HASH_JOIN"
hintNoHashJoin "NO_HASH_JOIN"
hintMerge "MERGE"
hintNoMerge "NO_MERGE"
hintIndexMerge "INDEX_MERGE"
hintNoIndexMerge "NO_INDEX_MERGE"
hintMRR "MRR"
hintNoMRR "NO_MRR"
hintNoICP "NO_ICP"
hintNoRangeOptimization "NO_RANGE_OPTIMIZATION"
hintSkipScan "SKIP_SCAN"
hintNoSkipScan "NO_SKIP_SCAN"
hintSemijoin "SEMIJOIN"
hintNoSemijoin "NO_SEMIJOIN"
hintMaxExecutionTime "MAX_EXECUTION_TIME"
hintSetVar "SET_VAR"
hintResourceGroup "RESOURCE_GROUP"
hintQBName "QB_NAME"
/* TiDB hint names */
hintAggToCop "AGG_TO_COP"
hintEnablePlanCache "ENABLE_PLAN_CACHE"
hintHashAgg "HASH_AGG"
hintIgnoreIndex "IGNORE_INDEX"
hintInlHashJoin "INL_HASH_JOIN"
hintInlJoin "INL_JOIN"
hintInlMergeJoin "INL_MERGE_JOIN"
hintMemoryQuota "MEMORY_QUOTA"
hintNoSwapJoinInputs "NO_SWAP_JOIN_INPUTS"
hintQueryType "QUERY_TYPE"
hintReadConsistentReplica "READ_CONSISTENT_REPLICA"
hintReadFromStorage "READ_FROM_STORAGE"
hintSMJoin "SM_JOIN"
hintStreamAgg "STREAM_AGG"
hintSwapJoinInputs "SWAP_JOIN_INPUTS"
hintUseIndexMerge "USE_INDEX_MERGE"
hintUseIndex "USE_INDEX"
hintUsePlanCache "USE_PLAN_CACHE"
hintUseToja "USE_TOJA"
/* Other keywords */
hintOLAP "OLAP"
hintOLTP "OLTP"
hintTiKV "TIKV"
hintTiFlash "TIFLASH"
hintFalse "FALSE"
hintTrue "TRUE"
hintMB "MB"
hintGB "GB"
hintDupsWeedOut "DUPSWEEDOUT"
hintFirstMatch "FIRSTMATCH"
hintLooseScan "LOOSESCAN"
hintMaterialization "MATERIALIZATION"
%type <ident>
Identifier "identifier (including keywords)"
QueryBlockOpt "Query block identifier optional"
JoinOrderOptimizerHintName
UnsupportedTableLevelOptimizerHintName
SupportedTableLevelOptimizerHintName
UnsupportedIndexLevelOptimizerHintName
SupportedIndexLevelOptimizerHintName
SubqueryOptimizerHintName
BooleanHintName "name of hints which take a boolean input"
NullaryHintName "name of hints which take no input"
SubqueryStrategy
Value "the value in the SET_VAR() hint"
HintQueryType "query type in optimizer hint (OLAP or OLTP)"
HintStorageType "storage type in optimizer hint (TiKV or TiFlash)"
%type <number>
UnitOfBytes "unit of bytes (MB or GB)"
CommaOpt "optional ','"
%type <hints>
OptimizerHintList "optimizer hint list"
StorageOptimizerHintOpt "storage level optimizer hint"
HintStorageTypeAndTableList "storage type and tables list in optimizer hint"
%type <hint>
TableOptimizerHintOpt "optimizer hint"
HintTableList "table list in optimizer hint"
HintTableListOpt "optional table list in optimizer hint"
HintIndexList "table name with index list in optimizer hint"
IndexNameList "index list in optimizer hint"
IndexNameListOpt "optional index list in optimizer hint"
SubqueryStrategies "subquery strategies"
SubqueryStrategiesOpt "optional subquery strategies"
HintTrueOrFalse "true or false in optimizer hint"
HintStorageTypeAndTable "storage type and tables in optimizer hint"
%type <table>
HintTable "Table in optimizer hint"
%start Start
%%
Start:
OptimizerHintList
{
parser.result = $1
}
OptimizerHintList:
TableOptimizerHintOpt
{
if $1 != nil {
$$ = []*ast.TableOptimizerHint{$1}
}
}
| OptimizerHintList CommaOpt TableOptimizerHintOpt
{
if $3 != nil {
$$ = append($1, $3)
} else {
$$ = $1
}
}
| StorageOptimizerHintOpt
{
$$ = $1
}
| OptimizerHintList CommaOpt StorageOptimizerHintOpt
{
$$ = append($1, $3...)
}
TableOptimizerHintOpt:
"JOIN_FIXED_ORDER" '(' QueryBlockOpt ')'
{
parser.warnUnsupportedHint($1)
$$ = nil
}
| JoinOrderOptimizerHintName '(' HintTableList ')'
{
parser.warnUnsupportedHint($1)
$$ = nil
}
| UnsupportedTableLevelOptimizerHintName '(' HintTableListOpt ')'
{
parser.warnUnsupportedHint($1)
$$ = nil
}
| SupportedTableLevelOptimizerHintName '(' HintTableListOpt ')'
{
h := $3
h.HintName = model.NewCIStr($1)
$$ = h
}
| UnsupportedIndexLevelOptimizerHintName '(' HintIndexList ')'
{
parser.warnUnsupportedHint($1)
$$ = nil
}
| SupportedIndexLevelOptimizerHintName '(' HintIndexList ')'
{
h := $3
h.HintName = model.NewCIStr($1)
$$ = h
}
| SubqueryOptimizerHintName '(' QueryBlockOpt SubqueryStrategiesOpt ')'
{
parser.warnUnsupportedHint($1)
$$ = nil
}
| "MAX_EXECUTION_TIME" '(' QueryBlockOpt hintIntLit ')'
{
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
QBName: model.NewCIStr($3),
MaxExecutionTime: $4,
}
}
| "SET_VAR" '(' Identifier '=' Value ')'
{
parser.warnUnsupportedHint($1)
$$ = nil
}
| "RESOURCE_GROUP" '(' Identifier ')'
{
parser.warnUnsupportedHint($1)
$$ = nil
}
| "QB_NAME" '(' Identifier ')'
{
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
QBName: model.NewCIStr($3),
}
}
| "MEMORY_QUOTA" '(' QueryBlockOpt hintIntLit UnitOfBytes ')'
{
maxValue := uint64(math.MaxInt64) / $5
if $4 <= maxValue {
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
MemoryQuota: int64($4 * $5),
QBName: model.NewCIStr($3),
}
} else {
yylex.AppendError(ErrWarnMemoryQuotaOverflow.GenWithStackByArgs(math.MaxInt64))
parser.lastErrorAsWarn()
$$ = nil
}
}
| BooleanHintName '(' QueryBlockOpt HintTrueOrFalse ')'
{
h := $4
h.HintName = model.NewCIStr($1)
h.QBName = model.NewCIStr($3)
$$ = h
}
| NullaryHintName '(' QueryBlockOpt ')'
{
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
QBName: model.NewCIStr($3),
}
}
| "QUERY_TYPE" '(' QueryBlockOpt HintQueryType ')'
{
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
QBName: model.NewCIStr($3),
QueryType: model.NewCIStr($4),
}
}
StorageOptimizerHintOpt:
"READ_FROM_STORAGE" '(' QueryBlockOpt HintStorageTypeAndTableList ')'
{
hs := $4
name := model.NewCIStr($1)
qb := model.NewCIStr($3)
for _, h := range hs {
h.HintName = name
h.QBName = qb
}
$$ = hs
}
HintStorageTypeAndTableList:
HintStorageTypeAndTable
{
$$ = []*ast.TableOptimizerHint{$1}
}
| HintStorageTypeAndTableList ',' HintStorageTypeAndTable
{
$$ = append($1, $3)
}
HintStorageTypeAndTable:
HintStorageType '[' HintTableList ']'
{
h := $3
h.StoreType = model.NewCIStr($1)
$$ = h
}
QueryBlockOpt:
/* empty */
{
$$ = ""
}
| hintSingleAtIdentifier
CommaOpt:
/*empty*/
{}
| ','
{}
/**
* HintTableListOpt:
*
* [@query_block_name] [tbl_name [, tbl_name] ...]
* [tbl_name@query_block_name [, tbl_name@query_block_name] ...]
*
*/
HintTableListOpt:
HintTableList
| QueryBlockOpt
{
$$ = &ast.TableOptimizerHint{
QBName: model.NewCIStr($1),
}
}
HintTableList:
QueryBlockOpt HintTable
{
$$ = &ast.TableOptimizerHint{
Tables: []ast.HintTable{$2},
QBName: model.NewCIStr($1),
}
}
| HintTableList ',' HintTable
{
h := $1
h.Tables = append(h.Tables, $3)
$$ = h
}
HintTable:
Identifier QueryBlockOpt
{
$$ = ast.HintTable{
TableName: model.NewCIStr($1),
QBName: model.NewCIStr($2),
}
}
| Identifier '.' Identifier QueryBlockOpt
{
$$ = ast.HintTable{
DBName: model.NewCIStr($1),
TableName: model.NewCIStr($3),
QBName: model.NewCIStr($4),
}
}
/**
* HintIndexList:
*
* [@query_block_name] tbl_name [index_name [, index_name] ...]
* tbl_name@query_block_name [index_name [, index_name] ...]
*/
HintIndexList:
QueryBlockOpt HintTable CommaOpt IndexNameListOpt
{
h := $4
h.Tables = []ast.HintTable{$2}
h.QBName = model.NewCIStr($1)
$$ = h
}
IndexNameListOpt:
/* empty */
{
$$ = &ast.TableOptimizerHint{}
}
| IndexNameList
IndexNameList:
Identifier
{
$$ = &ast.TableOptimizerHint{
Indexes: []model.CIStr{model.NewCIStr($1)},
}
}
| IndexNameList ',' Identifier
{
h := $1
h.Indexes = append(h.Indexes, model.NewCIStr($3))
$$ = h
}
/**
* Miscellaneous rules
*/
SubqueryStrategiesOpt:
/* empty */
{}
| SubqueryStrategies
SubqueryStrategies:
SubqueryStrategy
{}
| SubqueryStrategies ',' SubqueryStrategy
Value:
hintStringLit
| Identifier
| hintIntLit
{
$$ = strconv.FormatUint($1, 10)
}
UnitOfBytes:
"MB"
{
$$ = 1024 * 1024
}
| "GB"
{
$$ = 1024 * 1024 * 1024
}
HintTrueOrFalse:
"TRUE"
{
$$ = &ast.TableOptimizerHint{HintFlag: true}
}
| "FALSE"
{
$$ = &ast.TableOptimizerHint{HintFlag: false}
}
JoinOrderOptimizerHintName:
"JOIN_ORDER"
| "JOIN_PREFIX"
| "JOIN_SUFFIX"
UnsupportedTableLevelOptimizerHintName:
"BKA"
| "NO_BKA"
| "BNL"
| "NO_BNL"
/* HASH_JOIN is supported by TiDB */
| "NO_HASH_JOIN"
| "MERGE"
| "NO_MERGE"
SupportedTableLevelOptimizerHintName:
"SM_JOIN"
| "INL_JOIN"
| "INL_HASH_JOIN"
| "SWAP_JOIN_INPUTS"
| "NO_SWAP_JOIN_INPUTS"
| "INL_MERGE_JOIN"
| "HASH_JOIN"
UnsupportedIndexLevelOptimizerHintName:
"INDEX_MERGE"
/* NO_INDEX_MERGE is currently a nullary hint in TiDB */
| "MRR"
| "NO_MRR"
| "NO_ICP"
| "NO_RANGE_OPTIMIZATION"
| "SKIP_SCAN"
| "NO_SKIP_SCAN"
SupportedIndexLevelOptimizerHintName:
"USE_INDEX"
| "IGNORE_INDEX"
| "USE_INDEX_MERGE"
SubqueryOptimizerHintName:
"SEMIJOIN"
| "NO_SEMIJOIN"
SubqueryStrategy:
"DUPSWEEDOUT"
| "FIRSTMATCH"
| "LOOSESCAN"
| "MATERIALIZATION"
BooleanHintName:
"USE_TOJA"
| "ENABLE_PLAN_CACHE"
NullaryHintName:
"USE_PLAN_CACHE"
| "HASH_AGG"
| "STREAM_AGG"
| "AGG_TO_COP"
| "NO_INDEX_MERGE"
| "READ_CONSISTENT_REPLICA"
HintQueryType:
"OLAP"
| "OLTP"
HintStorageType:
"TIKV"
| "TIFLASH"
Identifier:
hintIdentifier
/* MySQL 8.0 hint names */
| "JOIN_FIXED_ORDER"
| "JOIN_ORDER"
| "JOIN_PREFIX"
| "JOIN_SUFFIX"
| "BKA"
| "NO_BKA"
| "BNL"
| "NO_BNL"
| "HASH_JOIN"
| "NO_HASH_JOIN"
| "MERGE"
| "NO_MERGE"
| "INDEX_MERGE"
| "NO_INDEX_MERGE"
| "MRR"
| "NO_MRR"
| "NO_ICP"
| "NO_RANGE_OPTIMIZATION"
| "SKIP_SCAN"
| "NO_SKIP_SCAN"
| "SEMIJOIN"
| "NO_SEMIJOIN"
| "MAX_EXECUTION_TIME"
| "SET_VAR"
| "RESOURCE_GROUP"
| "QB_NAME"
/* TiDB hint names */
| "AGG_TO_COP"
| "ENABLE_PLAN_CACHE"
| "HASH_AGG"
| "IGNORE_INDEX"
| "INL_HASH_JOIN"
| "INL_JOIN"
| "INL_MERGE_JOIN"
| "MEMORY_QUOTA"
| "NO_SWAP_JOIN_INPUTS"
| "QUERY_TYPE"
| "READ_CONSISTENT_REPLICA"
| "READ_FROM_STORAGE"
| "SM_JOIN"
| "STREAM_AGG"
| "SWAP_JOIN_INPUTS"
| "USE_INDEX_MERGE"
| "USE_INDEX"
| "USE_PLAN_CACHE"
| "USE_TOJA"
/* other keywords */
| "OLAP"
| "OLTP"
| "TIKV"
| "TIFLASH"
| "FALSE"
| "TRUE"
| "MB"
| "GB"
| "DUPSWEEDOUT"
| "FIRSTMATCH"
| "LOOSESCAN"
| "MATERIALIZATION"
%%
// Copyright 2020 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package parser
import (
"strconv"
"strings"
"unicode"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/parser/terror"
)
var (
ErrWarnOptimizerHintUnsupportedHint = terror.ClassParser.New(mysql.ErrWarnOptimizerHintUnsupportedHint, mysql.MySQLErrName[mysql.ErrWarnOptimizerHintUnsupportedHint])
ErrWarnOptimizerHintInvalidToken = terror.ClassParser.New(mysql.ErrWarnOptimizerHintInvalidToken, mysql.MySQLErrName[mysql.ErrWarnOptimizerHintInvalidToken])
ErrWarnMemoryQuotaOverflow = terror.ClassParser.New(mysql.ErrWarnMemoryQuotaOverflow, mysql.MySQLErrName[mysql.ErrWarnMemoryQuotaOverflow])
ErrWarnOptimizerHintParseError = terror.ClassParser.New(mysql.ErrWarnOptimizerHintParseError, mysql.MySQLErrName[mysql.ErrWarnOptimizerHintParseError])
ErrWarnOptimizerHintInvalidInteger = terror.ClassParser.New(mysql.ErrWarnOptimizerHintInvalidInteger, mysql.MySQLErrName[mysql.ErrWarnOptimizerHintInvalidInteger])
)
// hintScanner implements the yyhintLexer interface
type hintScanner struct {
Scanner
}
func (hs *hintScanner) Errorf(format string, args ...interface{}) error {
inner := hs.Scanner.Errorf(format, args...)
return ErrWarnOptimizerHintParseError.GenWithStackByArgs(inner)
}
func (hs *hintScanner) Lex(lval *yyhintSymType) int {
tok, pos, lit := hs.scan()
hs.lastScanOffset = pos.Offset
var errorTokenType string
switch tok {
case intLit:
n, e := strconv.ParseUint(lit, 10, 64)
if e != nil {
hs.AppendError(ErrWarnOptimizerHintInvalidInteger.GenWithStackByArgs(lit))
return int(unicode.ReplacementChar)
}
lval.number = n
return hintIntLit
case singleAtIdentifier:
lval.ident = lit
return hintSingleAtIdentifier
case identifier:
lval.ident = lit
if tok1, ok := hintTokenMap[strings.ToUpper(lit)]; ok {
return tok1
}
return hintIdentifier
case stringLit:
lval.ident = lit
if hs.sqlMode.HasANSIQuotesMode() && hs.r.s[pos.Offset] == '"' {
return hintIdentifier
}
return hintStringLit
case bitLit:
if strings.HasPrefix(lit, "0b") {
lval.ident = lit
return hintIdentifier
}
errorTokenType = "bit-value literal"
case hexLit:
if strings.HasPrefix(lit, "0x") {
lval.ident = lit
return hintIdentifier
}
errorTokenType = "hexadecimal literal"
case quotedIdentifier:
lval.ident = lit
return hintIdentifier
case eq:
return '='
case floatLit:
errorTokenType = "floating point number"
case decLit:
errorTokenType = "decimal number"
default:
if tok <= 0x7f {
return tok
}
errorTokenType = "unknown token"
}
hs.AppendError(ErrWarnOptimizerHintInvalidToken.GenWithStackByArgs(errorTokenType, lit, tok))
return int(unicode.ReplacementChar)
}
type hintParser struct {
lexer hintScanner
result []*ast.TableOptimizerHint
// the following fields are used by yyParse to reduce allocation.
cache []yyhintSymType
yylval yyhintSymType
yyVAL *yyhintSymType
}
func newHintParser() *hintParser {
return &hintParser{cache: make([]yyhintSymType, 50)}
}
func (hp *hintParser) parse(input string, sqlMode mysql.SQLMode, initPos Pos) ([]*ast.TableOptimizerHint, []error) {
hp.result = nil
hp.lexer.reset(input[3:])
hp.lexer.SetSQLMode(sqlMode)
hp.lexer.r.p = Pos{
Line: initPos.Line,
Col: initPos.Col + 3, // skipped the initial '/*+'
Offset: 0,
}
hp.lexer.inBangComment = true // skip the final '*/' (we need the '*/' for reporting warnings)
yyhintParse(&hp.lexer, hp)
warns, errs := hp.lexer.Errors()
if len(errs) == 0 {
errs = warns
}
return hp.result, errs
}
// ParseHint parses an optimizer hint (the interior of `/*+ ... */`).
func ParseHint(input string, sqlMode mysql.SQLMode, initPos Pos) ([]*ast.TableOptimizerHint, []error) {
hp := newHintParser()
return hp.parse(input, sqlMode, initPos)
}
func (hp *hintParser) warnUnsupportedHint(name string) {
warn := ErrWarnOptimizerHintUnsupportedHint.GenWithStackByArgs(name)
hp.lexer.warns = append(hp.lexer.warns, warn)
}
func (hp *hintParser) lastErrorAsWarn() {
hp.lexer.lastErrorAsWarn()
}
...@@ -42,8 +42,9 @@ type Scanner struct { ...@@ -42,8 +42,9 @@ type Scanner struct {
warns []error warns []error
stmtStartPos int stmtStartPos int
// For scanning such kind of comment: /*! MySQL-specific code */ or /*+ optimizer hint */ // inBangComment is true if we are inside a `/*! ... */` block.
specialComment specialCommentScanner // It is used to ignore a stray `*/` when scanning.
inBangComment bool
sqlMode mysql.SQLMode sqlMode mysql.SQLMode
...@@ -55,51 +56,13 @@ type Scanner struct { ...@@ -55,51 +56,13 @@ type Scanner struct {
// lastScanOffset indicates last offset returned by scan(). // lastScanOffset indicates last offset returned by scan().
// It's used to substring sql in syntax error message. // It's used to substring sql in syntax error message.
lastScanOffset int lastScanOffset int
}
type specialCommentScanner interface {
stmtTexter
scan() (tok int, pos Pos, lit string)
}
type mysqlSpecificCodeScanner struct {
*Scanner
Pos
}
func (s *mysqlSpecificCodeScanner) scan() (tok int, pos Pos, lit string) { // lastKeyword records the previous keyword returned by scan().
tok, pos, lit = s.Scanner.scan() // determine whether an optimizer hint should be parsed or ignored.
pos.Line += s.Pos.Line lastKeyword int
pos.Col += s.Pos.Col
pos.Offset += s.Pos.Offset
return
}
type optimizerHintScanner struct { // hintPos records the start position of the previous optimizer hint.
*Scanner lastHintPos Pos
Pos
end bool
}
func (s *optimizerHintScanner) scan() (tok int, pos Pos, lit string) {
tok, pos, lit = s.Scanner.scan()
pos.Line += s.Pos.Line
pos.Col += s.Pos.Col
pos.Offset += s.Pos.Offset
switch tok {
case 0:
if !s.end {
tok = hintEnd
s.end = true
}
case invalid:
// an optimizer hint is allowed to contain invalid characters, the
// remaining hints are just ignored.
// force advance the lexer even when encountering an invalid character
// to prevent infinite parser loop. (see issue #336)
s.r.inc()
}
return
} }
// Errors returns the errors and warns during a scan. // Errors returns the errors and warns during a scan.
...@@ -114,14 +77,11 @@ func (s *Scanner) reset(sql string) { ...@@ -114,14 +77,11 @@ func (s *Scanner) reset(sql string) {
s.errs = s.errs[:0] s.errs = s.errs[:0]
s.warns = s.warns[:0] s.warns = s.warns[:0]
s.stmtStartPos = 0 s.stmtStartPos = 0
s.specialComment = nil s.inBangComment = false
s.lastKeyword = 0
} }
func (s *Scanner) stmtText() string { func (s *Scanner) stmtText() string {
if s.specialComment != nil {
return s.specialComment.stmtText()
}
endPos := s.r.pos().Offset endPos := s.r.pos().Offset
if s.r.s[endPos-1] == '\n' { if s.r.s[endPos-1] == '\n' {
endPos = endPos - 1 // trim new line endPos = endPos - 1 // trim new line
...@@ -168,6 +128,7 @@ func (s *Scanner) AppendError(err error) { ...@@ -168,6 +128,7 @@ func (s *Scanner) AppendError(err error) {
func (s *Scanner) Lex(v *yySymType) int { func (s *Scanner) Lex(v *yySymType) int {
tok, pos, lit := s.scan() tok, pos, lit := s.scan()
s.lastScanOffset = pos.Offset s.lastScanOffset = pos.Offset
s.lastKeyword = 0
v.offset = pos.Offset v.offset = pos.Offset
v.ident = lit v.ident = lit
if tok == identifier { if tok == identifier {
...@@ -176,6 +137,7 @@ func (s *Scanner) Lex(v *yySymType) int { ...@@ -176,6 +137,7 @@ func (s *Scanner) Lex(v *yySymType) int {
if tok == identifier { if tok == identifier {
if tok1 := s.isTokenIdentifier(lit, pos.Offset); tok1 != 0 { if tok1 := s.isTokenIdentifier(lit, pos.Offset); tok1 != 0 {
tok = tok1 tok = tok1
s.lastKeyword = tok1
} }
} }
if s.sqlMode.HasANSIQuotesMode() && if s.sqlMode.HasANSIQuotesMode() &&
...@@ -253,19 +215,6 @@ func (s *Scanner) skipWhitespace() rune { ...@@ -253,19 +215,6 @@ func (s *Scanner) skipWhitespace() rune {
} }
func (s *Scanner) scan() (tok int, pos Pos, lit string) { func (s *Scanner) scan() (tok int, pos Pos, lit string) {
if s.specialComment != nil {
// Enter specialComment scan mode.
// for scanning such kind of comment: /*! MySQL-specific code */
specialComment := s.specialComment
tok, pos, lit = specialComment.scan()
if tok != 0 {
// return the specialComment scan result as the result
return
}
// leave specialComment scan mode after all stream consumed.
s.specialComment = nil
}
ch0 := s.r.peek() ch0 := s.r.peek()
if unicode.IsSpace(ch0) { if unicode.IsSpace(ch0) {
ch0 = s.skipWhitespace() ch0 = s.skipWhitespace()
...@@ -388,85 +337,95 @@ func startWithDash(s *Scanner) (tok int, pos Pos, lit string) { ...@@ -388,85 +337,95 @@ func startWithDash(s *Scanner) (tok int, pos Pos, lit string) {
func startWithSlash(s *Scanner) (tok int, pos Pos, lit string) { func startWithSlash(s *Scanner) (tok int, pos Pos, lit string) {
pos = s.r.pos() pos = s.r.pos()
s.r.inc() s.r.inc()
ch0 := s.r.peek() if s.r.peek() != '*' {
if ch0 == '*' { tok = int('/')
s.r.inc() return
startWithAsterisk := false }
for {
ch0 = s.r.readByte()
if startWithAsterisk && ch0 == '/' {
// Meets */, means comment end.
break
} else if ch0 == '*' {
startWithAsterisk = true
} else {
startWithAsterisk = false
}
if ch0 == unicode.ReplacementChar && s.r.eof() { isOptimizerHint := false
// unclosed comment currentCharIsStar := false
s.errs = append(s.errs, ParseErrorWith(s.r.data(&pos), s.r.p.Line))
return
}
s.r.inc() // we see '/*' so far.
switch s.r.readByte() {
case '!': // '/*!' MySQL-specific comments
// See http://dev.mysql.com/doc/refman/5.7/en/comments.html
// in '/*!', which we always recognize regardless of version.
_ = s.scanVersionDigits(5, 5)
s.inBangComment = true
return s.scan()
case 'T': // '/*T' maybe TiDB-specific comments
if s.r.peek() != '!' {
// '/*TX' is just normal comment.
break
}
s.r.inc()
// in '/*T!', try to consume the 5 to 6 digit version string.
commentVersion := s.scanVersionDigits(5, 6)
if commentVersion <= CommentCodeCurrentVersion {
s.inBangComment = true
return s.scan()
} }
comment := s.r.data(&pos) case 'M': // '/*M' maybe MariaDB-specific comments
// no special treatment for now.
break
case '+': // '/*+' optimizer hints
// See https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html // See https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html
if strings.HasPrefix(comment, "/*+") { if _, ok := hintedTokens[s.lastKeyword]; ok {
begin := sqlOffsetInComment(comment) // only recognize optimizers hints directly followed by certain
end := len(comment) - 2 // keywords like SELECT, INSERT, etc.
sql := comment[begin:end] isOptimizerHint = true
s.specialComment = &optimizerHintScanner{
Scanner: s.InheritScanner(sql),
Pos: Pos{
pos.Line,
pos.Col,
pos.Offset + begin,
},
}
tok = hintBegin
return
} }
// See http://dev.mysql.com/doc/refman/5.7/en/comments.html case '*': // '/**' if the next char is '/' it would close the comment.
// Convert "/*!VersionNumber MySQL-specific-code */" to "MySQL-specific-code". currentCharIsStar = true
if strings.HasPrefix(comment, "/*!") {
sql := specCodePattern.ReplaceAllStringFunc(comment, TrimComment)
s.specialComment = &mysqlSpecificCodeScanner{
Scanner: s.InheritScanner(sql),
Pos: Pos{
pos.Line,
pos.Col,
pos.Offset + sqlOffsetInComment(comment),
},
}
}
return s.scan() default:
break
} }
tok = int('/')
return
}
func sqlOffsetInComment(comment string) int { // standard C-like comment. read until we see '*/' then drop it.
// find the first SQL token offset in pattern like "/*!40101 mysql specific code */" for {
offset := 0 if currentCharIsStar || s.r.incAsLongAs(func(ch rune) bool { return ch != '*' }) == '*' {
for i := 0; i < len(comment); i++ { switch s.r.readByte() {
if unicode.IsSpace(rune(comment[i])) { case '/':
offset = i // Meets */, means comment end.
break if isOptimizerHint {
s.lastHintPos = pos
return hintComment, pos, s.r.data(&pos)
} else {
return s.scan()
}
case 0:
break
case '*':
currentCharIsStar = true
continue
default:
currentCharIsStar = false
continue
}
} }
// unclosed comment or other errors.
s.errs = append(s.errs, ParseErrorWith(s.r.data(&pos), s.r.p.Line))
return
} }
for offset < len(comment) { }
offset++
if !unicode.IsSpace(rune(comment[offset])) { func startWithStar(s *Scanner) (tok int, pos Pos, lit string) {
break pos = s.r.pos()
} s.r.inc()
// skip and exit '/*!' if we see '*/'
if s.inBangComment && s.r.peek() == '/' {
s.inBangComment = false
s.r.inc()
return s.scan()
} }
return offset // otherwise it is just a normal star.
return '*', pos, "*"
} }
func startWithAt(s *Scanner) (tok int, pos Pos, lit string) { func startWithAt(s *Scanner) (tok int, pos Pos, lit string) {
...@@ -787,6 +746,33 @@ func (s *Scanner) scanDigits() string { ...@@ -787,6 +746,33 @@ func (s *Scanner) scanDigits() string {
return s.r.data(&pos) return s.r.data(&pos)
} }
// scanVersionDigits scans for `min` to `max` digits (range inclusive) used in
// `/*!12345 ... */` comments.
func (s *Scanner) scanVersionDigits(min, max int) (version CommentCodeVersion) {
pos := s.r.pos()
for i := 0; i < max; i++ {
ch := s.r.peek()
if isDigit(ch) {
version = version*10 + CommentCodeVersion(ch-'0')
s.r.inc()
} else if i < min {
s.r.p = pos
return CommentCodeNoVersion
} else {
break
}
}
return
}
func (s *Scanner) lastErrorAsWarn() {
if len(s.errs) == 0 {
return
}
s.warns = append(s.warns, s.errs[len(s.errs)-1])
s.errs = s.errs[:len(s.errs)-1]
}
type reader struct { type reader struct {
s string s string
p Pos p Pos
......
...@@ -14,11 +14,31 @@ ...@@ -14,11 +14,31 @@
package parser package parser
import ( import (
"fmt"
"strings" "strings"
"github.com/pingcap/parser/charset" "github.com/pingcap/parser/charset"
) )
// CommentCodeVersion is used to track the highest version can be parsed in the comment with pattern /*T!00001 xxx */
type CommentCodeVersion int
const (
CommentCodeNoVersion CommentCodeVersion = iota
CommentCodeAutoRandom CommentCodeVersion = 40000
CommentCodeCurrentVersion
)
func (ccv CommentCodeVersion) String() string {
return fmt.Sprintf("%05d", ccv)
}
// WrapStringWithCodeVersion convert a string `str` to `/*T!xxxxx str */`, where `xxxxx` is determined by CommentCodeVersion.
func WrapStringWithCodeVersion(str string, ccv CommentCodeVersion) string {
return fmt.Sprintf("/*T!%05d %s */", ccv, str)
}
func isLetter(ch rune) bool { func isLetter(ch rune) bool {
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
} }
...@@ -82,7 +102,6 @@ func init() { ...@@ -82,7 +102,6 @@ func init() {
// set root trie node's token to invalid, so when input match nothing // set root trie node's token to invalid, so when input match nothing
// in the trie, invalid will be the default return token. // in the trie, invalid will be the default return token.
ruleTable.token = invalid ruleTable.token = invalid
initTokenByte('*', int('*'))
initTokenByte('/', int('/')) initTokenByte('/', int('/'))
initTokenByte('+', int('+')) initTokenByte('+', int('+'))
initTokenByte('>', int('>')) initTokenByte('>', int('>'))
...@@ -121,6 +140,7 @@ func init() { ...@@ -121,6 +140,7 @@ func init() {
initTokenFunc("@", startWithAt) initTokenFunc("@", startWithAt)
initTokenFunc("/", startWithSlash) initTokenFunc("/", startWithSlash)
initTokenFunc("*", startWithStar)
initTokenFunc("-", startWithDash) initTokenFunc("-", startWithDash)
initTokenFunc("#", startWithSharp) initTokenFunc("#", startWithSharp)
initTokenFunc("Xx", startWithXx) initTokenFunc("Xx", startWithXx)
...@@ -138,9 +158,10 @@ var tokenMap = map[string]int{ ...@@ -138,9 +158,10 @@ var tokenMap = map[string]int{
"ACTION": action, "ACTION": action,
"ADD": add, "ADD": add,
"ADDDATE": addDate, "ADDDATE": addDate,
"ADVISE": advise,
"ADMIN": admin, "ADMIN": admin,
"AFTER": after, "AFTER": after,
"AGG_TO_COP": hintAggToCop, "AGAINST": against,
"ALL": all, "ALL": all,
"ALGORITHM": algorithm, "ALGORITHM": algorithm,
"ALTER": alter, "ALTER": alter,
...@@ -152,6 +173,7 @@ var tokenMap = map[string]int{ ...@@ -152,6 +173,7 @@ var tokenMap = map[string]int{
"ASC": asc, "ASC": asc,
"ASCII": ascii, "ASCII": ascii,
"AUTO_INCREMENT": autoIncrement, "AUTO_INCREMENT": autoIncrement,
"AUTO_RANDOM": autoRandom,
"AVG": avg, "AVG": avg,
"AVG_ROW_LENGTH": avgRowLength, "AVG_ROW_LENGTH": avgRowLength,
"BEGIN": begin, "BEGIN": begin,
...@@ -168,16 +190,19 @@ var tokenMap = map[string]int{ ...@@ -168,16 +190,19 @@ var tokenMap = map[string]int{
"BOOL": boolType, "BOOL": boolType,
"BOOLEAN": booleanType, "BOOLEAN": booleanType,
"BOTH": both, "BOTH": both,
"BOUND": bound,
"BTREE": btree, "BTREE": btree,
"BUCKETS": buckets, "BUCKETS": buckets,
"BUILTINS": builtins, "BUILTINS": builtins,
"BY": by, "BY": by,
"BYTE": byteType, "BYTE": byteType,
"CACHE": cache,
"CANCEL": cancel, "CANCEL": cancel,
"CASCADE": cascade, "CASCADE": cascade,
"CASCADED": cascaded, "CASCADED": cascaded,
"CASE": caseKwd, "CASE": caseKwd,
"CAST": cast, "CAST": cast,
"CAPTURE": capture,
"CHANGE": change, "CHANGE": change,
"CHAR": charType, "CHAR": charType,
"CHARACTER": character, "CHARACTER": character,
...@@ -217,6 +242,7 @@ var tokenMap = map[string]int{ ...@@ -217,6 +242,7 @@ var tokenMap = map[string]int{
"CURRENT_USER": currentUser, "CURRENT_USER": currentUser,
"CURRENT_ROLE": currentRole, "CURRENT_ROLE": currentRole,
"CURTIME": curTime, "CURTIME": curTime,
"CYCLE": cycle,
"DATA": data, "DATA": data,
"DATABASE": database, "DATABASE": database,
"DATABASES": databases, "DATABASES": databases,
...@@ -257,7 +283,6 @@ var tokenMap = map[string]int{ ...@@ -257,7 +283,6 @@ var tokenMap = map[string]int{
"DYNAMIC": dynamic, "DYNAMIC": dynamic,
"ELSE": elseKwd, "ELSE": elseKwd,
"ENABLE": enable, "ENABLE": enable,
"ENABLE_PLAN_CACHE": hintEnablePlanCache,
"ENCLOSED": enclosed, "ENCLOSED": enclosed,
"ENCRYPTION": encryption, "ENCRYPTION": encryption,
"END": end, "END": end,
...@@ -265,25 +290,32 @@ var tokenMap = map[string]int{ ...@@ -265,25 +290,32 @@ var tokenMap = map[string]int{
"ENGINE": engine, "ENGINE": engine,
"ENGINES": engines, "ENGINES": engines,
"ENUM": enum, "ENUM": enum,
"ERROR": errorKwd,
"ESCAPE": escape, "ESCAPE": escape,
"ESCAPED": escaped, "ESCAPED": escaped,
"EVENT": event, "EVENT": event,
"EVENTS": events, "EVENTS": events,
"EVOLVE": evolve,
"EXACT": exact,
"EXCLUSIVE": exclusive, "EXCLUSIVE": exclusive,
"EXCEPT": except, "EXCEPT": except,
"EXCHANGE": exchange, "EXCHANGE": exchange,
"EXECUTE": execute, "EXECUTE": execute,
"EXISTS": exists, "EXISTS": exists,
"EXPANSION": expansion,
"EXPIRE": expire, "EXPIRE": expire,
"EXPLAIN": explain, "EXPLAIN": explain,
"EXTENDED": extended,
"EXTRACT": extract, "EXTRACT": extract,
"FALSE": falseKwd, "FALSE": falseKwd,
"FAULTS": faultsSym, "FAULTS": faultsSym,
"FIELDS": fields, "FIELDS": fields,
"FILE": file,
"FIRST": first, "FIRST": first,
"FIXED": fixed, "FIXED": fixed,
"FLOAT": floatType, "FLOAT": floatType,
"FLUSH": flush, "FLUSH": flush,
"FLASHBACK": flashback,
"FOLLOWING": following, "FOLLOWING": following,
"FOR": forKwd, "FOR": forKwd,
"FORCE": force, "FORCE": force,
...@@ -294,6 +326,7 @@ var tokenMap = map[string]int{ ...@@ -294,6 +326,7 @@ var tokenMap = map[string]int{
"FULLTEXT": fulltext, "FULLTEXT": fulltext,
"FUNCTION": function, "FUNCTION": function,
"GENERATED": generated, "GENERATED": generated,
"GENERAL": general,
"GET_FORMAT": getFormat, "GET_FORMAT": getFormat,
"GLOBAL": global, "GLOBAL": global,
"GRANT": grant, "GRANT": grant,
...@@ -301,11 +334,10 @@ var tokenMap = map[string]int{ ...@@ -301,11 +334,10 @@ var tokenMap = map[string]int{
"GROUP": group, "GROUP": group,
"GROUP_CONCAT": groupConcat, "GROUP_CONCAT": groupConcat,
"HASH": hash, "HASH": hash,
"HASH_AGG": hintHASHAGG,
"HASH_JOIN": hintHJ,
"HAVING": having, "HAVING": having,
"HIGH_PRIORITY": highPriority, "HIGH_PRIORITY": highPriority,
"HISTORY": history, "HISTORY": history,
"HOSTS": hosts,
"HOUR": hour, "HOUR": hour,
"HOUR_MICROSECOND": hourMicrosecond, "HOUR_MICROSECOND": hourMicrosecond,
"HOUR_MINUTE": hourMinute, "HOUR_MINUTE": hourMinute,
...@@ -313,14 +345,13 @@ var tokenMap = map[string]int{ ...@@ -313,14 +345,13 @@ var tokenMap = map[string]int{
"IDENTIFIED": identified, "IDENTIFIED": identified,
"IF": ifKwd, "IF": ifKwd,
"IGNORE": ignore, "IGNORE": ignore,
"IGNORE_INDEX": hintIgnoreIndex,
"IMPORT": importKwd, "IMPORT": importKwd,
"IN": in, "IN": in,
"INCREMENT": increment,
"INCREMENTAL": incremental, "INCREMENTAL": incremental,
"INDEX": index, "INDEX": index,
"INDEXES": indexes, "INDEXES": indexes,
"INFILE": infile, "INFILE": infile,
"INL_JOIN": hintINLJ,
"INNER": inner, "INNER": inner,
"INPLACE": inplace, "INPLACE": inplace,
"INSTANT": instant, "INSTANT": instant,
...@@ -352,6 +383,7 @@ var tokenMap = map[string]int{ ...@@ -352,6 +383,7 @@ var tokenMap = map[string]int{
"KEYS": keys, "KEYS": keys,
"KILL": kill, "KILL": kill,
"LABELS": labels, "LABELS": labels,
"LANGUAGE": language,
"LAST": last, "LAST": last,
"LEADING": leading, "LEADING": leading,
"LEFT": left, "LEFT": left,
...@@ -368,6 +400,7 @@ var tokenMap = map[string]int{ ...@@ -368,6 +400,7 @@ var tokenMap = map[string]int{
"LOCALTIMESTAMP": localTs, "LOCALTIMESTAMP": localTs,
"LOCATION": location, "LOCATION": location,
"LOCK": lock, "LOCK": lock,
"LOGS": logs,
"LONG": long, "LONG": long,
"LONGBLOB": longblobType, "LONGBLOB": longblobType,
"LONGTEXT": longtextType, "LONGTEXT": longtextType,
...@@ -376,7 +409,8 @@ var tokenMap = map[string]int{ ...@@ -376,7 +409,8 @@ var tokenMap = map[string]int{
"MATCH": match, "MATCH": match,
"MAX": max, "MAX": max,
"MAX_CONNECTIONS_PER_HOUR": maxConnectionsPerHour, "MAX_CONNECTIONS_PER_HOUR": maxConnectionsPerHour,
"MAX_EXECUTION_TIME": maxExecutionTime, "MAX_IDXNUM": max_idxnum,
"MAX_MINUTES": max_minutes,
"MAX_QUERIES_PER_HOUR": maxQueriesPerHour, "MAX_QUERIES_PER_HOUR": maxQueriesPerHour,
"MAX_ROWS": maxRows, "MAX_ROWS": maxRows,
"MAX_UPDATES_PER_HOUR": maxUpdatesPerHour, "MAX_UPDATES_PER_HOUR": maxUpdatesPerHour,
...@@ -386,7 +420,6 @@ var tokenMap = map[string]int{ ...@@ -386,7 +420,6 @@ var tokenMap = map[string]int{
"MEDIUMINT": mediumIntType, "MEDIUMINT": mediumIntType,
"MEDIUMTEXT": mediumtextType, "MEDIUMTEXT": mediumtextType,
"MEMORY": memory, "MEMORY": memory,
"MEMORY_QUOTA": hintMemoryQuota,
"MERGE": merge, "MERGE": merge,
"MICROSECOND": microsecond, "MICROSECOND": microsecond,
"MIN": min, "MIN": min,
...@@ -394,6 +427,7 @@ var tokenMap = map[string]int{ ...@@ -394,6 +427,7 @@ var tokenMap = map[string]int{
"MINUTE": minute, "MINUTE": minute,
"MINUTE_MICROSECOND": minuteMicrosecond, "MINUTE_MICROSECOND": minuteMicrosecond,
"MINUTE_SECOND": minuteSecond, "MINUTE_SECOND": minuteSecond,
"MINVALUE": minValue,
"MOD": mod, "MOD": mod,
"MODE": mode, "MODE": mode,
"MODIFY": modify, "MODIFY": modify,
...@@ -404,12 +438,16 @@ var tokenMap = map[string]int{ ...@@ -404,12 +438,16 @@ var tokenMap = map[string]int{
"NEVER": never, "NEVER": never,
"NEXT_ROW_ID": next_row_id, "NEXT_ROW_ID": next_row_id,
"NO": no, "NO": no,
"NO_INDEX_MERGE": hintNoIndexMerge,
"NO_WRITE_TO_BINLOG": noWriteToBinLog, "NO_WRITE_TO_BINLOG": noWriteToBinLog,
"NOCACHE": nocache,
"NOCYCLE": nocycle,
"NODE_ID": nodeID, "NODE_ID": nodeID,
"NODE_STATE": nodeState, "NODE_STATE": nodeState,
"NODEGROUP": nodegroup, "NODEGROUP": nodegroup,
"NOMAXVALUE": nomaxvalue,
"NOMINVALUE": nominvalue,
"NONE": none, "NONE": none,
"NOORDER": noorder,
"NOT": not, "NOT": not,
"NOW": now, "NOW": now,
"NULL": null, "NULL": null,
...@@ -418,8 +456,6 @@ var tokenMap = map[string]int{ ...@@ -418,8 +456,6 @@ var tokenMap = map[string]int{
"NCHAR": ncharType, "NCHAR": ncharType,
"NVARCHAR": nvarcharType, "NVARCHAR": nvarcharType,
"OFFSET": offset, "OFFSET": offset,
"OLAP": hintOLAP,
"OLTP": hintOLTP,
"ON": on, "ON": on,
"ONLY": only, "ONLY": only,
"OPTIMISTIC": optimistic, "OPTIMISTIC": optimistic,
...@@ -438,6 +474,8 @@ var tokenMap = map[string]int{ ...@@ -438,6 +474,8 @@ var tokenMap = map[string]int{
"PARTITIONS": partitions, "PARTITIONS": partitions,
"PASSWORD": password, "PASSWORD": password,
"PESSIMISTIC": pessimistic, "PESSIMISTIC": pessimistic,
"PER_TABLE": per_table,
"PER_DB": per_db,
"PLUGINS": plugins, "PLUGINS": plugins,
"POSITION": position, "POSITION": position,
"PRECEDING": preceding, "PRECEDING": preceding,
...@@ -451,10 +489,8 @@ var tokenMap = map[string]int{ ...@@ -451,10 +489,8 @@ var tokenMap = map[string]int{
"PROFILE": profile, "PROFILE": profile,
"PROFILES": profiles, "PROFILES": profiles,
"PUMP": pump, "PUMP": pump,
"QB_NAME": hintQBName,
"QUARTER": quarter, "QUARTER": quarter,
"QUERY": query, "QUERY": query,
"QUERY_TYPE": hintQueryType,
"QUERIES": queries, "QUERIES": queries,
"QUICK": quick, "QUICK": quick,
"SHARD_ROW_ID_BITS": shardRowIDBits, "SHARD_ROW_ID_BITS": shardRowIDBits,
...@@ -463,8 +499,6 @@ var tokenMap = map[string]int{ ...@@ -463,8 +499,6 @@ var tokenMap = map[string]int{
"RECOVER": recover, "RECOVER": recover,
"REBUILD": rebuild, "REBUILD": rebuild,
"READ": read, "READ": read,
"READ_CONSISTENT_REPLICA": hintReadConsistentReplica,
"READ_FROM_STORAGE": hintReadFromStorage,
"REAL": realType, "REAL": realType,
"RECENT": recent, "RECENT": recent,
"REDUNDANT": redundant, "REDUNDANT": redundant,
...@@ -506,6 +540,7 @@ var tokenMap = map[string]int{ ...@@ -506,6 +540,7 @@ var tokenMap = map[string]int{
"SECOND_MICROSECOND": secondMicrosecond, "SECOND_MICROSECOND": secondMicrosecond,
"SECURITY": security, "SECURITY": security,
"SELECT": selectKwd, "SELECT": selectKwd,
"SEQUENCE": sequence,
"SERIAL": serial, "SERIAL": serial,
"SERIALIZABLE": serializable, "SERIALIZABLE": serializable,
"SESSION": session, "SESSION": session,
...@@ -519,7 +554,6 @@ var tokenMap = map[string]int{ ...@@ -519,7 +554,6 @@ var tokenMap = map[string]int{
"SIMPLE": simple, "SIMPLE": simple,
"SLAVE": slave, "SLAVE": slave,
"SLOW": slow, "SLOW": slow,
"SM_JOIN": hintSMJ,
"SMALLINT": smallIntType, "SMALLINT": smallIntType,
"SNAPSHOT": snapshot, "SNAPSHOT": snapshot,
"SOME": some, "SOME": some,
...@@ -542,6 +576,7 @@ var tokenMap = map[string]int{ ...@@ -542,6 +576,7 @@ var tokenMap = map[string]int{
"SQL_TSI_YEAR": sqlTsiYear, "SQL_TSI_YEAR": sqlTsiYear,
"SOURCE": source, "SOURCE": source,
"SSL": ssl, "SSL": ssl,
"STALENESS": staleness,
"START": start, "START": start,
"STARTING": starting, "STARTING": starting,
"STATS": stats, "STATS": stats,
...@@ -564,7 +599,7 @@ var tokenMap = map[string]int{ ...@@ -564,7 +599,7 @@ var tokenMap = map[string]int{
"STDDEV_SAMP": stddevSamp, "STDDEV_SAMP": stddevSamp,
"STORED": stored, "STORED": stored,
"STRAIGHT_JOIN": straightJoin, "STRAIGHT_JOIN": straightJoin,
"STREAM_AGG": hintSTREAMAGG, "STRONG": strong,
"SUBDATE": subDate, "SUBDATE": subDate,
"SUBJECT": subject, "SUBJECT": subject,
"SUBPARTITION": subpartition, "SUBPARTITION": subpartition,
...@@ -584,11 +619,7 @@ var tokenMap = map[string]int{ ...@@ -584,11 +619,7 @@ var tokenMap = map[string]int{
"THAN": than, "THAN": than,
"THEN": then, "THEN": then,
"TIDB": tidb, "TIDB": tidb,
"TIDB_HJ": hintHJ, "TIFLASH": tiFlash,
"TIDB_INLJ": hintINLJ,
"TIDB_SMJ": hintSMJ,
"TIKV": hintTiKV,
"TIFLASH": hintTiFlash,
"TIME": timeType, "TIME": timeType,
"TIMESTAMP": timestampType, "TIMESTAMP": timestampType,
"TIMESTAMPADD": timestampAdd, "TIMESTAMPADD": timestampAdd,
...@@ -626,13 +657,10 @@ var tokenMap = map[string]int{ ...@@ -626,13 +657,10 @@ var tokenMap = map[string]int{
"UNKNOWN": unknown, "UNKNOWN": unknown,
"UNLOCK": unlock, "UNLOCK": unlock,
"UNSIGNED": unsigned, "UNSIGNED": unsigned,
"UNTIL": until,
"UPDATE": update, "UPDATE": update,
"USAGE": usage, "USAGE": usage,
"USE": use, "USE": use,
"USE_INDEX": hintUseIndex,
"USE_INDEX_MERGE": hintUseIndexMerge,
"USE_PLAN_CACHE": hintUsePlanCache,
"USE_TOJA": hintUseToja,
"USER": user, "USER": user,
"USING": using, "USING": using,
"UTC_DATE": utcDate, "UTC_DATE": utcDate,
...@@ -729,13 +757,94 @@ var windowFuncTokenMap = map[string]int{ ...@@ -729,13 +757,94 @@ var windowFuncTokenMap = map[string]int{
// aliases are strings directly map to another string and use the same token. // aliases are strings directly map to another string and use the same token.
var aliases = map[string]string{ var aliases = map[string]string{
"SCHEMA": "DATABASE", "SCHEMA": "DATABASE",
"SCHEMAS": "DATABASES", "SCHEMAS": "DATABASES",
"DEC": "DECIMAL", "DEC": "DECIMAL",
"SUBSTR": "SUBSTRING", "SUBSTR": "SUBSTRING",
"TIDB_HJ": "HASH_JOIN", }
"TIDB_INLJ": "INL_JOIN",
"TIDB_SMJ": "SM_JOIN", // hintedTokens is a set of tokens which recognizes a hint.
// According to https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html,
// only SELECT, INSERT, REPLACE, UPDATE and DELETE accept optimizer hints.
// additionally we support CREATE and PARTITION for hints at table creation.
var hintedTokens = map[int]struct{}{
selectKwd: {},
insert: {},
replace: {},
update: {},
deleteKwd: {},
create: {},
partition: {},
}
var hintTokenMap = map[string]int{
// MySQL 8.0 hint names
"JOIN_FIXED_ORDER": hintJoinFixedOrder,
"JOIN_ORDER": hintJoinOrder,
"JOIN_PREFIX": hintJoinPrefix,
"JOIN_SUFFIX": hintJoinSuffix,
"BKA": hintBKA,
"NO_BKA": hintNoBKA,
"BNL": hintBNL,
"NO_BNL": hintNoBNL,
"HASH_JOIN": hintHashJoin,
"NO_HASH_JOIN": hintNoHashJoin,
"MERGE": hintMerge,
"NO_MERGE": hintNoMerge,
"INDEX_MERGE": hintIndexMerge,
"NO_INDEX_MERGE": hintNoIndexMerge,
"MRR": hintMRR,
"NO_MRR": hintNoMRR,
"NO_ICP": hintNoICP,
"NO_RANGE_OPTIMIZATION": hintNoRangeOptimization,
"SKIP_SCAN": hintSkipScan,
"NO_SKIP_SCAN": hintNoSkipScan,
"SEMIJOIN": hintSemijoin,
"NO_SEMIJOIN": hintNoSemijoin,
"MAX_EXECUTION_TIME": hintMaxExecutionTime,
"SET_VAR": hintSetVar,
"RESOURCE_GROUP": hintResourceGroup,
"QB_NAME": hintQBName,
// TiDB hint names
"AGG_TO_COP": hintAggToCop,
"ENABLE_PLAN_CACHE": hintEnablePlanCache,
"HASH_AGG": hintHashAgg,
"IGNORE_INDEX": hintIgnoreIndex,
"INL_HASH_JOIN": hintInlHashJoin,
"INL_JOIN": hintInlJoin,
"INL_MERGE_JOIN": hintInlMergeJoin,
"MEMORY_QUOTA": hintMemoryQuota,
"NO_SWAP_JOIN_INPUTS": hintNoSwapJoinInputs,
"QUERY_TYPE": hintQueryType,
"READ_CONSISTENT_REPLICA": hintReadConsistentReplica,
"READ_FROM_STORAGE": hintReadFromStorage,
"SM_JOIN": hintSMJoin,
"STREAM_AGG": hintStreamAgg,
"SWAP_JOIN_INPUTS": hintSwapJoinInputs,
"USE_INDEX_MERGE": hintUseIndexMerge,
"USE_INDEX": hintUseIndex,
"USE_PLAN_CACHE": hintUsePlanCache,
"USE_TOJA": hintUseToja,
// TiDB hint aliases
"TIDB_HJ": hintHashJoin,
"TIDB_INLJ": hintInlJoin,
"TIDB_SMJ": hintSMJoin,
// Other keywords
"OLAP": hintOLAP,
"OLTP": hintOLTP,
"TIKV": hintTiKV,
"TIFLASH": hintTiFlash,
"FALSE": hintFalse,
"TRUE": hintTrue,
"MB": hintMB,
"GB": hintGB,
"DUPSWEEDOUT": hintDupsWeedOut,
"FIRSTMATCH": hintFirstMatch,
"LOOSESCAN": hintLooseScan,
"MATERIALIZATION": hintMaterialization,
} }
func (s *Scanner) isTokenIdentifier(lit string, offset int) int { func (s *Scanner) isTokenIdentifier(lit string, offset int) int {
...@@ -759,7 +868,7 @@ func (s *Scanner) isTokenIdentifier(lit string, offset int) int { ...@@ -759,7 +868,7 @@ func (s *Scanner) isTokenIdentifier(lit string, offset int) int {
} }
} }
checkBtFuncToken, tokenStr := false, string(data) checkBtFuncToken := false
if s.r.peek() == '(' { if s.r.peek() == '(' {
checkBtFuncToken = true checkBtFuncToken = true
} else if s.sqlMode.HasIgnoreSpaceMode() { } else if s.sqlMode.HasIgnoreSpaceMode() {
...@@ -769,7 +878,7 @@ func (s *Scanner) isTokenIdentifier(lit string, offset int) int { ...@@ -769,7 +878,7 @@ func (s *Scanner) isTokenIdentifier(lit string, offset int) int {
} }
} }
if checkBtFuncToken { if checkBtFuncToken {
if tok := btFuncTokenMap[tokenStr]; tok != 0 { if tok := btFuncTokenMap[string(data)]; tok != 0 {
return tok return tok
} }
} }
......
...@@ -61,10 +61,18 @@ const ( ...@@ -61,10 +61,18 @@ const (
ActionRepairTable ActionType = 29 ActionRepairTable ActionType = 29
ActionSetTiFlashReplica ActionType = 30 ActionSetTiFlashReplica ActionType = 30
ActionUpdateTiFlashReplicaStatus ActionType = 31 ActionUpdateTiFlashReplicaStatus ActionType = 31
ActionAddPrimaryKey ActionType = 32
ActionDropPrimaryKey ActionType = 33
ActionCreateSequence ActionType = 34
ActionAlterSequence ActionType = 35
ActionDropSequence ActionType = 36
) )
// AddIndexStr is a string related to the operation of "add index". const (
const AddIndexStr = "add index" // AddIndexStr is a string related to the operation of "add index".
AddIndexStr = "add index"
AddPrimaryKeyStr = "add primary key"
)
var actionMap = map[ActionType]string{ var actionMap = map[ActionType]string{
ActionCreateSchema: "create schema", ActionCreateSchema: "create schema",
...@@ -98,6 +106,11 @@ var actionMap = map[ActionType]string{ ...@@ -98,6 +106,11 @@ var actionMap = map[ActionType]string{
ActionRepairTable: "repair table", ActionRepairTable: "repair table",
ActionSetTiFlashReplica: "set tiflash replica", ActionSetTiFlashReplica: "set tiflash replica",
ActionUpdateTiFlashReplicaStatus: "update tiflash replica status", ActionUpdateTiFlashReplicaStatus: "update tiflash replica status",
ActionAddPrimaryKey: AddPrimaryKeyStr,
ActionDropPrimaryKey: "drop primary key",
ActionCreateSequence: "create sequence",
ActionAlterSequence: "alter sequence",
ActionDropSequence: "drop sequence",
} }
// String return current ddl action in string // String return current ddl action in string
......
...@@ -93,6 +93,8 @@ type ColumnInfo struct { ...@@ -93,6 +93,8 @@ type ColumnInfo struct {
types.FieldType `json:"type"` types.FieldType `json:"type"`
State SchemaState `json:"state"` State SchemaState `json:"state"`
Comment string `json:"comment"` Comment string `json:"comment"`
// A hidden column is used internally(expression index) and are not accessible by users.
Hidden bool `json:"hidden"`
// Version means the version of the column info. // Version means the version of the column info.
// Version = 0: For OriginDefaultValue and DefaultValue of timestamp column will stores the default time in system time zone. // Version = 0: For OriginDefaultValue and DefaultValue of timestamp column will stores the default time in system time zone.
// That is a bug if multiple TiDB servers in different system time zone. // That is a bug if multiple TiDB servers in different system time zone.
...@@ -141,6 +143,18 @@ func (c *ColumnInfo) GetDefaultValue() interface{} { ...@@ -141,6 +143,18 @@ func (c *ColumnInfo) GetDefaultValue() interface{} {
return c.DefaultValue return c.DefaultValue
} }
// GetTypeDesc gets the description for column type.
func (c *ColumnInfo) GetTypeDesc() string {
desc := c.FieldType.CompactStr()
if mysql.HasUnsignedFlag(c.Flag) && c.Tp != mysql.TypeBit && c.Tp != mysql.TypeYear {
desc += " unsigned"
}
if mysql.HasZerofillFlag(c.Flag) && c.Tp != mysql.TypeYear {
desc += " zerofill"
}
return desc
}
// FindColumnInfo finds ColumnInfo in cols by name. // FindColumnInfo finds ColumnInfo in cols by name.
func FindColumnInfo(cols []*ColumnInfo, name string) *ColumnInfo { func FindColumnInfo(cols []*ColumnInfo, name string) *ColumnInfo {
name = strings.ToLower(name) name = strings.ToLower(name)
...@@ -221,6 +235,8 @@ type TableInfo struct { ...@@ -221,6 +235,8 @@ type TableInfo struct {
ShardRowIDBits uint64 ShardRowIDBits uint64
// MaxShardRowIDBits uses to record the max ShardRowIDBits be used so far. // MaxShardRowIDBits uses to record the max ShardRowIDBits be used so far.
MaxShardRowIDBits uint64 `json:"max_shard_row_id_bits"` MaxShardRowIDBits uint64 `json:"max_shard_row_id_bits"`
// AutoRandomBits is used to set the bit number to shard automatically when PKIsHandle.
AutoRandomBits uint64 `json:"auto_random_bits"`
// PreSplitRegions specify the pre-split region when create table. // PreSplitRegions specify the pre-split region when create table.
// The pre-split region num is 2^(PreSplitRegions-1). // The pre-split region num is 2^(PreSplitRegions-1).
// And the PreSplitRegions should less than or equal to ShardRowIDBits. // And the PreSplitRegions should less than or equal to ShardRowIDBits.
...@@ -231,6 +247,9 @@ type TableInfo struct { ...@@ -231,6 +247,9 @@ type TableInfo struct {
Compression string `json:"compression"` Compression string `json:"compression"`
View *ViewInfo `json:"view"` View *ViewInfo `json:"view"`
Sequence *SequenceInfo `json:"sequence"`
// Lock represent the table lock info. // Lock represent the table lock info.
Lock *TableLockInfo `json:"Lock"` Lock *TableLockInfo `json:"Lock"`
...@@ -379,11 +398,9 @@ func (t *TableInfo) Clone() *TableInfo { ...@@ -379,11 +398,9 @@ func (t *TableInfo) Clone() *TableInfo {
// GetPkName will return the pk name if pk exists. // GetPkName will return the pk name if pk exists.
func (t *TableInfo) GetPkName() CIStr { func (t *TableInfo) GetPkName() CIStr {
if t.PKIsHandle { for _, colInfo := range t.Columns {
for _, colInfo := range t.Columns { if mysql.HasPriKeyFlag(colInfo.Flag) {
if mysql.HasPriKeyFlag(colInfo.Flag) { return colInfo.Name
return colInfo.Name
}
} }
} }
return CIStr{} return CIStr{}
...@@ -417,6 +434,19 @@ func (t *TableInfo) IsAutoIncColUnsigned() bool { ...@@ -417,6 +434,19 @@ func (t *TableInfo) IsAutoIncColUnsigned() bool {
return mysql.HasUnsignedFlag(col.Flag) return mysql.HasUnsignedFlag(col.Flag)
} }
// ContainsAutoRandomBits indicates whether a table contains auto_random column.
func (t *TableInfo) ContainsAutoRandomBits() bool {
return t.AutoRandomBits != 0
}
// IsAutoRandomBitColUnsigned indicates whether the auto_random column is unsigned. Make sure the table contains auto_random before calling this method.
func (t *TableInfo) IsAutoRandomBitColUnsigned() bool {
if !t.PKIsHandle || t.AutoRandomBits == 0 {
return false
}
return mysql.HasUnsignedFlag(t.GetPkColInfo().Flag)
}
// Cols returns the columns of the table in public state. // Cols returns the columns of the table in public state.
func (t *TableInfo) Cols() []*ColumnInfo { func (t *TableInfo) Cols() []*ColumnInfo {
publicColumns := make([]*ColumnInfo, len(t.Columns)) publicColumns := make([]*ColumnInfo, len(t.Columns))
...@@ -472,11 +502,16 @@ func (t *TableInfo) ColumnIsInIndex(c *ColumnInfo) bool { ...@@ -472,11 +502,16 @@ func (t *TableInfo) ColumnIsInIndex(c *ColumnInfo) bool {
return false return false
} }
// IsView checks if tableinfo is a view // IsView checks if TableInfo is a view.
func (t *TableInfo) IsView() bool { func (t *TableInfo) IsView() bool {
return t.View != nil return t.View != nil
} }
// IsSequence checks if TableInfo is a sequence.
func (t *TableInfo) IsSequence() bool {
return t.Sequence != nil
}
// ViewAlgorithm is VIEW's SQL AlGORITHM characteristic. // ViewAlgorithm is VIEW's SQL AlGORITHM characteristic.
// See https://dev.mysql.com/doc/refman/5.7/en/view-algorithms.html // See https://dev.mysql.com/doc/refman/5.7/en/view-algorithms.html
type ViewAlgorithm int type ViewAlgorithm int
...@@ -550,6 +585,33 @@ type ViewInfo struct { ...@@ -550,6 +585,33 @@ type ViewInfo struct {
Cols []CIStr `json:"view_cols"` Cols []CIStr `json:"view_cols"`
} }
const (
DefaultSequenceCacheBool = true
DefaultSequenceCycleBool = false
DefaultSequenceOrderBool = false
DefaultSequenceCacheValue = int64(1000)
DefaultSequenceIncrementValue = int64(1)
DefaultPositiveSequenceStartValue = int64(1)
DefaultNegativeSequenceStartValue = int64(-1)
DefaultPositiveSequenceMinValue = int64(1)
DefaultPositiveSequenceMaxValue = int64(9223372036854775806)
DefaultNegativeSequenceMaxValue = int64(-1)
DefaultNegativeSequenceMinValue = int64(-9223372036854775807)
)
// SequenceInfo provide meta data describing a DB sequence.
type SequenceInfo struct {
Start int64 `json:"sequence_start"`
Cache bool `json:"sequence_cache"`
Order bool `json:"sequence_order"`
Cycle bool `json:"sequence_cycle"`
MinValue int64 `json:"sequence_min_value"`
MaxValue int64 `json:"sequence_max_value"`
Increment int64 `json:"sequence_increment"`
CacheValue int64 `json:"sequence_cache_value"`
Comment string `json:"sequence_comment"`
}
// PartitionType is the type for PartitionInfo // PartitionType is the type for PartitionInfo
type PartitionType int type PartitionType int
......
...@@ -168,6 +168,8 @@ const ( ...@@ -168,6 +168,8 @@ const (
const ( const (
// SystemDB is the name of system database. // SystemDB is the name of system database.
SystemDB = "mysql" SystemDB = "mysql"
// GlobalPrivTable is the table in system db contains global scope privilege info.
GlobalPrivTable = "global_priv"
// UserTable is the table in system db contains user info. // UserTable is the table in system db contains user info.
UserTable = "User" UserTable = "User"
// DBTable is the table in system db contains db scope privilege info. // DBTable is the table in system db contains db scope privilege info.
...@@ -242,6 +244,10 @@ const ( ...@@ -242,6 +244,10 @@ const (
// ShutdownPriv the privilege to shutdown a server. // ShutdownPriv the privilege to shutdown a server.
ShutdownPriv ShutdownPriv
// ReloadPriv is the privilege to enable the use of the FLUSH statement.
ReloadPriv
// FilePriv is the privilege to enable the use of LOAD DATA and SELECT ... INTO OUTFILE.
FilePriv
// AllPriv is the privilege for all actions. // AllPriv is the privilege for all actions.
AllPriv AllPriv
...@@ -315,6 +321,8 @@ var Priv2UserCol = map[PrivilegeType]string{ ...@@ -315,6 +321,8 @@ var Priv2UserCol = map[PrivilegeType]string{
AlterRoutinePriv: "Alter_routine_priv", AlterRoutinePriv: "Alter_routine_priv",
EventPriv: "Event_priv", EventPriv: "Event_priv",
ShutdownPriv: "Shutdown_priv", ShutdownPriv: "Shutdown_priv",
ReloadPriv: "Reload_priv",
FilePriv: "File_priv",
} }
// Col2PrivType is the privilege tables column name to privilege type. // Col2PrivType is the privilege tables column name to privilege type.
...@@ -345,6 +353,8 @@ var Col2PrivType = map[string]PrivilegeType{ ...@@ -345,6 +353,8 @@ var Col2PrivType = map[string]PrivilegeType{
"Alter_routine_priv": AlterRoutinePriv, "Alter_routine_priv": AlterRoutinePriv,
"Event_priv": EventPriv, "Event_priv": EventPriv,
"Shutdown_priv": ShutdownPriv, "Shutdown_priv": ShutdownPriv,
"Reload_priv": ReloadPriv,
"File_priv": FilePriv,
} }
// Command2Str is the command information to command name. // Command2Str is the command information to command name.
...@@ -411,6 +421,8 @@ var Priv2Str = map[PrivilegeType]string{ ...@@ -411,6 +421,8 @@ var Priv2Str = map[PrivilegeType]string{
AlterRoutinePriv: "ALTER ROUTINE", AlterRoutinePriv: "ALTER ROUTINE",
EventPriv: "EVENT", EventPriv: "EVENT",
ShutdownPriv: "SHUTDOWN", ShutdownPriv: "SHUTDOWN",
ReloadPriv: "RELOAD",
FilePriv: "FILE",
} }
// Priv2SetStr is the map for privilege to string. // Priv2SetStr is the map for privilege to string.
...@@ -449,7 +461,7 @@ var SetStr2Priv = map[string]PrivilegeType{ ...@@ -449,7 +461,7 @@ var SetStr2Priv = map[string]PrivilegeType{
} }
// AllGlobalPrivs is all the privileges in global scope. // AllGlobalPrivs is all the privileges in global scope.
var AllGlobalPrivs = []PrivilegeType{SelectPriv, InsertPriv, UpdatePriv, DeletePriv, CreatePriv, DropPriv, ProcessPriv, ReferencesPriv, AlterPriv, ShowDBPriv, SuperPriv, ExecutePriv, IndexPriv, CreateUserPriv, TriggerPriv, CreateViewPriv, ShowViewPriv, CreateRolePriv, DropRolePriv, CreateTMPTablePriv, LockTablesPriv, CreateRoutinePriv, AlterRoutinePriv, EventPriv, ShutdownPriv} var AllGlobalPrivs = []PrivilegeType{SelectPriv, InsertPriv, UpdatePriv, DeletePriv, CreatePriv, DropPriv, ProcessPriv, ReferencesPriv, AlterPriv, ShowDBPriv, SuperPriv, ExecutePriv, IndexPriv, CreateUserPriv, TriggerPriv, CreateViewPriv, ShowViewPriv, CreateRolePriv, DropRolePriv, CreateTMPTablePriv, LockTablesPriv, CreateRoutinePriv, AlterRoutinePriv, EventPriv, ShutdownPriv, ReloadPriv, FilePriv}
// AllDBPrivs is all the privileges in database scope. // AllDBPrivs is all the privileges in database scope.
var AllDBPrivs = []PrivilegeType{SelectPriv, InsertPriv, UpdatePriv, DeletePriv, CreatePriv, DropPriv, AlterPriv, ExecutePriv, IndexPriv, CreateViewPriv, ShowViewPriv} var AllDBPrivs = []PrivilegeType{SelectPriv, InsertPriv, UpdatePriv, DeletePriv, CreatePriv, DropPriv, AlterPriv, ExecutePriv, IndexPriv, CreateViewPriv, ShowViewPriv}
......
...@@ -884,6 +884,7 @@ const ( ...@@ -884,6 +884,7 @@ const (
ErrErrorLast = 1863 ErrErrorLast = 1863
ErrMaxExecTimeExceeded = 1907 ErrMaxExecTimeExceeded = 1907
ErrInvalidFieldSize = 3013 ErrInvalidFieldSize = 3013
ErrIncorrectType = 3064
ErrInvalidJSONData = 3069 ErrInvalidJSONData = 3069
ErrGeneratedColumnFunctionIsNotAllowed = 3102 ErrGeneratedColumnFunctionIsNotAllowed = 3102
ErrUnsupportedAlterInplaceOnVirtualColumn = 3103 ErrUnsupportedAlterInplaceOnVirtualColumn = 3103
...@@ -899,8 +900,9 @@ const ( ...@@ -899,8 +900,9 @@ const (
ErrInvalidJSONPathWildcard = 3149 ErrInvalidJSONPathWildcard = 3149
ErrInvalidJSONContainsPathType = 3150 ErrInvalidJSONContainsPathType = 3150
ErrJSONUsedAsKey = 3152 ErrJSONUsedAsKey = 3152
ErrInvalidJSONPathArrayCell = 3165
ErrBadUser = 3162 ErrBadUser = 3162
ErrUserAlreadyExists = 3163
ErrInvalidJSONPathArrayCell = 3165
ErrInvalidEncryptionOption = 3184 ErrInvalidEncryptionOption = 3184
ErrRoleNotGranted = 3530 ErrRoleNotGranted = 3530
ErrLockAcquireFailAndNoWaitSet = 3572 ErrLockAcquireFailAndNoWaitSet = 3572
...@@ -925,28 +927,144 @@ const ( ...@@ -925,28 +927,144 @@ const (
ErrWindowNoGroupOrderUnused = 3597 ErrWindowNoGroupOrderUnused = 3597
ErrWindowExplainJson = 3598 ErrWindowExplainJson = 3598
ErrWindowFunctionIgnoresFrame = 3599 ErrWindowFunctionIgnoresFrame = 3599
ErrDataTruncatedFunctionalIndex = 3751
ErrDataOutOfRangeFunctionalIndex = 3752
ErrFunctionalIndexOnJsonOrGeometryFunction = 3753
ErrFunctionalIndexRefAutoIncrement = 3754
ErrCannotDropColumnFunctionalIndex = 3755
ErrFunctionalIndexPrimaryKey = 3756
ErrFunctionalIndexOnLob = 3757
ErrFunctionalIndexFunctionIsNotAllowed = 3758
ErrFulltextFunctionalIndex = 3759
ErrSpatialFunctionalIndex = 3760
ErrWrongKeyColumnFunctionalIndex = 3761
ErrFunctionalIndexOnField = 3762
ErrFKIncompatibleColumns = 3780
ErrFunctionalIndexRowValueIsNotAllowed = 3800
ErrDependentByFunctionalIndex = 3837
ErrInvalidJsonValueForFuncIndex = 3903
ErrJsonValueOutOfRangeForFuncIndex = 3904
ErrFunctionalIndexDataIsTooLong = 3907
ErrFunctionalIndexNotApplicable = 3909
// MariaDB errors. // MariaDB errors.
ErrOnlyOneDefaultPartionAllowed = 4030 ErrOnlyOneDefaultPartionAllowed = 4030
ErrWrongPartitionTypeExpectedSystemTime = 4113 ErrWrongPartitionTypeExpectedSystemTime = 4113
ErrSystemVersioningWrongPartitions = 4128 ErrSystemVersioningWrongPartitions = 4128
ErrSequenceRunOut = 4135
ErrSequenceInvalidData = 4136
ErrSequenceAccessFail = 4137
ErrNotSequence = 4138
ErrUnknownSequence = 4139
ErrWrongInsertIntoSequence = 4140
ErrSequenceInvalidTableStructure = 4141
// TiDB self-defined errors. // TiDB self-defined errors.
ErrMemExceedThreshold = 8001 ErrMemExceedThreshold = 8001
ErrForUpdateCantRetry = 8002 ErrForUpdateCantRetry = 8002
ErrAdminCheckTable = 8003 ErrAdminCheckTable = 8003
ErrTxnTooLarge = 8004 ErrTxnTooLarge = 8004
ErrWriteConflictInTiDB = 8005 ErrWriteConflictInTiDB = 8005
ErrInvalidPluginID = 8101 ErrInvalidPluginID = 8101
ErrInvalidPluginManifest = 8102 ErrInvalidPluginManifest = 8102
ErrInvalidPluginName = 8103 ErrInvalidPluginName = 8103
ErrInvalidPluginVersion = 8104 ErrInvalidPluginVersion = 8104
ErrDuplicatePlugin = 8105 ErrDuplicatePlugin = 8105
ErrInvalidPluginSysVarName = 8106 ErrInvalidPluginSysVarName = 8106
ErrRequireVersionCheckFail = 8107 ErrRequireVersionCheckFail = 8107
ErrUnsupportedReloadPlugin = 8018 ErrUnsupportedType = 8108
ErrUnsupportedReloadPluginVar = 8019 ErrAnalyzeMissIndex = 8109
ErrTableLocked = 8020 ErrCartesianProductUnsupported = 8110
ErrPreparedStmtNotFound = 8111
ErrWrongParamCount = 8112
ErrSchemaChanged = 8113
ErrUnknownPlan = 8114
ErrPrepareMulti = 8115
ErrPrepareDDL = 8116
ErrResultIsEmpty = 8117
ErrBuildExecutor = 8118
ErrBatchInsertFail = 8119
ErrGetStartTS = 8120
ErrPrivilegeCheckFail = 8121
ErrInvalidWildCard = 8122
ErrMixOfGroupFuncAndFieldsIncompatible = 8123
ErrUnsupportedReloadPlugin = 8018
ErrUnsupportedReloadPluginVar = 8019
ErrTableLocked = 8020
ErrNotExist = 8021
ErrTxnRetryable = 8022
ErrCannotSetNilValue = 8023
ErrInvalidTxn = 8024
ErrEntryTooLarge = 8025
ErrNotImplemented = 8026
ErrInfoSchemaExpired = 8027
ErrInfoSchemaChanged = 8028
ErrBadNumber = 8029
ErrCastAsSignedOverflow = 8030
ErrCastNegIntAsUnsigned = 8031
ErrInvalidYearFormat = 8032
ErrInvalidYear = 8033
ErrIncorrectDatetimeValue = 8034
ErrInvalidTimeFormat = 8036
ErrInvalidWeekModeFormat = 8037
ErrFieldGetDefaultFailed = 8038
ErrIndexOutBound = 8039
ErrUnsupportedOp = 8040
ErrRowNotFound = 8041
ErrTableStateCantNone = 8042
ErrColumnStateNonPublic = 8043
ErrIndexStateCantNone = 8044
ErrInvalidRecordKey = 8045
ErrColumnStateCantNone = 8046
ErrUnsupportedValueForVar = 8047
ErrUnsupportedIsolationLevel = 8048
ErrLoadPrivilege = 8049
ErrInvalidPrivilegeType = 8050
ErrUnknownFieldType = 8051
ErrInvalidSequence = 8052
ErrCantGetValidID = 8053
ErrCantSetToNull = 8054
ErrSnapshotTooOld = 8055
ErrInvalidTableID = 8056
ErrInvalidType = 8057
ErrUnknownAllocatorType = 8058
ErrAutoRandReadFailed = 8059
ErrInvalidIncrementAndOffset = 8060
ErrWarnOptimizerHintUnsupportedHint = 8061
ErrWarnOptimizerHintInvalidToken = 8062
ErrWarnMemoryQuotaOverflow = 8063
ErrWarnOptimizerHintParseError = 8064
ErrWarnOptimizerHintInvalidInteger = 8065
// Error codes used by TiDB ddl package
ErrUnsupportedDDLOperation = 8200
ErrNotOwner = 8201
ErrCantDecodeIndex = 8202
ErrInvalidDDLWorker = 8203
ErrInvalidDDLJob = 8204
ErrInvalidDDLJobFlag = 8205
ErrWaitReorgTimeout = 8206
ErrInvalidStoreVersion = 8207
ErrUnknownTypeLength = 8208
ErrUnknownFractionLength = 8209
ErrInvalidDDLState = 8210
ErrReorgPanic = 8211
ErrInvalidSplitRegionRanges = 8212
ErrInvalidDDLJobVersion = 8213
ErrCancelledDDLJob = 8214
ErrRepairTable = 8215
ErrInvalidAutoRandom = 8216
ErrInvalidHashKeyFlag = 8217
ErrInvalidListIndex = 8218
ErrInvalidListMetaData = 8219
ErrWriteOnSnapshot = 8220
ErrInvalidKey = 8221
ErrInvalidIndexKey = 8222
ErrDataInConsistent = 8223
ErrDDLJobNotFound = 8224
ErrCancelFinishedDDLJob = 8225
ErrCannotCancelDDLJob = 8226
ErrSequenceUnsupportedTableOption = 8227
// TiKV/PD errors. // TiKV/PD errors.
ErrPDServerTimeout = 9001 ErrPDServerTimeout = 9001
...@@ -956,4 +1074,5 @@ const ( ...@@ -956,4 +1074,5 @@ const (
ErrRegionUnavailable = 9005 ErrRegionUnavailable = 9005
ErrGCTooEarly = 9006 ErrGCTooEarly = 9006
ErrWriteConflict = 9007 ErrWriteConflict = 9007
ErrTiKVStoreLimit = 9008
) )
...@@ -77,7 +77,7 @@ var MySQLErrName = map[uint16]string{ ...@@ -77,7 +77,7 @@ var MySQLErrName = map[uint16]string{
ErrTooLongIdent: "Identifier name '%-.100s' is too long", ErrTooLongIdent: "Identifier name '%-.100s' is too long",
ErrDupFieldName: "Duplicate column name '%-.192s'", ErrDupFieldName: "Duplicate column name '%-.192s'",
ErrDupKeyName: "Duplicate key name '%-.192s'", ErrDupKeyName: "Duplicate key name '%-.192s'",
ErrDupEntry: "Duplicate entry '%-.192s' for key %d", ErrDupEntry: "Duplicate entry '%-.64s' for key '%-.192s'",
ErrWrongFieldSpec: "Incorrect column specifier for column '%-.192s'", ErrWrongFieldSpec: "Incorrect column specifier for column '%-.192s'",
ErrParse: "%s %s", ErrParse: "%s %s",
ErrEmptyQuery: "Query was empty", ErrEmptyQuery: "Query was empty",
...@@ -265,7 +265,7 @@ var MySQLErrName = map[uint16]string{ ...@@ -265,7 +265,7 @@ var MySQLErrName = map[uint16]string{
ErrIllegalReference: "Reference '%-.64s' not supported (%s)", ErrIllegalReference: "Reference '%-.64s' not supported (%s)",
ErrDerivedMustHaveAlias: "Every derived table must have its own alias", ErrDerivedMustHaveAlias: "Every derived table must have its own alias",
ErrSelectReduced: "Select %d was reduced during optimization", ErrSelectReduced: "Select %d was reduced during optimization",
ErrTablenameNotAllowedHere: "Table '%-.192s' from one of the SELECTs cannot be used in %-.32s", ErrTablenameNotAllowedHere: "Table '%s' from one of the %ss cannot be used in %s",
ErrNotSupportedAuthMode: "Client does not support authentication protocol requested by server; consider upgrading MySQL client", ErrNotSupportedAuthMode: "Client does not support authentication protocol requested by server; consider upgrading MySQL client",
ErrSpatialCantHaveNull: "All parts of a SPATIAL index must be NOT NULL", ErrSpatialCantHaveNull: "All parts of a SPATIAL index must be NOT NULL",
ErrCollationCharsetMismatch: "COLLATION '%s' is not valid for CHARACTER SET '%s'", ErrCollationCharsetMismatch: "COLLATION '%s' is not valid for CHARACTER SET '%s'",
...@@ -888,6 +888,7 @@ var MySQLErrName = map[uint16]string{ ...@@ -888,6 +888,7 @@ var MySQLErrName = map[uint16]string{
ErrDependentByGeneratedColumn: "Column '%s' has a generated column dependency.", ErrDependentByGeneratedColumn: "Column '%s' has a generated column dependency.",
ErrGeneratedColumnRefAutoInc: "Generated column '%s' cannot refer to auto-increment column.", ErrGeneratedColumnRefAutoInc: "Generated column '%s' cannot refer to auto-increment column.",
ErrInvalidFieldSize: "Invalid size for column '%s'.", ErrInvalidFieldSize: "Invalid size for column '%s'.",
ErrIncorrectType: "Incorrect type for argument %s in function %s.",
ErrInvalidJSONData: "Invalid JSON data provided to function %s: %s", ErrInvalidJSONData: "Invalid JSON data provided to function %s: %s",
ErrInvalidJSONText: "Invalid JSON text: %-.192s", ErrInvalidJSONText: "Invalid JSON text: %-.192s",
ErrInvalidJSONPath: "Invalid JSON path expression %s.", ErrInvalidJSONPath: "Invalid JSON path expression %s.",
...@@ -895,6 +896,8 @@ var MySQLErrName = map[uint16]string{ ...@@ -895,6 +896,8 @@ var MySQLErrName = map[uint16]string{
ErrInvalidJSONPathWildcard: "In this situation, path expressions may not contain the * and ** tokens.", ErrInvalidJSONPathWildcard: "In this situation, path expressions may not contain the * and ** tokens.",
ErrInvalidJSONContainsPathType: "The second argument can only be either 'one' or 'all'.", ErrInvalidJSONContainsPathType: "The second argument can only be either 'one' or 'all'.",
ErrJSONUsedAsKey: "JSON column '%-.192s' cannot be used in key specification.", ErrJSONUsedAsKey: "JSON column '%-.192s' cannot be used in key specification.",
ErrBadUser: "User %s does not exist.",
ErrUserAlreadyExists: "User %s already exists.",
ErrInvalidJSONPathArrayCell: "A path expression is not a path to a cell in an array.", ErrInvalidJSONPathArrayCell: "A path expression is not a path to a cell in an array.",
ErrInvalidEncryptionOption: "Invalid encryption option.", ErrInvalidEncryptionOption: "Invalid encryption option.",
ErrWindowNoSuchWindow: "Window name '%s' is not defined.", ErrWindowNoSuchWindow: "Window name '%s' is not defined.",
...@@ -921,17 +924,43 @@ var MySQLErrName = map[uint16]string{ ...@@ -921,17 +924,43 @@ var MySQLErrName = map[uint16]string{
ErrRoleNotGranted: "%s is is not granted to %s", ErrRoleNotGranted: "%s is is not granted to %s",
ErrMaxExecTimeExceeded: "Query execution was interrupted, max_execution_time exceeded.", ErrMaxExecTimeExceeded: "Query execution was interrupted, max_execution_time exceeded.",
ErrLockAcquireFailAndNoWaitSet: "Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set.", ErrLockAcquireFailAndNoWaitSet: "Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set.",
ErrDataTruncatedFunctionalIndex: "Data truncated for functional index '%s' at row %d",
ErrDataOutOfRangeFunctionalIndex: "Value is out of range for functional index '%s' at row %d",
ErrFunctionalIndexOnJsonOrGeometryFunction: "Cannot create a functional index on a function that returns a JSON or GEOMETRY value",
ErrFunctionalIndexRefAutoIncrement: "Functional index '%s' cannot refer to an auto-increment column",
ErrCannotDropColumnFunctionalIndex: "Cannot drop column '%s' because it is used by a functional index. In order to drop the column, you must remove the functional index",
ErrFunctionalIndexPrimaryKey: "The primary key cannot be a functional index",
ErrFunctionalIndexOnLob: "Cannot create a functional index on an expression that returns a BLOB or TEXT. Please consider using CAST",
ErrFunctionalIndexFunctionIsNotAllowed: "Expression of functional index '%s' contains a disallowed function",
ErrFulltextFunctionalIndex: "Fulltext functional index is not supported",
ErrSpatialFunctionalIndex: "Spatial functional index is not supported",
ErrWrongKeyColumnFunctionalIndex: "The used storage engine cannot index the expression '%s'",
ErrFunctionalIndexOnField: "Functional index on a column is not supported. Consider using a regular index instead",
ErrFKIncompatibleColumns: "Referencing column '%s' in foreign key constraint '%s' are incompatible",
ErrFunctionalIndexRowValueIsNotAllowed: "Expression of functional index '%s' cannot refer to a row value",
ErrDependentByFunctionalIndex: "Column '%s' has a functional index dependency and cannot be dropped or renamed",
ErrInvalidJsonValueForFuncIndex: "Invalid JSON value for CAST for functional index '%s'",
ErrJsonValueOutOfRangeForFuncIndex: "Out of range JSON value for CAST for functional index '%s'",
ErrFunctionalIndexDataIsTooLong: "Data too long for functional index '%s'",
ErrFunctionalIndexNotApplicable: "Cannot use functional index '%s' due to type or collation conversion",
// MariaDB errors. // MariaDB errors.
ErrOnlyOneDefaultPartionAllowed: "Only one DEFAULT partition allowed", ErrOnlyOneDefaultPartionAllowed: "Only one DEFAULT partition allowed",
ErrWrongPartitionTypeExpectedSystemTime: "Wrong partitioning type, expected type: `SYSTEM_TIME`", ErrWrongPartitionTypeExpectedSystemTime: "Wrong partitioning type, expected type: `SYSTEM_TIME`",
ErrSystemVersioningWrongPartitions: "Wrong Partitions: must have at least one HISTORY and exactly one last CURRENT", ErrSystemVersioningWrongPartitions: "Wrong Partitions: must have at least one HISTORY and exactly one last CURRENT",
ErrSequenceRunOut: "Sequence '%-.64s.%-.64s' has run out",
ErrSequenceInvalidData: "Sequence '%-.64s.%-.64s' values are conflicting",
ErrSequenceAccessFail: "Sequence '%-.64s.%-.64s' access error",
ErrNotSequence: "'%-.64s.%-.64s' is not a SEQUENCE",
ErrUnknownSequence: "Unknown SEQUENCE: '%-.300s'",
ErrWrongInsertIntoSequence: "Wrong INSERT into a SEQUENCE. One can only do single table INSERT into a sequence object (like with mysqldump). If you want to change the SEQUENCE, use ALTER SEQUENCE instead.",
ErrSequenceInvalidTableStructure: "Sequence '%-.64s.%-.64s' table structure is invalid (%s)",
// TiDB errors. // TiDB errors.
ErrMemExceedThreshold: "%s holds %dB memory, exceeds threshold %dB.%s", ErrMemExceedThreshold: "%s holds %dB memory, exceeds threshold %dB.%s",
ErrForUpdateCantRetry: "[%d] can not retry select for update statement", ErrForUpdateCantRetry: "[%d] can not retry select for update statement",
ErrAdminCheckTable: "TiDB admin check table failed.", ErrAdminCheckTable: "TiDB admin check table failed.",
ErrTxnTooLarge: "Transaction is too large", ErrTxnTooLarge: "Transaction is too large, size: %d",
ErrWriteConflictInTiDB: "Write conflict, txnStartTS %d is stale", ErrWriteConflictInTiDB: "Write conflict, txnStartTS %d is stale",
ErrInvalidPluginID: "Wrong plugin id: %s, valid plugin id is [name]-[version], both name and version should not contain '-'", ErrInvalidPluginID: "Wrong plugin id: %s, valid plugin id is [name]-[version], both name and version should not contain '-'",
ErrInvalidPluginManifest: "Cannot read plugin %s's manifest", ErrInvalidPluginManifest: "Cannot read plugin %s's manifest",
...@@ -943,6 +972,96 @@ var MySQLErrName = map[uint16]string{ ...@@ -943,6 +972,96 @@ var MySQLErrName = map[uint16]string{
ErrUnsupportedReloadPlugin: "Plugin %s isn't loaded so cannot be reloaded", ErrUnsupportedReloadPlugin: "Plugin %s isn't loaded so cannot be reloaded",
ErrUnsupportedReloadPluginVar: "Reload plugin with different sysVar is unsupported %v", ErrUnsupportedReloadPluginVar: "Reload plugin with different sysVar is unsupported %v",
ErrTableLocked: "Table '%s' was locked in %s by %v", ErrTableLocked: "Table '%s' was locked in %s by %v",
ErrNotExist: "Error: key not exist",
ErrTxnRetryable: "Error: KV error safe to retry %s ",
ErrCannotSetNilValue: "can not set nil value",
ErrInvalidTxn: "invalid transaction",
ErrEntryTooLarge: "entry too large, the max entry size is %d, the size of data is %d",
ErrNotImplemented: "not implemented",
ErrInfoSchemaExpired: "Information schema is out of date: schema failed to update in 1 lease, please make sure TiDB can connect to TiKV",
ErrInfoSchemaChanged: "Information schema is changed during the execution of the statement(for example, table definition may be updated by other DDL ran in parallel). If you see this error often, try increasing `tidb_max_delta_schema_count`",
ErrBadNumber: "Bad Number",
ErrCastAsSignedOverflow: "Cast to signed converted positive out-of-range integer to it's negative complement",
ErrCastNegIntAsUnsigned: "Cast to unsigned converted negative integer to it's positive complement",
ErrInvalidYearFormat: "invalid year format",
ErrInvalidYear: "invalid year",
ErrIncorrectDatetimeValue: "Incorrect datetime value: '%s'",
ErrInvalidTimeFormat: "invalid time format: '%v'",
ErrInvalidWeekModeFormat: "invalid week mode format: '%v'",
ErrFieldGetDefaultFailed: "Field '%s' get default value fail",
ErrIndexOutBound: "Index column %s offset out of bound, offset: %d, row: %v",
ErrUnsupportedOp: "operation not supported",
ErrRowNotFound: "can not find the row: %s",
ErrTableStateCantNone: "table %s can't be in none state",
ErrColumnStateCantNone: "column %s can't be in none state",
ErrColumnStateNonPublic: "can not use non-public column",
ErrIndexStateCantNone: "index %s can't be in none state",
ErrInvalidRecordKey: "invalid record key",
ErrUnsupportedValueForVar: "variable '%s' does not yet support value: %s",
ErrUnsupportedIsolationLevel: "The isolation level '%s' is not supported. Set tidb_skip_isolation_level_check=1 to skip this error",
ErrInvalidDDLWorker: "Invalid DDL worker",
ErrUnsupportedDDLOperation: "Unsupported %s",
ErrNotOwner: "TiDB server is not a DDL owner",
ErrCantDecodeIndex: "Cannot decode index value, because %s",
ErrInvalidDDLJob: "Invalid DDL job",
ErrInvalidDDLJobFlag: "Invalid DDL job flag",
ErrWaitReorgTimeout: "Timeout waiting for data reorganization",
ErrInvalidStoreVersion: "Invalid storage current version: %d",
ErrUnknownTypeLength: "Unknown length for type %d",
ErrUnknownFractionLength: "Unknown length for type %d and fraction %d",
ErrInvalidDDLJobVersion: "Version %d of DDL job is greater than current one: %d",
ErrInvalidSplitRegionRanges: "Failed to split region ranges",
ErrReorgPanic: "Reorg worker panic",
ErrInvalidDDLState: "Invalid %s state: %v",
ErrCancelledDDLJob: "Cancelled DDL job",
ErrRepairTable: "Failed to repair table: %s",
ErrLoadPrivilege: "Load privilege table fail: %s",
ErrInvalidPrivilegeType: "unknown privilege type %s",
ErrUnknownFieldType: "unknown field type",
ErrInvalidSequence: "invalid sequence",
ErrInvalidType: "invalid type",
ErrCantGetValidID: "cannot get valid auto-increment id in retry",
ErrCantSetToNull: "cannot set variable to null",
ErrSnapshotTooOld: "snapshot is older than GC safe point %s",
ErrInvalidTableID: "invalid TableID",
ErrInvalidAutoRandom: "Invalid auto random: %s",
ErrInvalidHashKeyFlag: "invalid encoded hash key flag",
ErrInvalidListIndex: "invalid list index",
ErrInvalidListMetaData: "invalid list meta data",
ErrWriteOnSnapshot: "write on snapshot",
ErrInvalidKey: "invalid key",
ErrInvalidIndexKey: "invalid index key",
ErrDataInConsistent: "data isn't equal",
ErrDDLJobNotFound: "DDL Job:%v not found",
ErrCancelFinishedDDLJob: "This job:%v is finished, so can't be cancelled",
ErrCannotCancelDDLJob: "This job:%v is almost finished, can't be cancelled now",
ErrUnknownAllocatorType: "Invalid allocator type",
ErrAutoRandReadFailed: "Failed to read auto-random value from storage engine",
ErrInvalidIncrementAndOffset: "Invalid auto_increment settings: auto_increment_increment: %d, auto_increment_offset: %d, both of them must be in range [1..65535]",
ErrWarnOptimizerHintInvalidInteger: "integer value is out of range in '%s'",
ErrWarnOptimizerHintUnsupportedHint: "Optimizer hint %s is not supported by TiDB and is ignored",
ErrWarnOptimizerHintInvalidToken: "Cannot use %s '%s' (tok = %d) in an optimizer hint",
ErrWarnMemoryQuotaOverflow: "Max value of MEMORY_QUOTA is %d bytes, ignore this invalid limit",
ErrWarnOptimizerHintParseError: "Optimizer hint syntax error at %v",
ErrSequenceUnsupportedTableOption: "Unsupported sequence table-option %s",
ErrUnsupportedType: "Unsupported type %T",
ErrAnalyzeMissIndex: "Index '%s' in field list does not exist in table '%s'",
ErrCartesianProductUnsupported: "Cartesian product is unsupported",
ErrPreparedStmtNotFound: "Prepared statement not found",
ErrWrongParamCount: "Wrong parameter count",
ErrSchemaChanged: "Schema has changed",
ErrUnknownPlan: "Unknown plan",
ErrPrepareMulti: "Can not prepare multiple statements",
ErrPrepareDDL: "Can not prepare DDL statements with parameters",
ErrResultIsEmpty: "Result is empty",
ErrBuildExecutor: "Failed to build executor",
ErrBatchInsertFail: "Batch insert failed, please clean the table and try again.",
ErrGetStartTS: "Can not get start ts",
ErrPrivilegeCheckFail: "privilege check fail", // this error message should begin lowercased to be compatible with the test
ErrInvalidWildCard: "Wildcard fields without any table name appears in wrong place",
ErrMixOfGroupFuncAndFieldsIncompatible: "In aggregated query without GROUP BY, expression #%d of SELECT list contains nonaggregated column '%s'; this is incompatible with sql_mode=only_full_group_by",
// TiKV/PD errors. // TiKV/PD errors.
ErrPDServerTimeout: "PD server timeout", ErrPDServerTimeout: "PD server timeout",
...@@ -952,4 +1071,5 @@ var MySQLErrName = map[uint16]string{ ...@@ -952,4 +1071,5 @@ var MySQLErrName = map[uint16]string{
ErrRegionUnavailable: "Region is unavailable", ErrRegionUnavailable: "Region is unavailable",
ErrGCTooEarly: "GC life time is shorter than transaction duration, transaction starts at %v, GC safe point is %v", ErrGCTooEarly: "GC life time is shorter than transaction duration, transaction starts at %v, GC safe point is %v",
ErrWriteConflict: "Write conflict, txnStartTS=%d, conflictStartTS=%d, conflictCommitTS=%d, key=%s", ErrWriteConflict: "Write conflict, txnStartTS=%d, conflictStartTS=%d, conflictCommitTS=%d, key=%s",
ErrTiKVStoreLimit: "Store token is up to the limit, store id = %d",
} }
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
...@@ -19,8 +19,9 @@ import ( ...@@ -19,8 +19,9 @@ import (
"strconv" "strconv"
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/log"
"github.com/pingcap/parser/mysql" "github.com/pingcap/parser/mysql"
log "github.com/sirupsen/logrus" "go.uber.org/zap"
) )
// Global error instances. // Global error instances.
...@@ -83,6 +84,7 @@ const ( ...@@ -83,6 +84,7 @@ const (
ClassTiKV ClassTiKV
ClassSession ClassSession
ClassPlugin ClassPlugin
ClassUtil
// Add more as needed. // Add more as needed.
) )
...@@ -111,6 +113,7 @@ var errClz2Str = map[ErrClass]string{ ...@@ -111,6 +113,7 @@ var errClz2Str = map[ErrClass]string{
ClassTiKV: "tikv", ClassTiKV: "tikv",
ClassSession: "session", ClassSession: "session",
ClassPlugin: "plugin", ClassPlugin: "plugin",
ClassUtil: "util",
} }
// String implements fmt.Stringer interface. // String implements fmt.Stringer interface.
...@@ -285,12 +288,12 @@ var defaultMySQLErrorCode uint16 ...@@ -285,12 +288,12 @@ var defaultMySQLErrorCode uint16
func (e *Error) getMySQLErrorCode() uint16 { func (e *Error) getMySQLErrorCode() uint16 {
codeMap, ok := ErrClassToMySQLCodes[e.class] codeMap, ok := ErrClassToMySQLCodes[e.class]
if !ok { if !ok {
log.Warnf("Unknown error class: %v", e.class) log.Warn("Unknown error class", zap.Int("class", int(e.class)))
return defaultMySQLErrorCode return defaultMySQLErrorCode
} }
code, ok := codeMap[e.code] code, ok := codeMap[e.code]
if !ok { if !ok {
log.Debugf("Unknown error class: %v code: %v", e.class, e.code) log.Debug("Unknown error code", zap.Int("class", int(e.class)), zap.Uint16("code", code))
return defaultMySQLErrorCode return defaultMySQLErrorCode
} }
return code return code
...@@ -339,7 +342,7 @@ func MustNil(err error, closeFuns ...func()) { ...@@ -339,7 +342,7 @@ func MustNil(err error, closeFuns ...func()) {
for _, f := range closeFuns { for _, f := range closeFuns {
f() f()
} }
log.Fatalf(errors.ErrorStack(err)) log.Fatal("unexpected error", zap.Error(err))
} }
} }
...@@ -347,13 +350,13 @@ func MustNil(err error, closeFuns ...func()) { ...@@ -347,13 +350,13 @@ func MustNil(err error, closeFuns ...func()) {
func Call(fn func() error) { func Call(fn func() error) {
err := fn() err := fn()
if err != nil { if err != nil {
log.Error(errors.ErrorStack(err)) log.Error("function call errored", zap.Error(err))
} }
} }
// Log logs the error if it is not nil. // Log logs the error if it is not nil.
func Log(err error) { func Log(err error) {
if err != nil { if err != nil {
log.Error(errors.ErrorStack(err)) log.Error("encountered error", zap.Error(err))
} }
} }
{ GO111MODULE=on go test -p 1 -race -covermode=atomic -coverprofile=coverage.txt -coverpkg=./... ./...
mv go.mod1 go.mod
mv go.sum1 go.sum
GO111MODULE=on go test -p 1 -race -covermode=atomic -coverprofile=coverage.txt -coverpkg=./... ./...
} || {
mv go.mod go.mod1
mv go.sum go.sum1
}
mv go.mod go.mod1
mv go.sum go.sum1
...@@ -104,9 +104,5 @@ const ( ...@@ -104,9 +104,5 @@ const (
wordSize = 4 // A word is 4 bytes int32. wordSize = 4 // A word is 4 bytes int32.
) )
const (
codeInvalidDefault = terror.ErrCode(mysql.ErrInvalidDefault)
)
// ErrInvalidDefault is returned when meet a invalid default value. // ErrInvalidDefault is returned when meet a invalid default value.
var ErrInvalidDefault = terror.ClassTypes.New(codeInvalidDefault, "Invalid default value for '%s'") var ErrInvalidDefault = terror.ClassTypes.New(mysql.ErrInvalidDefault, mysql.MySQLErrName[mysql.ErrInvalidDefault])
...@@ -26,59 +26,50 @@ import ( ...@@ -26,59 +26,50 @@ import (
"github.com/pingcap/parser/terror" "github.com/pingcap/parser/terror"
) )
const (
codeErrParse = terror.ErrCode(mysql.ErrParse)
codeErrSyntax = terror.ErrCode(mysql.ErrSyntax)
codeErrUnknownCharacterSet = terror.ErrCode(mysql.ErrUnknownCharacterSet)
codeErrInvalidYearColumnLength = terror.ErrCode(mysql.ErrInvalidYearColumnLength)
codeWrongArgument = terror.ErrCode(mysql.ErrWrongArguments)
codeWrongFieldTerminators = terror.ErrCode(mysql.ErrWrongFieldTerminators)
codeTooBigDisplayWidth = terror.ErrCode(mysql.ErrTooBigDisplaywidth)
codeErrUnknownAlterLock = terror.ErrCode(mysql.ErrUnknownAlterLock)
codeErrUnknownAlterAlgorithm = terror.ErrCode(mysql.ErrUnknownAlterAlgorithm)
codeErrTooBigPrecision = terror.ErrCode(mysql.ErrTooBigPrecision)
)
var ( var (
// ErrSyntax returns for sql syntax error. // ErrSyntax returns for sql syntax error.
ErrSyntax = terror.ClassParser.New(codeErrSyntax, mysql.MySQLErrName[mysql.ErrSyntax]) ErrSyntax = terror.ClassParser.New(mysql.ErrSyntax, mysql.MySQLErrName[mysql.ErrSyntax])
// ErrParse returns for sql parse error. // ErrParse returns for sql parse error.
ErrParse = terror.ClassParser.New(codeErrParse, mysql.MySQLErrName[mysql.ErrParse]) ErrParse = terror.ClassParser.New(mysql.ErrParse, mysql.MySQLErrName[mysql.ErrParse])
// ErrUnknownCharacterSet returns for no character set found error. // ErrUnknownCharacterSet returns for no character set found error.
ErrUnknownCharacterSet = terror.ClassParser.New(codeErrUnknownCharacterSet, mysql.MySQLErrName[mysql.ErrUnknownCharacterSet]) ErrUnknownCharacterSet = terror.ClassParser.New(mysql.ErrUnknownCharacterSet, mysql.MySQLErrName[mysql.ErrUnknownCharacterSet])
// ErrInvalidYearColumnLength returns for illegal column length for year type. // ErrInvalidYearColumnLength returns for illegal column length for year type.
ErrInvalidYearColumnLength = terror.ClassParser.New(codeErrInvalidYearColumnLength, mysql.MySQLErrName[mysql.ErrInvalidYearColumnLength]) ErrInvalidYearColumnLength = terror.ClassParser.New(mysql.ErrInvalidYearColumnLength, mysql.MySQLErrName[mysql.ErrInvalidYearColumnLength])
// ErrWrongArguments returns for illegal argument. // ErrWrongArguments returns for illegal argument.
ErrWrongArguments = terror.ClassParser.New(codeWrongArgument, mysql.MySQLErrName[mysql.ErrWrongArguments]) ErrWrongArguments = terror.ClassParser.New(mysql.ErrWrongArguments, mysql.MySQLErrName[mysql.ErrWrongArguments])
// ErrWrongFieldTerminators returns for illegal field terminators. // ErrWrongFieldTerminators returns for illegal field terminators.
ErrWrongFieldTerminators = terror.ClassParser.New(codeWrongFieldTerminators, mysql.MySQLErrName[mysql.ErrWrongFieldTerminators]) ErrWrongFieldTerminators = terror.ClassParser.New(mysql.ErrWrongFieldTerminators, mysql.MySQLErrName[mysql.ErrWrongFieldTerminators])
// ErrTooBigDisplayWidth returns for data display width exceed limit . // ErrTooBigDisplayWidth returns for data display width exceed limit .
ErrTooBigDisplayWidth = terror.ClassParser.New(codeTooBigDisplayWidth, mysql.MySQLErrName[mysql.ErrTooBigDisplaywidth]) ErrTooBigDisplayWidth = terror.ClassParser.New(mysql.ErrTooBigDisplaywidth, mysql.MySQLErrName[mysql.ErrTooBigDisplaywidth])
// ErrTooBigPrecision returns for data precision exceed limit. // ErrTooBigPrecision returns for data precision exceed limit.
ErrTooBigPrecision = terror.ClassParser.New(codeErrTooBigPrecision, mysql.MySQLErrName[mysql.ErrTooBigPrecision]) ErrTooBigPrecision = terror.ClassParser.New(mysql.ErrTooBigPrecision, mysql.MySQLErrName[mysql.ErrTooBigPrecision])
// ErrUnknownAlterLock returns for no alter lock type found error. // ErrUnknownAlterLock returns for no alter lock type found error.
ErrUnknownAlterLock = terror.ClassParser.New(codeErrUnknownAlterLock, mysql.MySQLErrName[mysql.ErrUnknownAlterLock]) ErrUnknownAlterLock = terror.ClassParser.New(mysql.ErrUnknownAlterLock, mysql.MySQLErrName[mysql.ErrUnknownAlterLock])
// ErrUnknownAlterAlgorithm returns for no alter algorithm found error. // ErrUnknownAlterAlgorithm returns for no alter algorithm found error.
ErrUnknownAlterAlgorithm = terror.ClassParser.New(codeErrUnknownAlterAlgorithm, mysql.MySQLErrName[mysql.ErrUnknownAlterAlgorithm]) ErrUnknownAlterAlgorithm = terror.ClassParser.New(mysql.ErrUnknownAlterAlgorithm, mysql.MySQLErrName[mysql.ErrUnknownAlterAlgorithm])
// SpecFieldPattern special result field pattern // SpecFieldPattern special result field pattern
SpecFieldPattern = regexp.MustCompile(`(\/\*!(M?[0-9]{5,6})?|\*\/)`) SpecFieldPattern = regexp.MustCompile(`(\/\*!(M?[0-9]{5,6})?|\*\/)`)
specCodePattern = regexp.MustCompile(`\/\*!(M?[0-9]{5,6})?([^*]|\*+[^*/])*\*+\/`) specCodePattern = regexp.MustCompile(`\/\*!(M?[0-9]{5,6})?([^*]|\*+[^*/])*\*+\/`)
specCodeStart = regexp.MustCompile(`^\/\*!(M?[0-9]{5,6})?[ \t]*`) specCodeStart = regexp.MustCompile(`^\/\*!(M?[0-9]{5,6})?[ \t]*`)
specCodeEnd = regexp.MustCompile(`[ \t]*\*\/$`) specCodeEnd = regexp.MustCompile(`[ \t]*\*\/$`)
// SpecVersionCodePattern is a pattern for special comments with version.
SpecVersionCodePattern = regexp.MustCompile(`\/\*T![0-9]{5,6}([^*]|\*+[^*/])*\*+\/`)
specVersionCodeStart = regexp.MustCompile(`^\/\*T![0-9]{5,6}[ \t]*`)
specVersionCodeValue = regexp.MustCompile(`[0-9]{5,6}`)
) )
func init() { func init() {
parserMySQLErrCodes := map[terror.ErrCode]uint16{ parserMySQLErrCodes := map[terror.ErrCode]uint16{
codeErrSyntax: mysql.ErrSyntax, mysql.ErrSyntax: mysql.ErrSyntax,
codeErrParse: mysql.ErrParse, mysql.ErrParse: mysql.ErrParse,
codeErrUnknownCharacterSet: mysql.ErrUnknownCharacterSet, mysql.ErrUnknownCharacterSet: mysql.ErrUnknownCharacterSet,
codeErrInvalidYearColumnLength: mysql.ErrInvalidYearColumnLength, mysql.ErrInvalidYearColumnLength: mysql.ErrInvalidYearColumnLength,
codeWrongArgument: mysql.ErrWrongArguments, mysql.ErrWrongArguments: mysql.ErrWrongArguments,
codeWrongFieldTerminators: mysql.ErrWrongFieldTerminators, mysql.ErrWrongFieldTerminators: mysql.ErrWrongFieldTerminators,
codeTooBigDisplayWidth: mysql.ErrTooBigDisplaywidth, mysql.ErrTooBigDisplaywidth: mysql.ErrTooBigDisplaywidth,
codeErrUnknownAlterLock: mysql.ErrUnknownAlterLock, mysql.ErrUnknownAlterLock: mysql.ErrUnknownAlterLock,
codeErrUnknownAlterAlgorithm: mysql.ErrUnknownAlterAlgorithm, mysql.ErrUnknownAlterAlgorithm: mysql.ErrUnknownAlterAlgorithm,
codeErrTooBigPrecision: mysql.ErrTooBigPrecision, mysql.ErrTooBigPrecision: mysql.ErrTooBigPrecision,
} }
terror.ErrClassToMySQLCodes[terror.ClassParser] = parserMySQLErrCodes terror.ErrClassToMySQLCodes[terror.ClassParser] = parserMySQLErrCodes
} }
...@@ -89,13 +80,19 @@ func TrimComment(txt string) string { ...@@ -89,13 +80,19 @@ func TrimComment(txt string) string {
return specCodeEnd.ReplaceAllString(txt, "") return specCodeEnd.ReplaceAllString(txt, "")
} }
func TrimCodeVersionComment(txt string) string {
txt = specVersionCodeStart.ReplaceAllString(txt, "")
return specCodeEnd.ReplaceAllString(txt, "")
}
// Parser represents a parser instance. Some temporary objects are stored in it to reduce object allocation during Parse function. // Parser represents a parser instance. Some temporary objects are stored in it to reduce object allocation during Parse function.
type Parser struct { type Parser struct {
charset string charset string
collation string collation string
result []ast.StmtNode result []ast.StmtNode
src string src string
lexer Scanner lexer Scanner
hintParser *hintParser
// the following fields are used by yyParse to reduce allocation. // the following fields are used by yyParse to reduce allocation.
cache []yySymType cache []yySymType
...@@ -156,11 +153,7 @@ func (parser *Parser) Parse(sql, charset, collation string) (stmt []ast.StmtNode ...@@ -156,11 +153,7 @@ func (parser *Parser) Parse(sql, charset, collation string) (stmt []ast.StmtNode
} }
func (parser *Parser) lastErrorAsWarn() { func (parser *Parser) lastErrorAsWarn() {
if len(parser.lexer.errs) == 0 { parser.lexer.lastErrorAsWarn()
return
}
parser.lexer.warns = append(parser.lexer.warns, parser.lexer.errs[len(parser.lexer.errs)-1])
parser.lexer.errs = parser.lexer.errs[:len(parser.lexer.errs)-1]
} }
// ParseOneStmt parses a query and returns an ast.StmtNode. // ParseOneStmt parses a query and returns an ast.StmtNode.
...@@ -217,6 +210,13 @@ func (parser *Parser) endOffset(v *yySymType) int { ...@@ -217,6 +210,13 @@ func (parser *Parser) endOffset(v *yySymType) int {
return offset return offset
} }
func (parser *Parser) parseHint(input string) ([]*ast.TableOptimizerHint, []error) {
if parser.hintParser == nil {
parser.hintParser = newHintParser()
}
return parser.hintParser.parse(input, parser.lexer.GetSQLMode(), parser.lexer.lastHintPos)
}
func toInt(l yyLexer, lval *yySymType, str string) int { func toInt(l yyLexer, lval *yySymType, str string) int {
n, err := strconv.ParseUint(str, 10, 64) n, err := strconv.ParseUint(str, 10, 64)
if err != nil { if err != nil {
...@@ -296,3 +296,11 @@ func getUint64FromNUM(num interface{}) uint64 { ...@@ -296,3 +296,11 @@ func getUint64FromNUM(num interface{}) uint64 {
} }
return 0 return 0
} }
func getInt64FromNUM(num interface{}) int64 {
switch v := num.(type) {
case int64:
return v
}
return -1
}
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"github.com/pingcap/parser" "github.com/pingcap/parser"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql" "github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/util/disk"
"github.com/pingcap/tidb/util/execdetails" "github.com/pingcap/tidb/util/execdetails"
"github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/memory"
"go.uber.org/zap" "go.uber.org/zap"
...@@ -67,15 +68,9 @@ type StatementContext struct { ...@@ -67,15 +68,9 @@ type StatementContext struct {
OverflowAsWarning bool OverflowAsWarning bool
InShowWarning bool InShowWarning bool
UseCache bool UseCache bool
PadCharToFullLength bool
BatchCheck bool BatchCheck bool
InNullRejectCheck bool InNullRejectCheck bool
AllowInvalidDate bool AllowInvalidDate bool
// CastStrToIntStrict is used to control the way we cast float format string to int.
// If ConvertStrToIntStrict is false, we convert it to a valid float string first,
// then cast the float string to int string. Otherwise, we cast string to integer
// prefix in a strict way, only extract 0-9 and (+ or - in first bit).
CastStrToIntStrict bool
// mu struct holds variables that change during execution. // mu struct holds variables that change during execution.
mu struct { mu struct {
...@@ -118,11 +113,15 @@ type StatementContext struct { ...@@ -118,11 +113,15 @@ type StatementContext struct {
// InsertID is the given insert ID of an auto_increment column. // InsertID is the given insert ID of an auto_increment column.
InsertID uint64 InsertID uint64
BaseRowID int64
MaxRowID int64
// Copied from SessionVars.TimeZone. // Copied from SessionVars.TimeZone.
TimeZone *time.Location TimeZone *time.Location
Priority mysql.PriorityEnum Priority mysql.PriorityEnum
NotFillCache bool NotFillCache bool
MemTracker *memory.Tracker MemTracker *memory.Tracker
DiskTracker *disk.Tracker
RuntimeStatsColl *execdetails.RuntimeStatsColl RuntimeStatsColl *execdetails.RuntimeStatsColl
TableIDs []int64 TableIDs []int64
IndexNames []string IndexNames []string
...@@ -135,23 +134,30 @@ type StatementContext struct { ...@@ -135,23 +134,30 @@ type StatementContext struct {
normalized string normalized string
digest string digest string
} }
Tables []TableEntry // planNormalized use for cache the normalized plan, avoid duplicate builds.
PointExec bool // for point update cached execution, Constant expression need to set "paramMarker" planNormalized string
planDigest string
Tables []TableEntry
PointExec bool // for point update cached execution, Constant expression need to set "paramMarker"
lockWaitStartTime *time.Time // LockWaitStartTime stores the pessimistic lock wait start time
PessimisticLockWaited int32
LockKeysDuration time.Duration
} }
// StmtHints are SessionVars related sql hints. // StmtHints are SessionVars related sql hints.
type StmtHints struct { type StmtHints struct {
// Hint Information
MemQuotaQuery int64
MaxExecutionTime uint64
ReplicaRead byte
AllowInSubqToJoinAndAgg bool
NoIndexMergeHint bool
// Hint flags // Hint flags
HasAllowInSubqToJoinAndAggHint bool HasAllowInSubqToJoinAndAggHint bool
HasEnableIndexMergeHint bool
HasMemQuotaHint bool HasMemQuotaHint bool
HasReplicaReadHint bool HasReplicaReadHint bool
HasMaxExecutionTime bool
// Hint Information
AllowInSubqToJoinAndAgg bool
EnableIndexMerge bool
MemQuotaQuery int64
ReplicaRead byte
} }
// GetNowTsCached getter for nowTs, if not set get now time and cache it // GetNowTsCached getter for nowTs, if not set get now time and cache it
...@@ -178,6 +184,16 @@ func (sc *StatementContext) SQLDigest() (normalized, sqlDigest string) { ...@@ -178,6 +184,16 @@ func (sc *StatementContext) SQLDigest() (normalized, sqlDigest string) {
return sc.digestMemo.normalized, sc.digestMemo.digest return sc.digestMemo.normalized, sc.digestMemo.digest
} }
// GetPlanDigest gets the normalized plan and plan digest.
func (sc *StatementContext) GetPlanDigest() (normalized, planDigest string) {
return sc.planNormalized, sc.planDigest
}
// SetPlanDigest sets the normalized plan and plan digest.
func (sc *StatementContext) SetPlanDigest(normalized, planDigest string) {
sc.planNormalized, sc.planDigest = normalized, planDigest
}
// TableEntry presents table in db. // TableEntry presents table in db.
type TableEntry struct { type TableEntry struct {
DB string DB string
...@@ -309,30 +325,12 @@ func (sc *StatementContext) WarningCount() uint16 { ...@@ -309,30 +325,12 @@ func (sc *StatementContext) WarningCount() uint16 {
return wc return wc
} }
const zero = "0"
// NumErrorWarnings gets warning and error count. // NumErrorWarnings gets warning and error count.
func (sc *StatementContext) NumErrorWarnings() (ec, wc string) { func (sc *StatementContext) NumErrorWarnings() (ec uint16, wc int) {
var (
ecNum uint16
wcNum int
)
sc.mu.Lock() sc.mu.Lock()
ecNum = sc.mu.errorCount ec = sc.mu.errorCount
wcNum = len(sc.mu.warnings) wc = len(sc.mu.warnings)
sc.mu.Unlock() sc.mu.Unlock()
if ecNum == 0 {
ec = zero
} else {
ec = strconv.Itoa(int(ecNum))
}
if wcNum == 0 {
wc = zero
} else {
wc = strconv.Itoa(wcNum)
}
return return
} }
...@@ -428,6 +426,8 @@ func (sc *StatementContext) ResetForRetry() { ...@@ -428,6 +426,8 @@ func (sc *StatementContext) ResetForRetry() {
sc.mu.execDetails = execdetails.ExecDetails{} sc.mu.execDetails = execdetails.ExecDetails{}
sc.mu.allExecDetails = make([]*execdetails.ExecDetails, 0, 4) sc.mu.allExecDetails = make([]*execdetails.ExecDetails, 0, 4)
sc.mu.Unlock() sc.mu.Unlock()
sc.MaxRowID = 0
sc.BaseRowID = 0
sc.TableIDs = sc.TableIDs[:0] sc.TableIDs = sc.TableIDs[:0]
sc.IndexNames = sc.IndexNames[:0] sc.IndexNames = sc.IndexNames[:0]
} }
...@@ -454,6 +454,7 @@ func (sc *StatementContext) GetExecDetails() execdetails.ExecDetails { ...@@ -454,6 +454,7 @@ func (sc *StatementContext) GetExecDetails() execdetails.ExecDetails {
var details execdetails.ExecDetails var details execdetails.ExecDetails
sc.mu.Lock() sc.mu.Lock()
details = sc.mu.execDetails details = sc.mu.execDetails
details.LockKeysDuration = sc.LockKeysDuration
sc.mu.Unlock() sc.mu.Unlock()
return details return details
} }
...@@ -500,9 +501,6 @@ func (sc *StatementContext) PushDownFlags() uint64 { ...@@ -500,9 +501,6 @@ func (sc *StatementContext) PushDownFlags() uint64 {
if sc.DividedByZeroAsWarning { if sc.DividedByZeroAsWarning {
flags |= model.FlagDividedByZeroAsWarning flags |= model.FlagDividedByZeroAsWarning
} }
if sc.PadCharToFullLength {
flags |= model.FlagPadCharToFullLength
}
if sc.InLoadDataStmt { if sc.InLoadDataStmt {
flags |= model.FlagInLoadDataStmt flags |= model.FlagInLoadDataStmt
} }
...@@ -514,7 +512,15 @@ func (sc *StatementContext) CopTasksDetails() *CopTasksDetails { ...@@ -514,7 +512,15 @@ func (sc *StatementContext) CopTasksDetails() *CopTasksDetails {
sc.mu.Lock() sc.mu.Lock()
defer sc.mu.Unlock() defer sc.mu.Unlock()
n := len(sc.mu.allExecDetails) n := len(sc.mu.allExecDetails)
d := &CopTasksDetails{NumCopTasks: n} d := &CopTasksDetails{
NumCopTasks: n,
MaxBackoffTime: make(map[string]time.Duration),
AvgBackoffTime: make(map[string]time.Duration),
P90BackoffTime: make(map[string]time.Duration),
TotBackoffTime: make(map[string]time.Duration),
TotBackoffTimes: make(map[string]int),
MaxBackoffAddress: make(map[string]string),
}
if n == 0 { if n == 0 {
return d return d
} }
...@@ -534,9 +540,68 @@ func (sc *StatementContext) CopTasksDetails() *CopTasksDetails { ...@@ -534,9 +540,68 @@ func (sc *StatementContext) CopTasksDetails() *CopTasksDetails {
d.P90WaitTime = sc.mu.allExecDetails[n*9/10].WaitTime d.P90WaitTime = sc.mu.allExecDetails[n*9/10].WaitTime
d.MaxWaitTime = sc.mu.allExecDetails[n-1].WaitTime d.MaxWaitTime = sc.mu.allExecDetails[n-1].WaitTime
d.MaxWaitAddress = sc.mu.allExecDetails[n-1].CalleeAddress d.MaxWaitAddress = sc.mu.allExecDetails[n-1].CalleeAddress
// calculate backoff details
type backoffItem struct {
callee string
sleepTime time.Duration
times int
}
backoffInfo := make(map[string][]backoffItem)
for _, ed := range sc.mu.allExecDetails {
for backoff := range ed.BackoffTimes {
backoffInfo[backoff] = append(backoffInfo[backoff], backoffItem{
callee: ed.CalleeAddress,
sleepTime: ed.BackoffSleep[backoff],
times: ed.BackoffTimes[backoff],
})
}
}
for backoff, items := range backoffInfo {
if len(items) == 0 {
continue
}
sort.Slice(items, func(i, j int) bool {
return items[i].sleepTime < items[j].sleepTime
})
n := len(items)
d.MaxBackoffAddress[backoff] = items[n-1].callee
d.MaxBackoffTime[backoff] = items[n-1].sleepTime
d.P90BackoffTime[backoff] = items[n*9/10].sleepTime
var totalTime time.Duration
totalTimes := 0
for _, it := range items {
totalTime += it.sleepTime
totalTimes += it.times
}
d.AvgBackoffTime[backoff] = totalTime / time.Duration(n)
d.TotBackoffTime[backoff] = totalTime
d.TotBackoffTimes[backoff] = totalTimes
}
return d return d
} }
// SetFlagsFromPBFlag set the flag of StatementContext from a `tipb.SelectRequest.Flags`.
func (sc *StatementContext) SetFlagsFromPBFlag(flags uint64) {
sc.IgnoreTruncate = (flags & model.FlagIgnoreTruncate) > 0
sc.TruncateAsWarning = (flags & model.FlagTruncateAsWarning) > 0
sc.InInsertStmt = (flags & model.FlagInInsertStmt) > 0
sc.InSelectStmt = (flags & model.FlagInSelectStmt) > 0
sc.OverflowAsWarning = (flags & model.FlagOverflowAsWarning) > 0
sc.IgnoreZeroInDate = (flags & model.FlagIgnoreZeroInDate) > 0
sc.DividedByZeroAsWarning = (flags & model.FlagDividedByZeroAsWarning) > 0
}
// GetLockWaitStartTime returns the statement pessimistic lock wait start time
func (sc *StatementContext) GetLockWaitStartTime() time.Time {
if sc.lockWaitStartTime == nil {
curTime := time.Now()
sc.lockWaitStartTime = &curTime
}
return *sc.lockWaitStartTime
}
//CopTasksDetails collects some useful information of cop-tasks during execution. //CopTasksDetails collects some useful information of cop-tasks during execution.
type CopTasksDetails struct { type CopTasksDetails struct {
NumCopTasks int NumCopTasks int
...@@ -550,6 +615,13 @@ type CopTasksDetails struct { ...@@ -550,6 +615,13 @@ type CopTasksDetails struct {
P90WaitTime time.Duration P90WaitTime time.Duration
MaxWaitAddress string MaxWaitAddress string
MaxWaitTime time.Duration MaxWaitTime time.Duration
MaxBackoffTime map[string]time.Duration
MaxBackoffAddress map[string]string
AvgBackoffTime map[string]time.Duration
P90BackoffTime map[string]time.Duration
TotBackoffTime map[string]time.Duration
TotBackoffTimes map[string]int
} }
// ToZapFields wraps the CopTasksDetails as zap.Fileds. // ToZapFields wraps the CopTasksDetails as zap.Fileds.
......
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
package types package types
import (
"math"
"time"
)
// CompareInt64 returns an integer comparing the int64 x to y. // CompareInt64 returns an integer comparing the int64 x to y.
func CompareInt64(x, y int64) int { func CompareInt64(x, y int64) int {
if x < y { if x < y {
...@@ -35,6 +40,66 @@ func CompareUint64(x, y uint64) int { ...@@ -35,6 +40,66 @@ func CompareUint64(x, y uint64) int {
return 1 return 1
} }
//VecCompareUU returns []int64 comparing the []uint64 x to []uint64 y
func VecCompareUU(x, y []uint64, res []int64) {
n := len(x)
for i := 0; i < n; i++ {
if x[i] < y[i] {
res[i] = -1
} else if x[i] == y[i] {
res[i] = 0
} else {
res[i] = 1
}
}
}
//VecCompareII returns []int64 comparing the []int64 x to []int64 y
func VecCompareII(x, y, res []int64) {
n := len(x)
for i := 0; i < n; i++ {
if x[i] < y[i] {
res[i] = -1
} else if x[i] == y[i] {
res[i] = 0
} else {
res[i] = 1
}
}
}
//VecCompareUI returns []int64 comparing the []uint64 x to []int64y
func VecCompareUI(x []uint64, y, res []int64) {
n := len(x)
for i := 0; i < n; i++ {
if y[i] < 0 || x[i] > math.MaxInt64 {
res[i] = 1
} else if int64(x[i]) < y[i] {
res[i] = -1
} else if int64(x[i]) == y[i] {
res[i] = 0
} else {
res[i] = 1
}
}
}
//VecCompareIU returns []int64 comparing the []int64 x to []uint64y
func VecCompareIU(x []int64, y []uint64, res []int64) {
n := len(x)
for i := 0; i < n; i++ {
if x[i] < 0 || uint64(y[i]) > math.MaxInt64 {
res[i] = -1
} else if x[i] < int64(y[i]) {
res[i] = -1
} else if x[i] == int64(y[i]) {
res[i] = 0
} else {
res[i] = 1
}
}
}
// CompareFloat64 returns an integer comparing the float64 x to y. // CompareFloat64 returns an integer comparing the float64 x to y.
func CompareFloat64(x, y float64) int { func CompareFloat64(x, y float64) int {
if x < y { if x < y {
...@@ -56,3 +121,14 @@ func CompareString(x, y string) int { ...@@ -56,3 +121,14 @@ func CompareString(x, y string) int {
return 1 return 1
} }
// CompareDuration returns an integer comparing the duration x to y.
func CompareDuration(x, y time.Duration) int {
if x < y {
return -1
} else if x == y {
return 0
}
return 1
}
...@@ -168,8 +168,16 @@ func ConvertFloatToUint(sc *stmtctx.StatementContext, fval float64, upperBound u ...@@ -168,8 +168,16 @@ func ConvertFloatToUint(sc *stmtctx.StatementContext, fval float64, upperBound u
return uint64(int64(val)), overflow(val, tp) return uint64(int64(val)), overflow(val, tp)
} }
if val > float64(upperBound) { ubf := float64(upperBound)
return upperBound, overflow(val, tp) // Because math.MaxUint64 can not be represented precisely in iee754(64bit),
// so `float64(math.MaxUint64)` will make a num bigger than math.MaxUint64,
// which can not be represented by 64bit integer.
// So `uint64(float64(math.MaxUint64))` is undefined behavior.
if val == ubf {
return uint64(math.MaxInt64), nil
}
if val > ubf {
return uint64(math.MaxInt64), overflow(val, tp)
} }
return uint64(val), nil return uint64(val), nil
} }
...@@ -348,9 +356,9 @@ func NumberToDuration(number int64, fsp int8) (Duration, error) { ...@@ -348,9 +356,9 @@ func NumberToDuration(number int64, fsp int8) (Duration, error) {
} }
if number/10000 > TimeMaxHour || number%100 >= 60 || (number/100)%100 >= 60 { if number/10000 > TimeMaxHour || number%100 >= 60 || (number/100)%100 >= 60 {
return ZeroDuration, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(number)) return ZeroDuration, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, strconv.FormatInt(number, 10)))
} }
t := Time{Time: FromDate(0, 0, 0, int(number/10000), int((number/100)%100), int(number%100), 0), Type: mysql.TypeDuration, Fsp: fsp} t := NewTime(FromDate(0, 0, 0, int(number/10000), int((number/100)%100), int(number%100), 0), mysql.TypeDuration, fsp)
dur, err := t.ConvertToDuration() dur, err := t.ConvertToDuration()
if err != nil { if err != nil {
return ZeroDuration, errors.Trace(err) return ZeroDuration, errors.Trace(err)
...@@ -363,7 +371,7 @@ func NumberToDuration(number int64, fsp int8) (Duration, error) { ...@@ -363,7 +371,7 @@ func NumberToDuration(number int64, fsp int8) (Duration, error) {
// getValidIntPrefix gets prefix of the string which can be successfully parsed as int. // getValidIntPrefix gets prefix of the string which can be successfully parsed as int.
func getValidIntPrefix(sc *stmtctx.StatementContext, str string) (string, error) { func getValidIntPrefix(sc *stmtctx.StatementContext, str string) (string, error) {
if !sc.CastStrToIntStrict { if !sc.InSelectStmt {
floatPrefix, err := getValidFloatPrefix(sc, str) floatPrefix, err := getValidFloatPrefix(sc, str)
if err != nil { if err != nil {
return floatPrefix, errors.Trace(err) return floatPrefix, errors.Trace(err)
...@@ -561,18 +569,20 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned ...@@ -561,18 +569,20 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned
if !unsigned { if !unsigned {
lBound := IntergerSignedLowerBound(mysql.TypeLonglong) lBound := IntergerSignedLowerBound(mysql.TypeLonglong)
uBound := IntergerSignedUpperBound(mysql.TypeLonglong) uBound := IntergerSignedUpperBound(mysql.TypeLonglong)
return ConvertFloatToInt(f, lBound, uBound, mysql.TypeLonglong) u, e := ConvertFloatToInt(f, lBound, uBound, mysql.TypeLonglong)
return u, sc.HandleOverflow(e, e)
} }
bound := IntergerUnsignedUpperBound(mysql.TypeLonglong) bound := IntergerUnsignedUpperBound(mysql.TypeLonglong)
u, err := ConvertFloatToUint(sc, f, bound, mysql.TypeLonglong) u, err := ConvertFloatToUint(sc, f, bound, mysql.TypeLonglong)
return int64(u), errors.Trace(err) return int64(u), sc.HandleOverflow(err, err)
case json.TypeCodeString: case json.TypeCodeString:
str := string(hack.String(j.GetString())) str := string(hack.String(j.GetString()))
if !unsigned { if !unsigned {
return StrToInt(sc, str) r, e := StrToInt(sc, str)
return r, sc.HandleOverflow(e, e)
} }
u, err := StrToUint(sc, str) u, err := StrToUint(sc, str)
return int64(u), errors.Trace(err) return int64(u), sc.HandleOverflow(err, err)
} }
return 0, errors.New("Unknown type code in JSON") return 0, errors.New("Unknown type code in JSON")
} }
...@@ -619,7 +629,7 @@ func ConvertJSONToDecimal(sc *stmtctx.StatementContext, j json.BinaryJSON) (*MyD ...@@ -619,7 +629,7 @@ func ConvertJSONToDecimal(sc *stmtctx.StatementContext, j json.BinaryJSON) (*MyD
// getValidFloatPrefix gets prefix of string which can be successfully parsed as float. // getValidFloatPrefix gets prefix of string which can be successfully parsed as float.
func getValidFloatPrefix(sc *stmtctx.StatementContext, s string) (valid string, err error) { func getValidFloatPrefix(sc *stmtctx.StatementContext, s string) (valid string, err error) {
if (sc.InDeleteStmt || sc.InSelectStmt || sc.InUpdateStmt) && s == "" { if (sc.InDeleteStmt || sc.InSelectStmt) && s == "" {
return "0", nil return "0", nil
} }
...@@ -663,7 +673,7 @@ func getValidFloatPrefix(sc *stmtctx.StatementContext, s string) (valid string, ...@@ -663,7 +673,7 @@ func getValidFloatPrefix(sc *stmtctx.StatementContext, s string) (valid string,
valid = "0" valid = "0"
} }
if validLen == 0 || validLen != len(s) { if validLen == 0 || validLen != len(s) {
err = errors.Trace(handleTruncateError(sc, ErrTruncated)) err = errors.Trace(handleTruncateError(sc, ErrTruncatedWrongVal.GenWithStackByArgs("FLOAT", s)))
} }
return valid, err return valid, err
} }
......
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
"strings" "strings"
"time" "time"
"unicode/utf8" "unicode/utf8"
"unsafe"
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/charset" "github.com/pingcap/parser/charset"
...@@ -722,6 +723,7 @@ func (d *Datum) compareMysqlTime(sc *stmtctx.StatementContext, time Time) (int, ...@@ -722,6 +723,7 @@ func (d *Datum) compareMysqlTime(sc *stmtctx.StatementContext, time Time) (int,
} }
// ConvertTo converts a datum to the target field type. // ConvertTo converts a datum to the target field type.
// change this method need sync modification to type2Kind in rowcodec/types.go
func (d *Datum) ConvertTo(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) { func (d *Datum) ConvertTo(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
if d.k == KindNull { if d.k == KindNull {
return Datum{}, nil return Datum{}, nil
...@@ -1005,7 +1007,7 @@ func (d *Datum) convertToMysqlTimestamp(sc *stmtctx.StatementContext, target *Fi ...@@ -1005,7 +1007,7 @@ func (d *Datum) convertToMysqlTimestamp(sc *stmtctx.StatementContext, target *Fi
default: default:
return invalidConv(d, mysql.TypeTimestamp) return invalidConv(d, mysql.TypeTimestamp)
} }
t.Type = mysql.TypeTimestamp t.SetType(mysql.TypeTimestamp)
ret.SetMysqlTime(t) ret.SetMysqlTime(t)
if err != nil { if err != nil {
return ret, errors.Trace(err) return ret, errors.Trace(err)
...@@ -1050,7 +1052,7 @@ func (d *Datum) convertToMysqlTime(sc *stmtctx.StatementContext, target *FieldTy ...@@ -1050,7 +1052,7 @@ func (d *Datum) convertToMysqlTime(sc *stmtctx.StatementContext, target *FieldTy
} }
if tp == mysql.TypeDate { if tp == mysql.TypeDate {
// Truncate hh:mm:ss part if the type is Date. // Truncate hh:mm:ss part if the type is Date.
t.Time = FromDate(t.Time.Year(), t.Time.Month(), t.Time.Day(), 0, 0, 0, 0) t.SetCoreTime(FromDate(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0))
} }
ret.SetValue(t) ret.SetValue(t)
if err != nil { if err != nil {
...@@ -1098,10 +1100,10 @@ func (d *Datum) convertToMysqlDuration(sc *stmtctx.StatementContext, target *Fie ...@@ -1098,10 +1100,10 @@ func (d *Datum) convertToMysqlDuration(sc *stmtctx.StatementContext, target *Fie
if timeNum > MaxDuration && timeNum < 10000000000 { if timeNum > MaxDuration && timeNum < 10000000000 {
// mysql return max in no strict sql mode. // mysql return max in no strict sql mode.
ret.SetValue(Duration{Duration: MaxTime, Fsp: 0}) ret.SetValue(Duration{Duration: MaxTime, Fsp: 0})
return ret, ErrInvalidTimeFormat.GenWithStack("Incorrect time value: '%s'", timeStr) return ret, ErrWrongValue.GenWithStackByArgs(TimeStr, timeStr)
} }
if timeNum < -MaxDuration { if timeNum < -MaxDuration {
return ret, ErrInvalidTimeFormat.GenWithStack("Incorrect time value: '%s'", timeStr) return ret, ErrWrongValue.GenWithStackByArgs(TimeStr, timeStr)
} }
t, err := ParseDuration(sc, timeStr, fsp) t, err := ParseDuration(sc, timeStr, fsp)
ret.SetValue(t) ret.SetValue(t)
...@@ -1195,10 +1197,10 @@ func ProduceDecWithSpecifiedTp(dec *MyDecimal, tp *FieldType, sc *stmtctx.Statem ...@@ -1195,10 +1197,10 @@ func ProduceDecWithSpecifiedTp(dec *MyDecimal, tp *FieldType, sc *stmtctx.Statem
if sc.InInsertStmt || sc.InUpdateStmt || sc.InDeleteStmt { if sc.InInsertStmt || sc.InUpdateStmt || sc.InDeleteStmt {
// fix https://github.com/pingcap/tidb/issues/3895 // fix https://github.com/pingcap/tidb/issues/3895
// fix https://github.com/pingcap/tidb/issues/5532 // fix https://github.com/pingcap/tidb/issues/5532
sc.AppendWarning(ErrTruncated) sc.AppendWarning(ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", &old))
err = nil err = nil
} else { } else {
err = sc.HandleTruncate(ErrTruncated) err = sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", &old))
} }
} }
} }
...@@ -1234,7 +1236,7 @@ func (d *Datum) convertToMysqlYear(sc *stmtctx.StatementContext, target *FieldTy ...@@ -1234,7 +1236,7 @@ func (d *Datum) convertToMysqlYear(sc *stmtctx.StatementContext, target *FieldTy
adjust = true adjust = true
} }
case KindMysqlTime: case KindMysqlTime:
y = int64(d.GetMysqlTime().Time.Year()) y = int64(d.GetMysqlTime().Year())
case KindMysqlDuration: case KindMysqlDuration:
y = int64(time.Now().Year()) y = int64(time.Now().Year())
default: default:
...@@ -1659,23 +1661,6 @@ func invalidConv(d *Datum, tp byte) (Datum, error) { ...@@ -1659,23 +1661,6 @@ func invalidConv(d *Datum, tp byte) (Datum, error) {
return Datum{}, errors.Errorf("cannot convert datum from %s to type %s.", KindStr(d.Kind()), TypeStr(tp)) return Datum{}, errors.Errorf("cannot convert datum from %s to type %s.", KindStr(d.Kind()), TypeStr(tp))
} }
func (d *Datum) convergeType(hasUint, hasDecimal, hasFloat *bool) (x Datum) {
x = *d
switch d.Kind() {
case KindUint64:
*hasUint = true
case KindFloat32:
f := d.GetFloat32()
x.SetFloat64(float64(f))
*hasFloat = true
case KindFloat64:
*hasFloat = true
case KindMysqlDecimal:
*hasDecimal = true
}
return x
}
// NewDatum creates a new Datum from an interface{}. // NewDatum creates a new Datum from an interface{}.
func NewDatum(in interface{}) (d Datum) { func NewDatum(in interface{}) (d Datum) {
switch x := in.(type) { switch x := in.(type) {
...@@ -1759,6 +1744,12 @@ func NewMysqlEnumDatum(e Enum) (d Datum) { ...@@ -1759,6 +1744,12 @@ func NewMysqlEnumDatum(e Enum) (d Datum) {
return d return d
} }
// NewMysqlSetDatum creates a new MysqlSet Datum for a Enum value.
func NewMysqlSetDatum(e Set) (d Datum) {
d.SetMysqlSet(e)
return d
}
// MakeDatums creates datum slice from interfaces. // MakeDatums creates datum slice from interfaces.
func MakeDatums(args ...interface{}) []Datum { func MakeDatums(args ...interface{}) []Datum {
datums := make([]Datum, len(args)) datums := make([]Datum, len(args))
...@@ -1895,3 +1886,209 @@ func CloneRow(dr []Datum) []Datum { ...@@ -1895,3 +1886,209 @@ func CloneRow(dr []Datum) []Datum {
} }
return c return c
} }
// GetMaxValue returns the max value datum for each type.
func GetMaxValue(ft *FieldType) (max Datum) {
switch ft.Tp {
case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong:
if mysql.HasUnsignedFlag(ft.Flag) {
max.SetUint64(IntergerUnsignedUpperBound(ft.Tp))
} else {
max.SetInt64(IntergerSignedUpperBound(ft.Tp))
}
case mysql.TypeFloat:
max.SetFloat32(float32(GetMaxFloat(ft.Flen, ft.Decimal)))
case mysql.TypeDouble:
max.SetFloat64(GetMaxFloat(ft.Flen, ft.Decimal))
case mysql.TypeString, mysql.TypeVarString, mysql.TypeVarchar, mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
// codec.Encode KindMaxValue, to avoid import circle
bytes := []byte{250}
max.SetBytes(bytes)
case mysql.TypeNewDecimal:
max.SetMysqlDecimal(NewMaxOrMinDec(false, ft.Flen, ft.Decimal))
case mysql.TypeDuration:
max.SetMysqlDuration(Duration{Duration: MaxTime})
case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp:
if ft.Tp == mysql.TypeDate || ft.Tp == mysql.TypeDatetime {
max.SetMysqlTime(NewTime(MaxDatetime, ft.Tp, 0))
} else {
max.SetMysqlTime(MaxTimestamp)
}
}
return
}
// GetMinValue returns the min value datum for each type.
func GetMinValue(ft *FieldType) (min Datum) {
switch ft.Tp {
case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong:
if mysql.HasUnsignedFlag(ft.Flag) {
min.SetUint64(0)
} else {
min.SetInt64(IntergerSignedLowerBound(ft.Tp))
}
case mysql.TypeFloat:
min.SetFloat32(float32(-GetMaxFloat(ft.Flen, ft.Decimal)))
case mysql.TypeDouble:
min.SetFloat64(-GetMaxFloat(ft.Flen, ft.Decimal))
case mysql.TypeString, mysql.TypeVarString, mysql.TypeVarchar, mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
// codec.Encode KindMinNotNull, to avoid import circle
bytes := []byte{1}
min.SetBytes(bytes)
case mysql.TypeNewDecimal:
min.SetMysqlDecimal(NewMaxOrMinDec(true, ft.Flen, ft.Decimal))
case mysql.TypeDuration:
min.SetMysqlDuration(Duration{Duration: MinTime})
case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeTimestamp:
if ft.Tp == mysql.TypeDate || ft.Tp == mysql.TypeDatetime {
min.SetMysqlTime(NewTime(MinDatetime, ft.Tp, 0))
} else {
min.SetMysqlTime(MinTimestamp)
}
}
return
}
// RoundingType is used to indicate the rounding type for reversing evaluation.
type RoundingType uint8
const (
// Ceiling means rounding up.
Ceiling RoundingType = iota
// Floor means rounding down.
Floor
)
func getDatumBound(retType *FieldType, rType RoundingType) Datum {
if rType == Ceiling {
return GetMaxValue(retType)
}
return GetMinValue(retType)
}
// ChangeReverseResultByUpperLowerBound is for expression's reverse evaluation.
// Here is an example for what's effort for the function: CastRealAsInt(t.a),
// if the type of column `t.a` is mysql.TypeDouble, and there is a row that t.a == MaxFloat64
// then the cast function will arrive a result MaxInt64. But when we do the reverse evaluation,
// if the result is MaxInt64, and the rounding type is ceiling. Then we should get the MaxFloat64
// instead of float64(MaxInt64).
// Another example: cast(1.1 as signed) = 1,
// when we get the answer 1, we can only reversely evaluate 1.0 as the column value. So in this
// case, we should judge whether the rounding type are ceiling. If it is, then we should plus one for
// 1.0 and get the reverse result 2.0.
func ChangeReverseResultByUpperLowerBound(
sc *stmtctx.StatementContext,
retType *FieldType,
res Datum,
rType RoundingType) (Datum, error) {
d, err := res.ConvertTo(sc, retType)
if terror.ErrorEqual(err, ErrOverflow) {
return d, nil
}
if err != nil {
return d, err
}
resRetType := FieldType{}
switch res.Kind() {
case KindInt64:
resRetType.Tp = mysql.TypeLonglong
case KindUint64:
resRetType.Tp = mysql.TypeLonglong
resRetType.Flag |= mysql.UnsignedFlag
case KindFloat32:
resRetType.Tp = mysql.TypeFloat
case KindFloat64:
resRetType.Tp = mysql.TypeDouble
case KindMysqlDecimal:
resRetType.Tp = mysql.TypeNewDecimal
resRetType.Flen = int(res.GetMysqlDecimal().GetDigitsFrac() + res.GetMysqlDecimal().GetDigitsInt())
resRetType.Decimal = int(res.GetMysqlDecimal().GetDigitsInt())
}
bound := getDatumBound(&resRetType, rType)
cmp, err := d.CompareDatum(sc, &bound)
if err != nil {
return d, err
}
if cmp == 0 {
d = getDatumBound(retType, rType)
} else if rType == Ceiling {
switch retType.Tp {
case mysql.TypeShort:
if mysql.HasUnsignedFlag(retType.Flag) {
if d.GetUint64() != math.MaxUint16 {
d.SetUint64(d.GetUint64() + 1)
}
} else {
if d.GetInt64() != math.MaxInt16 {
d.SetInt64(d.GetInt64() + 1)
}
}
case mysql.TypeLong:
if mysql.HasUnsignedFlag(retType.Flag) {
if d.GetUint64() != math.MaxUint32 {
d.SetUint64(d.GetUint64() + 1)
}
} else {
if d.GetInt64() != math.MaxInt32 {
d.SetInt64(d.GetInt64() + 1)
}
}
case mysql.TypeLonglong:
if mysql.HasUnsignedFlag(retType.Flag) {
if d.GetUint64() != math.MaxUint64 {
d.SetUint64(d.GetUint64() + 1)
}
} else {
if d.GetInt64() != math.MaxInt64 {
d.SetInt64(d.GetInt64() + 1)
}
}
case mysql.TypeFloat:
if d.GetFloat32() != math.MaxFloat32 {
d.SetFloat32(d.GetFloat32() + 1.0)
}
case mysql.TypeDouble:
if d.GetFloat64() != math.MaxFloat64 {
d.SetFloat64(d.GetFloat64() + 1.0)
}
case mysql.TypeNewDecimal:
if d.GetMysqlDecimal().Compare(NewMaxOrMinDec(false, retType.Flen, retType.Decimal)) != 0 {
var decimalOne, newD MyDecimal
one := decimalOne.FromInt(1)
err = DecimalAdd(d.GetMysqlDecimal(), one, &newD)
if err != nil {
return d, err
}
d = NewDecimalDatum(&newD)
}
}
}
return d, nil
}
const (
sizeOfEmptyDatum = int(unsafe.Sizeof(Datum{}))
sizeOfMysqlTime = int(unsafe.Sizeof(ZeroTime))
sizeOfMyDecimal = MyDecimalStructSize
)
// EstimatedMemUsage returns the estimated bytes consumed of a one-dimensional
// or two-dimensional datum array.
func EstimatedMemUsage(array []Datum, numOfRows int) int64 {
if numOfRows == 0 {
return 0
}
var bytesConsumed int
for _, d := range array {
switch d.Kind() {
case KindMysqlDecimal:
bytesConsumed += sizeOfMyDecimal
case KindMysqlTime:
bytesConsumed += sizeOfMysqlTime
default:
bytesConsumed += len(d.b)
}
}
bytesConsumed += len(array) * sizeOfEmptyDatum
return int64(bytesConsumed * numOfRows)
}
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
package types package types
import ( import (
"github.com/cznic/mathutil"
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/opcode" "github.com/pingcap/parser/opcode"
"github.com/pingcap/tidb/util/mathutil"
) )
// ComputePlus computes the result of a+b. // ComputePlus computes the result of a+b.
......
...@@ -14,122 +14,96 @@ ...@@ -14,122 +14,96 @@
package types package types
import ( import (
"github.com/pingcap/errors"
"github.com/pingcap/parser/mysql" "github.com/pingcap/parser/mysql"
"github.com/pingcap/parser/terror" "github.com/pingcap/parser/terror"
parser_types "github.com/pingcap/parser/types" parser_types "github.com/pingcap/parser/types"
) )
// const strings for ErrWrongValue
const (
DateTimeStr = "datetime"
TimeStr = "time"
)
var ( var (
// ErrInvalidDefault is returned when meet a invalid default value.
ErrInvalidDefault = parser_types.ErrInvalidDefault
// ErrDataTooLong is returned when converts a string value that is longer than field type length. // ErrDataTooLong is returned when converts a string value that is longer than field type length.
ErrDataTooLong = terror.ClassTypes.New(codeDataTooLong, "Data Too Long") ErrDataTooLong = terror.ClassTypes.New(mysql.ErrDataTooLong, mysql.MySQLErrName[mysql.ErrDataTooLong])
// ErrIllegalValueForType is returned when value of type is illegal. // ErrIllegalValueForType is returned when value of type is illegal.
ErrIllegalValueForType = terror.ClassTypes.New(codeIllegalValueForType, mysql.MySQLErrName[mysql.ErrIllegalValueForType]) ErrIllegalValueForType = terror.ClassTypes.New(mysql.ErrIllegalValueForType, mysql.MySQLErrName[mysql.ErrIllegalValueForType])
// ErrTruncated is returned when data has been truncated during conversion. // ErrTruncated is returned when data has been truncated during conversion.
ErrTruncated = terror.ClassTypes.New(codeTruncated, "Data Truncated") ErrTruncated = terror.ClassTypes.New(mysql.WarnDataTruncated, mysql.MySQLErrName[mysql.WarnDataTruncated])
// ErrTruncatedWrongVal is returned when data has been truncated during conversion.
ErrTruncatedWrongVal = terror.ClassTypes.New(codeTruncatedWrongValue, msgTruncatedWrongVal)
// ErrOverflow is returned when data is out of range for a field type. // ErrOverflow is returned when data is out of range for a field type.
ErrOverflow = terror.ClassTypes.New(codeOverflow, msgOverflow) ErrOverflow = terror.ClassTypes.New(mysql.ErrDataOutOfRange, mysql.MySQLErrName[mysql.ErrDataOutOfRange])
// ErrDivByZero is return when do division by 0. // ErrDivByZero is return when do division by 0.
ErrDivByZero = terror.ClassTypes.New(codeDivByZero, "Division by 0") ErrDivByZero = terror.ClassTypes.New(mysql.ErrDivisionByZero, mysql.MySQLErrName[mysql.ErrDivisionByZero])
// ErrTooBigDisplayWidth is return when display width out of range for column. // ErrTooBigDisplayWidth is return when display width out of range for column.
ErrTooBigDisplayWidth = terror.ClassTypes.New(codeTooBigDisplayWidth, mysql.MySQLErrName[mysql.ErrTooBigDisplaywidth]) ErrTooBigDisplayWidth = terror.ClassTypes.New(mysql.ErrTooBigDisplaywidth, mysql.MySQLErrName[mysql.ErrTooBigDisplaywidth])
// ErrTooBigFieldLength is return when column length too big for column. // ErrTooBigFieldLength is return when column length too big for column.
ErrTooBigFieldLength = terror.ClassTypes.New(codeTooBigFieldLength, "Too Big Field length") ErrTooBigFieldLength = terror.ClassTypes.New(mysql.ErrTooBigFieldlength, mysql.MySQLErrName[mysql.ErrTooBigFieldlength])
// ErrTooBigSet is returned when too many strings for column. // ErrTooBigSet is returned when too many strings for column.
ErrTooBigSet = terror.ClassTypes.New(codeTooBigSet, "Too Big Set") ErrTooBigSet = terror.ClassTypes.New(mysql.ErrTooBigSet, mysql.MySQLErrName[mysql.ErrTooBigSet])
// ErrTooBigScale is returned when type DECIMAL/NUMERIC scale is bigger than mysql.MaxDecimalScale. // ErrTooBigScale is returned when type DECIMAL/NUMERIC scale is bigger than mysql.MaxDecimalScale.
ErrTooBigScale = terror.ClassTypes.New(codeTooBigScale, mysql.MySQLErrName[mysql.ErrTooBigScale]) ErrTooBigScale = terror.ClassTypes.New(mysql.ErrTooBigScale, mysql.MySQLErrName[mysql.ErrTooBigScale])
// ErrTooBigPrecision is returned when type DECIMAL/NUMERIC precision is bigger than mysql.MaxDecimalWidth // ErrTooBigPrecision is returned when type DECIMAL/NUMERIC precision is bigger than mysql.MaxDecimalWidth
ErrTooBigPrecision = terror.ClassTypes.New(codeTooBigPrecision, mysql.MySQLErrName[mysql.ErrTooBigPrecision]) ErrTooBigPrecision = terror.ClassTypes.New(mysql.ErrTooBigPrecision, mysql.MySQLErrName[mysql.ErrTooBigPrecision])
// ErrWrongFieldSpec is return when incorrect column specifier for column.
ErrWrongFieldSpec = terror.ClassTypes.New(codeWrongFieldSpec, "Wrong Field Spec")
// ErrBadNumber is return when parsing an invalid binary decimal number. // ErrBadNumber is return when parsing an invalid binary decimal number.
ErrBadNumber = terror.ClassTypes.New(codeBadNumber, "Bad Number") ErrBadNumber = terror.ClassTypes.New(mysql.ErrBadNumber, mysql.MySQLErrName[mysql.ErrBadNumber])
// ErrInvalidDefault is returned when meet a invalid default value.
ErrInvalidDefault = parser_types.ErrInvalidDefault
// ErrInvalidFieldSize is returned when the precision of a column is out of range. // ErrInvalidFieldSize is returned when the precision of a column is out of range.
ErrInvalidFieldSize = terror.ClassTypes.New(codeInvalidFieldSize, mysql.MySQLErrName[mysql.ErrInvalidFieldSize]) ErrInvalidFieldSize = terror.ClassTypes.New(mysql.ErrInvalidFieldSize, mysql.MySQLErrName[mysql.ErrInvalidFieldSize])
// ErrCastAsSignedOverflow is returned when positive out-of-range integer, and convert to it's negative complement.
ErrCastAsSignedOverflow = terror.ClassTypes.New(codeUnknown, msgCastAsSignedOverflow)
// ErrCastNegIntAsUnsigned is returned when a negative integer be casted to an unsigned int.
ErrCastNegIntAsUnsigned = terror.ClassTypes.New(codeUnknown, msgCastNegIntAsUnsigned)
// ErrMBiggerThanD is returned when precision less than the scale. // ErrMBiggerThanD is returned when precision less than the scale.
ErrMBiggerThanD = terror.ClassTypes.New(codeMBiggerThanD, mysql.MySQLErrName[mysql.ErrMBiggerThanD]) ErrMBiggerThanD = terror.ClassTypes.New(mysql.ErrMBiggerThanD, mysql.MySQLErrName[mysql.ErrMBiggerThanD])
// ErrWarnDataOutOfRange is returned when the value in a numeric column that is outside the permissible range of the column data type. // ErrWarnDataOutOfRange is returned when the value in a numeric column that is outside the permissible range of the column data type.
// See https://dev.mysql.com/doc/refman/5.5/en/out-of-range-and-overflow.html for details // See https://dev.mysql.com/doc/refman/5.5/en/out-of-range-and-overflow.html for details
ErrWarnDataOutOfRange = terror.ClassTypes.New(codeDataOutOfRange, mysql.MySQLErrName[mysql.ErrWarnDataOutOfRange]) ErrWarnDataOutOfRange = terror.ClassTypes.New(mysql.ErrWarnDataOutOfRange, mysql.MySQLErrName[mysql.ErrWarnDataOutOfRange])
// ErrDuplicatedValueInType is returned when enum column has duplicated value. // ErrDuplicatedValueInType is returned when enum column has duplicated value.
ErrDuplicatedValueInType = terror.ClassTypes.New(codeDuplicatedValueInType, mysql.MySQLErrName[mysql.ErrDuplicatedValueInType]) ErrDuplicatedValueInType = terror.ClassTypes.New(mysql.ErrDuplicatedValueInType, mysql.MySQLErrName[mysql.ErrDuplicatedValueInType])
// ErrDatetimeFunctionOverflow is returned when the calculation in datetime function cause overflow. // ErrDatetimeFunctionOverflow is returned when the calculation in datetime function cause overflow.
ErrDatetimeFunctionOverflow = terror.ClassTypes.New(codeDatetimeFunctionOverflow, mysql.MySQLErrName[mysql.ErrDatetimeFunctionOverflow]) ErrDatetimeFunctionOverflow = terror.ClassTypes.New(mysql.ErrDatetimeFunctionOverflow, mysql.MySQLErrName[mysql.ErrDatetimeFunctionOverflow])
// ErrInvalidTimeFormat is returned when the time format is not correct. // ErrCastAsSignedOverflow is returned when positive out-of-range integer, and convert to it's negative complement.
ErrInvalidTimeFormat = terror.ClassTypes.New(mysql.ErrTruncatedWrongValue, "invalid time format: '%v'") ErrCastAsSignedOverflow = terror.ClassTypes.New(mysql.ErrCastAsSignedOverflow, mysql.MySQLErrName[mysql.ErrCastAsSignedOverflow])
// ErrInvalidWeekModeFormat is returned when the week mode is wrong. // ErrCastNegIntAsUnsigned is returned when a negative integer be casted to an unsigned int.
ErrInvalidWeekModeFormat = terror.ClassTypes.New(mysql.ErrTruncatedWrongValue, "invalid week mode format: '%v'") ErrCastNegIntAsUnsigned = terror.ClassTypes.New(mysql.ErrCastNegIntAsUnsigned, mysql.MySQLErrName[mysql.ErrCastNegIntAsUnsigned])
// ErrInvalidYearFormat is returned when the input is not a valid year format. // ErrInvalidYearFormat is returned when the input is not a valid year format.
ErrInvalidYearFormat = errors.New("invalid year format") ErrInvalidYearFormat = terror.ClassTypes.New(mysql.ErrInvalidYearFormat, mysql.MySQLErrName[mysql.ErrInvalidYearFormat])
// ErrInvalidYear is returned when the input value is not a valid year. // ErrInvalidYear is returned when the input value is not a valid year.
ErrInvalidYear = errors.New("invalid year") ErrInvalidYear = terror.ClassTypes.New(mysql.ErrInvalidYear, mysql.MySQLErrName[mysql.ErrInvalidYear])
// ErrIncorrectDatetimeValue is returned when the input is not valid date time value. // ErrTruncatedWrongVal is returned when data has been truncated during conversion.
ErrIncorrectDatetimeValue = terror.ClassTypes.New(mysql.ErrTruncatedWrongValue, "Incorrect datetime value: '%s'") ErrTruncatedWrongVal = terror.ClassTypes.New(mysql.ErrTruncatedWrongValue, mysql.MySQLErrName[mysql.ErrTruncatedWrongValue])
// ErrTruncatedWrongValue is returned then // ErrInvalidWeekModeFormat is returned when the week mode is wrong.
ErrTruncatedWrongValue = terror.ClassTypes.New(mysql.ErrTruncatedWrongValue, mysql.MySQLErrName[mysql.ErrTruncatedWrongValue]) ErrInvalidWeekModeFormat = terror.ClassTypes.New(mysql.ErrInvalidWeekModeFormat, mysql.MySQLErrName[mysql.ErrInvalidWeekModeFormat])
) // ErrWrongValue is returned when the input value is in wrong format.
ErrWrongValue = terror.ClassTypes.New(mysql.ErrWrongValue, mysql.MySQLErrName[mysql.ErrWrongValue])
const (
codeBadNumber terror.ErrCode = 1
codeDataTooLong = terror.ErrCode(mysql.ErrDataTooLong)
codeIllegalValueForType = terror.ErrCode(mysql.ErrIllegalValueForType)
codeTruncated = terror.ErrCode(mysql.WarnDataTruncated)
codeOverflow = terror.ErrCode(mysql.ErrDataOutOfRange)
codeDivByZero = terror.ErrCode(mysql.ErrDivisionByZero)
codeTooBigDisplayWidth = terror.ErrCode(mysql.ErrTooBigDisplaywidth)
codeTooBigFieldLength = terror.ErrCode(mysql.ErrTooBigFieldlength)
codeTooBigSet = terror.ErrCode(mysql.ErrTooBigSet)
codeTooBigScale = terror.ErrCode(mysql.ErrTooBigScale)
codeTooBigPrecision = terror.ErrCode(mysql.ErrTooBigPrecision)
codeWrongFieldSpec = terror.ErrCode(mysql.ErrWrongFieldSpec)
codeTruncatedWrongValue = terror.ErrCode(mysql.ErrTruncatedWrongValue)
codeUnknown = terror.ErrCode(mysql.ErrUnknown)
codeInvalidDefault = terror.ErrCode(mysql.ErrInvalidDefault)
codeInvalidFieldSize = terror.ErrCode(mysql.ErrInvalidFieldSize)
codeMBiggerThanD = terror.ErrCode(mysql.ErrMBiggerThanD)
codeDataOutOfRange = terror.ErrCode(mysql.ErrWarnDataOutOfRange)
codeDuplicatedValueInType = terror.ErrCode(mysql.ErrDuplicatedValueInType)
codeDatetimeFunctionOverflow = terror.ErrCode(mysql.ErrDatetimeFunctionOverflow)
)
var (
msgOverflow = mysql.MySQLErrName[mysql.ErrDataOutOfRange]
msgTruncatedWrongVal = mysql.MySQLErrName[mysql.ErrTruncatedWrongValue]
msgCastAsSignedOverflow = "Cast to signed converted positive out-of-range integer to it's negative complement"
msgCastNegIntAsUnsigned = "Cast to unsigned converted negative integer to it's positive complement"
) )
func init() { func init() {
typesMySQLErrCodes := map[terror.ErrCode]uint16{ typesMySQLErrCodes := map[terror.ErrCode]uint16{
codeDataTooLong: mysql.ErrDataTooLong, mysql.ErrInvalidDefault: mysql.ErrInvalidDefault,
codeIllegalValueForType: mysql.ErrIllegalValueForType, mysql.ErrDataTooLong: mysql.ErrDataTooLong,
codeTruncated: mysql.WarnDataTruncated, mysql.ErrIllegalValueForType: mysql.ErrIllegalValueForType,
codeOverflow: mysql.ErrDataOutOfRange, mysql.WarnDataTruncated: mysql.WarnDataTruncated,
codeDivByZero: mysql.ErrDivisionByZero, mysql.ErrDataOutOfRange: mysql.ErrDataOutOfRange,
codeTooBigDisplayWidth: mysql.ErrTooBigDisplaywidth, mysql.ErrDivisionByZero: mysql.ErrDivisionByZero,
codeTooBigFieldLength: mysql.ErrTooBigFieldlength, mysql.ErrTooBigDisplaywidth: mysql.ErrTooBigDisplaywidth,
codeTooBigSet: mysql.ErrTooBigSet, mysql.ErrTooBigFieldlength: mysql.ErrTooBigFieldlength,
codeTooBigScale: mysql.ErrTooBigScale, mysql.ErrTooBigSet: mysql.ErrTooBigSet,
codeTooBigPrecision: mysql.ErrTooBigPrecision, mysql.ErrTooBigScale: mysql.ErrTooBigScale,
codeWrongFieldSpec: mysql.ErrWrongFieldSpec, mysql.ErrTooBigPrecision: mysql.ErrTooBigPrecision,
codeTruncatedWrongValue: mysql.ErrTruncatedWrongValue, mysql.ErrBadNumber: mysql.ErrBadNumber,
codeUnknown: mysql.ErrUnknown, mysql.ErrInvalidFieldSize: mysql.ErrInvalidFieldSize,
codeInvalidDefault: mysql.ErrInvalidDefault, mysql.ErrMBiggerThanD: mysql.ErrMBiggerThanD,
codeInvalidFieldSize: mysql.ErrInvalidFieldSize, mysql.ErrWarnDataOutOfRange: mysql.ErrWarnDataOutOfRange,
codeMBiggerThanD: mysql.ErrMBiggerThanD, mysql.ErrDuplicatedValueInType: mysql.ErrDuplicatedValueInType,
codeDataOutOfRange: mysql.ErrWarnDataOutOfRange, mysql.ErrDatetimeFunctionOverflow: mysql.ErrDatetimeFunctionOverflow,
codeDuplicatedValueInType: mysql.ErrDuplicatedValueInType, mysql.ErrCastAsSignedOverflow: mysql.ErrCastAsSignedOverflow,
codeDatetimeFunctionOverflow: mysql.ErrDatetimeFunctionOverflow, mysql.ErrCastNegIntAsUnsigned: mysql.ErrCastNegIntAsUnsigned,
mysql.ErrInvalidYearFormat: mysql.ErrInvalidYearFormat,
mysql.ErrInvalidYear: mysql.ErrInvalidYear,
mysql.ErrTruncatedWrongValue: mysql.ErrTruncatedWrongValue,
mysql.ErrInvalidTimeFormat: mysql.ErrInvalidTimeFormat,
mysql.ErrInvalidWeekModeFormat: mysql.ErrInvalidWeekModeFormat,
mysql.ErrWrongValue: mysql.ErrWrongValue,
} }
terror.ErrClassToMySQLCodes[terror.ClassTypes] = typesMySQLErrCodes terror.ErrClassToMySQLCodes[terror.ClassTypes] = typesMySQLErrCodes
} }
...@@ -26,17 +26,37 @@ type FieldName struct { ...@@ -26,17 +26,37 @@ type FieldName struct {
DBName model.CIStr DBName model.CIStr
TblName model.CIStr TblName model.CIStr
ColName model.CIStr ColName model.CIStr
Hidden bool
} }
const emptyName = "EMPTY_NAME"
// String implements Stringer interface. // String implements Stringer interface.
func (name *FieldName) String() string { func (name *FieldName) String() string {
builder := strings.Builder{} builder := strings.Builder{}
if name.TblName.L != "" { if name.Hidden {
builder.WriteString(name.TblName.L + ".") return emptyName
} }
if name.DBName.L != "" { if name.DBName.L != "" {
builder.WriteString(name.DBName.L + ".") builder.WriteString(name.DBName.L + ".")
} }
if name.TblName.L != "" {
builder.WriteString(name.TblName.L + ".")
}
builder.WriteString(name.ColName.L) builder.WriteString(name.ColName.L)
return builder.String() return builder.String()
} }
// NameSlice is the slice of the *fieldName
type NameSlice []*FieldName
// Shallow is a shallow copy, only making a new slice.
func (s NameSlice) Shallow() NameSlice {
ret := make(NameSlice, len(s))
copy(ret, s)
return ret
}
// EmptyName is to occupy the position in the name slice. If it's set, that column's name is hidden.
var EmptyName = &FieldName{Hidden: true}
...@@ -219,17 +219,17 @@ func DefaultTypeForValue(value interface{}, tp *FieldType) { ...@@ -219,17 +219,17 @@ func DefaultTypeForValue(value interface{}, tp *FieldType) {
tp.Flag &= ^mysql.BinaryFlag tp.Flag &= ^mysql.BinaryFlag
tp.Flag |= mysql.UnsignedFlag tp.Flag |= mysql.UnsignedFlag
case Time: case Time:
tp.Tp = x.Type tp.Tp = x.Type()
switch x.Type { switch x.Type() {
case mysql.TypeDate: case mysql.TypeDate:
tp.Flen = mysql.MaxDateWidth tp.Flen = mysql.MaxDateWidth
tp.Decimal = UnspecifiedLength tp.Decimal = UnspecifiedLength
case mysql.TypeDatetime, mysql.TypeTimestamp: case mysql.TypeDatetime, mysql.TypeTimestamp:
tp.Flen = mysql.MaxDatetimeWidthNoFsp tp.Flen = mysql.MaxDatetimeWidthNoFsp
if x.Fsp > DefaultFsp { // consider point('.') and the fractional part. if x.Fsp() > DefaultFsp { // consider point('.') and the fractional part.
tp.Flen += int(x.Fsp) + 1 tp.Flen += int(x.Fsp()) + 1
} }
tp.Decimal = int(x.Fsp) tp.Decimal = int(x.Fsp())
} }
SetBinChsClnFlag(tp) SetBinChsClnFlag(tp)
case Duration: case Duration:
......
...@@ -357,23 +357,6 @@ func marshalStringTo(buf, s []byte) []byte { ...@@ -357,23 +357,6 @@ func marshalStringTo(buf, s []byte) []byte {
return buf return buf
} }
func (bj BinaryJSON) marshalValueEntryTo(buf []byte, entryOff int) ([]byte, error) {
tpCode := bj.Value[entryOff]
switch tpCode {
case TypeCodeLiteral:
buf = marshalLiteralTo(buf, bj.Value[entryOff+1])
default:
offset := endian.Uint32(bj.Value[entryOff+1:])
tmp := BinaryJSON{TypeCode: tpCode, Value: bj.Value[offset:]}
var err error
buf, err = tmp.marshalTo(buf)
if err != nil {
return nil, errors.Trace(err)
}
}
return buf, nil
}
func marshalLiteralTo(b []byte, litType byte) []byte { func marshalLiteralTo(b []byte, litType byte) []byte {
switch litType { switch litType {
case LiteralFalse: case LiteralFalse:
......
...@@ -19,7 +19,6 @@ import ( ...@@ -19,7 +19,6 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"sort" "sort"
"strconv"
"unicode/utf8" "unicode/utf8"
"unsafe" "unsafe"
...@@ -55,33 +54,33 @@ func (bj BinaryJSON) Type() string { ...@@ -55,33 +54,33 @@ func (bj BinaryJSON) Type() string {
} }
} }
// Quote is for JSON_QUOTE
func (bj BinaryJSON) Quote() string {
str := hack.String(bj.GetString())
return strconv.Quote(string(str))
}
// Unquote is for JSON_UNQUOTE. // Unquote is for JSON_UNQUOTE.
func (bj BinaryJSON) Unquote() (string, error) { func (bj BinaryJSON) Unquote() (string, error) {
switch bj.TypeCode { switch bj.TypeCode {
case TypeCodeString: case TypeCodeString:
tmp := string(hack.String(bj.GetString())) str := string(hack.String(bj.GetString()))
tlen := len(tmp) return UnquoteString(str)
if tlen < 2 {
return tmp, nil
}
head, tail := tmp[0], tmp[tlen-1]
if head == '"' && tail == '"' {
// Remove prefix and suffix '"' before unquoting
return unquoteString(tmp[1 : tlen-1])
}
// if value is not double quoted, do nothing
return tmp, nil
default: default:
return bj.String(), nil return bj.String(), nil
} }
} }
// UnquoteString remove quotes in a string,
// including the quotes at the head and tail of string.
func UnquoteString(str string) (string, error) {
strLen := len(str)
if strLen < 2 {
return str, nil
}
head, tail := str[0], str[strLen-1]
if head == '"' && tail == '"' {
// Remove prefix and suffix '"' before unquoting
return unquoteString(str[1 : strLen-1])
}
// if value is not double quoted, do nothing
return str, nil
}
// unquoteString recognizes the escape sequences shown in: // unquoteString recognizes the escape sequences shown in:
// https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#json-unquote-character-escape-sequences // https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#json-unquote-character-escape-sequences
func unquoteString(s string) (string, error) { func unquoteString(s string) (string, error) {
......
...@@ -250,6 +250,11 @@ func (d *MyDecimal) GetDigitsFrac() int8 { ...@@ -250,6 +250,11 @@ func (d *MyDecimal) GetDigitsFrac() int8 {
return d.digitsFrac return d.digitsFrac
} }
// GetDigitsInt returns the digitsInt.
func (d *MyDecimal) GetDigitsInt() int8 {
return d.digitsInt
}
// String returns the decimal string representation rounded to resultFrac. // String returns the decimal string representation rounded to resultFrac.
func (d *MyDecimal) String() string { func (d *MyDecimal) String() string {
tmp := *d tmp := *d
...@@ -1781,10 +1786,10 @@ func doAdd(from1, from2, to *MyDecimal) error { ...@@ -1781,10 +1786,10 @@ func doAdd(from1, from2, to *MyDecimal) error {
stop = 0 stop = 0
if wordsInt1 > wordsInt2 { if wordsInt1 > wordsInt2 {
idx1 = wordsInt1 - wordsInt2 idx1 = wordsInt1 - wordsInt2
dec1, dec2 = from1, from2 dec1 = from1
} else { } else {
idx1 = wordsInt2 - wordsInt1 idx1 = wordsInt2 - wordsInt1
dec1, dec2 = from2, from1 dec1 = from2
} }
for idx1 > stop { for idx1 > stop {
idxTo-- idxTo--
......
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
gotime "time" gotime "time"
"fmt" "fmt"
"github.com/pingcap/errors" "github.com/pingcap/errors"
) )
...@@ -121,7 +122,7 @@ func (t MysqlTime) GoTime(loc *gotime.Location) (gotime.Time, error) { ...@@ -121,7 +122,7 @@ func (t MysqlTime) GoTime(loc *gotime.Location) (gotime.Time, error) {
if year != t.Year() || int(month) != t.Month() || day != t.Day() || if year != t.Year() || int(month) != t.Month() || day != t.Day() ||
hour != t.Hour() || minute != t.Minute() || second != t.Second() || hour != t.Hour() || minute != t.Minute() || second != t.Second() ||
microsec != t.Microsecond() { microsec != t.Microsecond() {
return tm, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(t)) return tm, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, t))
} }
return tm, nil return tm, nil
} }
......
...@@ -49,6 +49,16 @@ func AddDuration(a time.Duration, b time.Duration) (time.Duration, error) { ...@@ -49,6 +49,16 @@ func AddDuration(a time.Duration, b time.Duration) (time.Duration, error) {
return a + b, nil return a + b, nil
} }
// SubDuration subtracts time.Duration a with b and returns time.Duration if no overflow error.
func SubDuration(a time.Duration, b time.Duration) (time.Duration, error) {
if (a > 0 && b < 0 && math.MaxInt64-a < -b) ||
(a < 0 && b > 0 && math.MinInt64-a > -b) ||
(a == 0 && b == math.MinInt64) {
return 0, ErrOverflow.GenWithStackByArgs("BIGINT", fmt.Sprintf("(%d, %d)", a, b))
}
return a - b, nil
}
// AddInteger adds uint64 a and int64 b and returns uint64 if no overflow error. // AddInteger adds uint64 a and int64 b and returns uint64 if no overflow error.
func AddInteger(a uint64, b int64) (uint64, error) { func AddInteger(a uint64, b int64) (uint64, error) {
if b >= 0 { if b >= 0 {
......
...@@ -106,8 +106,12 @@ func (n *ValueExpr) Restore(ctx *format.RestoreCtx) error { ...@@ -106,8 +106,12 @@ func (n *ValueExpr) Restore(ctx *format.RestoreCtx) error {
} else { } else {
ctx.WritePlain(n.GetBinaryLiteral().ToBitLiteralString(true)) ctx.WritePlain(n.GetBinaryLiteral().ToBitLiteralString(true))
} }
case types.KindMysqlDuration, types.KindMysqlEnum, case types.KindMysqlDuration:
types.KindMysqlBit, types.KindMysqlSet, types.KindMysqlTime, ctx.WritePlainf("'%s'", n.GetMysqlDuration())
case types.KindMysqlTime:
ctx.WritePlainf("'%s'", n.GetMysqlTime())
case types.KindMysqlEnum,
types.KindMysqlBit, types.KindMysqlSet,
types.KindInterface, types.KindMinNotNull, types.KindMaxValue, types.KindInterface, types.KindMinNotNull, types.KindMaxValue,
types.KindRaw, types.KindMysqlJSON: types.KindRaw, types.KindMysqlJSON:
// TODO implement Restore function // TODO implement Restore function
......
...@@ -117,28 +117,31 @@ var ( ...@@ -117,28 +117,31 @@ var (
// ZeroDuration is the zero value for Duration type. // ZeroDuration is the zero value for Duration type.
ZeroDuration = Duration{Duration: gotime.Duration(0), Fsp: DefaultFsp} ZeroDuration = Duration{Duration: gotime.Duration(0), Fsp: DefaultFsp}
// ZeroTime is the zero value for TimeInternal type. // ZeroCoreTime is the zero value for TimeInternal type.
ZeroTime = MysqlTime{} ZeroCoreTime = MysqlTime{}
// ZeroCoreTime is the zero value for Time type.
ZeroTime = Time{}
// ZeroDatetime is the zero value for datetime Time. // ZeroDatetime is the zero value for datetime Time.
ZeroDatetime = Time{ ZeroDatetime = Time{
Time: ZeroTime, time: ZeroCoreTime,
Type: mysql.TypeDatetime, tp: mysql.TypeDatetime,
Fsp: DefaultFsp, fsp: DefaultFsp,
} }
// ZeroTimestamp is the zero value for timestamp Time. // ZeroTimestamp is the zero value for timestamp Time.
ZeroTimestamp = Time{ ZeroTimestamp = Time{
Time: ZeroTime, time: ZeroCoreTime,
Type: mysql.TypeTimestamp, tp: mysql.TypeTimestamp,
Fsp: DefaultFsp, fsp: DefaultFsp,
} }
// ZeroDate is the zero value for date Time. // ZeroDate is the zero value for date Time.
ZeroDate = Time{ ZeroDate = Time{
Time: ZeroTime, time: ZeroCoreTime,
Type: mysql.TypeDate, tp: mysql.TypeDate,
Fsp: DefaultFsp, fsp: DefaultFsp,
} }
) )
...@@ -152,15 +155,15 @@ var ( ...@@ -152,15 +155,15 @@ var (
BoundTimezone = gotime.UTC BoundTimezone = gotime.UTC
// MinTimestamp is the minimum for mysql timestamp type. // MinTimestamp is the minimum for mysql timestamp type.
MinTimestamp = Time{ MinTimestamp = Time{
Time: FromDate(1970, 1, 1, 0, 0, 1, 0), time: FromDate(1970, 1, 1, 0, 0, 1, 0),
Type: mysql.TypeTimestamp, tp: mysql.TypeTimestamp,
Fsp: DefaultFsp, fsp: DefaultFsp,
} }
// MaxTimestamp is the maximum for mysql timestamp type. // MaxTimestamp is the maximum for mysql timestamp type.
MaxTimestamp = Time{ MaxTimestamp = Time{
Time: FromDate(2038, 1, 19, 3, 14, 7, 999999), time: FromDate(2038, 1, 19, 3, 14, 7, 999999),
Type: mysql.TypeTimestamp, tp: mysql.TypeTimestamp,
Fsp: DefaultFsp, fsp: DefaultFsp,
} }
// WeekdayNames lists names of weekdays, which are used in builtin time function `dayname`. // WeekdayNames lists names of weekdays, which are used in builtin time function `dayname`.
...@@ -216,47 +219,147 @@ func FromDate(year int, month int, day int, hour int, minute int, second int, mi ...@@ -216,47 +219,147 @@ func FromDate(year int, month int, day int, hour int, minute int, second int, mi
} }
} }
// MaxMySQLTime returns Duration with maximum mysql time.
func MaxMySQLTime(fsp int8) Time {
return NewTime(FromDate(0, 0, 0, TimeMaxHour, TimeMaxMinute, TimeMaxSecond, 0), mysql.TypeDuration, fsp)
}
// Clock returns the hour, minute, and second within the day specified by t. // Clock returns the hour, minute, and second within the day specified by t.
func (t Time) Clock() (hour int, minute int, second int) { func (t Time) Clock() (hour int, minute int, second int) {
return t.Time.Hour(), t.Time.Minute(), t.Time.Second() return t.time.Hour(), t.time.Minute(), t.time.Second()
} }
// Time is the struct for handling datetime, timestamp and date. // Time is the struct for handling datetime, timestamp and date.
// TODO: check if need a NewTime function to set Fsp default value? // TODO: check if need a NewTime function to set Fsp default value?
type Time struct { type Time struct {
Time MysqlTime time MysqlTime
Type uint8 tp uint8
// Fsp is short for Fractional Seconds Precision. // Fsp is short for Fractional Seconds Precision.
// See http://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html // See http://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html
Fsp int8 fsp int8
} }
// MaxMySQLTime returns Time with maximum mysql time type. // NewTime constructs time from core time, type and fsp.
func MaxMySQLTime(fsp int8) Time { func NewTime(mt MysqlTime, tp uint8, fsp int8) Time {
return Time{Time: FromDate(0, 0, 0, TimeMaxHour, TimeMaxMinute, TimeMaxSecond, 0), Type: mysql.TypeDuration, Fsp: fsp} return Time{
time: mt,
tp: tp,
fsp: fsp,
}
}
// Year returns year value.
func (t Time) Year() int {
return t.time.Year()
}
// Month returns month value.
func (t Time) Month() int {
return t.time.Month()
}
// Day returns day value.
func (t Time) Day() int {
return t.time.Day()
}
// Hour returns hour value.
func (t Time) Hour() int {
return t.time.Hour()
}
// Minute returns minute value.
func (t Time) Minute() int {
return t.time.Minute()
}
// Second returns second value.
func (t Time) Second() int {
return t.time.Second()
}
// Microsecond returns microsecond value.
func (t Time) Microsecond() int {
return t.time.Microsecond()
}
// Type returns type value.
func (t Time) Type() uint8 {
return t.tp
}
// Fsp returns fsp value.
func (t Time) Fsp() int8 {
return t.fsp
}
// SetType updates the type in Time.
// Only DateTime/Date/Time is valid.
func (t *Time) SetType(tp uint8) {
t.tp = tp
}
// SetFsp updates the fsp in Time.
func (t *Time) SetFsp(fsp int8) {
t.fsp = fsp
}
// CoreTime returns core time.
func (t Time) CoreTime() MysqlTime {
return t.time
}
// SetCoreTime updates core time.
func (t *Time) SetCoreTime(mt MysqlTime) {
t.time = mt
}
// GoTime converts Time to GoTime.
func (t Time) GoTime(loc *gotime.Location) (gotime.Time, error) {
return t.time.GoTime(loc)
}
// Weekday returns weekday value.
func (t Time) Weekday() gotime.Weekday {
return t.time.Weekday()
}
// YearWeek returns year and week.
func (t Time) YearWeek(mode int) (int, int) {
return t.time.YearWeek(mode)
}
// Week returns week value.
func (t Time) Week(mode int) int {
return t.time.Week(mode)
}
// YearDay returns year and day.
func (t Time) YearDay() int {
return t.time.YearDay()
} }
// CurrentTime returns current time with type tp. // CurrentTime returns current time with type tp.
func CurrentTime(tp uint8) Time { func CurrentTime(tp uint8) Time {
return Time{Time: FromGoTime(gotime.Now()), Type: tp, Fsp: 0} return Time{time: FromGoTime(gotime.Now()), tp: tp, fsp: 0}
} }
// ConvertTimeZone converts the time value from one timezone to another. // ConvertTimeZone converts the time value from one timezone to another.
// The input time should be a valid timestamp. // The input time should be a valid timestamp.
func (t *Time) ConvertTimeZone(from, to *gotime.Location) error { func (t *Time) ConvertTimeZone(from, to *gotime.Location) error {
if !t.IsZero() { if !t.IsZero() {
raw, err := t.Time.GoTime(from) raw, err := t.time.GoTime(from)
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
converted := raw.In(to) converted := raw.In(to)
t.Time = FromGoTime(converted) t.time = FromGoTime(converted)
} }
return nil return nil
} }
func (t Time) String() string { func (t Time) String() string {
if t.Type == mysql.TypeDate { if t.tp == mysql.TypeDate {
// We control the format, so no error would occur. // We control the format, so no error would occur.
str, err := t.DateFormat("%Y-%m-%d") str, err := t.DateFormat("%Y-%m-%d")
terror.Log(errors.Trace(err)) terror.Log(errors.Trace(err))
...@@ -265,22 +368,22 @@ func (t Time) String() string { ...@@ -265,22 +368,22 @@ func (t Time) String() string {
str, err := t.DateFormat("%Y-%m-%d %H:%i:%s") str, err := t.DateFormat("%Y-%m-%d %H:%i:%s")
terror.Log(errors.Trace(err)) terror.Log(errors.Trace(err))
if t.Fsp > 0 { if t.fsp > 0 {
tmp := fmt.Sprintf(".%06d", t.Time.Microsecond()) tmp := fmt.Sprintf(".%06d", t.time.Microsecond())
str = str + tmp[:1+t.Fsp] str = str + tmp[:1+t.fsp]
} }
return str return str
} }
// IsZero returns a boolean indicating whether the time is equal to ZeroTime. // IsZero returns a boolean indicating whether the time is equal to ZeroCoreTime.
func (t Time) IsZero() bool { func (t Time) IsZero() bool {
return compareTime(t.Time, ZeroTime) == 0 return compareTime(t.time, ZeroCoreTime) == 0
} }
// InvalidZero returns a boolean indicating whether the month or day is zero. // InvalidZero returns a boolean indicating whether the month or day is zero.
func (t Time) InvalidZero() bool { func (t Time) InvalidZero() bool {
return t.Time.Month() == 0 || t.Time.Day() == 0 return t.time.Month() == 0 || t.time.Day() == 0
} }
const numberFormat = "%Y%m%d%H%i%s" const numberFormat = "%Y%m%d%H%i%s"
...@@ -308,7 +411,7 @@ func (t Time) FillNumber(dec *MyDecimal) { ...@@ -308,7 +411,7 @@ func (t Time) FillNumber(dec *MyDecimal) {
// Fix issue #1046 // Fix issue #1046
// Prevents from converting 2012-12-12 to 20121212000000 // Prevents from converting 2012-12-12 to 20121212000000
var tfStr string var tfStr string
if t.Type == mysql.TypeDate { if t.tp == mysql.TypeDate {
tfStr = dateFormat tfStr = dateFormat
} else { } else {
tfStr = numberFormat tfStr = numberFormat
...@@ -319,9 +422,9 @@ func (t Time) FillNumber(dec *MyDecimal) { ...@@ -319,9 +422,9 @@ func (t Time) FillNumber(dec *MyDecimal) {
logutil.BgLogger().Error("[fatal] never happen because we've control the format!") logutil.BgLogger().Error("[fatal] never happen because we've control the format!")
} }
if t.Fsp > 0 { if t.fsp > 0 {
s1 := fmt.Sprintf("%s.%06d", s, t.Time.Microsecond()) s1 := fmt.Sprintf("%s.%06d", s, t.time.Microsecond())
s = s1[:len(s)+int(t.Fsp)+1] s = s1[:len(s)+int(t.fsp)+1]
} }
// We skip checking error here because time formatted string can be parsed certainly. // We skip checking error here because time formatted string can be parsed certainly.
err = dec.FromString([]byte(s)) err = dec.FromString([]byte(s))
...@@ -330,11 +433,11 @@ func (t Time) FillNumber(dec *MyDecimal) { ...@@ -330,11 +433,11 @@ func (t Time) FillNumber(dec *MyDecimal) {
// Convert converts t with type tp. // Convert converts t with type tp.
func (t Time) Convert(sc *stmtctx.StatementContext, tp uint8) (Time, error) { func (t Time) Convert(sc *stmtctx.StatementContext, tp uint8) (Time, error) {
if t.Type == tp || t.IsZero() { if t.tp == tp || t.IsZero() {
return Time{Time: t.Time, Type: tp, Fsp: t.Fsp}, nil return Time{time: t.time, tp: tp, fsp: t.fsp}, nil
} }
t1 := Time{Time: t.Time, Type: tp, Fsp: t.Fsp} t1 := Time{time: t.time, tp: tp, fsp: t.fsp}
err := t1.check(sc) err := t1.check(sc)
return t1, errors.Trace(err) return t1, errors.Trace(err)
} }
...@@ -349,17 +452,17 @@ func (t Time) ConvertToDuration() (Duration, error) { ...@@ -349,17 +452,17 @@ func (t Time) ConvertToDuration() (Duration, error) {
} }
hour, minute, second := t.Clock() hour, minute, second := t.Clock()
frac := t.Time.Microsecond() * 1000 frac := t.time.Microsecond() * 1000
d := gotime.Duration(hour*3600+minute*60+second)*gotime.Second + gotime.Duration(frac) d := gotime.Duration(hour*3600+minute*60+second)*gotime.Second + gotime.Duration(frac)
// TODO: check convert validation // TODO: check convert validation
return Duration{Duration: d, Fsp: t.Fsp}, nil return Duration{Duration: d, Fsp: t.fsp}, nil
} }
// Compare returns an integer comparing the time instant t to o. // Compare returns an integer comparing the time instant t to o.
// If t is after o, return 1, equal o, return 0, before o, return -1. // If t is after o, returns 1, equal o, returns 0, before o, returns -1.
func (t Time) Compare(o Time) int { func (t Time) Compare(o Time) int {
return compareTime(t.Time, o.Time) return compareTime(t.time, o.time)
} }
// compareTime compare two MysqlTime. // compareTime compare two MysqlTime.
...@@ -392,7 +495,7 @@ func compareTime(a, b MysqlTime) int { ...@@ -392,7 +495,7 @@ func compareTime(a, b MysqlTime) int {
// but parses string to Time then compares. // but parses string to Time then compares.
func (t Time) CompareString(sc *stmtctx.StatementContext, str string) (int, error) { func (t Time) CompareString(sc *stmtctx.StatementContext, str string) (int, error) {
// use MaxFsp to parse the string // use MaxFsp to parse the string
o, err := ParseTime(sc, str, t.Type, MaxFsp) o, err := ParseTime(sc, str, t.tp, MaxFsp)
if err != nil { if err != nil {
return 0, errors.Trace(err) return 0, errors.Trace(err)
} }
...@@ -408,7 +511,7 @@ func roundTime(t gotime.Time, fsp int8) gotime.Time { ...@@ -408,7 +511,7 @@ func roundTime(t gotime.Time, fsp int8) gotime.Time {
// RoundFrac rounds the fraction part of a time-type value according to `fsp`. // RoundFrac rounds the fraction part of a time-type value according to `fsp`.
func (t Time) RoundFrac(sc *stmtctx.StatementContext, fsp int8) (Time, error) { func (t Time) RoundFrac(sc *stmtctx.StatementContext, fsp int8) (Time, error) {
if t.Type == mysql.TypeDate || t.IsZero() { if t.tp == mysql.TypeDate || t.IsZero() {
// date type has no fsp // date type has no fsp
return t, nil return t, nil
} }
...@@ -418,19 +521,19 @@ func (t Time) RoundFrac(sc *stmtctx.StatementContext, fsp int8) (Time, error) { ...@@ -418,19 +521,19 @@ func (t Time) RoundFrac(sc *stmtctx.StatementContext, fsp int8) (Time, error) {
return t, errors.Trace(err) return t, errors.Trace(err)
} }
if fsp == t.Fsp { if fsp == t.fsp {
// have same fsp // have same fsp
return t, nil return t, nil
} }
var nt MysqlTime var nt MysqlTime
if t1, err := t.Time.GoTime(sc.TimeZone); err == nil { if t1, err := t.time.GoTime(sc.TimeZone); err == nil {
t1 = roundTime(t1, fsp) t1 = roundTime(t1, fsp)
nt = FromGoTime(t1) nt = FromGoTime(t1)
} else { } else {
// Take the hh:mm:ss part out to avoid handle month or day = 0. // Take the hh:mm:ss part out to avoid handle month or day = 0.
hour, minute, second, microsecond := t.Time.Hour(), t.Time.Minute(), t.Time.Second(), t.Time.Microsecond() hour, minute, second, microsecond := t.time.Hour(), t.time.Minute(), t.time.Second(), t.time.Microsecond()
t1 := gotime.Date(1, 1, 1, hour, minute, second, microsecond*1000, gotime.Local) t1 := gotime.Date(1, 1, 1, hour, minute, second, microsecond*1000, sc.TimeZone)
t2 := roundTime(t1, fsp) t2 := roundTime(t1, fsp)
hour, minute, second = t2.Clock() hour, minute, second = t2.Clock()
microsecond = t2.Nanosecond() / 1000 microsecond = t2.Nanosecond() / 1000
...@@ -438,12 +541,12 @@ func (t Time) RoundFrac(sc *stmtctx.StatementContext, fsp int8) (Time, error) { ...@@ -438,12 +541,12 @@ func (t Time) RoundFrac(sc *stmtctx.StatementContext, fsp int8) (Time, error) {
// TODO: when hh:mm:ss overflow one day after rounding, it should be add to yy:mm:dd part, // TODO: when hh:mm:ss overflow one day after rounding, it should be add to yy:mm:dd part,
// but mm:dd may contain 0, it makes the code complex, so we ignore it here. // but mm:dd may contain 0, it makes the code complex, so we ignore it here.
if t2.Day()-1 > 0 { if t2.Day()-1 > 0 {
return t, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(t.String())) return t, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, t.String()))
} }
nt = FromDate(t.Time.Year(), t.Time.Month(), t.Time.Day(), hour, minute, second, microsecond) nt = FromDate(t.time.Year(), t.time.Month(), t.time.Day(), hour, minute, second, microsecond)
} }
return Time{Time: nt, Type: t.Type, Fsp: fsp}, nil return Time{time: nt, tp: t.tp, fsp: fsp}, nil
} }
// GetFsp gets the fsp of a string. // GetFsp gets the fsp of a string.
...@@ -517,7 +620,7 @@ func TruncateFrac(t gotime.Time, fsp int8) (gotime.Time, error) { ...@@ -517,7 +620,7 @@ func TruncateFrac(t gotime.Time, fsp int8) (gotime.Time, error) {
// 0YYYYYYY.YYYYYYYY.YYdddddh.hhhhmmmm.mmssssss.ffffffff.ffffffff.ffffffff // 0YYYYYYY.YYYYYYYY.YYdddddh.hhhhmmmm.mmssssss.ffffffff.ffffffff.ffffffff
// //
func (t Time) ToPackedUint() (uint64, error) { func (t Time) ToPackedUint() (uint64, error) {
tm := t.Time tm := t.time
if t.IsZero() { if t.IsZero() {
return 0, nil return 0, nil
} }
...@@ -532,7 +635,7 @@ func (t Time) ToPackedUint() (uint64, error) { ...@@ -532,7 +635,7 @@ func (t Time) ToPackedUint() (uint64, error) {
// FromPackedUint decodes Time from a packed uint64 value. // FromPackedUint decodes Time from a packed uint64 value.
func (t *Time) FromPackedUint(packed uint64) error { func (t *Time) FromPackedUint(packed uint64) error {
if packed == 0 { if packed == 0 {
t.Time = ZeroTime t.time = ZeroCoreTime
return nil return nil
} }
ymdhms := packed >> 24 ymdhms := packed >> 24
...@@ -548,7 +651,7 @@ func (t *Time) FromPackedUint(packed uint64) error { ...@@ -548,7 +651,7 @@ func (t *Time) FromPackedUint(packed uint64) error {
hour := int(hms >> 12) hour := int(hms >> 12)
microsec := int(packed % (1 << 24)) microsec := int(packed % (1 << 24))
t.Time = FromDate(year, month, day, hour, minute, second, microsec) t.time = FromDate(year, month, day, hour, minute, second, microsec)
return nil return nil
} }
...@@ -565,13 +668,11 @@ func (t *Time) check(sc *stmtctx.StatementContext) error { ...@@ -565,13 +668,11 @@ func (t *Time) check(sc *stmtctx.StatementContext) error {
allowInvalidDate = sc.AllowInvalidDate allowInvalidDate = sc.AllowInvalidDate
} }
var err error var err error
switch t.Type { switch t.tp {
case mysql.TypeTimestamp: case mysql.TypeTimestamp:
err = checkTimestampType(sc, t.Time) err = checkTimestampType(sc, t.time)
case mysql.TypeDatetime: case mysql.TypeDatetime, mysql.TypeDate:
err = checkDatetimeType(t.Time, allowZeroInDate, allowInvalidDate) err = checkDatetimeType(t.time, allowZeroInDate, allowInvalidDate)
case mysql.TypeDate:
err = checkDateType(t.Time, allowZeroInDate, allowInvalidDate)
} }
return errors.Trace(err) return errors.Trace(err)
} }
...@@ -585,23 +686,23 @@ func (t *Time) Check(sc *stmtctx.StatementContext) error { ...@@ -585,23 +686,23 @@ func (t *Time) Check(sc *stmtctx.StatementContext) error {
// Note that sub should not be done on different time types. // Note that sub should not be done on different time types.
func (t *Time) Sub(sc *stmtctx.StatementContext, t1 *Time) Duration { func (t *Time) Sub(sc *stmtctx.StatementContext, t1 *Time) Duration {
var duration gotime.Duration var duration gotime.Duration
if t.Type == mysql.TypeTimestamp && t1.Type == mysql.TypeTimestamp { if t.tp == mysql.TypeTimestamp && t1.tp == mysql.TypeTimestamp {
a, err := t.Time.GoTime(sc.TimeZone) a, err := t.time.GoTime(sc.TimeZone)
terror.Log(errors.Trace(err)) terror.Log(errors.Trace(err))
b, err := t1.Time.GoTime(sc.TimeZone) b, err := t1.time.GoTime(sc.TimeZone)
terror.Log(errors.Trace(err)) terror.Log(errors.Trace(err))
duration = a.Sub(b) duration = a.Sub(b)
} else { } else {
seconds, microseconds, neg := calcTimeDiff(t.Time, t1.Time, 1) seconds, microseconds, neg := calcTimeDiff(t.time, t1.time, 1)
duration = gotime.Duration(seconds*1e9 + microseconds*1e3) duration = gotime.Duration(seconds*1e9 + microseconds*1e3)
if neg { if neg {
duration = -duration duration = -duration
} }
} }
fsp := t.Fsp fsp := t.fsp
if fsp < t1.Fsp { if fsp < t1.fsp {
fsp = t1.Fsp fsp = t1.fsp
} }
return Duration{ return Duration{
Duration: duration, Duration: duration,
...@@ -612,26 +713,26 @@ func (t *Time) Sub(sc *stmtctx.StatementContext, t1 *Time) Duration { ...@@ -612,26 +713,26 @@ func (t *Time) Sub(sc *stmtctx.StatementContext, t1 *Time) Duration {
// Add adds d to t, returns the result time value. // Add adds d to t, returns the result time value.
func (t *Time) Add(sc *stmtctx.StatementContext, d Duration) (Time, error) { func (t *Time) Add(sc *stmtctx.StatementContext, d Duration) (Time, error) {
sign, hh, mm, ss, micro := splitDuration(d.Duration) sign, hh, mm, ss, micro := splitDuration(d.Duration)
seconds, microseconds, _ := calcTimeDiff(t.Time, FromDate(0, 0, 0, hh, mm, ss, micro), -sign) seconds, microseconds, _ := calcTimeDiff(t.time, FromDate(0, 0, 0, hh, mm, ss, micro), -sign)
days := seconds / secondsIn24Hour days := seconds / secondsIn24Hour
year, month, day := getDateFromDaynr(uint(days)) year, month, day := getDateFromDaynr(uint(days))
var tm MysqlTime var tm MysqlTime
tm.year, tm.month, tm.day = uint16(year), uint8(month), uint8(day) tm.year, tm.month, tm.day = uint16(year), uint8(month), uint8(day)
calcTimeFromSec(&tm, seconds%secondsIn24Hour, microseconds) calcTimeFromSec(&tm, seconds%secondsIn24Hour, microseconds)
if t.Type == mysql.TypeDate { if t.tp == mysql.TypeDate {
tm.hour = 0 tm.hour = 0
tm.minute = 0 tm.minute = 0
tm.second = 0 tm.second = 0
tm.microsecond = 0 tm.microsecond = 0
} }
fsp := t.Fsp fsp := t.fsp
if d.Fsp > fsp { if d.Fsp > fsp {
fsp = d.Fsp fsp = d.Fsp
} }
ret := Time{ ret := Time{
Time: tm, time: tm,
Type: t.Type, tp: t.tp,
Fsp: fsp, fsp: fsp,
} }
return ret, ret.Check(sc) return ret, ret.Check(sc)
} }
...@@ -640,7 +741,7 @@ func (t *Time) Add(sc *stmtctx.StatementContext, d Duration) (Time, error) { ...@@ -640,7 +741,7 @@ func (t *Time) Add(sc *stmtctx.StatementContext, d Duration) (Time, error) {
// The unit for the result (an integer) is given by the unit argument. // The unit for the result (an integer) is given by the unit argument.
// The legal values for unit are "YEAR" "QUARTER" "MONTH" "DAY" "HOUR" "SECOND" and so on. // The legal values for unit are "YEAR" "QUARTER" "MONTH" "DAY" "HOUR" "SECOND" and so on.
func TimestampDiff(unit string, t1 Time, t2 Time) int64 { func TimestampDiff(unit string, t1 Time, t2 Time) int64 {
return timestampDiff(unit, t1.Time, t2.Time) return timestampDiff(unit, t1.time, t2.time)
} }
// ParseDateFormat parses a formatted date string and returns separated components. // ParseDateFormat parses a formatted date string and returns separated components.
...@@ -735,7 +836,7 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b ...@@ -735,7 +836,7 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b
_, err = fmt.Sscanf(seps[0], "%2d%2d%2d", &year, &month, &day) _, err = fmt.Sscanf(seps[0], "%2d%2d%2d", &year, &month, &day)
year = adjustYear(year) year = adjustYear(year)
default: default:
return ZeroDatetime, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(str)) return ZeroDatetime, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, str))
} }
if l == 5 || l == 6 || l == 8 { if l == 5 || l == 6 || l == 8 {
// YYMMDD or YYYYMMDD // YYMMDD or YYYYMMDD
...@@ -767,13 +868,13 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b ...@@ -767,13 +868,13 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b
truncatedOrIncorrect = err != nil truncatedOrIncorrect = err != nil
} }
if truncatedOrIncorrect && sc != nil { if truncatedOrIncorrect && sc != nil {
sc.AppendWarning(ErrTruncatedWrongValue.GenWithStackByArgs("datetime", str)) sc.AppendWarning(ErrTruncatedWrongVal.GenWithStackByArgs("datetime", str))
err = nil err = nil
} }
case 2: case 2:
// YYYY-MM is not valid // YYYY-MM is not valid
if len(fracStr) == 0 { if len(fracStr) == 0 {
return ZeroDatetime, errors.Trace(ErrIncorrectDatetimeValue.GenWithStackByArgs(str)) return ZeroDatetime, errors.Trace(ErrWrongValue.GenWithStackByArgs(DateTimeStr, str))
} }
// YYYY-MM.DD, DD is treat as fracStr // YYYY-MM.DD, DD is treat as fracStr
...@@ -794,7 +895,7 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b ...@@ -794,7 +895,7 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b
err = scanTimeArgs(seps, &year, &month, &day, &hour, &minute, &second) err = scanTimeArgs(seps, &year, &month, &day, &hour, &minute, &second)
hhmmss = true hhmmss = true
default: default:
return ZeroDatetime, errors.Trace(ErrIncorrectDatetimeValue.GenWithStackByArgs(str)) return ZeroDatetime, errors.Trace(ErrWrongValue.GenWithStackByArgs(DateTimeStr, str))
} }
if err != nil { if err != nil {
return ZeroDatetime, errors.Trace(err) return ZeroDatetime, errors.Trace(err)
...@@ -824,7 +925,7 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b ...@@ -824,7 +925,7 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b
tmp := FromDate(year, month, day, hour, minute, second, microsecond) tmp := FromDate(year, month, day, hour, minute, second, microsecond)
if overflow { if overflow {
// Convert to Go time and add 1 second, to handle input like 2017-01-05 08:40:59.575601 // Convert to Go time and add 1 second, to handle input like 2017-01-05 08:40:59.575601
t1, err := tmp.GoTime(gotime.Local) t1, err := tmp.GoTime(sc.TimeZone)
if err != nil { if err != nil {
return ZeroDatetime, errors.Trace(err) return ZeroDatetime, errors.Trace(err)
} }
...@@ -832,16 +933,16 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b ...@@ -832,16 +933,16 @@ func parseDatetime(sc *stmtctx.StatementContext, str string, fsp int8, isFloat b
} }
nt := Time{ nt := Time{
Time: tmp, time: tmp,
Type: mysql.TypeDatetime, tp: mysql.TypeDatetime,
Fsp: fsp} fsp: fsp}
return nt, nil return nt, nil
} }
func scanTimeArgs(seps []string, args ...*int) error { func scanTimeArgs(seps []string, args ...*int) error {
if len(seps) != len(args) { if len(seps) != len(args) {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(seps)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, seps))
} }
var err error var err error
...@@ -901,6 +1002,14 @@ func AdjustYear(y int64, shouldAdjust bool) (int64, error) { ...@@ -901,6 +1002,14 @@ func AdjustYear(y int64, shouldAdjust bool) (int64, error) {
return y, nil return y, nil
} }
// NewDuration construct duration with time.
func NewDuration(hour, minute, second, microsecond int, fsp int8) Duration {
return Duration{
Duration: gotime.Duration(hour)*gotime.Hour + gotime.Duration(minute)*gotime.Minute + gotime.Duration(second)*gotime.Second,
Fsp: fsp,
}
}
// Duration is the type for MySQL TIME type. // Duration is the type for MySQL TIME type.
type Duration struct { type Duration struct {
gotime.Duration gotime.Duration
...@@ -911,7 +1020,7 @@ type Duration struct { ...@@ -911,7 +1020,7 @@ type Duration struct {
//Add adds d to d, returns a duration value. //Add adds d to d, returns a duration value.
func (d Duration) Add(v Duration) (Duration, error) { func (d Duration) Add(v Duration) (Duration, error) {
if &v == nil { if v == (Duration{}) {
return d, nil return d, nil
} }
dsum, err := AddInt64(int64(d.Duration), int64(v.Duration)) dsum, err := AddInt64(int64(d.Duration), int64(v.Duration))
...@@ -926,7 +1035,7 @@ func (d Duration) Add(v Duration) (Duration, error) { ...@@ -926,7 +1035,7 @@ func (d Duration) Add(v Duration) (Duration, error) {
// Sub subtracts d to d, returns a duration value. // Sub subtracts d to d, returns a duration value.
func (d Duration) Sub(v Duration) (Duration, error) { func (d Duration) Sub(v Duration) (Duration, error) {
if &v == nil { if v == (Duration{}) {
return d, nil return d, nil
} }
dsum, err := SubInt64(int64(d.Duration), int64(v.Duration)) dsum, err := SubInt64(int64(d.Duration), int64(v.Duration))
...@@ -1001,9 +1110,9 @@ func (d Duration) ConvertToTime(sc *stmtctx.StatementContext, tp uint8) (Time, e ...@@ -1001,9 +1110,9 @@ func (d Duration) ConvertToTime(sc *stmtctx.StatementContext, tp uint8) (Time, e
mixDateAndTime(&datePart, &timePart, sign < 0) mixDateAndTime(&datePart, &timePart, sign < 0)
t := Time{ t := Time{
Time: datePart, time: datePart,
Type: mysql.TypeDatetime, tp: mysql.TypeDatetime,
Fsp: d.Fsp, fsp: d.Fsp,
} }
return t.Convert(sc, tp) return t.Convert(sc, tp)
} }
...@@ -1028,7 +1137,7 @@ func (d Duration) RoundFrac(fsp int8) (Duration, error) { ...@@ -1028,7 +1137,7 @@ func (d Duration) RoundFrac(fsp int8) (Duration, error) {
} }
// Compare returns an integer comparing the Duration instant t to o. // Compare returns an integer comparing the Duration instant t to o.
// If d is after o, return 1, equal o, return 0, before o, return -1. // If d is after o, returns 1, equal o, returns 0, before o, returns -1.
func (d Duration) Compare(o Duration) int { func (d Duration) Compare(o Duration) int {
if d.Duration > o.Duration { if d.Duration > o.Duration {
return 1 return 1
...@@ -1203,7 +1312,7 @@ func ParseDuration(sc *stmtctx.StatementContext, str string, fsp int8) (Duration ...@@ -1203,7 +1312,7 @@ func ParseDuration(sc *stmtctx.StatementContext, str string, fsp int8) (Duration
return Duration{Duration: d, Fsp: fsp}, errors.Trace(err) return Duration{Duration: d, Fsp: fsp}, errors.Trace(err)
} }
// TruncateOverflowMySQLTime truncates d when it overflows, and return ErrTruncatedWrongVal. // TruncateOverflowMySQLTime truncates d when it overflows, and returns ErrTruncatedWrongVal.
func TruncateOverflowMySQLTime(d gotime.Duration) (gotime.Duration, error) { func TruncateOverflowMySQLTime(d gotime.Duration) (gotime.Duration, error) {
if d > MaxTime { if d > MaxTime {
return MaxTime, ErrTruncatedWrongVal.GenWithStackByArgs("time", d) return MaxTime, ErrTruncatedWrongVal.GenWithStackByArgs("time", d)
...@@ -1249,9 +1358,9 @@ func getTime(sc *stmtctx.StatementContext, num int64, tp byte) (Time, error) { ...@@ -1249,9 +1358,9 @@ func getTime(sc *stmtctx.StatementContext, num int64, tp byte) (Time, error) {
second := int(s2 % 100) second := int(s2 % 100)
t := Time{ t := Time{
Time: FromDate(year, month, day, hour, minute, second, 0), time: FromDate(year, month, day, hour, minute, second, 0),
Type: tp, tp: tp,
Fsp: DefaultFsp, fsp: DefaultFsp,
} }
err := t.check(sc) err := t.check(sc)
return t, errors.Trace(err) return t, errors.Trace(err)
...@@ -1269,73 +1378,73 @@ func parseDateTimeFromNum(sc *stmtctx.StatementContext, num int64) (Time, error) ...@@ -1269,73 +1378,73 @@ func parseDateTimeFromNum(sc *stmtctx.StatementContext, num int64) (Time, error)
// Check datetime type. // Check datetime type.
if num >= 10000101000000 { if num >= 10000101000000 {
t.Type = mysql.TypeDatetime t.tp = mysql.TypeDatetime
return getTime(sc, num, t.Type) return getTime(sc, num, t.tp)
} }
// Check MMDD. // Check MMDD.
if num < 101 { if num < 101 {
return t, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(num)) return t, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, strconv.FormatInt(num, 10)))
} }
// Adjust year // Adjust year
// YYMMDD, year: 2000-2069 // YYMMDD, year: 2000-2069
if num <= (70-1)*10000+1231 { if num <= (70-1)*10000+1231 {
num = (num + 20000000) * 1000000 num = (num + 20000000) * 1000000
return getTime(sc, num, t.Type) return getTime(sc, num, t.tp)
} }
// Check YYMMDD. // Check YYMMDD.
if num < 70*10000+101 { if num < 70*10000+101 {
return t, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(num)) return t, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, num))
} }
// Adjust year // Adjust year
// YYMMDD, year: 1970-1999 // YYMMDD, year: 1970-1999
if num <= 991231 { if num <= 991231 {
num = (num + 19000000) * 1000000 num = (num + 19000000) * 1000000
return getTime(sc, num, t.Type) return getTime(sc, num, t.tp)
} }
// Check YYYYMMDD. // Check YYYYMMDD.
if num < 10000101 { if num < 10000101 {
return t, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(num)) return t, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, num))
} }
// Adjust hour/min/second. // Adjust hour/min/second.
if num <= 99991231 { if num <= 99991231 {
num = num * 1000000 num = num * 1000000
return getTime(sc, num, t.Type) return getTime(sc, num, t.tp)
} }
// Check MMDDHHMMSS. // Check MMDDHHMMSS.
if num < 101000000 { if num < 101000000 {
return t, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(num)) return t, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, num))
} }
// Set TypeDatetime type. // Set TypeDatetime type.
t.Type = mysql.TypeDatetime t.tp = mysql.TypeDatetime
// Adjust year // Adjust year
// YYMMDDHHMMSS, 2000-2069 // YYMMDDHHMMSS, 2000-2069
if num <= 69*10000000000+1231235959 { if num <= 69*10000000000+1231235959 {
num = num + 20000000000000 num = num + 20000000000000
return getTime(sc, num, t.Type) return getTime(sc, num, t.tp)
} }
// Check YYYYMMDDHHMMSS. // Check YYYYMMDDHHMMSS.
if num < 70*10000000000+101000000 { if num < 70*10000000000+101000000 {
return t, errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(num)) return t, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, num))
} }
// Adjust year // Adjust year
// YYMMDDHHMMSS, 1970-1999 // YYMMDDHHMMSS, 1970-1999
if num <= 991231235959 { if num <= 991231235959 {
num = num + 19000000000000 num = num + 19000000000000
return getTime(sc, num, t.Type) return getTime(sc, num, t.tp)
} }
return getTime(sc, num, t.Type) return getTime(sc, num, t.tp)
} }
// ParseTime parses a formatted string with type tp and specific fsp. // ParseTime parses a formatted string with type tp and specific fsp.
...@@ -1355,23 +1464,27 @@ func ParseTime(sc *stmtctx.StatementContext, str string, tp byte, fsp int8) (Tim ...@@ -1355,23 +1464,27 @@ func ParseTime(sc *stmtctx.StatementContext, str string, tp byte, fsp int8) (Tim
// ParseTimeFromFloatString is similar to ParseTime, except that it's used to parse a float converted string. // ParseTimeFromFloatString is similar to ParseTime, except that it's used to parse a float converted string.
func ParseTimeFromFloatString(sc *stmtctx.StatementContext, str string, tp byte, fsp int8) (Time, error) { func ParseTimeFromFloatString(sc *stmtctx.StatementContext, str string, tp byte, fsp int8) (Time, error) {
// MySQL compatibility: 0.0 should not be converted to null, see #11203
if len(str) >= 3 && str[:3] == "0.0" {
return Time{time: ZeroCoreTime, tp: tp}, nil
}
return parseTime(sc, str, tp, fsp, true) return parseTime(sc, str, tp, fsp, true)
} }
func parseTime(sc *stmtctx.StatementContext, str string, tp byte, fsp int8, isFloat bool) (Time, error) { func parseTime(sc *stmtctx.StatementContext, str string, tp byte, fsp int8, isFloat bool) (Time, error) {
fsp, err := CheckFsp(int(fsp)) fsp, err := CheckFsp(int(fsp))
if err != nil { if err != nil {
return Time{Time: ZeroTime, Type: tp}, errors.Trace(err) return Time{time: ZeroCoreTime, tp: tp}, errors.Trace(err)
} }
t, err := parseDatetime(sc, str, fsp, isFloat) t, err := parseDatetime(sc, str, fsp, isFloat)
if err != nil { if err != nil {
return Time{Time: ZeroTime, Type: tp}, errors.Trace(err) return Time{time: ZeroCoreTime, tp: tp}, errors.Trace(err)
} }
t.Type = tp t.tp = tp
if err = t.check(sc); err != nil { if err = t.check(sc); err != nil {
return Time{Time: ZeroTime, Type: tp}, errors.Trace(err) return Time{time: ZeroCoreTime, tp: tp}, errors.Trace(err)
} }
return t, nil return t, nil
} }
...@@ -1395,20 +1508,24 @@ func ParseDate(sc *stmtctx.StatementContext, str string) (Time, error) { ...@@ -1395,20 +1508,24 @@ func ParseDate(sc *stmtctx.StatementContext, str string) (Time, error) {
// ParseTimeFromNum parses a formatted int64, // ParseTimeFromNum parses a formatted int64,
// returns the value which type is tp. // returns the value which type is tp.
func ParseTimeFromNum(sc *stmtctx.StatementContext, num int64, tp byte, fsp int8) (Time, error) { func ParseTimeFromNum(sc *stmtctx.StatementContext, num int64, tp byte, fsp int8) (Time, error) {
// MySQL compatibility: 0 should not be converted to null, see #11203
if num == 0 {
return Time{time: ZeroCoreTime, tp: tp}, nil
}
fsp, err := CheckFsp(int(fsp)) fsp, err := CheckFsp(int(fsp))
if err != nil { if err != nil {
return Time{Time: ZeroTime, Type: tp}, errors.Trace(err) return Time{time: ZeroCoreTime, tp: tp}, errors.Trace(err)
} }
t, err := parseDateTimeFromNum(sc, num) t, err := parseDateTimeFromNum(sc, num)
if err != nil { if err != nil {
return Time{Time: ZeroTime, Type: tp}, errors.Trace(err) return Time{time: ZeroCoreTime, tp: tp}, errors.Trace(err)
} }
t.Type = tp t.tp = tp
t.Fsp = fsp t.fsp = fsp
if err := t.check(sc); err != nil { if err := t.check(sc); err != nil {
return Time{Time: ZeroTime, Type: tp}, errors.Trace(err) return Time{time: ZeroCoreTime, tp: tp}, errors.Trace(err)
} }
return t, nil return t, nil
} }
...@@ -1433,17 +1550,17 @@ func ParseDateFromNum(sc *stmtctx.StatementContext, num int64) (Time, error) { ...@@ -1433,17 +1550,17 @@ func ParseDateFromNum(sc *stmtctx.StatementContext, num int64) (Time, error) {
func TimeFromDays(num int64) Time { func TimeFromDays(num int64) Time {
if num < 0 { if num < 0 {
return Time{ return Time{
Time: FromDate(0, 0, 0, 0, 0, 0, 0), time: FromDate(0, 0, 0, 0, 0, 0, 0),
Type: mysql.TypeDate, tp: mysql.TypeDate,
Fsp: 0, fsp: 0,
} }
} }
year, month, day := getDateFromDaynr(uint(num)) year, month, day := getDateFromDaynr(uint(num))
return Time{ return Time{
Time: FromDate(int(year), int(month), int(day), 0, 0, 0, 0), time: FromDate(int(year), int(month), int(day), 0, 0, 0, 0),
Type: mysql.TypeDate, tp: mysql.TypeDate,
Fsp: 0, fsp: 0,
} }
} }
...@@ -1454,7 +1571,7 @@ func checkDateType(t MysqlTime, allowZeroInDate, allowInvalidDate bool) error { ...@@ -1454,7 +1571,7 @@ func checkDateType(t MysqlTime, allowZeroInDate, allowInvalidDate bool) error {
} }
if !allowZeroInDate && (month == 0 || day == 0) { if !allowZeroInDate && (month == 0 || day == 0) {
return ErrIncorrectDatetimeValue.GenWithStackByArgs(fmt.Sprintf("%04d-%02d-%02d", year, month, day)) return ErrWrongValue.GenWithStackByArgs(DateTimeStr, fmt.Sprintf("%04d-%02d-%02d", year, month, day))
} }
if err := checkDateRange(t); err != nil { if err := checkDateRange(t); err != nil {
...@@ -1472,17 +1589,17 @@ func checkDateRange(t MysqlTime) error { ...@@ -1472,17 +1589,17 @@ func checkDateRange(t MysqlTime) error {
// Oddly enough, MySQL document says date range should larger than '1000-01-01', // Oddly enough, MySQL document says date range should larger than '1000-01-01',
// but we can insert '0001-01-01' actually. // but we can insert '0001-01-01' actually.
if t.Year() < 0 || t.Month() < 0 || t.Day() < 0 { if t.Year() < 0 || t.Month() < 0 || t.Day() < 0 {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(t)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, t))
} }
if compareTime(t, MaxDatetime) > 0 { if compareTime(t, MaxDatetime) > 0 {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(t)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, t))
} }
return nil return nil
} }
func checkMonthDay(year, month, day int, allowInvalidDate bool) error { func checkMonthDay(year, month, day int, allowInvalidDate bool) error {
if month < 0 || month > 12 { if month < 0 || month > 12 {
return errors.Trace(ErrIncorrectDatetimeValue.GenWithStackByArgs(fmt.Sprintf("%d-%d-%d", year, month, day))) return errors.Trace(ErrWrongValue.GenWithStackByArgs(DateTimeStr, fmt.Sprintf("%d-%d-%d", year, month, day)))
} }
maxDay := 31 maxDay := 31
...@@ -1496,13 +1613,13 @@ func checkMonthDay(year, month, day int, allowInvalidDate bool) error { ...@@ -1496,13 +1613,13 @@ func checkMonthDay(year, month, day int, allowInvalidDate bool) error {
} }
if day < 0 || day > maxDay { if day < 0 || day > maxDay {
return errors.Trace(ErrIncorrectDatetimeValue.GenWithStackByArgs(fmt.Sprintf("%d-%d-%d", year, month, day))) return errors.Trace(ErrWrongValue.GenWithStackByArgs(DateTimeStr, fmt.Sprintf("%d-%d-%d", year, month, day)))
} }
return nil return nil
} }
func checkTimestampType(sc *stmtctx.StatementContext, t MysqlTime) error { func checkTimestampType(sc *stmtctx.StatementContext, t MysqlTime) error {
if compareTime(t, ZeroTime) == 0 { if compareTime(t, ZeroCoreTime) == 0 {
return nil return nil
} }
...@@ -1512,20 +1629,20 @@ func checkTimestampType(sc *stmtctx.StatementContext, t MysqlTime) error { ...@@ -1512,20 +1629,20 @@ func checkTimestampType(sc *stmtctx.StatementContext, t MysqlTime) error {
var checkTime MysqlTime var checkTime MysqlTime
if sc.TimeZone != BoundTimezone { if sc.TimeZone != BoundTimezone {
convertTime := Time{Time: t, Type: mysql.TypeTimestamp} convertTime := Time{time: t, tp: mysql.TypeTimestamp}
err := convertTime.ConvertTimeZone(sc.TimeZone, BoundTimezone) err := convertTime.ConvertTimeZone(sc.TimeZone, BoundTimezone)
if err != nil { if err != nil {
return err return err
} }
checkTime = convertTime.Time checkTime = convertTime.time
} else { } else {
checkTime = t checkTime = t
} }
if compareTime(checkTime, MaxTimestamp.Time) > 0 || compareTime(checkTime, MinTimestamp.Time) < 0 { if compareTime(checkTime, MaxTimestamp.time) > 0 || compareTime(checkTime, MinTimestamp.time) < 0 {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(t)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, t))
} }
if _, err := t.GoTime(gotime.Local); err != nil { if _, err := t.GoTime(sc.TimeZone); err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
...@@ -1539,13 +1656,13 @@ func checkDatetimeType(t MysqlTime, allowZeroInDate, allowInvalidDate bool) erro ...@@ -1539,13 +1656,13 @@ func checkDatetimeType(t MysqlTime, allowZeroInDate, allowInvalidDate bool) erro
hour, minute, second := t.Hour(), t.Minute(), t.Second() hour, minute, second := t.Hour(), t.Minute(), t.Second()
if hour < 0 || hour >= 24 { if hour < 0 || hour >= 24 {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(hour)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, hour))
} }
if minute < 0 || minute >= 60 { if minute < 0 || minute >= 60 {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(minute)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, minute))
} }
if second < 0 || second >= 60 { if second < 0 || second >= 60 {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(second)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, second))
} }
return nil return nil
...@@ -1556,39 +1673,39 @@ func ExtractDatetimeNum(t *Time, unit string) (int64, error) { ...@@ -1556,39 +1673,39 @@ func ExtractDatetimeNum(t *Time, unit string) (int64, error) {
// TODO: Consider time_zone variable. // TODO: Consider time_zone variable.
switch strings.ToUpper(unit) { switch strings.ToUpper(unit) {
case "DAY": case "DAY":
return int64(t.Time.Day()), nil return int64(t.time.Day()), nil
case "WEEK": case "WEEK":
week := t.Time.Week(0) week := t.time.Week(0)
return int64(week), nil return int64(week), nil
case "MONTH": case "MONTH":
return int64(t.Time.Month()), nil return int64(t.time.Month()), nil
case "QUARTER": case "QUARTER":
m := int64(t.Time.Month()) m := int64(t.time.Month())
// 1 - 3 -> 1 // 1 - 3 -> 1
// 4 - 6 -> 2 // 4 - 6 -> 2
// 7 - 9 -> 3 // 7 - 9 -> 3
// 10 - 12 -> 4 // 10 - 12 -> 4
return (m + 2) / 3, nil return (m + 2) / 3, nil
case "YEAR": case "YEAR":
return int64(t.Time.Year()), nil return int64(t.time.Year()), nil
case "DAY_MICROSECOND": case "DAY_MICROSECOND":
h, m, s := t.Clock() h, m, s := t.Clock()
d := t.Time.Day() d := t.time.Day()
return int64(d*1000000+h*10000+m*100+s)*1000000 + int64(t.Time.Microsecond()), nil return int64(d*1000000+h*10000+m*100+s)*1000000 + int64(t.time.Microsecond()), nil
case "DAY_SECOND": case "DAY_SECOND":
h, m, s := t.Clock() h, m, s := t.Clock()
d := t.Time.Day() d := t.time.Day()
return int64(d)*1000000 + int64(h)*10000 + int64(m)*100 + int64(s), nil return int64(d)*1000000 + int64(h)*10000 + int64(m)*100 + int64(s), nil
case "DAY_MINUTE": case "DAY_MINUTE":
h, m, _ := t.Clock() h, m, _ := t.Clock()
d := t.Time.Day() d := t.time.Day()
return int64(d)*10000 + int64(h)*100 + int64(m), nil return int64(d)*10000 + int64(h)*100 + int64(m), nil
case "DAY_HOUR": case "DAY_HOUR":
h, _, _ := t.Clock() h, _, _ := t.Clock()
d := t.Time.Day() d := t.time.Day()
return int64(d)*100 + int64(h), nil return int64(d)*100 + int64(h), nil
case "YEAR_MONTH": case "YEAR_MONTH":
y, m := t.Time.Year(), t.Time.Month() y, m := t.time.Year(), t.time.Month()
return int64(y)*100 + int64(m), nil return int64(y)*100 + int64(m), nil
default: default:
return 0, errors.Errorf("invalid unit %s", unit) return 0, errors.Errorf("invalid unit %s", unit)
...@@ -1638,7 +1755,7 @@ func parseSingleTimeValue(unit string, format string, strictCheck bool) (int64, ...@@ -1638,7 +1755,7 @@ func parseSingleTimeValue(unit string, format string, strictCheck bool) (int64,
} }
iv, err := strconv.ParseInt(format[0:decimalPointPos], 10, 64) iv, err := strconv.ParseInt(format[0:decimalPointPos], 10, 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(format) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, format)
} }
riv := iv // Rounded integer value riv := iv // Rounded integer value
...@@ -1649,18 +1766,18 @@ func parseSingleTimeValue(unit string, format string, strictCheck bool) (int64, ...@@ -1649,18 +1766,18 @@ func parseSingleTimeValue(unit string, format string, strictCheck bool) (int64,
if lf-decimalPointPos >= 6 { if lf-decimalPointPos >= 6 {
// MySQL rounds down to 1e-6. // MySQL rounds down to 1e-6.
if dv, err = strconv.ParseInt(format[decimalPointPos+1:decimalPointPos+7], 10, 64); err != nil { if dv, err = strconv.ParseInt(format[decimalPointPos+1:decimalPointPos+7], 10, 64); err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(format) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, format)
} }
} else { } else {
if dv, err = strconv.ParseInt(format[decimalPointPos+1:]+"000000"[:6-(lf-decimalPointPos)], 10, 64); err != nil { if dv, err = strconv.ParseInt(format[decimalPointPos+1:]+"000000"[:6-(lf-decimalPointPos)], 10, 64); err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(format) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, format)
} }
} }
if dv >= 500000 { // Round up, and we should keep 6 digits for microsecond, so dv should in [000000, 999999]. if dv >= 500000 { // Round up, and we should keep 6 digits for microsecond, so dv should in [000000, 999999].
riv += sign riv += sign
} }
if unit != "SECOND" { if unit != "SECOND" {
err = ErrTruncatedWrongValue.GenWithStackByArgs(format) err = ErrTruncatedWrongVal.GenWithStackByArgs(format)
} }
dv *= sign dv *= sign
} }
...@@ -1741,7 +1858,7 @@ func parseTimeValue(format string, index, cnt int) (int64, int64, int64, int64, ...@@ -1741,7 +1858,7 @@ func parseTimeValue(format string, index, cnt int) (int64, int64, int64, int64,
} }
matches := numericRegex.FindAllString(format, -1) matches := numericRegex.FindAllString(format, -1)
if len(matches) > cnt { if len(matches) > cnt {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(originalFmt) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, originalFmt)
} }
for i := range matches { for i := range matches {
if neg { if neg {
...@@ -1754,32 +1871,32 @@ func parseTimeValue(format string, index, cnt int) (int64, int64, int64, int64, ...@@ -1754,32 +1871,32 @@ func parseTimeValue(format string, index, cnt int) (int64, int64, int64, int64,
years, err := strconv.ParseInt(fields[YearIndex], 10, 64) years, err := strconv.ParseInt(fields[YearIndex], 10, 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(originalFmt) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, originalFmt)
} }
months, err := strconv.ParseInt(fields[MonthIndex], 10, 64) months, err := strconv.ParseInt(fields[MonthIndex], 10, 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(originalFmt) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, originalFmt)
} }
days, err := strconv.ParseInt(fields[DayIndex], 10, 64) days, err := strconv.ParseInt(fields[DayIndex], 10, 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(originalFmt) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, originalFmt)
} }
hours, err := strconv.ParseInt(fields[HourIndex], 10, 64) hours, err := strconv.ParseInt(fields[HourIndex], 10, 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(originalFmt) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, originalFmt)
} }
minutes, err := strconv.ParseInt(fields[MinuteIndex], 10, 64) minutes, err := strconv.ParseInt(fields[MinuteIndex], 10, 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(originalFmt) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, originalFmt)
} }
seconds, err := strconv.ParseInt(fields[SecondIndex], 10, 64) seconds, err := strconv.ParseInt(fields[SecondIndex], 10, 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(originalFmt) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, originalFmt)
} }
microseconds, err := strconv.ParseInt(alignFrac(fields[MicrosecondIndex], int(MaxFsp)), 10, 64) microseconds, err := strconv.ParseInt(alignFrac(fields[MicrosecondIndex], int(MaxFsp)), 10, 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, ErrIncorrectDatetimeValue.GenWithStackByArgs(originalFmt) return 0, 0, 0, 0, ErrWrongValue.GenWithStackByArgs(DateTimeStr, originalFmt)
} }
seconds = hours*3600 + minutes*60 + seconds seconds = hours*3600 + minutes*60 + seconds
days += seconds / (3600 * 24) days += seconds / (3600 * 24)
...@@ -1915,7 +2032,7 @@ func ExtractDurationValue(unit string, format string) (Duration, error) { ...@@ -1915,7 +2032,7 @@ func ExtractDurationValue(unit string, format string) (Duration, error) {
if err != nil { if err != nil {
return ZeroDuration, err return ZeroDuration, err
} }
// MONTH must exceed the limit of mysql's duration. So just return overflow error. // MONTH must exceed the limit of mysql's duration. So just returns overflow error.
return ZeroDuration, ErrDatetimeFunctionOverflow.GenWithStackByArgs("time") return ZeroDuration, ErrDatetimeFunctionOverflow.GenWithStackByArgs("time")
default: default:
return ZeroDuration, errors.Errorf("invalid single timeunit - %s", unit) return ZeroDuration, errors.Errorf("invalid single timeunit - %s", unit)
...@@ -1989,113 +2106,113 @@ var abbrevWeekdayName = []string{ ...@@ -1989,113 +2106,113 @@ var abbrevWeekdayName = []string{
func (t Time) convertDateFormat(b rune, buf *bytes.Buffer) error { func (t Time) convertDateFormat(b rune, buf *bytes.Buffer) error {
switch b { switch b {
case 'b': case 'b':
m := t.Time.Month() m := t.time.Month()
if m == 0 || m > 12 { if m == 0 || m > 12 {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(m)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, m))
} }
buf.WriteString(MonthNames[m-1][:3]) buf.WriteString(MonthNames[m-1][:3])
case 'M': case 'M':
m := t.Time.Month() m := t.time.Month()
if m == 0 || m > 12 { if m == 0 || m > 12 {
return errors.Trace(ErrInvalidTimeFormat.GenWithStackByArgs(m)) return errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, m))
} }
buf.WriteString(MonthNames[m-1]) buf.WriteString(MonthNames[m-1])
case 'm': case 'm':
buf.WriteString(FormatIntWidthN(t.Time.Month(), 2)) buf.WriteString(FormatIntWidthN(t.time.Month(), 2))
case 'c': case 'c':
buf.WriteString(strconv.FormatInt(int64(t.Time.Month()), 10)) buf.WriteString(strconv.FormatInt(int64(t.time.Month()), 10))
case 'D': case 'D':
buf.WriteString(strconv.FormatInt(int64(t.Time.Day()), 10)) buf.WriteString(strconv.FormatInt(int64(t.time.Day()), 10))
buf.WriteString(abbrDayOfMonth(t.Time.Day())) buf.WriteString(abbrDayOfMonth(t.time.Day()))
case 'd': case 'd':
buf.WriteString(FormatIntWidthN(t.Time.Day(), 2)) buf.WriteString(FormatIntWidthN(t.time.Day(), 2))
case 'e': case 'e':
buf.WriteString(strconv.FormatInt(int64(t.Time.Day()), 10)) buf.WriteString(strconv.FormatInt(int64(t.time.Day()), 10))
case 'j': case 'j':
fmt.Fprintf(buf, "%03d", t.Time.YearDay()) fmt.Fprintf(buf, "%03d", t.time.YearDay())
case 'H': case 'H':
buf.WriteString(FormatIntWidthN(t.Time.Hour(), 2)) buf.WriteString(FormatIntWidthN(t.time.Hour(), 2))
case 'k': case 'k':
buf.WriteString(strconv.FormatInt(int64(t.Time.Hour()), 10)) buf.WriteString(strconv.FormatInt(int64(t.time.Hour()), 10))
case 'h', 'I': case 'h', 'I':
t := t.Time.Hour() t := t.time.Hour()
if t%12 == 0 { if t%12 == 0 {
buf.WriteString("12") buf.WriteString("12")
} else { } else {
buf.WriteString(FormatIntWidthN(t%12, 2)) buf.WriteString(FormatIntWidthN(t%12, 2))
} }
case 'l': case 'l':
t := t.Time.Hour() t := t.time.Hour()
if t%12 == 0 { if t%12 == 0 {
buf.WriteString("12") buf.WriteString("12")
} else { } else {
buf.WriteString(strconv.FormatInt(int64(t%12), 10)) buf.WriteString(strconv.FormatInt(int64(t%12), 10))
} }
case 'i': case 'i':
buf.WriteString(FormatIntWidthN(t.Time.Minute(), 2)) buf.WriteString(FormatIntWidthN(t.time.Minute(), 2))
case 'p': case 'p':
hour := t.Time.Hour() hour := t.time.Hour()
if hour/12%2 == 0 { if hour/12%2 == 0 {
buf.WriteString("AM") buf.WriteString("AM")
} else { } else {
buf.WriteString("PM") buf.WriteString("PM")
} }
case 'r': case 'r':
h := t.Time.Hour() h := t.time.Hour()
h %= 24 h %= 24
switch { switch {
case h == 0: case h == 0:
fmt.Fprintf(buf, "%02d:%02d:%02d AM", 12, t.Time.Minute(), t.Time.Second()) fmt.Fprintf(buf, "%02d:%02d:%02d AM", 12, t.time.Minute(), t.time.Second())
case h == 12: case h == 12:
fmt.Fprintf(buf, "%02d:%02d:%02d PM", 12, t.Time.Minute(), t.Time.Second()) fmt.Fprintf(buf, "%02d:%02d:%02d PM", 12, t.time.Minute(), t.time.Second())
case h < 12: case h < 12:
fmt.Fprintf(buf, "%02d:%02d:%02d AM", h, t.Time.Minute(), t.Time.Second()) fmt.Fprintf(buf, "%02d:%02d:%02d AM", h, t.time.Minute(), t.time.Second())
default: default:
fmt.Fprintf(buf, "%02d:%02d:%02d PM", h-12, t.Time.Minute(), t.Time.Second()) fmt.Fprintf(buf, "%02d:%02d:%02d PM", h-12, t.time.Minute(), t.time.Second())
} }
case 'T': case 'T':
fmt.Fprintf(buf, "%02d:%02d:%02d", t.Time.Hour(), t.Time.Minute(), t.Time.Second()) fmt.Fprintf(buf, "%02d:%02d:%02d", t.time.Hour(), t.time.Minute(), t.time.Second())
case 'S', 's': case 'S', 's':
buf.WriteString(FormatIntWidthN(t.Time.Second(), 2)) buf.WriteString(FormatIntWidthN(t.time.Second(), 2))
case 'f': case 'f':
fmt.Fprintf(buf, "%06d", t.Time.Microsecond()) fmt.Fprintf(buf, "%06d", t.time.Microsecond())
case 'U': case 'U':
w := t.Time.Week(0) w := t.time.Week(0)
buf.WriteString(FormatIntWidthN(w, 2)) buf.WriteString(FormatIntWidthN(w, 2))
case 'u': case 'u':
w := t.Time.Week(1) w := t.time.Week(1)
buf.WriteString(FormatIntWidthN(w, 2)) buf.WriteString(FormatIntWidthN(w, 2))
case 'V': case 'V':
w := t.Time.Week(2) w := t.time.Week(2)
buf.WriteString(FormatIntWidthN(w, 2)) buf.WriteString(FormatIntWidthN(w, 2))
case 'v': case 'v':
_, w := t.Time.YearWeek(3) _, w := t.time.YearWeek(3)
buf.WriteString(FormatIntWidthN(w, 2)) buf.WriteString(FormatIntWidthN(w, 2))
case 'a': case 'a':
weekday := t.Time.Weekday() weekday := t.time.Weekday()
buf.WriteString(abbrevWeekdayName[weekday]) buf.WriteString(abbrevWeekdayName[weekday])
case 'W': case 'W':
buf.WriteString(t.Time.Weekday().String()) buf.WriteString(t.time.Weekday().String())
case 'w': case 'w':
buf.WriteString(strconv.FormatInt(int64(t.Time.Weekday()), 10)) buf.WriteString(strconv.FormatInt(int64(t.time.Weekday()), 10))
case 'X': case 'X':
year, _ := t.Time.YearWeek(2) year, _ := t.time.YearWeek(2)
if year < 0 { if year < 0 {
buf.WriteString(strconv.FormatUint(uint64(math.MaxUint32), 10)) buf.WriteString(strconv.FormatUint(uint64(math.MaxUint32), 10))
} else { } else {
buf.WriteString(FormatIntWidthN(year, 4)) buf.WriteString(FormatIntWidthN(year, 4))
} }
case 'x': case 'x':
year, _ := t.Time.YearWeek(3) year, _ := t.time.YearWeek(3)
if year < 0 { if year < 0 {
buf.WriteString(strconv.FormatUint(uint64(math.MaxUint32), 10)) buf.WriteString(strconv.FormatUint(uint64(math.MaxUint32), 10))
} else { } else {
buf.WriteString(FormatIntWidthN(year, 4)) buf.WriteString(FormatIntWidthN(year, 4))
} }
case 'Y': case 'Y':
buf.WriteString(FormatIntWidthN(t.Time.Year(), 4)) buf.WriteString(FormatIntWidthN(t.time.Year(), 4))
case 'y': case 'y':
str := FormatIntWidthN(t.Time.Year(), 4) str := FormatIntWidthN(t.time.Year(), 4)
buf.WriteString(str[2:]) buf.WriteString(str[2:])
default: default:
buf.WriteRune(b) buf.WriteRune(b)
...@@ -2138,17 +2255,17 @@ func (t *Time) StrToDate(sc *stmtctx.StatementContext, date, format string) bool ...@@ -2138,17 +2255,17 @@ func (t *Time) StrToDate(sc *stmtctx.StatementContext, date, format string) bool
ctx := make(map[string]int) ctx := make(map[string]int)
var tm MysqlTime var tm MysqlTime
if !strToDate(&tm, date, format, ctx) { if !strToDate(&tm, date, format, ctx) {
t.Time = ZeroTime t.time = ZeroCoreTime
t.Type = mysql.TypeDatetime t.tp = mysql.TypeDatetime
t.Fsp = 0 t.fsp = 0
return false return false
} }
if err := mysqlTimeFix(&tm, ctx); err != nil { if err := mysqlTimeFix(&tm, ctx); err != nil {
return false return false
} }
t.Time = tm t.time = tm
t.Type = mysql.TypeDatetime t.tp = mysql.TypeDatetime
return t.check(sc) == nil return t.check(sc) == nil
} }
...@@ -2161,10 +2278,10 @@ func mysqlTimeFix(t *MysqlTime, ctx map[string]int) error { ...@@ -2161,10 +2278,10 @@ func mysqlTimeFix(t *MysqlTime, ctx map[string]int) error {
} }
if valueAMorPm, ok := ctx["%p"]; ok { if valueAMorPm, ok := ctx["%p"]; ok {
if _, ok := ctx["%H"]; ok { if _, ok := ctx["%H"]; ok {
return ErrInvalidTimeFormat.GenWithStackByArgs(t) return ErrWrongValue.GenWithStackByArgs(TimeStr, t)
} }
if t.hour == 0 { if t.hour == 0 {
return ErrInvalidTimeFormat.GenWithStackByArgs(t) return ErrWrongValue.GenWithStackByArgs(TimeStr, t)
} }
if t.hour == 12 { if t.hour == 12 {
// 12 is a special hour. // 12 is a special hour.
...@@ -2244,16 +2361,6 @@ func skipWhiteSpace(input string) string { ...@@ -2244,16 +2361,6 @@ func skipWhiteSpace(input string) string {
return "" return ""
} }
var weekdayAbbrev = map[string]gotime.Weekday{
"Sun": gotime.Sunday,
"Mon": gotime.Monday,
"Tue": gotime.Tuesday,
"Wed": gotime.Wednesday,
"Thu": gotime.Tuesday,
"Fri": gotime.Friday,
"Sat": gotime.Saturday,
}
var monthAbbrev = map[string]gotime.Month{ var monthAbbrev = map[string]gotime.Month{
"Jan": gotime.January, "Jan": gotime.January,
"Feb": gotime.February, "Feb": gotime.February,
...@@ -2483,34 +2590,12 @@ func isAMOrPM(t *MysqlTime, input string, ctx map[string]int) (string, bool) { ...@@ -2483,34 +2590,12 @@ func isAMOrPM(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
// digitRegex: it was used to scan a variable-length monthly day or month in the string. Ex: "01" or "1" or "30" // digitRegex: it was used to scan a variable-length monthly day or month in the string. Ex: "01" or "1" or "30"
var oneOrTwoDigitRegex = regexp.MustCompile("^[0-9]{1,2}") var oneOrTwoDigitRegex = regexp.MustCompile("^[0-9]{1,2}")
// twoDigitRegex: it was just for two digit number string. Ex: "01" or "12"
var twoDigitRegex = regexp.MustCompile("^[1-9][0-9]?")
// oneToSixDigitRegex: it was just for [0, 999999] // oneToSixDigitRegex: it was just for [0, 999999]
var oneToSixDigitRegex = regexp.MustCompile("^[0-9]{0,6}") var oneToSixDigitRegex = regexp.MustCompile("^[0-9]{0,6}")
// numericRegex: it was for any numeric characters // numericRegex: it was for any numeric characters
var numericRegex = regexp.MustCompile("[0-9]+") var numericRegex = regexp.MustCompile("[0-9]+")
// parseTwoNumeric is used for pattens 0..31 0..24 0..60 and so on.
// It returns the parsed int, and remain data after parse.
func parseTwoNumeric(input string) (int, string) {
if len(input) > 1 && input[0] == '0' {
return 0, input[1:]
}
matched := twoDigitRegex.FindAllString(input, -1)
if len(matched) == 0 {
return 0, input
}
str := matched[0]
v, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return 0, input
}
return int(v), input[len(str):]
}
func dayOfMonthNumeric(t *MysqlTime, input string, ctx map[string]int) (string, bool) { func dayOfMonthNumeric(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
result := oneOrTwoDigitRegex.FindString(input) // 0..31 result := oneOrTwoDigitRegex.FindString(input) // 0..31
length := len(result) length := len(result)
...@@ -2608,17 +2693,6 @@ func dayOfYearThreeDigits(t *MysqlTime, input string, ctx map[string]int) (strin ...@@ -2608,17 +2693,6 @@ func dayOfYearThreeDigits(t *MysqlTime, input string, ctx map[string]int) (strin
return input[3:], true return input[3:], true
} }
func abbreviatedWeekday(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
if len(input) >= 3 {
dayName := input[:3]
if _, ok := weekdayAbbrev[dayName]; ok {
// TODO: We need refact mysql time to support this.
return input, false
}
}
return input, false
}
func abbreviatedMonth(t *MysqlTime, input string, ctx map[string]int) (string, bool) { func abbreviatedMonth(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
if len(input) >= 3 { if len(input) >= 3 {
monthName := input[:3] monthName := input[:3]
...@@ -2653,45 +2727,6 @@ func monthNumeric(t *MysqlTime, input string, ctx map[string]int) (string, bool) ...@@ -2653,45 +2727,6 @@ func monthNumeric(t *MysqlTime, input string, ctx map[string]int) (string, bool)
return input[length:], true return input[length:], true
} }
// dayOfMonthWithSuffix returns different suffix according t being which day. i.e. 0 return th. 1 return st.
func dayOfMonthWithSuffix(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
month, remain := parseOrdinalNumbers(input)
if month >= 0 {
t.month = uint8(month)
return remain, true
}
return input, false
}
func parseOrdinalNumbers(input string) (value int, remain string) {
for i, c := range input {
if !unicode.IsDigit(c) {
v, err := strconv.ParseUint(input[:i], 10, 64)
if err != nil {
return -1, input
}
value = int(v)
break
}
}
switch {
case strings.HasPrefix(remain, "st"):
if value == 1 {
remain = remain[2:]
return
}
case strings.HasPrefix(remain, "nd"):
if value == 2 {
remain = remain[2:]
return
}
case strings.HasPrefix(remain, "th"):
remain = remain[2:]
return
}
return -1, input
}
// DateFSP gets fsp from date string. // DateFSP gets fsp from date string.
func DateFSP(date string) (fsp int) { func DateFSP(date string) (fsp int) {
i := strings.LastIndex(date, ".") i := strings.LastIndex(date, ".")
...@@ -2701,7 +2736,7 @@ func DateFSP(date string) (fsp int) { ...@@ -2701,7 +2736,7 @@ func DateFSP(date string) (fsp int) {
return return
} }
// DateTimeIsOverflow return if this date is overflow. // DateTimeIsOverflow returns if this date is overflow.
// See: https://dev.mysql.com/doc/refman/8.0/en/datetime.html // See: https://dev.mysql.com/doc/refman/8.0/en/datetime.html
func DateTimeIsOverflow(sc *stmtctx.StatementContext, date Time) (bool, error) { func DateTimeIsOverflow(sc *stmtctx.StatementContext, date Time) (bool, error) {
tz := sc.TimeZone tz := sc.TimeZone
...@@ -2711,7 +2746,7 @@ func DateTimeIsOverflow(sc *stmtctx.StatementContext, date Time) (bool, error) { ...@@ -2711,7 +2746,7 @@ func DateTimeIsOverflow(sc *stmtctx.StatementContext, date Time) (bool, error) {
var err error var err error
var b, e, t gotime.Time var b, e, t gotime.Time
switch date.Type { switch date.tp {
case mysql.TypeDate, mysql.TypeDatetime: case mysql.TypeDate, mysql.TypeDatetime:
if b, err = MinDatetime.GoTime(tz); err != nil { if b, err = MinDatetime.GoTime(tz); err != nil {
return false, err return false, err
...@@ -2729,17 +2764,17 @@ func DateTimeIsOverflow(sc *stmtctx.StatementContext, date Time) (bool, error) { ...@@ -2729,17 +2764,17 @@ func DateTimeIsOverflow(sc *stmtctx.StatementContext, date Time) (bool, error) {
return false, err return false, err
} }
} }
if b, err = minTS.Time.GoTime(tz); err != nil { if b, err = minTS.time.GoTime(tz); err != nil {
return false, err return false, err
} }
if e, err = maxTS.Time.GoTime(tz); err != nil { if e, err = maxTS.time.GoTime(tz); err != nil {
return false, err return false, err
} }
default: default:
return false, nil return false, nil
} }
if t, err = date.Time.GoTime(tz); err != nil { if t, err = date.time.GoTime(tz); err != nil {
return false, err return false, err
} }
......
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package disk
import (
"github.com/pingcap/tidb/util/memory"
)
// Tracker is used to track the disk usage during query execution.
type Tracker = memory.Tracker
// NewTracker creates a disk tracker.
// 1. "label" is the label used in the usage string.
// 2. "bytesLimit <= 0" means no limit.
var NewTracker = memory.NewTracker
...@@ -33,24 +33,28 @@ var CommitDetailCtxKey = commitDetailCtxKeyType{} ...@@ -33,24 +33,28 @@ var CommitDetailCtxKey = commitDetailCtxKeyType{}
// ExecDetails contains execution detail information. // ExecDetails contains execution detail information.
type ExecDetails struct { type ExecDetails struct {
CalleeAddress string CalleeAddress string
ProcessTime time.Duration ProcessTime time.Duration
WaitTime time.Duration WaitTime time.Duration
BackoffTime time.Duration BackoffTime time.Duration
RequestCount int LockKeysDuration time.Duration
TotalKeys int64 BackoffSleep map[string]time.Duration
ProcessedKeys int64 BackoffTimes map[string]int
CommitDetail *CommitDetails RequestCount int
TotalKeys int64
ProcessedKeys int64
CommitDetail *CommitDetails
} }
// CommitDetails contains commit detail information. // CommitDetails contains commit detail information.
type CommitDetails struct { type CommitDetails struct {
GetCommitTsTime time.Duration GetCommitTsTime time.Duration
PrewriteTime time.Duration PrewriteTime time.Duration
CommitTime time.Duration BinlogPrewriteTime time.Duration
LocalLatchTime time.Duration CommitTime time.Duration
CommitBackoffTime int64 LocalLatchTime time.Duration
Mu struct { CommitBackoffTime int64
Mu struct {
sync.Mutex sync.Mutex
BackoffTypes []fmt.Stringer BackoffTypes []fmt.Stringer
} }
...@@ -68,12 +72,38 @@ const ( ...@@ -68,12 +72,38 @@ const (
WaitTimeStr = "Wait_time" WaitTimeStr = "Wait_time"
// BackoffTimeStr means the time of all back-off. // BackoffTimeStr means the time of all back-off.
BackoffTimeStr = "Backoff_time" BackoffTimeStr = "Backoff_time"
// LockKeysTimeStr means the time interval between pessimistic lock wait start and lock got obtain
LockKeysTimeStr = "LockKeys_time"
// RequestCountStr means the request count. // RequestCountStr means the request count.
RequestCountStr = "Request_count" RequestCountStr = "Request_count"
// TotalKeysStr means the total scan keys. // TotalKeysStr means the total scan keys.
TotalKeysStr = "Total_keys" TotalKeysStr = "Total_keys"
// ProcessKeysStr means the total processed keys. // ProcessKeysStr means the total processed keys.
ProcessKeysStr = "Process_keys" ProcessKeysStr = "Process_keys"
// PreWriteTimeStr means the time of pre-write.
PreWriteTimeStr = "Prewrite_time"
// BinlogPrewriteTimeStr means the time of binlog prewrite
BinlogPrewriteTimeStr = "Binlog_prewrite_time"
// CommitTimeStr means the time of commit.
CommitTimeStr = "Commit_time"
// GetCommitTSTimeStr means the time of getting commit ts.
GetCommitTSTimeStr = "Get_commit_ts_time"
// CommitBackoffTimeStr means the time of commit backoff.
CommitBackoffTimeStr = "Commit_backoff_time"
// BackoffTypesStr means the backoff type.
BackoffTypesStr = "Backoff_types"
// ResolveLockTimeStr means the time of resolving lock.
ResolveLockTimeStr = "Resolve_lock_time"
// LocalLatchWaitTimeStr means the time of waiting in local latch.
LocalLatchWaitTimeStr = "Local_latch_wait_time"
// WriteKeysStr means the count of keys in the transaction.
WriteKeysStr = "Write_keys"
// WriteSizeStr means the key/value size in the transaction.
WriteSizeStr = "Write_size"
// PrewriteRegionStr means the count of region when pre-write.
PrewriteRegionStr = "Prewrite_region"
// TxnRetryStr means the count of transaction retry.
TxnRetryStr = "Txn_retry"
) )
// String implements the fmt.Stringer interface. // String implements the fmt.Stringer interface.
...@@ -88,6 +118,9 @@ func (d ExecDetails) String() string { ...@@ -88,6 +118,9 @@ func (d ExecDetails) String() string {
if d.BackoffTime > 0 { if d.BackoffTime > 0 {
parts = append(parts, BackoffTimeStr+": "+strconv.FormatFloat(d.BackoffTime.Seconds(), 'f', -1, 64)) parts = append(parts, BackoffTimeStr+": "+strconv.FormatFloat(d.BackoffTime.Seconds(), 'f', -1, 64))
} }
if d.LockKeysDuration > 0 {
parts = append(parts, LockKeysTimeStr+": "+strconv.FormatFloat(d.LockKeysDuration.Seconds(), 'f', -1, 64))
}
if d.RequestCount > 0 { if d.RequestCount > 0 {
parts = append(parts, RequestCountStr+": "+strconv.FormatInt(int64(d.RequestCount), 10)) parts = append(parts, RequestCountStr+": "+strconv.FormatInt(int64(d.RequestCount), 10))
} }
...@@ -100,42 +133,45 @@ func (d ExecDetails) String() string { ...@@ -100,42 +133,45 @@ func (d ExecDetails) String() string {
commitDetails := d.CommitDetail commitDetails := d.CommitDetail
if commitDetails != nil { if commitDetails != nil {
if commitDetails.PrewriteTime > 0 { if commitDetails.PrewriteTime > 0 {
parts = append(parts, fmt.Sprintf("Prewrite_time: %v", commitDetails.PrewriteTime.Seconds())) parts = append(parts, PreWriteTimeStr+": "+strconv.FormatFloat(commitDetails.PrewriteTime.Seconds(), 'f', -1, 64))
}
if commitDetails.BinlogPrewriteTime > 0 {
parts = append(parts, BinlogPrewriteTimeStr+": "+strconv.FormatFloat(commitDetails.BinlogPrewriteTime.Seconds(), 'f', -1, 64))
} }
if commitDetails.CommitTime > 0 { if commitDetails.CommitTime > 0 {
parts = append(parts, fmt.Sprintf("Commit_time: %v", commitDetails.CommitTime.Seconds())) parts = append(parts, CommitTimeStr+": "+strconv.FormatFloat(commitDetails.CommitTime.Seconds(), 'f', -1, 64))
} }
if commitDetails.GetCommitTsTime > 0 { if commitDetails.GetCommitTsTime > 0 {
parts = append(parts, fmt.Sprintf("Get_commit_ts_time: %v", commitDetails.GetCommitTsTime.Seconds())) parts = append(parts, GetCommitTSTimeStr+": "+strconv.FormatFloat(commitDetails.GetCommitTsTime.Seconds(), 'f', -1, 64))
} }
commitBackoffTime := atomic.LoadInt64(&commitDetails.CommitBackoffTime) commitBackoffTime := atomic.LoadInt64(&commitDetails.CommitBackoffTime)
if commitBackoffTime > 0 { if commitBackoffTime > 0 {
parts = append(parts, fmt.Sprintf("Commit_backoff_time: %v", time.Duration(commitBackoffTime).Seconds())) parts = append(parts, CommitBackoffTimeStr+": "+strconv.FormatFloat(time.Duration(commitBackoffTime).Seconds(), 'f', -1, 64))
} }
commitDetails.Mu.Lock() commitDetails.Mu.Lock()
if len(commitDetails.Mu.BackoffTypes) > 0 { if len(commitDetails.Mu.BackoffTypes) > 0 {
parts = append(parts, fmt.Sprintf("Backoff_types: %v", commitDetails.Mu.BackoffTypes)) parts = append(parts, BackoffTypesStr+": "+fmt.Sprintf("%v", commitDetails.Mu.BackoffTypes))
} }
commitDetails.Mu.Unlock() commitDetails.Mu.Unlock()
resolveLockTime := atomic.LoadInt64(&commitDetails.ResolveLockTime) resolveLockTime := atomic.LoadInt64(&commitDetails.ResolveLockTime)
if resolveLockTime > 0 { if resolveLockTime > 0 {
parts = append(parts, fmt.Sprintf("Resolve_lock_time: %v", time.Duration(resolveLockTime).Seconds())) parts = append(parts, ResolveLockTimeStr+": "+strconv.FormatFloat(time.Duration(resolveLockTime).Seconds(), 'f', -1, 64))
} }
if commitDetails.LocalLatchTime > 0 { if commitDetails.LocalLatchTime > 0 {
parts = append(parts, fmt.Sprintf("Local_latch_wait_time: %v", commitDetails.LocalLatchTime.Seconds())) parts = append(parts, LocalLatchWaitTimeStr+": "+strconv.FormatFloat(commitDetails.LocalLatchTime.Seconds(), 'f', -1, 64))
} }
if commitDetails.WriteKeys > 0 { if commitDetails.WriteKeys > 0 {
parts = append(parts, fmt.Sprintf("Write_keys: %d", commitDetails.WriteKeys)) parts = append(parts, WriteKeysStr+": "+strconv.FormatInt(int64(commitDetails.WriteKeys), 10))
} }
if commitDetails.WriteSize > 0 { if commitDetails.WriteSize > 0 {
parts = append(parts, fmt.Sprintf("Write_size: %d", commitDetails.WriteSize)) parts = append(parts, WriteSizeStr+": "+strconv.FormatInt(int64(commitDetails.WriteSize), 10))
} }
prewriteRegionNum := atomic.LoadInt32(&commitDetails.PrewriteRegionNum) prewriteRegionNum := atomic.LoadInt32(&commitDetails.PrewriteRegionNum)
if prewriteRegionNum > 0 { if prewriteRegionNum > 0 {
parts = append(parts, fmt.Sprintf("Prewrite_region: %d", prewriteRegionNum)) parts = append(parts, PrewriteRegionStr+": "+strconv.FormatInt(int64(prewriteRegionNum), 10))
} }
if commitDetails.TxnRetry > 0 { if commitDetails.TxnRetry > 0 {
parts = append(parts, fmt.Sprintf("Txn_retry: %d", commitDetails.TxnRetry)) parts = append(parts, TxnRetryStr+": "+strconv.FormatInt(int64(commitDetails.TxnRetry), 10))
} }
} }
return strings.Join(parts, " ") return strings.Join(parts, " ")
...@@ -223,7 +259,9 @@ func (crs *CopRuntimeStats) RecordOneCopTask(address string, summary *tipb.Execu ...@@ -223,7 +259,9 @@ func (crs *CopRuntimeStats) RecordOneCopTask(address string, summary *tipb.Execu
crs.Lock() crs.Lock()
defer crs.Unlock() defer crs.Unlock()
crs.stats[address] = append(crs.stats[address], crs.stats[address] = append(crs.stats[address],
&RuntimeStats{int32(*summary.NumIterations), int64(*summary.TimeProcessedNs), int64(*summary.NumProducedRows)}) &RuntimeStats{loop: int32(*summary.NumIterations),
consume: int64(*summary.TimeProcessedNs),
rows: int64(*summary.NumProducedRows)})
} }
func (crs *CopRuntimeStats) String() string { func (crs *CopRuntimeStats) String() string {
...@@ -258,13 +296,15 @@ type ReaderRuntimeStats struct { ...@@ -258,13 +296,15 @@ type ReaderRuntimeStats struct {
sync.Mutex sync.Mutex
copRespTime []time.Duration copRespTime []time.Duration
procKeys []int64
} }
// recordOneCopTask record once cop response time to update maxcopRespTime // recordOneCopTask record once cop response time to update maxcopRespTime
func (rrs *ReaderRuntimeStats) recordOneCopTask(t time.Duration) { func (rrs *ReaderRuntimeStats) recordOneCopTask(t time.Duration, detail *ExecDetails) {
rrs.Lock() rrs.Lock()
defer rrs.Unlock() defer rrs.Unlock()
rrs.copRespTime = append(rrs.copRespTime, t) rrs.copRespTime = append(rrs.copRespTime, t)
rrs.procKeys = append(rrs.procKeys, detail.ProcessedKeys)
} }
func (rrs *ReaderRuntimeStats) String() string { func (rrs *ReaderRuntimeStats) String() string {
...@@ -273,7 +313,7 @@ func (rrs *ReaderRuntimeStats) String() string { ...@@ -273,7 +313,7 @@ func (rrs *ReaderRuntimeStats) String() string {
return "" return ""
} }
if size == 1 { if size == 1 {
return fmt.Sprintf("rpc time:%v", rrs.copRespTime[0]) return fmt.Sprintf("rpc num: 1, rpc time:%v, proc keys:%v", rrs.copRespTime[0], rrs.procKeys[0])
} }
sort.Slice(rrs.copRespTime, func(i, j int) bool { sort.Slice(rrs.copRespTime, func(i, j int) bool {
return rrs.copRespTime[i] < rrs.copRespTime[j] return rrs.copRespTime[i] < rrs.copRespTime[j]
...@@ -285,7 +325,13 @@ func (rrs *ReaderRuntimeStats) String() string { ...@@ -285,7 +325,13 @@ func (rrs *ReaderRuntimeStats) String() string {
sum += float64(t) sum += float64(t)
} }
vAvg := time.Duration(sum / float64(size)) vAvg := time.Duration(sum / float64(size))
return fmt.Sprintf("rpc max:%v, min:%v, avg:%v, p80:%v, p95:%v", vMax, vMin, vAvg, vP80, vP95)
sort.Slice(rrs.procKeys, func(i, j int) bool {
return rrs.procKeys[i] < rrs.procKeys[j]
})
keyMax := rrs.procKeys[size-1]
keyP95 := rrs.procKeys[size*19/20]
return fmt.Sprintf("rpc num: %v, rpc max:%v, min:%v, avg:%v, p80:%v, p95:%v, proc keys max:%v, p95:%v", size, vMax, vMin, vAvg, vP80, vP95, keyMax, keyP95)
} }
// RuntimeStatsColl collects executors's execution info. // RuntimeStatsColl collects executors's execution info.
...@@ -296,6 +342,12 @@ type RuntimeStatsColl struct { ...@@ -296,6 +342,12 @@ type RuntimeStatsColl struct {
readerStats map[string]*ReaderRuntimeStats readerStats map[string]*ReaderRuntimeStats
} }
// concurrencyInfo is used to save the concurrency information of the executor operator
type concurrencyInfo struct {
concurrencyName string
concurrencyNum int
}
// RuntimeStats collects one executor's execution info. // RuntimeStats collects one executor's execution info.
type RuntimeStats struct { type RuntimeStats struct {
// executor's Next() called times. // executor's Next() called times.
...@@ -304,6 +356,10 @@ type RuntimeStats struct { ...@@ -304,6 +356,10 @@ type RuntimeStats struct {
consume int64 consume int64
// executor return row count. // executor return row count.
rows int64 rows int64
mu sync.Mutex
// executor concurrency information
concurrency []concurrencyInfo
} }
// NewRuntimeStatsColl creates new executor collector. // NewRuntimeStatsColl creates new executor collector.
...@@ -343,9 +399,9 @@ func (e *RuntimeStatsColl) RecordOneCopTask(planID, address string, summary *tip ...@@ -343,9 +399,9 @@ func (e *RuntimeStatsColl) RecordOneCopTask(planID, address string, summary *tip
} }
// RecordOneReaderStats records a specific stats for TableReader, IndexReader and IndexLookupReader. // RecordOneReaderStats records a specific stats for TableReader, IndexReader and IndexLookupReader.
func (e *RuntimeStatsColl) RecordOneReaderStats(planID string, copRespTime time.Duration) { func (e *RuntimeStatsColl) RecordOneReaderStats(planID string, copRespTime time.Duration, detail *ExecDetails) {
readerStats := e.GetReaderStats(planID) readerStats := e.GetReaderStats(planID)
readerStats.recordOneCopTask(copRespTime) readerStats.recordOneCopTask(copRespTime, detail)
} }
// ExistsRootStats checks if the planID exists in the rootStats collection. // ExistsRootStats checks if the planID exists in the rootStats collection.
...@@ -388,6 +444,24 @@ func (e *RuntimeStats) SetRowNum(rowNum int64) { ...@@ -388,6 +444,24 @@ func (e *RuntimeStats) SetRowNum(rowNum int64) {
atomic.StoreInt64(&e.rows, rowNum) atomic.StoreInt64(&e.rows, rowNum)
} }
// SetConcurrencyInfo sets the concurrency information.
// When the num <= 0, it means the exector operator is not executed parallel.
func (e *RuntimeStats) SetConcurrencyInfo(name string, num int) {
e.mu.Lock()
defer e.mu.Unlock()
e.concurrency = append(e.concurrency, concurrencyInfo{concurrencyName: name, concurrencyNum: num})
}
func (e *RuntimeStats) String() string { func (e *RuntimeStats) String() string {
return fmt.Sprintf("time:%v, loops:%d, rows:%d", time.Duration(e.consume), e.loop, e.rows) result := fmt.Sprintf("time:%v, loops:%d, rows:%d", time.Duration(e.consume), e.loop, e.rows)
if len(e.concurrency) > 0 {
for _, concurrency := range e.concurrency {
if concurrency.concurrencyNum > 0 {
result += fmt.Sprintf(", %s:%d", concurrency.concurrencyName, concurrency.concurrencyNum)
} else {
result += fmt.Sprintf(", %s:OFF", concurrency.concurrencyName)
}
}
}
return result
} }
...@@ -18,7 +18,7 @@ import ( ...@@ -18,7 +18,7 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"path" "path/filepath"
"runtime" "runtime"
"sort" "sort"
"strings" "strings"
...@@ -47,6 +47,8 @@ const ( ...@@ -47,6 +47,8 @@ const (
DefaultQueryLogMaxLen = 4096 DefaultQueryLogMaxLen = 4096
// DefaultRecordPlanInSlowLog is the default value for whether enable log query plan in the slow log. // DefaultRecordPlanInSlowLog is the default value for whether enable log query plan in the slow log.
DefaultRecordPlanInSlowLog = 1 DefaultRecordPlanInSlowLog = 1
// DefaultTiDBEnableSlowLog enables TiDB to log slow queries.
DefaultTiDBEnableSlowLog = 1
) )
// EmptyFileLogConfig is an empty FileLogConfig. // EmptyFileLogConfig is an empty FileLogConfig.
...@@ -110,7 +112,7 @@ func (hook *contextHook) Fire(entry *log.Entry) error { ...@@ -110,7 +112,7 @@ func (hook *contextHook) Fire(entry *log.Entry) error {
name := fu.Name() name := fu.Name()
if !isSkippedPackageName(name) { if !isSkippedPackageName(name) {
file, line := fu.FileLine(pc[i] - 1) file, line := fu.FileLine(pc[i] - 1)
entry.Data["file"] = path.Base(file) entry.Data["file"] = filepath.Base(file)
entry.Data["line"] = line entry.Data["line"] = line
break break
} }
......
// Copyright 2019-present PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
//
// +build darwin linux windows
package mathutil
// Reexport functions and variables from mathutil
import (
"github.com/cznic/mathutil"
)
const (
// MaxInt presents the maximum number of Int
MaxInt = mathutil.MaxInt
// MinInt presents the minimum number of Int
MinInt = mathutil.MinInt
)
// MaxUint64 returns the larger of a and b.
var MaxUint64 = mathutil.MaxUint64
// MinUint64 returns the smaller of a and b.
var MinUint64 = mathutil.MinUint64
// MaxUint32 returns the larger of a and b.
var MaxUint32 = mathutil.MaxUint32
// MinUint32 returns the smaller of a and b.
var MinUint32 = mathutil.MinUint32
// MaxInt64 returns the larger of a and b.
var MaxInt64 = mathutil.MaxInt64
// MinInt64 returns the smaller of a and b.
var MinInt64 = mathutil.MinInt64
// MaxInt8 returns the larger of a and b.
var MaxInt8 = mathutil.MaxInt8
// MinInt8 returns the smaller of a and b.
var MinInt8 = mathutil.MinInt8
// Max returns the larger of a and b.
var Max = mathutil.Max
// Min returns the smaller of a and b.
var Min = mathutil.Min
...@@ -100,12 +100,17 @@ func (a *PanicOnExceed) Action(t *Tracker) { ...@@ -100,12 +100,17 @@ func (a *PanicOnExceed) Action(t *Tracker) {
func (a *PanicOnExceed) SetFallback(ActionOnExceed) {} func (a *PanicOnExceed) SetFallback(ActionOnExceed) {}
var ( var (
errMemExceedThreshold = terror.ClassExecutor.New(codeMemExceedThreshold, mysql.MySQLErrName[mysql.ErrMemExceedThreshold]) errMemExceedThreshold = terror.ClassUtil.New(mysql.ErrMemExceedThreshold, mysql.MySQLErrName[mysql.ErrMemExceedThreshold])
) )
const ( const (
codeMemExceedThreshold terror.ErrCode = 8001
// PanicMemoryExceed represents the panic message when out of memory quota. // PanicMemoryExceed represents the panic message when out of memory quota.
PanicMemoryExceed string = "Out Of Memory Quota!" PanicMemoryExceed string = "Out Of Memory Quota!"
) )
func init() {
errCodes := map[terror.ErrCode]uint16{
mysql.ErrMemExceedThreshold: mysql.ErrMemExceedThreshold,
}
terror.ErrClassToMySQLCodes[terror.ClassUtil] = errCodes
}
...@@ -78,6 +78,12 @@ func (t *Tracker) SetBytesLimit(bytesLimit int64) { ...@@ -78,6 +78,12 @@ func (t *Tracker) SetBytesLimit(bytesLimit int64) {
t.bytesLimit = bytesLimit t.bytesLimit = bytesLimit
} }
// GetBytesLimit gets the bytes limit for this tracker.
// "bytesLimit <= 0" means no limit.
func (t *Tracker) GetBytesLimit() int64 {
return t.bytesLimit
}
// SetActionOnExceed sets the action when memory usage exceeds bytesLimit. // SetActionOnExceed sets the action when memory usage exceeds bytesLimit.
func (t *Tracker) SetActionOnExceed(a ActionOnExceed) { func (t *Tracker) SetActionOnExceed(a ActionOnExceed) {
t.actionMu.Lock() t.actionMu.Lock()
......
...@@ -129,118 +129,130 @@ ...@@ -129,118 +129,130 @@
"revisionTime": "2019-03-07T07:54:52Z" "revisionTime": "2019-03-07T07:54:52Z"
}, },
{ {
"checksumSHA1": "2uDnUGEufCT0+kt4oKwe7G81+OQ=", "checksumSHA1": "x0w2l4mX3KAUCjN7Mfmq90wnL3I=",
"path": "github.com/pingcap/parser", "path": "github.com/pingcap/parser",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "C7qqPFYLpVVMKb2EnxetcWvjv1M=", "checksumSHA1": "wGQgFMSgWkhFqiJtr7dEy8rOkiE=",
"path": "github.com/pingcap/parser/ast", "path": "github.com/pingcap/parser/ast",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "xiv40YqnvHcbIhaEzJqjh5K7ehM=", "checksumSHA1": "xiv40YqnvHcbIhaEzJqjh5K7ehM=",
"path": "github.com/pingcap/parser/auth", "path": "github.com/pingcap/parser/auth",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "EvDXpplklIXmKqLclzWzaN/uHKQ=", "checksumSHA1": "TzEoDeNTNXUuF9vVhR7VvVyRx7Q=",
"path": "github.com/pingcap/parser/charset", "path": "github.com/pingcap/parser/charset",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "Aao6Mul/qqogOwPwM2arBKZkYZs=", "checksumSHA1": "Aao6Mul/qqogOwPwM2arBKZkYZs=",
"path": "github.com/pingcap/parser/format", "path": "github.com/pingcap/parser/format",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "p8oGDBAfGZ6nLZxwwKvMLuWCBh8=", "checksumSHA1": "KNnqAlb2DcHrRDTeVMA6eiIWaG8=",
"path": "github.com/pingcap/parser/model", "path": "github.com/pingcap/parser/model",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "KSbc38GqBQdMUeDXRbC1m0cmkfI=", "checksumSHA1": "yP9hVKQMaUmF6FBDPYaywPGdrgQ=",
"path": "github.com/pingcap/parser/mysql", "path": "github.com/pingcap/parser/mysql",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "olapD16WCMBU9vrA5PtlERGFfXw=", "checksumSHA1": "olapD16WCMBU9vrA5PtlERGFfXw=",
"path": "github.com/pingcap/parser/opcode", "path": "github.com/pingcap/parser/opcode",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "L6rzy3sJU1RPf7AkJN+0zcwW/YY=", "checksumSHA1": "LdDSLgXILDGAQZvsb9ZjDWqJl3M=",
"path": "github.com/pingcap/parser/terror", "path": "github.com/pingcap/parser/terror",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "u1Lmm4Fa3su4ElZMN4w0hPzFZl4=", "checksumSHA1": "B7Zc5543lu8iMhXHAzlCNsLx4v8=",
"path": "github.com/pingcap/parser/types", "path": "github.com/pingcap/parser/types",
"revision": "b10cc800c4e47e8ac3809c8549c4123a5271dcca", "revision": "a9496438d77d525d8759e0103f6eca40ce1d2788",
"revisionTime": "2019-10-22T01:55:17Z" "revisionTime": "2020-01-09T07:39:33Z"
}, },
{ {
"checksumSHA1": "guCKXZsHObqyjp6P2BwLSUpcG+Y=", "checksumSHA1": "hfByQZbnJqTW/nRSNUUDddDr1o0=",
"path": "github.com/pingcap/tidb/sessionctx/stmtctx", "path": "github.com/pingcap/tidb/sessionctx/stmtctx",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "oz6sCtUOhry0rhxsqKbWaJX8Suk=", "checksumSHA1": "ZXNwXm/paIiOIglpGYtmIMASj/k=",
"path": "github.com/pingcap/tidb/types", "path": "github.com/pingcap/tidb/types",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "OSOQVeP518zWu3RoYSDWoh7DIjg=", "checksumSHA1": "8Qt9iPMDstYhopu+Vp6VqCDzbdo=",
"path": "github.com/pingcap/tidb/types/json", "path": "github.com/pingcap/tidb/types/json",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "45zWX5Q6D6aTEWtc4p/lbD9WD4o=", "checksumSHA1": "/9fZXPSiOXGiAV3gr4K+O7VBAwU=",
"path": "github.com/pingcap/tidb/types/parser_driver", "path": "github.com/pingcap/tidb/types/parser_driver",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "oCrNchmOGNQTnrkjk5CxFZpu2rE=", "checksumSHA1": "r42gSWnL/iIbPJAQR3UovAX+Isk=",
"path": "github.com/pingcap/tidb/util/disk",
"revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2020-01-14T08:48:05Z"
},
{
"checksumSHA1": "Oz765RDVnDA6wI446nvSLBgSeGE=",
"path": "github.com/pingcap/tidb/util/execdetails", "path": "github.com/pingcap/tidb/util/execdetails",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "QGCTegCx13wJyB0isXsV7mNIljE=", "checksumSHA1": "QGCTegCx13wJyB0isXsV7mNIljE=",
"path": "github.com/pingcap/tidb/util/hack", "path": "github.com/pingcap/tidb/util/hack",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "NHsKdiYnPgrXvKeFN53WMH+SRwU=", "checksumSHA1": "8nife6o7pS8uIHTMs5rqUWvpd2Y=",
"path": "github.com/pingcap/tidb/util/logutil", "path": "github.com/pingcap/tidb/util/logutil",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "OveQu0ABBJmMEwmmthqSRQC2Ef0=", "checksumSHA1": "OveQu0ABBJmMEwmmthqSRQC2Ef0=",
"path": "github.com/pingcap/tidb/util/math", "path": "github.com/pingcap/tidb/util/math",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
},
{
"checksumSHA1": "iu44GDEX+A+ZaVD5zUtvCQPPehM=",
"path": "github.com/pingcap/tidb/util/mathutil",
"revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "EhvViFDlyohEB9dvepvISTP28Zg=", "checksumSHA1": "tP8ueCldgzZOWIoh5nDciyVzOjw=",
"path": "github.com/pingcap/tidb/util/memory", "path": "github.com/pingcap/tidb/util/memory",
"revision": "58fc7d44f73b65cc4cf9121bd540d905c774b588", "revision": "562a448b7db7860cd41ee49a45eb74264955a6ed",
"revisionTime": "2019-10-23T07:08:59Z" "revisionTime": "2020-01-14T08:48:05Z"
}, },
{ {
"checksumSHA1": "QPIBwDNUFF5Whrnd41S3mkKa4gQ=", "checksumSHA1": "QPIBwDNUFF5Whrnd41S3mkKa4gQ=",
...@@ -495,76 +507,76 @@ ...@@ -495,76 +507,76 @@
"revisionTime": "2018-03-28T19:50:20Z" "revisionTime": "2018-03-28T19:50:20Z"
}, },
{ {
"checksumSHA1": "aKn1oKcY74N8TRLm3Ayt7Q4bbI4=", "checksumSHA1": "dRbI5r3wRXlPJlhThNi+ZIwvMOA=",
"path": "vitess.io/vitess/go/bytes2", "path": "vitess.io/vitess/go/bytes2",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "bhE6CGQgZTIgLPp9lnvlKW/47xc=", "checksumSHA1": "lChcpAPjulTg/0MA41yJpgMRCUM=",
"path": "vitess.io/vitess/go/hack", "path": "vitess.io/vitess/go/hack",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "v2dgco7U/RQtQbdX9ULGEXsZw6k=", "checksumSHA1": "Q2Sv9aDGRWUvXvy4r4X3TfJD1T4=",
"path": "vitess.io/vitess/go/sqltypes", "path": "vitess.io/vitess/go/sqltypes",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "a39Nes10plscGYzwVlSRgXFAITk=", "checksumSHA1": "a39Nes10plscGYzwVlSRgXFAITk=",
"path": "vitess.io/vitess/go/vt/log", "path": "vitess.io/vitess/go/vt/log",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "PTiZ/ErlpNltBWLO7WK7FI1c79c=", "checksumSHA1": "CqSEuJNyRE+WLXPGWdEAmVGc0nk=",
"path": "vitess.io/vitess/go/vt/proto/binlogdata", "path": "vitess.io/vitess/go/vt/proto/binlogdata",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "U2N66XbwVN2UbS7mI2fQqODKTFU=", "checksumSHA1": "nLwTtV+IDkd8PN9Jqwa2wEZDURw=",
"path": "vitess.io/vitess/go/vt/proto/query", "path": "vitess.io/vitess/go/vt/proto/query",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "mioM1BFNP3voMMt6rvT6i9BMxTA=", "checksumSHA1": "/AkZlEOi7Kvw77h8em5MQiJ7b5A=",
"path": "vitess.io/vitess/go/vt/proto/topodata", "path": "vitess.io/vitess/go/vt/proto/topodata",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "vFv/sVYQzHQFzLdxfLA3vX5Nz0U=", "checksumSHA1": "sQwqkZ6/oBHrEe9Gm5T+x7VPbAk=",
"path": "vitess.io/vitess/go/vt/proto/vtgate", "path": "vitess.io/vitess/go/vt/proto/vtgate",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "6Pzimtq+Jv8CI6kTqkAjMkPoZZI=", "checksumSHA1": "HKM1AAfKgu+xD6rTGRJFD+Y8zkU=",
"path": "vitess.io/vitess/go/vt/proto/vtrpc", "path": "vitess.io/vitess/go/vt/proto/vtrpc",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "IpnM59xLwj3/Kv5sbEFXBUvcj0o=", "checksumSHA1": "pXbu1siV2bm1n8UuSvJHbQAVgW8=",
"path": "vitess.io/vitess/go/vt/proto/vttime", "path": "vitess.io/vitess/go/vt/proto/vttime",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "kt8JHcyRpFLLC1IjaAMwY1ZnmFU=", "checksumSHA1": "f5Z2Sku3jYBhQXtEvvo3dOImvxI=",
"path": "vitess.io/vitess/go/vt/sqlparser", "path": "vitess.io/vitess/go/vt/sqlparser",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
}, },
{ {
"checksumSHA1": "FT4i3QIXo5VAM/jg8UK5uyigyQY=", "checksumSHA1": "Cdl92fcfynnZSF1rZyrWxHC6jq8=",
"path": "vitess.io/vitess/go/vt/vterrors", "path": "vitess.io/vitess/go/vt/vterrors",
"revision": "590a06f9277fd29d7c9f77d50c4b11f1ba48f41c", "revision": "6b55d8456f9e5289877becf84bf58f02e7970f20",
"revisionTime": "2019-10-19T20:56:25Z" "revisionTime": "2020-01-14T00:21:54Z"
} }
], ],
"rootPath": "github.com/XiaoMi/soar" "rootPath": "github.com/XiaoMi/soar"
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -109,6 +109,37 @@ func Multiply(v1, v2 Value) (Value, error) { ...@@ -109,6 +109,37 @@ func Multiply(v1, v2 Value) (Value, error) {
return castFromNumeric(lresult, lresult.typ), nil return castFromNumeric(lresult, lresult.typ), nil
} }
// Float Division for MySQL. Replicates behavior of "/" operator
func Divide(v1, v2 Value) (Value, error) {
if v1.IsNull() || v2.IsNull() {
return NULL, nil
}
lv2AsFloat, err := ToFloat64(v2)
divisorIsZero := lv2AsFloat == 0
if divisorIsZero || err != nil {
return NULL, err
}
lv1, err := newNumeric(v1)
if err != nil {
return NULL, err
}
lv2, err := newNumeric(v2)
if err != nil {
return NULL, err
}
lresult, err := divideNumericWithError(lv1, lv2)
if err != nil {
return NULL, err
}
return castFromNumeric(lresult, lresult.typ), nil
}
// NullsafeAdd adds two Values in a null-safe manner. A null value // NullsafeAdd adds two Values in a null-safe manner. A null value
// is treated as 0. If both values are null, then a null is returned. // is treated as 0. If both values are null, then a null is returned.
// If both values are not null, a numeric value is built // If both values are not null, a numeric value is built
...@@ -470,6 +501,20 @@ func multiplyNumericWithError(v1, v2 numeric) (numeric, error) { ...@@ -470,6 +501,20 @@ func multiplyNumericWithError(v1, v2 numeric) (numeric, error) {
panic("unreachable") panic("unreachable")
} }
func divideNumericWithError(v1, v2 numeric) (numeric, error) {
switch v1.typ {
case Int64:
return floatDivideAnyWithError(float64(v1.ival), v2)
case Uint64:
return floatDivideAnyWithError(float64(v1.uval), v2)
case Float64:
return floatDivideAnyWithError(v1.fval, v2)
}
panic("unreachable")
}
// prioritize reorders the input parameters // prioritize reorders the input parameters
// to be Float64, Uint64, Int64. // to be Float64, Uint64, Int64.
func prioritize(v1, v2 numeric) (altv1, altv2 numeric) { func prioritize(v1, v2 numeric) (altv1, altv2 numeric) {
...@@ -523,6 +568,7 @@ func intTimesIntWithError(v1, v2 int64) (numeric, error) { ...@@ -523,6 +568,7 @@ func intTimesIntWithError(v1, v2 int64) (numeric, error) {
return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v * %v", v1, v2) return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v * %v", v1, v2)
} }
return numeric{typ: Int64, ival: result}, nil return numeric{typ: Int64, ival: result}, nil
} }
func intMinusUintWithError(v1 int64, v2 uint64) (numeric, error) { func intMinusUintWithError(v1 int64, v2 uint64) (numeric, error) {
...@@ -626,6 +672,24 @@ func floatTimesAny(v1 float64, v2 numeric) numeric { ...@@ -626,6 +672,24 @@ func floatTimesAny(v1 float64, v2 numeric) numeric {
return numeric{typ: Float64, fval: v1 * v2.fval} return numeric{typ: Float64, fval: v1 * v2.fval}
} }
func floatDivideAnyWithError(v1 float64, v2 numeric) (numeric, error) {
switch v2.typ {
case Int64:
v2.fval = float64(v2.ival)
case Uint64:
v2.fval = float64(v2.uval)
}
result := v1 / v2.fval
divisorLessThanOne := v2.fval < 1
resultMismatch := (v2.fval*result != v1)
if divisorLessThanOne && resultMismatch {
return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT is out of range in %v / %v", v1, v2.fval)
}
return numeric{typ: Float64, fval: v1 / v2.fval}, nil
}
func anyMinusFloat(v1 numeric, v2 float64) numeric { func anyMinusFloat(v1 numeric, v2 float64) numeric {
switch v1.typ { switch v1.typ {
case Int64: case Int64:
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -7,7 +7,7 @@ You may obtain a copy of the License at ...@@ -7,7 +7,7 @@ You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreedto in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -7,7 +7,7 @@ You may obtain a copy of the License at ...@@ -7,7 +7,7 @@ You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreedto in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
...@@ -5,8 +5,9 @@ package binlogdata ...@@ -5,8 +5,9 @@ package binlogdata
import ( import (
fmt "fmt" fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math" math "math"
proto "github.com/golang/protobuf/proto"
query "vitess.io/vitess/go/vt/proto/query" query "vitess.io/vitess/go/vt/proto/query"
topodata "vitess.io/vitess/go/vt/proto/topodata" topodata "vitess.io/vitess/go/vt/proto/topodata"
vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" vtrpc "vitess.io/vitess/go/vt/proto/vtrpc"
...@@ -715,10 +716,16 @@ type BinlogSource struct { ...@@ -715,10 +716,16 @@ type BinlogSource struct {
// for the filter. // for the filter.
Filter *Filter `protobuf:"bytes,6,opt,name=filter,proto3" json:"filter,omitempty"` Filter *Filter `protobuf:"bytes,6,opt,name=filter,proto3" json:"filter,omitempty"`
// on_ddl specifies the action to be taken when a DDL is encountered. // on_ddl specifies the action to be taken when a DDL is encountered.
OnDdl OnDDLAction `protobuf:"varint,7,opt,name=on_ddl,json=onDdl,proto3,enum=binlogdata.OnDDLAction" json:"on_ddl,omitempty"` OnDdl OnDDLAction `protobuf:"varint,7,opt,name=on_ddl,json=onDdl,proto3,enum=binlogdata.OnDDLAction" json:"on_ddl,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` // Source is an external mysql. This attribute should be set to the username
XXX_unrecognized []byte `json:"-"` // to use in the connection
XXX_sizecache int32 `json:"-"` ExternalMysql string `protobuf:"bytes,8,opt,name=external_mysql,json=externalMysql,proto3" json:"external_mysql,omitempty"`
// stop_after_copy specifies if vreplication should be stopped
// after copying is done.
StopAfterCopy bool `protobuf:"varint,9,opt,name=stop_after_copy,json=stopAfterCopy,proto3" json:"stop_after_copy,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *BinlogSource) Reset() { *m = BinlogSource{} } func (m *BinlogSource) Reset() { *m = BinlogSource{} }
...@@ -795,6 +802,20 @@ func (m *BinlogSource) GetOnDdl() OnDDLAction { ...@@ -795,6 +802,20 @@ func (m *BinlogSource) GetOnDdl() OnDDLAction {
return OnDDLAction_IGNORE return OnDDLAction_IGNORE
} }
func (m *BinlogSource) GetExternalMysql() string {
if m != nil {
return m.ExternalMysql
}
return ""
}
func (m *BinlogSource) GetStopAfterCopy() bool {
if m != nil {
return m.StopAfterCopy
}
return false
}
// RowChange represents one row change // RowChange represents one row change
type RowChange struct { type RowChange struct {
Before *query.Row `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"` Before *query.Row `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"`
...@@ -1176,6 +1197,7 @@ type VEvent struct { ...@@ -1176,6 +1197,7 @@ type VEvent struct {
FieldEvent *FieldEvent `protobuf:"bytes,6,opt,name=field_event,json=fieldEvent,proto3" json:"field_event,omitempty"` FieldEvent *FieldEvent `protobuf:"bytes,6,opt,name=field_event,json=fieldEvent,proto3" json:"field_event,omitempty"`
Vgtid *VGtid `protobuf:"bytes,7,opt,name=vgtid,proto3" json:"vgtid,omitempty"` Vgtid *VGtid `protobuf:"bytes,7,opt,name=vgtid,proto3" json:"vgtid,omitempty"`
Journal *Journal `protobuf:"bytes,8,opt,name=journal,proto3" json:"journal,omitempty"` Journal *Journal `protobuf:"bytes,8,opt,name=journal,proto3" json:"journal,omitempty"`
Dml string `protobuf:"bytes,9,opt,name=dml,proto3" json:"dml,omitempty"`
// current_time specifies the current time to handle clock skew. // current_time specifies the current time to handle clock skew.
CurrentTime int64 `protobuf:"varint,20,opt,name=current_time,json=currentTime,proto3" json:"current_time,omitempty"` CurrentTime int64 `protobuf:"varint,20,opt,name=current_time,json=currentTime,proto3" json:"current_time,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
...@@ -1264,6 +1286,13 @@ func (m *VEvent) GetJournal() *Journal { ...@@ -1264,6 +1286,13 @@ func (m *VEvent) GetJournal() *Journal {
return nil return nil
} }
func (m *VEvent) GetDml() string {
if m != nil {
return m.Dml
}
return ""
}
func (m *VEvent) GetCurrentTime() int64 { func (m *VEvent) GetCurrentTime() int64 {
if m != nil { if m != nil {
return m.CurrentTime return m.CurrentTime
...@@ -1527,6 +1556,128 @@ func (m *VStreamRowsResponse) GetLastpk() *query.Row { ...@@ -1527,6 +1556,128 @@ func (m *VStreamRowsResponse) GetLastpk() *query.Row {
return nil return nil
} }
// VStreamResultsRequest is the payload for VStreamResults
// The ids match VStreamRows, in case we decide to merge the two.
type VStreamResultsRequest struct {
EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId,proto3" json:"effective_caller_id,omitempty"`
ImmediateCallerId *query.VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId,proto3" json:"immediate_caller_id,omitempty"`
Target *query.Target `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"`
Query string `protobuf:"bytes,4,opt,name=query,proto3" json:"query,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *VStreamResultsRequest) Reset() { *m = VStreamResultsRequest{} }
func (m *VStreamResultsRequest) String() string { return proto.CompactTextString(m) }
func (*VStreamResultsRequest) ProtoMessage() {}
func (*VStreamResultsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_5fd02bcb2e350dad, []int{21}
}
func (m *VStreamResultsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VStreamResultsRequest.Unmarshal(m, b)
}
func (m *VStreamResultsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_VStreamResultsRequest.Marshal(b, m, deterministic)
}
func (m *VStreamResultsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_VStreamResultsRequest.Merge(m, src)
}
func (m *VStreamResultsRequest) XXX_Size() int {
return xxx_messageInfo_VStreamResultsRequest.Size(m)
}
func (m *VStreamResultsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_VStreamResultsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_VStreamResultsRequest proto.InternalMessageInfo
func (m *VStreamResultsRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
return m.EffectiveCallerId
}
return nil
}
func (m *VStreamResultsRequest) GetImmediateCallerId() *query.VTGateCallerID {
if m != nil {
return m.ImmediateCallerId
}
return nil
}
func (m *VStreamResultsRequest) GetTarget() *query.Target {
if m != nil {
return m.Target
}
return nil
}
func (m *VStreamResultsRequest) GetQuery() string {
if m != nil {
return m.Query
}
return ""
}
// VStreamResultsResponse is the response from VStreamResults
// The ids match VStreamRows, in case we decide to merge the two.
type VStreamResultsResponse struct {
Fields []*query.Field `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"`
Gtid string `protobuf:"bytes,3,opt,name=gtid,proto3" json:"gtid,omitempty"`
Rows []*query.Row `protobuf:"bytes,4,rep,name=rows,proto3" json:"rows,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *VStreamResultsResponse) Reset() { *m = VStreamResultsResponse{} }
func (m *VStreamResultsResponse) String() string { return proto.CompactTextString(m) }
func (*VStreamResultsResponse) ProtoMessage() {}
func (*VStreamResultsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_5fd02bcb2e350dad, []int{22}
}
func (m *VStreamResultsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VStreamResultsResponse.Unmarshal(m, b)
}
func (m *VStreamResultsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_VStreamResultsResponse.Marshal(b, m, deterministic)
}
func (m *VStreamResultsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_VStreamResultsResponse.Merge(m, src)
}
func (m *VStreamResultsResponse) XXX_Size() int {
return xxx_messageInfo_VStreamResultsResponse.Size(m)
}
func (m *VStreamResultsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_VStreamResultsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_VStreamResultsResponse proto.InternalMessageInfo
func (m *VStreamResultsResponse) GetFields() []*query.Field {
if m != nil {
return m.Fields
}
return nil
}
func (m *VStreamResultsResponse) GetGtid() string {
if m != nil {
return m.Gtid
}
return ""
}
func (m *VStreamResultsResponse) GetRows() []*query.Row {
if m != nil {
return m.Rows
}
return nil
}
func init() { func init() {
proto.RegisterEnum("binlogdata.OnDDLAction", OnDDLAction_name, OnDDLAction_value) proto.RegisterEnum("binlogdata.OnDDLAction", OnDDLAction_name, OnDDLAction_value)
proto.RegisterEnum("binlogdata.VEventType", VEventType_name, VEventType_value) proto.RegisterEnum("binlogdata.VEventType", VEventType_name, VEventType_value)
...@@ -1555,112 +1706,119 @@ func init() { ...@@ -1555,112 +1706,119 @@ func init() {
proto.RegisterType((*VStreamResponse)(nil), "binlogdata.VStreamResponse") proto.RegisterType((*VStreamResponse)(nil), "binlogdata.VStreamResponse")
proto.RegisterType((*VStreamRowsRequest)(nil), "binlogdata.VStreamRowsRequest") proto.RegisterType((*VStreamRowsRequest)(nil), "binlogdata.VStreamRowsRequest")
proto.RegisterType((*VStreamRowsResponse)(nil), "binlogdata.VStreamRowsResponse") proto.RegisterType((*VStreamRowsResponse)(nil), "binlogdata.VStreamRowsResponse")
proto.RegisterType((*VStreamResultsRequest)(nil), "binlogdata.VStreamResultsRequest")
proto.RegisterType((*VStreamResultsResponse)(nil), "binlogdata.VStreamResultsResponse")
} }
func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_5fd02bcb2e350dad) } func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_5fd02bcb2e350dad) }
var fileDescriptor_5fd02bcb2e350dad = []byte{ var fileDescriptor_5fd02bcb2e350dad = []byte{
// 1625 bytes of a gzipped FileDescriptorProto // 1709 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0xcd, 0x72, 0xdb, 0xc8, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x4b, 0x73, 0x23, 0x49,
0x11, 0x16, 0x49, 0xf0, 0xaf, 0x21, 0x51, 0xd0, 0xe8, 0x27, 0x8c, 0x2a, 0x4e, 0xc9, 0xa8, 0x38, 0x11, 0x9e, 0xd6, 0x5b, 0xd9, 0xb6, 0xdc, 0x2e, 0x3f, 0x10, 0x13, 0x2c, 0xe1, 0xed, 0x60, 0x76,
0x92, 0x55, 0x15, 0x2a, 0x61, 0x12, 0xe7, 0xe4, 0x38, 0xfc, 0x81, 0x24, 0x4a, 0x20, 0x29, 0x0f, 0xbc, 0x8e, 0x40, 0x06, 0x01, 0xc3, 0x69, 0x59, 0xf4, 0x68, 0x7b, 0x34, 0xd3, 0x92, 0x3c, 0xa5,
0x21, 0x39, 0xe5, 0x0b, 0x0a, 0x22, 0x87, 0x12, 0x22, 0x10, 0xa0, 0x81, 0xa1, 0x14, 0x3d, 0x40, 0x1e, 0x0f, 0xb1, 0x97, 0x8e, 0xb6, 0x54, 0xf6, 0x34, 0xee, 0xd7, 0x74, 0x97, 0xec, 0xd5, 0x0f,
0x2a, 0x0f, 0x90, 0x6b, 0x5e, 0x20, 0xe7, 0x5c, 0x93, 0xeb, 0xde, 0xf7, 0x09, 0xf6, 0xb4, 0xef, 0x20, 0xf8, 0x01, 0xfc, 0x0a, 0xce, 0x5c, 0xe1, 0xca, 0x9d, 0x3b, 0x57, 0x4e, 0x9c, 0xf8, 0x07,
0xb1, 0x35, 0x3f, 0x00, 0x09, 0xc9, 0x6b, 0xcb, 0x5b, 0xb5, 0x87, 0xbd, 0xa0, 0x7a, 0x7a, 0xba, 0x44, 0x3d, 0xba, 0xd5, 0xad, 0x59, 0x76, 0x3c, 0x1b, 0xc1, 0x01, 0x2e, 0x8a, 0xac, 0xec, 0xcc,
0x7b, 0x7a, 0xbe, 0xf9, 0x7a, 0x1a, 0x03, 0xda, 0xa5, 0xeb, 0x7b, 0xc1, 0xd5, 0xc8, 0xa1, 0x4e, 0xac, 0xcc, 0x2f, 0x1f, 0x55, 0x25, 0xd0, 0xae, 0xdc, 0xc0, 0x0b, 0x6f, 0x16, 0x0e, 0x75, 0x3a,
0x6d, 0x1a, 0x06, 0x34, 0x40, 0x30, 0xd7, 0x6c, 0xab, 0xb7, 0x34, 0x9c, 0x0e, 0xc5, 0xc4, 0xb6, 0x51, 0x1c, 0xd2, 0x10, 0xc1, 0x9a, 0xf3, 0x58, 0xbd, 0xa3, 0x71, 0x34, 0x17, 0x1f, 0x1e, 0xab,
0xfa, 0x61, 0x46, 0xc2, 0x7b, 0x39, 0xa8, 0xd0, 0x60, 0x1a, 0xcc, 0xbd, 0xf4, 0x2e, 0x14, 0x5b, 0xef, 0x96, 0x24, 0x5e, 0xc9, 0x45, 0x8b, 0x86, 0x51, 0xb8, 0xd6, 0xd2, 0xc7, 0x50, 0x1f, 0xbc,
0xd7, 0x4e, 0x18, 0x11, 0x8a, 0xb6, 0xa0, 0x30, 0xf4, 0x5c, 0xe2, 0xd3, 0x6a, 0x66, 0x27, 0xb3, 0x75, 0xe2, 0x84, 0x50, 0x74, 0x08, 0xb5, 0xb9, 0xe7, 0x92, 0x80, 0xb6, 0x95, 0x23, 0xe5, 0xb8,
0x97, 0xc7, 0x72, 0x84, 0x10, 0x28, 0xc3, 0xc0, 0xf7, 0xab, 0x59, 0xae, 0xe5, 0x32, 0xb3, 0x8d, 0x8a, 0xe5, 0x0a, 0x21, 0xa8, 0xcc, 0xc3, 0x20, 0x68, 0x97, 0x38, 0x97, 0xd3, 0x4c, 0x36, 0x21,
0x48, 0x78, 0x4b, 0xc2, 0x6a, 0x4e, 0xd8, 0x8a, 0x91, 0xfe, 0x6d, 0x0e, 0xd6, 0x9a, 0x3c, 0x0f, 0xf1, 0x1d, 0x89, 0xdb, 0x65, 0x21, 0x2b, 0x56, 0xfa, 0x3f, 0xca, 0xb0, 0xdb, 0xe7, 0x7e, 0x58,
0x2b, 0x74, 0xfc, 0xc8, 0x19, 0x52, 0x37, 0xf0, 0xd1, 0x11, 0x40, 0x44, 0x1d, 0x4a, 0x26, 0xc4, 0xb1, 0x13, 0x24, 0xce, 0x9c, 0xba, 0x61, 0x80, 0xce, 0x01, 0x12, 0xea, 0x50, 0xe2, 0x93, 0x80,
0xa7, 0x51, 0x35, 0xb3, 0x93, 0xdb, 0x53, 0xeb, 0xbb, 0xb5, 0x85, 0x1d, 0x3c, 0x72, 0xa9, 0x0d, 0x26, 0x6d, 0xe5, 0xa8, 0x7c, 0xac, 0x76, 0x9f, 0x76, 0x72, 0x11, 0xbc, 0xa7, 0xd2, 0x99, 0xa5,
0x62, 0x7b, 0xbc, 0xe0, 0x8a, 0xea, 0xa0, 0x92, 0x5b, 0xe2, 0x53, 0x9b, 0x06, 0x37, 0xc4, 0xaf, 0xf2, 0x38, 0xa7, 0x8a, 0xba, 0xa0, 0x92, 0x3b, 0x12, 0x50, 0x9b, 0x86, 0xb7, 0x24, 0x68, 0x57,
0x2a, 0x3b, 0x99, 0x3d, 0xb5, 0xbe, 0x56, 0x13, 0x1b, 0x34, 0xd8, 0x8c, 0xc5, 0x26, 0x30, 0x90, 0x8e, 0x94, 0x63, 0xb5, 0xbb, 0xdb, 0x11, 0x01, 0x1a, 0xec, 0x8b, 0xc5, 0x3e, 0x60, 0x20, 0x19,
0x44, 0xde, 0xfe, 0x2a, 0x0b, 0xe5, 0x24, 0x1a, 0x32, 0xa1, 0x34, 0x74, 0x28, 0xb9, 0x0a, 0xc2, 0xfd, 0xf8, 0xaf, 0x25, 0x68, 0x66, 0xd6, 0x90, 0x09, 0x8d, 0xb9, 0x43, 0xc9, 0x4d, 0x18, 0xaf,
0x7b, 0xbe, 0xcd, 0x4a, 0xfd, 0xb7, 0x4f, 0x4c, 0xa4, 0xd6, 0x92, 0x7e, 0x38, 0x89, 0x80, 0x7e, 0x78, 0x98, 0xad, 0xee, 0x4f, 0x1e, 0xe8, 0x48, 0x67, 0x20, 0xf5, 0x70, 0x66, 0x01, 0xfd, 0x18,
0x03, 0xc5, 0xa1, 0x40, 0x8f, 0xa3, 0xa3, 0xd6, 0xd7, 0x17, 0x83, 0x49, 0x60, 0x71, 0x6c, 0x83, 0xea, 0x73, 0x81, 0x1e, 0x47, 0x47, 0xed, 0xee, 0xe5, 0x8d, 0x49, 0x60, 0x71, 0x2a, 0x83, 0x34,
0x34, 0xc8, 0x45, 0x1f, 0x3c, 0x0e, 0xd9, 0x32, 0x66, 0xa2, 0xfe, 0x9f, 0x0c, 0x94, 0xe2, 0xb8, 0x28, 0x27, 0xef, 0x3c, 0x0e, 0xd9, 0x16, 0x66, 0xa4, 0xfe, 0x47, 0x05, 0x1a, 0xa9, 0x5d, 0xb4,
0x68, 0x1d, 0x56, 0x9b, 0xa6, 0x7d, 0xde, 0xc3, 0x46, 0xab, 0x7f, 0xd4, 0xeb, 0xbc, 0x37, 0xda, 0x07, 0x3b, 0x7d, 0xd3, 0x7e, 0x3d, 0xc1, 0xc6, 0x60, 0x7a, 0x3e, 0x19, 0x7d, 0x65, 0x0c, 0xb5,
0xda, 0x12, 0x5a, 0x86, 0x52, 0xd3, 0xb4, 0x9b, 0xc6, 0x51, 0xa7, 0xa7, 0x65, 0xd0, 0x0a, 0x94, 0x47, 0x68, 0x0b, 0x1a, 0x7d, 0xd3, 0xee, 0x1b, 0xe7, 0xa3, 0x89, 0xa6, 0xa0, 0x6d, 0x68, 0xf6,
0x9b, 0xa6, 0xdd, 0xea, 0x77, 0xbb, 0x1d, 0x4b, 0xcb, 0xa2, 0x55, 0x50, 0x9b, 0xa6, 0x8d, 0xfb, 0x4d, 0x7b, 0x30, 0x1d, 0x8f, 0x47, 0x96, 0x56, 0x42, 0x3b, 0xa0, 0xf6, 0x4d, 0x1b, 0x4f, 0x4d,
0xa6, 0xd9, 0x6c, 0xb4, 0x4e, 0xb5, 0x1c, 0xda, 0x84, 0xb5, 0xa6, 0x69, 0xb7, 0xbb, 0xa6, 0xdd, 0xb3, 0xdf, 0x1b, 0xbc, 0xd4, 0xca, 0xe8, 0x00, 0x76, 0xfb, 0xa6, 0x3d, 0x1c, 0x9b, 0xf6, 0xd0,
0x36, 0xce, 0xb0, 0xd1, 0x6a, 0x58, 0x46, 0x5b, 0x53, 0x10, 0x40, 0x81, 0xa9, 0xdb, 0xa6, 0x96, 0xb8, 0xc0, 0xc6, 0xa0, 0x67, 0x19, 0x43, 0xad, 0x82, 0x00, 0x6a, 0x8c, 0x3d, 0x34, 0xb5, 0xaa,
0x97, 0xf2, 0xc0, 0xb0, 0xb4, 0x82, 0x0c, 0xd7, 0xe9, 0x0d, 0x0c, 0x6c, 0x69, 0x45, 0x39, 0x3c, 0xa4, 0x67, 0x86, 0xa5, 0xd5, 0xa4, 0xb9, 0xd1, 0x64, 0x66, 0x60, 0x4b, 0xab, 0xcb, 0xe5, 0xeb,
0x3f, 0x6b, 0x37, 0x2c, 0x43, 0x2b, 0xc9, 0x61, 0xdb, 0x30, 0x0d, 0xcb, 0xd0, 0xca, 0x27, 0x4a, 0x8b, 0x61, 0xcf, 0x32, 0xb4, 0x86, 0x5c, 0x0e, 0x0d, 0xd3, 0xb0, 0x0c, 0xad, 0xf9, 0xa2, 0xd2,
0x29, 0xab, 0xe5, 0x4e, 0x94, 0x52, 0x4e, 0x53, 0xf4, 0x7f, 0x65, 0x60, 0x73, 0x40, 0x43, 0xe2, 0x28, 0x69, 0xe5, 0x17, 0x95, 0x46, 0x59, 0xab, 0xe8, 0x7f, 0x50, 0xe0, 0x60, 0x46, 0x63, 0xe2,
0x4c, 0x4e, 0xc9, 0x3d, 0x76, 0xfc, 0x2b, 0x82, 0xc9, 0x87, 0x19, 0x89, 0x28, 0xda, 0x86, 0xd2, 0xf8, 0x2f, 0xc9, 0x0a, 0x3b, 0xc1, 0x0d, 0xc1, 0xe4, 0xdd, 0x92, 0x24, 0x14, 0x3d, 0x86, 0x46,
0x34, 0x88, 0x5c, 0x86, 0x1d, 0x07, 0xb8, 0x8c, 0x93, 0x31, 0x3a, 0x80, 0xf2, 0x0d, 0xb9, 0xb7, 0x14, 0x26, 0x2e, 0xc3, 0x8e, 0x03, 0xdc, 0xc4, 0xd9, 0x1a, 0x9d, 0x42, 0xf3, 0x96, 0xac, 0xec,
0x43, 0x66, 0x2f, 0x01, 0x43, 0xb5, 0x84, 0x90, 0x49, 0xa4, 0xd2, 0x8d, 0x94, 0x16, 0xf1, 0xcd, 0x98, 0xc9, 0x4b, 0xc0, 0x50, 0x27, 0x2b, 0xc8, 0xcc, 0x52, 0xe3, 0x56, 0x52, 0x79, 0x7c, 0xcb,
0x7d, 0x1e, 0x5f, 0x7d, 0x0c, 0x5b, 0x0f, 0x93, 0x8a, 0xa6, 0x81, 0x1f, 0x11, 0x64, 0x02, 0x12, 0x1f, 0xc6, 0x57, 0xbf, 0x86, 0xc3, 0x4d, 0xa7, 0x92, 0x28, 0x0c, 0x12, 0x82, 0x4c, 0x40, 0x42,
0x8e, 0x36, 0x9d, 0x9f, 0x2d, 0xcf, 0x4f, 0xad, 0x3f, 0xfb, 0x24, 0x01, 0xf0, 0xda, 0xe5, 0x43, 0xd1, 0xa6, 0xeb, 0xdc, 0x72, 0xff, 0xd4, 0xee, 0x27, 0xdf, 0x5a, 0x00, 0x78, 0xf7, 0x6a, 0x93,
0x95, 0xfe, 0x77, 0x58, 0x17, 0xeb, 0x58, 0xce, 0xa5, 0x47, 0xa2, 0xa7, 0x6c, 0x7d, 0x0b, 0x0a, 0xa5, 0x7f, 0x0d, 0x7b, 0x62, 0x1f, 0xcb, 0xb9, 0xf2, 0x48, 0xf2, 0x90, 0xd0, 0x0f, 0xa1, 0x46,
0x94, 0x1b, 0x57, 0xb3, 0x3b, 0xb9, 0xbd, 0x32, 0x96, 0xa3, 0x2f, 0xdd, 0xe1, 0x08, 0x36, 0xd2, 0xb9, 0x70, 0xbb, 0x74, 0x54, 0x3e, 0x6e, 0x62, 0xb9, 0xfa, 0xd8, 0x08, 0x17, 0xb0, 0x5f, 0xdc,
0x2b, 0xff, 0x28, 0xfb, 0xfb, 0x03, 0x28, 0x78, 0xe6, 0x11, 0xb4, 0x01, 0xf9, 0x89, 0x43, 0x87, 0xf9, 0xbf, 0x12, 0xdf, 0xcf, 0xa1, 0x82, 0x97, 0x1e, 0x41, 0xfb, 0x50, 0xf5, 0x1d, 0x3a, 0x7f,
0xd7, 0x72, 0x37, 0x62, 0xc0, 0xb6, 0x32, 0x76, 0x3d, 0x4a, 0x42, 0x7e, 0x84, 0x65, 0x2c, 0x47, 0x2b, 0xa3, 0x11, 0x0b, 0x16, 0xca, 0xb5, 0xeb, 0x51, 0x12, 0xf3, 0x14, 0x36, 0xb1, 0x5c, 0xe9,
0xfa, 0x7f, 0x33, 0x50, 0x38, 0xe4, 0x22, 0xfa, 0x35, 0xe4, 0xc3, 0x19, 0xdb, 0xac, 0xa8, 0x75, 0x7f, 0x52, 0xa0, 0x76, 0xc6, 0x49, 0xf4, 0x19, 0x54, 0xe3, 0x25, 0x0b, 0x56, 0xf4, 0xba, 0x96,
0x6d, 0x31, 0x03, 0x16, 0x19, 0x8b, 0x69, 0xd4, 0x81, 0xca, 0xd8, 0x25, 0xde, 0x88, 0x97, 0x6e, 0xf7, 0x80, 0x59, 0xc6, 0xe2, 0x33, 0x1a, 0x41, 0xeb, 0xda, 0x25, 0xde, 0x82, 0xb7, 0xee, 0x38,
0x37, 0x18, 0x09, 0x56, 0x54, 0xea, 0xcf, 0x17, 0x1d, 0x44, 0xcc, 0xda, 0x61, 0xca, 0x10, 0x3f, 0x5c, 0x88, 0xaa, 0x68, 0x75, 0x3f, 0xcd, 0x2b, 0x08, 0x9b, 0x9d, 0xb3, 0x82, 0x20, 0xde, 0x50,
0x70, 0xd4, 0x5f, 0x41, 0x25, 0x6d, 0xc1, 0xca, 0xc9, 0xc0, 0xd8, 0xee, 0xf7, 0xec, 0x6e, 0x67, 0xd4, 0x9f, 0x41, 0xab, 0x28, 0xc1, 0xda, 0xc9, 0xc0, 0xd8, 0x9e, 0x4e, 0xec, 0xf1, 0x68, 0x36,
0xd0, 0x6d, 0x58, 0xad, 0x63, 0x6d, 0x89, 0x57, 0x8c, 0x31, 0xb0, 0x6c, 0xe3, 0xf0, 0xb0, 0x8f, 0xee, 0x59, 0x83, 0xe7, 0xda, 0x23, 0xde, 0x31, 0xc6, 0xcc, 0xb2, 0x8d, 0xb3, 0xb3, 0x29, 0xb6,
0x2d, 0x2d, 0xa3, 0xff, 0x3b, 0x0b, 0xcb, 0x02, 0x94, 0x41, 0x30, 0x0b, 0x87, 0x84, 0x9d, 0xe2, 0x34, 0x45, 0xff, 0x67, 0x09, 0xb6, 0x04, 0x28, 0xb3, 0x70, 0x19, 0xcf, 0x09, 0xcb, 0xe2, 0x2d,
0x0d, 0xb9, 0x8f, 0xa6, 0xce, 0x90, 0xc4, 0xa7, 0x18, 0x8f, 0x19, 0x20, 0xd1, 0xb5, 0x13, 0x8e, 0x59, 0x25, 0x91, 0x33, 0x27, 0x69, 0x16, 0xd3, 0x35, 0x03, 0x24, 0x79, 0xeb, 0xc4, 0x0b, 0x19,
0xe4, 0xce, 0xc5, 0x00, 0xfd, 0x11, 0x54, 0x7e, 0x9a, 0xd4, 0xa6, 0xf7, 0x53, 0xc2, 0xcf, 0xb1, 0xb9, 0x58, 0xa0, 0x5f, 0x80, 0xca, 0xb3, 0x49, 0x6d, 0xba, 0x8a, 0x08, 0xcf, 0x63, 0xab, 0xbb,
0x52, 0xdf, 0x98, 0x13, 0x9b, 0x9f, 0x15, 0xb5, 0xee, 0xa7, 0x04, 0x03, 0x4d, 0xe4, 0x74, 0x35, 0xbf, 0x2e, 0x6c, 0x9e, 0x2b, 0x6a, 0xad, 0x22, 0x82, 0x81, 0x66, 0x74, 0xb1, 0x1b, 0x2a, 0x0f,
0x28, 0x4f, 0xa8, 0x86, 0x39, 0x87, 0xf2, 0x29, 0x0e, 0xed, 0x27, 0x07, 0x52, 0x90, 0x51, 0x1e, 0xe8, 0x86, 0x75, 0x0d, 0x55, 0x0b, 0x35, 0x74, 0x92, 0x25, 0xa4, 0x26, 0xad, 0xbc, 0x87, 0x5e,
0xa1, 0x17, 0x1f, 0x12, 0xaa, 0x41, 0x21, 0xf0, 0xed, 0xd1, 0xc8, 0xab, 0x16, 0x79, 0x9a, 0x3f, 0x9a, 0x24, 0xd4, 0x81, 0x5a, 0x18, 0xd8, 0x8b, 0x85, 0xd7, 0xae, 0x73, 0x37, 0xbf, 0x97, 0x97,
0x5b, 0xb4, 0xed, 0xfb, 0xed, 0xb6, 0xd9, 0x10, 0xb4, 0xc8, 0x07, 0x7e, 0x7b, 0xe4, 0xe9, 0x6f, 0x9d, 0x06, 0xc3, 0xa1, 0xd9, 0x13, 0x65, 0x51, 0x0d, 0x83, 0xe1, 0xc2, 0x43, 0x4f, 0xa0, 0x45,
0xa1, 0x8c, 0x83, 0xbb, 0xd6, 0x35, 0x4f, 0x40, 0x87, 0xc2, 0x25, 0x19, 0x07, 0x21, 0x91, 0xcc, 0xbe, 0xa6, 0x24, 0x0e, 0x1c, 0xcf, 0xf6, 0x57, 0x6c, 0x7a, 0x35, 0x78, 0xe8, 0xdb, 0x29, 0x77,
0x02, 0x79, 0xf3, 0xe2, 0xe0, 0x0e, 0xcb, 0x19, 0xb4, 0x03, 0x79, 0x67, 0x1c, 0x93, 0x23, 0x6d, 0xcc, 0x98, 0xe8, 0x33, 0xd8, 0x49, 0x68, 0x18, 0xd9, 0xce, 0x35, 0x25, 0xb1, 0x3d, 0x0f, 0xa3,
0x22, 0x26, 0x74, 0x07, 0x4a, 0x38, 0xb8, 0xe3, 0xe7, 0x84, 0x9e, 0x81, 0x40, 0xc4, 0xf6, 0x9d, 0x55, 0xbb, 0x79, 0xa4, 0x1c, 0x37, 0xf0, 0x36, 0x63, 0xf7, 0x18, 0x77, 0x10, 0x46, 0x2b, 0xfd,
0x49, 0x0c, 0x77, 0x99, 0x6b, 0x7a, 0xce, 0x84, 0xa0, 0x57, 0xa0, 0x86, 0xc1, 0x9d, 0x3d, 0xe4, 0x15, 0x34, 0x71, 0x78, 0x3f, 0x78, 0xcb, 0xe3, 0xd1, 0xa1, 0x76, 0x45, 0xae, 0xc3, 0x98, 0xc8,
0xcb, 0x8b, 0xd2, 0x51, 0xeb, 0x9b, 0x29, 0x36, 0xc5, 0xc9, 0x61, 0x08, 0x63, 0x31, 0xd2, 0xdf, 0x42, 0x05, 0x39, 0xc8, 0x71, 0x78, 0x8f, 0xe5, 0x17, 0x74, 0x04, 0x55, 0x6e, 0x53, 0x8e, 0x8b,
0x02, 0xcc, 0xc9, 0xf0, 0xb9, 0x45, 0x7e, 0xc5, 0xe0, 0x23, 0xde, 0x28, 0x8e, 0xbf, 0x2c, 0x53, 0xbc, 0x88, 0xf8, 0xa0, 0x3b, 0xd0, 0xc0, 0xe1, 0x3d, 0x4f, 0x3b, 0xfa, 0x04, 0x04, 0xc0, 0x76,
0xe6, 0x11, 0xb0, 0x9c, 0x63, 0x40, 0x0c, 0xd8, 0x69, 0x1f, 0x51, 0x77, 0xf4, 0x03, 0x38, 0x82, 0xe0, 0xf8, 0x69, 0xf6, 0x9a, 0x9c, 0x33, 0x71, 0x7c, 0x82, 0x9e, 0x81, 0x1a, 0x87, 0xf7, 0xf6,
0x40, 0xb9, 0xa2, 0xee, 0x88, 0x93, 0xa3, 0x8c, 0xb9, 0xac, 0xbf, 0x81, 0xfc, 0x05, 0x0f, 0xf7, 0x9c, 0x6f, 0x2f, 0x3a, 0x51, 0xed, 0x1e, 0x14, 0x8a, 0x33, 0x75, 0x0e, 0x43, 0x9c, 0x92, 0x89,
0x0a, 0x54, 0x6e, 0x65, 0x33, 0x75, 0x5c, 0x34, 0xa9, 0x6d, 0x26, 0x4b, 0x63, 0x88, 0x62, 0x31, 0xfe, 0x0a, 0x60, 0x5d, 0x5b, 0x1f, 0xda, 0xe4, 0x47, 0x2c, 0x1b, 0xc4, 0x5b, 0xa4, 0xf6, 0xb7,
0xd2, 0x1b, 0xb0, 0x72, 0x2a, 0x97, 0xe5, 0x06, 0x5f, 0x9e, 0x97, 0xfe, 0xbf, 0x2c, 0x14, 0x4f, 0xa4, 0xcb, 0xdc, 0x02, 0x96, 0xdf, 0x18, 0x10, 0x33, 0x56, 0x3c, 0xe7, 0xd4, 0x5d, 0x7c, 0x87,
0x82, 0x59, 0xe8, 0x3b, 0x1e, 0xaa, 0x40, 0xd6, 0x1d, 0x71, 0xbf, 0x1c, 0xce, 0xba, 0x23, 0xf4, 0x92, 0x43, 0x50, 0xb9, 0xa1, 0xee, 0x82, 0xd7, 0x5a, 0x13, 0x73, 0x5a, 0xff, 0x12, 0xaa, 0x97,
0x17, 0xa8, 0x4c, 0xdc, 0xab, 0xd0, 0x61, 0x7c, 0x10, 0xd4, 0x16, 0xd5, 0xf9, 0xf3, 0xc5, 0xcc, 0xdc, 0xdc, 0x33, 0x50, 0xb9, 0x94, 0xcd, 0xd8, 0x69, 0x0f, 0x16, 0xc2, 0xcc, 0xb6, 0xc6, 0x90,
0xba, 0xb1, 0x05, 0xe7, 0xf7, 0xca, 0x64, 0x71, 0xb8, 0xc0, 0xd8, 0x5c, 0x8a, 0xb1, 0x2f, 0xa0, 0xa4, 0x64, 0xa2, 0xf7, 0x60, 0xfb, 0xa5, 0xdc, 0x96, 0x0b, 0x7c, 0xbc, 0x5f, 0xfa, 0x9f, 0x4b,
0xe2, 0x05, 0x43, 0xc7, 0xb3, 0x93, 0xfb, 0x52, 0xe1, 0x49, 0xad, 0x70, 0xed, 0x59, 0x7c, 0x69, 0x50, 0x7f, 0x11, 0x2e, 0x59, 0x61, 0xa0, 0x16, 0x94, 0xdc, 0x05, 0xd7, 0x2b, 0xe3, 0x92, 0xbb,
0x3e, 0xc0, 0x25, 0xff, 0x44, 0x5c, 0xd0, 0x6b, 0x58, 0x9e, 0x3a, 0x21, 0x75, 0x87, 0xee, 0xd4, 0x40, 0xbf, 0x86, 0x96, 0xef, 0xde, 0xc4, 0x0e, 0x2b, 0x2f, 0xd1, 0x29, 0xa2, 0xd9, 0xbf, 0x9f,
0x61, 0x7f, 0x1c, 0x05, 0xee, 0x98, 0x4a, 0x3b, 0x85, 0x1b, 0x4e, 0x99, 0xa3, 0x97, 0xa0, 0x45, 0xf7, 0x6c, 0x9c, 0x4a, 0xf0, 0x76, 0xd9, 0xf6, 0xf3, 0xcb, 0x5c, 0x03, 0x94, 0x0b, 0x0d, 0xf0,
0xfc, 0x2e, 0xb0, 0xef, 0x82, 0xf0, 0x66, 0xec, 0x05, 0x77, 0x51, 0xb5, 0xc8, 0xf3, 0x5f, 0x15, 0x04, 0x5a, 0x5e, 0x38, 0x77, 0x3c, 0x3b, 0x1b, 0xbf, 0x15, 0x51, 0xa4, 0x9c, 0x7b, 0x91, 0xce,
0xfa, 0x77, 0xb1, 0x5a, 0xff, 0x26, 0x0b, 0x85, 0x0b, 0xc1, 0xb2, 0x7d, 0x50, 0x38, 0x46, 0xe2, 0xe0, 0x0d, 0x5c, 0xaa, 0x0f, 0xc4, 0x05, 0x7d, 0x01, 0x5b, 0x91, 0x13, 0x53, 0x77, 0xee, 0x46,
0xaf, 0x62, 0x6b, 0x71, 0x31, 0x61, 0xc1, 0x01, 0xe2, 0x36, 0xe8, 0x17, 0x50, 0xa6, 0xee, 0x84, 0x0e, 0xbb, 0xc0, 0xd4, 0xb8, 0x62, 0xc1, 0xed, 0x02, 0x6e, 0xb8, 0x20, 0x8e, 0x3e, 0x07, 0x2d,
0x44, 0xd4, 0x99, 0x4c, 0x39, 0xa8, 0x39, 0x3c, 0x57, 0x7c, 0x8c, 0x2b, 0xec, 0xd7, 0x81, 0x15, 0xe1, 0xa3, 0xc5, 0xbe, 0x0f, 0xe3, 0xdb, 0x6b, 0x2f, 0xbc, 0x4f, 0xda, 0x75, 0xee, 0xff, 0x8e,
0xad, 0x80, 0x89, 0x89, 0xe8, 0x77, 0x50, 0x66, 0xb5, 0xc1, 0xff, 0x74, 0xaa, 0x79, 0x5e, 0x6c, 0xe0, 0xbf, 0x49, 0xd9, 0xfa, 0xbf, 0x4a, 0x50, 0xbb, 0x14, 0x55, 0x76, 0x02, 0x15, 0x8e, 0x91,
0x1b, 0x0f, 0x2a, 0x83, 0x2f, 0x8b, 0x4b, 0x61, 0x5c, 0x6d, 0x7f, 0x02, 0x95, 0xb3, 0x59, 0x3a, 0xb8, 0xa4, 0x1c, 0xe6, 0x37, 0x13, 0x12, 0x1c, 0x20, 0x2e, 0x83, 0x7e, 0x00, 0x4d, 0xea, 0xfa,
0x89, 0xdb, 0x62, 0x2b, 0x7d, 0x5b, 0xc4, 0x55, 0x83, 0x61, 0x7e, 0xc1, 0xa2, 0x5d, 0xc8, 0xdf, 0x24, 0xa1, 0x8e, 0x1f, 0x71, 0x50, 0xcb, 0x78, 0xcd, 0xf8, 0xa6, 0x5a, 0x61, 0x37, 0x11, 0x36,
0xf2, 0x94, 0x8a, 0xf2, 0x8f, 0x6b, 0x71, 0x73, 0x1c, 0x7e, 0x31, 0xcf, 0xda, 0xd9, 0xdf, 0x04, 0x03, 0x04, 0x4c, 0x8c, 0x44, 0x3f, 0x85, 0x26, 0xeb, 0x0d, 0x7e, 0x71, 0x6a, 0x57, 0x79, 0xb3,
0x9b, 0xaa, 0xa5, 0xc7, 0xed, 0x4c, 0x12, 0x0d, 0xc7, 0x36, 0xe8, 0x39, 0x2c, 0x0f, 0x67, 0x61, 0xed, 0x6f, 0x74, 0x06, 0xdf, 0x16, 0x37, 0xe2, 0xb4, 0xdb, 0x7e, 0x09, 0x2a, 0xaf, 0x66, 0xa9,
0xc8, 0xff, 0xe8, 0xdc, 0x09, 0xa9, 0x6e, 0x70, 0x28, 0x54, 0xa9, 0xb3, 0xdc, 0x09, 0xd1, 0xff, 0x24, 0x86, 0xcf, 0x61, 0x71, 0xf8, 0xa4, 0x5d, 0x83, 0x61, 0x3d, 0xaf, 0xd1, 0x53, 0xa8, 0xde,
0x99, 0x85, 0xca, 0x85, 0xe8, 0x79, 0x71, 0x9f, 0x7d, 0x03, 0xeb, 0x64, 0x3c, 0x26, 0x43, 0xea, 0x71, 0x97, 0xea, 0xf2, 0x02, 0x97, 0x0f, 0x8e, 0xc3, 0x2f, 0xbe, 0xb3, 0xd3, 0xf1, 0xb7, 0xa2,
0xde, 0x12, 0x7b, 0xe8, 0x78, 0x1e, 0x09, 0x6d, 0x49, 0x5c, 0xb5, 0xbe, 0x5a, 0x13, 0xff, 0xbe, 0x9a, 0xf8, 0xd8, 0xd9, 0x38, 0x1d, 0x65, 0xa1, 0xe1, 0x54, 0x86, 0x47, 0xe5, 0x7b, 0x7c, 0xf2,
0x2d, 0xae, 0xef, 0xb4, 0xf1, 0x5a, 0x62, 0x2b, 0x55, 0x23, 0x64, 0xc0, 0xba, 0x3b, 0x99, 0x90, 0xb0, 0xa8, 0x7c, 0x0f, 0x7d, 0x0a, 0x5b, 0xf3, 0x65, 0x1c, 0xf3, 0x2b, 0xa3, 0xeb, 0x93, 0xf6,
0x91, 0xeb, 0xd0, 0xc5, 0x00, 0xe2, 0xc6, 0xda, 0x94, 0xe5, 0x7f, 0x61, 0x1d, 0x39, 0x94, 0xcc, 0x3e, 0x07, 0x47, 0x95, 0x3c, 0xcb, 0xf5, 0x89, 0xfe, 0xfb, 0x12, 0xb4, 0x2e, 0xc5, 0xa1, 0x9a,
0xc3, 0x24, 0x1e, 0x49, 0x98, 0x17, 0x8c, 0xdd, 0xe1, 0x55, 0xd2, 0xba, 0x57, 0xa4, 0xa7, 0xc5, 0x1e, 0xe4, 0x5f, 0xc2, 0x1e, 0xb9, 0xbe, 0x26, 0x73, 0xea, 0xde, 0x11, 0x7b, 0xee, 0x78, 0x1e,
0x95, 0x58, 0x4e, 0xa6, 0x7e, 0x0b, 0x94, 0x07, 0xbf, 0x05, 0xf3, 0xab, 0x3b, 0xff, 0xb9, 0xab, 0x89, 0x6d, 0x59, 0xca, 0x6a, 0x77, 0xa7, 0x23, 0x2e, 0xd7, 0x03, 0xce, 0x1f, 0x0d, 0xf1, 0x6e,
0x5b, 0x7f, 0x0d, 0xab, 0x09, 0x10, 0xb2, 0xed, 0xef, 0x43, 0x81, 0x1f, 0x65, 0x7c, 0x67, 0xa0, 0x26, 0x2b, 0x59, 0x0b, 0x64, 0xc0, 0x9e, 0xeb, 0xfb, 0x64, 0xe1, 0x3a, 0x34, 0x6f, 0x40, 0xcc,
0xc7, 0xac, 0xc3, 0xd2, 0x42, 0xff, 0x47, 0x16, 0x50, 0xec, 0x1f, 0xdc, 0x45, 0x3f, 0x51, 0x30, 0xb0, 0x03, 0x39, 0x10, 0x2e, 0xad, 0x73, 0x87, 0x92, 0xb5, 0x99, 0x4c, 0x23, 0x33, 0xf3, 0x84,
0x37, 0x20, 0xcf, 0xf5, 0x12, 0x49, 0x31, 0x60, 0x38, 0x78, 0x4e, 0x44, 0xa7, 0x37, 0x09, 0x8c, 0xd5, 0x7b, 0x7c, 0x93, 0xdd, 0x0d, 0xb6, 0xa5, 0xa6, 0xc5, 0x99, 0x58, 0x7e, 0x2c, 0xdc, 0x3b,
0xc2, 0xf9, 0x2d, 0xfb, 0x62, 0x12, 0xcd, 0x3c, 0x8a, 0xa5, 0x85, 0xfe, 0xff, 0x0c, 0xac, 0xa7, 0x2a, 0x1b, 0xf7, 0x8e, 0xf5, 0xd9, 0x50, 0xfd, 0xd0, 0xd9, 0xa0, 0x7f, 0x01, 0x3b, 0x19, 0x10,
0x70, 0x90, 0x58, 0xce, 0xdb, 0x40, 0xe6, 0xfb, 0xdb, 0x00, 0xda, 0x83, 0xd2, 0xf4, 0xe6, 0x13, 0xf2, 0x5e, 0x71, 0x02, 0x35, 0x9e, 0xdc, 0x74, 0x8a, 0xa0, 0xf7, 0xeb, 0x10, 0x4b, 0x09, 0xfd,
0xed, 0x22, 0x99, 0xfd, 0x68, 0x15, 0xff, 0x12, 0x94, 0x90, 0xdd, 0x26, 0x0a, 0xf7, 0x5c, 0xec, 0x77, 0x25, 0x40, 0xa9, 0x7e, 0x78, 0x9f, 0xfc, 0x8f, 0x82, 0xb9, 0x0f, 0x55, 0xce, 0x97, 0x48,
0x8d, 0x5c, 0xcf, 0x1a, 0x6c, 0x6a, 0x1f, 0xa9, 0x06, 0x2b, 0x66, 0xf6, 0xff, 0x0c, 0xea, 0x42, 0x8a, 0x05, 0xc3, 0xc1, 0x73, 0x12, 0x1a, 0xdd, 0x66, 0x30, 0x0a, 0xe5, 0x57, 0xec, 0x17, 0x93,
0x9f, 0x66, 0xbf, 0xf3, 0x9d, 0xa3, 0x5e, 0x1f, 0x1b, 0xda, 0x12, 0x2a, 0x81, 0x32, 0xb0, 0xfa, 0x64, 0xe9, 0x51, 0x2c, 0x25, 0xf4, 0xbf, 0x28, 0xb0, 0x57, 0xc0, 0x41, 0x62, 0xb9, 0x3e, 0x18,
0x67, 0x5a, 0x86, 0x49, 0xc6, 0x5f, 0x8d, 0x96, 0x78, 0x22, 0x30, 0xc9, 0x96, 0x46, 0xb9, 0xfd, 0x94, 0xff, 0x7c, 0x30, 0xa0, 0x63, 0x68, 0x44, 0xb7, 0xdf, 0x72, 0x80, 0x64, 0x5f, 0xbf, 0xb1,
0xaf, 0x33, 0x00, 0xf3, 0x0b, 0x09, 0xa9, 0x50, 0x3c, 0xef, 0x9d, 0xf6, 0xfa, 0xef, 0x7a, 0x22, 0xaf, 0x7f, 0x08, 0x95, 0x98, 0xcd, 0x97, 0x0a, 0xd7, 0xcc, 0x9f, 0x96, 0x9c, 0xcf, 0x8e, 0xdc,
0xc0, 0x91, 0xd5, 0x69, 0x6b, 0x19, 0x54, 0x86, 0xbc, 0x78, 0x73, 0x64, 0xd9, 0x0a, 0xf2, 0xc1, 0x42, 0x1c, 0x85, 0x23, 0x57, 0xfa, 0xff, 0x77, 0x05, 0x0e, 0xd6, 0x75, 0xb0, 0xf4, 0xe8, 0xff,
0x91, 0x63, 0xaf, 0x91, 0xe4, 0xb5, 0xa1, 0xa0, 0x22, 0xe4, 0x92, 0x37, 0x85, 0x7c, 0x44, 0x14, 0x55, 0x2a, 0xf5, 0x18, 0x0e, 0x37, 0xa3, 0xfb, 0xa8, 0x04, 0x7d, 0x07, 0xd8, 0x4f, 0x7e, 0x05,
0x58, 0x40, 0x6c, 0x9c, 0x99, 0x8d, 0x96, 0xa1, 0x15, 0xd9, 0x44, 0xf2, 0x9c, 0x00, 0x28, 0xc4, 0x6a, 0xee, 0x6e, 0xc5, 0x9e, 0x60, 0xa3, 0xf3, 0xc9, 0x14, 0x1b, 0xda, 0x23, 0xd4, 0x80, 0xca,
0x6f, 0x09, 0xe6, 0xc9, 0x5e, 0x20, 0xc0, 0xd6, 0xe9, 0x5b, 0xc7, 0x06, 0xd6, 0x54, 0xa6, 0xc3, 0xcc, 0x9a, 0x5e, 0x68, 0x0a, 0xa3, 0x8c, 0xdf, 0x18, 0x03, 0xf1, 0xac, 0x63, 0x94, 0x2d, 0x85,
0xfd, 0x77, 0xda, 0x32, 0xd3, 0x1d, 0x76, 0x0c, 0xb3, 0xad, 0xad, 0xb0, 0x27, 0xc8, 0xb1, 0xd1, 0xca, 0x27, 0x7f, 0x53, 0x00, 0xd6, 0x53, 0x1f, 0xa9, 0x50, 0x7f, 0x3d, 0x79, 0x39, 0x99, 0xbe,
0xc0, 0x56, 0xd3, 0x68, 0x58, 0x5a, 0x85, 0xcd, 0x5c, 0xf0, 0x04, 0x57, 0xd9, 0x32, 0x27, 0xfd, 0x99, 0x08, 0x03, 0xe7, 0xd6, 0x68, 0xa8, 0x29, 0xa8, 0x09, 0x55, 0xf1, 0x4e, 0x2c, 0xb1, 0x1d,
0x73, 0xdc, 0x6b, 0x98, 0x9a, 0xb6, 0xbf, 0x0b, 0x2b, 0xa9, 0x3e, 0xc4, 0xd6, 0xb2, 0x1a, 0x4d, 0xe4, 0x23, 0xb1, 0xcc, 0x5e, 0x90, 0xd9, 0x0b, 0xb1, 0x82, 0xea, 0x50, 0xce, 0xde, 0x81, 0xf2,
0xd3, 0x18, 0x68, 0x4b, 0x4c, 0x1e, 0x1c, 0x37, 0x70, 0x7b, 0xa0, 0x65, 0x9a, 0x2f, 0xdf, 0xef, 0xe1, 0x57, 0x63, 0x06, 0xb1, 0x71, 0x61, 0xf6, 0x06, 0x86, 0x56, 0x67, 0x1f, 0xb2, 0x27, 0x20,
0xde, 0xba, 0x94, 0x44, 0x51, 0xcd, 0x0d, 0x0e, 0x84, 0x74, 0x70, 0x15, 0x1c, 0xdc, 0xd2, 0x03, 0x40, 0x2d, 0x7d, 0xff, 0x31, 0x4d, 0xf6, 0x6a, 0x04, 0xb6, 0xcf, 0xd4, 0x7a, 0x6e, 0x60, 0x4d,
0xfe, 0x1c, 0x3e, 0x98, 0x97, 0xcf, 0x65, 0x81, 0x6b, 0x7e, 0xff, 0x5d, 0x00, 0x00, 0x00, 0xff, 0x65, 0x3c, 0x3c, 0x7d, 0xa3, 0x6d, 0x31, 0xde, 0xd9, 0xc8, 0x30, 0x87, 0xda, 0x36, 0x7b, 0x36,
0xff, 0x49, 0x0f, 0x06, 0xcd, 0x6a, 0x0f, 0x00, 0x00, 0x3e, 0x37, 0x7a, 0xd8, 0xea, 0x1b, 0x3d, 0x4b, 0x6b, 0xb1, 0x2f, 0x97, 0xdc, 0xc1, 0x1d, 0xb6,
0xcd, 0x8b, 0xe9, 0x6b, 0x3c, 0xe9, 0x99, 0x9a, 0x76, 0xf2, 0x14, 0xb6, 0x0b, 0x87, 0x3d, 0xdb,
0xcb, 0xea, 0xf5, 0x4d, 0x63, 0xa6, 0x3d, 0x62, 0xf4, 0xec, 0x79, 0x0f, 0x0f, 0x67, 0x9a, 0xd2,
0xff, 0xfc, 0xab, 0xa7, 0x77, 0x2e, 0x25, 0x49, 0xd2, 0x71, 0xc3, 0x53, 0x41, 0x9d, 0xde, 0x84,
0xa7, 0x77, 0xf4, 0x94, 0xff, 0x85, 0x71, 0xba, 0x9e, 0x48, 0x57, 0x35, 0xce, 0xf9, 0xd9, 0xbf,
0x03, 0x00, 0x00, 0xff, 0xff, 0x78, 0x33, 0x5b, 0xba, 0x1e, 0x11, 0x00, 0x00,
} }
...@@ -5,8 +5,9 @@ package query ...@@ -5,8 +5,9 @@ package query
import ( import (
fmt "fmt" fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math" math "math"
proto "github.com/golang/protobuf/proto"
topodata "vitess.io/vitess/go/vt/proto/topodata" topodata "vitess.io/vitess/go/vt/proto/topodata"
vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" vtrpc "vitess.io/vitess/go/vt/proto/vtrpc"
) )
...@@ -3881,14 +3882,10 @@ func (m *AggregateStats) GetSecondsBehindMasterMax() uint32 { ...@@ -3881,14 +3882,10 @@ func (m *AggregateStats) GetSecondsBehindMasterMax() uint32 {
} }
// StreamHealthResponse is streamed by StreamHealth on a regular basis. // StreamHealthResponse is streamed by StreamHealth on a regular basis.
// When StreamHealth is used between a vtgate and vttablet: // It is expected to be used between a vtgate and vttablet:
// - target describes the tablet. // - target describes the tablet.
// - realtime_stats is set. // - realtime_stats is set.
// - aggregate_stats is not set. // - aggregate_stats is not set (deprecated)
// When StreamHealth is used between two vtgates:
// - target describes the group of tablets.
// - realtime_stats is not set.
// - aggregate_stats is set.
type StreamHealthResponse struct { type StreamHealthResponse struct {
// target is the current server type. Only queries with that exact Target // target is the current server type. Only queries with that exact Target
// record will be accepted (the cell may not match, however). // record will be accepted (the cell may not match, however).
...@@ -3927,9 +3924,6 @@ type StreamHealthResponse struct { ...@@ -3927,9 +3924,6 @@ type StreamHealthResponse struct {
// realtime_stats contains information about the tablet status. // realtime_stats contains information about the tablet status.
// It is only filled in if the information is about a tablet. // It is only filled in if the information is about a tablet.
RealtimeStats *RealtimeStats `protobuf:"bytes,4,opt,name=realtime_stats,json=realtimeStats,proto3" json:"realtime_stats,omitempty"` RealtimeStats *RealtimeStats `protobuf:"bytes,4,opt,name=realtime_stats,json=realtimeStats,proto3" json:"realtime_stats,omitempty"`
// AggregateStats constrains information about the group of tablet status.
// It is only filled in if the information is about a group of tablets.
AggregateStats *AggregateStats `protobuf:"bytes,6,opt,name=aggregate_stats,json=aggregateStats,proto3" json:"aggregate_stats,omitempty"`
// tablet_alias is the alias of the sending tablet. The discovery/healthcheck.go // tablet_alias is the alias of the sending tablet. The discovery/healthcheck.go
// code uses it to verify that it's talking to the correct tablet and that it // code uses it to verify that it's talking to the correct tablet and that it
// hasn't changed in the meantime e.g. due to tablet restarts where ports or // hasn't changed in the meantime e.g. due to tablet restarts where ports or
...@@ -3993,13 +3987,6 @@ func (m *StreamHealthResponse) GetRealtimeStats() *RealtimeStats { ...@@ -3993,13 +3987,6 @@ func (m *StreamHealthResponse) GetRealtimeStats() *RealtimeStats {
return nil return nil
} }
func (m *StreamHealthResponse) GetAggregateStats() *AggregateStats {
if m != nil {
return m.AggregateStats
}
return nil
}
func (m *StreamHealthResponse) GetTabletAlias() *topodata.TabletAlias { func (m *StreamHealthResponse) GetTabletAlias() *topodata.TabletAlias {
if m != nil { if m != nil {
return m.TabletAlias return m.TabletAlias
...@@ -4266,210 +4253,209 @@ func init() { ...@@ -4266,210 +4253,209 @@ func init() {
func init() { proto.RegisterFile("query.proto", fileDescriptor_5c6ac9b241082464) } func init() { proto.RegisterFile("query.proto", fileDescriptor_5c6ac9b241082464) }
var fileDescriptor_5c6ac9b241082464 = []byte{ var fileDescriptor_5c6ac9b241082464 = []byte{
// 3270 bytes of a gzipped FileDescriptorProto // 3258 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcb, 0x73, 0x1b, 0xc9, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcb, 0x73, 0xdb, 0x48,
0x79, 0xd7, 0xe0, 0x45, 0xe0, 0x03, 0x01, 0x36, 0x1b, 0xa4, 0x84, 0xe5, 0xbe, 0xe8, 0xb1, 0xd7, 0x7a, 0x37, 0xf8, 0x12, 0xf9, 0x51, 0xa4, 0x5a, 0x4d, 0xc9, 0xe6, 0x68, 0x5e, 0x5a, 0xec, 0xce,
0x66, 0x68, 0x87, 0xd2, 0x72, 0x65, 0x45, 0x59, 0x3b, 0x8e, 0x86, 0xe0, 0x50, 0x0b, 0x0b, 0x18, 0xae, 0xa2, 0xdd, 0xc8, 0x1e, 0x8d, 0xd7, 0x71, 0x66, 0x37, 0x89, 0x21, 0x0a, 0xf2, 0x70, 0x4c,
0x40, 0x8d, 0x81, 0x64, 0x6d, 0xb9, 0x6a, 0x6a, 0x08, 0xb4, 0xc0, 0x29, 0x0e, 0x66, 0xa0, 0x99, 0x82, 0x74, 0x13, 0xb4, 0xd7, 0x53, 0x5b, 0x85, 0x82, 0xc8, 0x36, 0x85, 0x12, 0x08, 0xd0, 0x00,
0x01, 0x29, 0xde, 0x94, 0x38, 0xce, 0xfb, 0xb1, 0x79, 0x6e, 0x9c, 0x54, 0x36, 0xa9, 0xca, 0x21, 0x28, 0x59, 0x37, 0x27, 0x9b, 0xcd, 0xfb, 0x31, 0x79, 0x4e, 0x36, 0xa9, 0x4c, 0x52, 0x95, 0x43,
0xb7, 0xfc, 0x0d, 0xa9, 0x1c, 0x72, 0xcc, 0x2d, 0x87, 0x24, 0x87, 0x1c, 0x52, 0xa9, 0xdc, 0x5c, 0x2a, 0x97, 0xfc, 0x0d, 0xa9, 0x1c, 0x72, 0xcc, 0x2d, 0x87, 0x24, 0x87, 0x9c, 0x52, 0xb9, 0x6d,
0x39, 0xe5, 0x90, 0x43, 0x2a, 0xd5, 0x8f, 0x19, 0x0c, 0x48, 0xec, 0x4a, 0x56, 0x7c, 0xa1, 0x76, 0xe5, 0x94, 0x43, 0x0e, 0xa9, 0x54, 0x3f, 0x00, 0x82, 0x12, 0x67, 0xec, 0x75, 0x72, 0x91, 0x67,
0x6f, 0xdd, 0xdf, 0xf7, 0xf5, 0xe3, 0xf7, 0xfb, 0xbe, 0xf9, 0xba, 0xa7, 0xbb, 0xa1, 0xfc, 0x64, 0x6e, 0xdd, 0xdf, 0xf7, 0xf5, 0xe3, 0xf7, 0xfb, 0x3e, 0x7c, 0xdd, 0xe8, 0x6e, 0x28, 0x3f, 0x99,
0x4a, 0x83, 0xb3, 0x9d, 0x49, 0xe0, 0x47, 0x3e, 0xce, 0xf3, 0xca, 0x46, 0x35, 0xf2, 0x27, 0xfe, 0xd2, 0xe0, 0x6c, 0x67, 0x12, 0xf8, 0x91, 0x8f, 0xf3, 0xbc, 0xb2, 0x51, 0x8d, 0xfc, 0x89, 0x3f,
0xd0, 0x8e, 0x6c, 0x21, 0xde, 0x28, 0x9f, 0x44, 0xc1, 0x64, 0x20, 0x2a, 0xea, 0x0f, 0x15, 0x28, 0xb4, 0x23, 0x5b, 0x88, 0x37, 0xca, 0x27, 0x51, 0x30, 0x19, 0x88, 0x8a, 0xfa, 0x43, 0x05, 0x0a,
0x98, 0x76, 0x30, 0xa2, 0x11, 0xde, 0x80, 0xe2, 0x31, 0x3d, 0x0b, 0x27, 0xf6, 0x80, 0xd6, 0x95, 0xa6, 0x1d, 0x8c, 0x68, 0x84, 0x37, 0xa0, 0x78, 0x4c, 0xcf, 0xc2, 0x89, 0x3d, 0xa0, 0x75, 0x65,
0x4d, 0x65, 0xab, 0x44, 0x92, 0x3a, 0x5e, 0x83, 0x7c, 0x78, 0x64, 0x07, 0xc3, 0x7a, 0x86, 0x2b, 0x53, 0xd9, 0x2a, 0x91, 0xa4, 0x8e, 0xd7, 0x20, 0x1f, 0x1e, 0xd9, 0xc1, 0xb0, 0x9e, 0xe1, 0x0a,
0x44, 0x05, 0x7f, 0x13, 0xca, 0x91, 0x7d, 0xe8, 0xd2, 0xc8, 0x8a, 0xce, 0x26, 0xb4, 0x9e, 0xdd, 0x51, 0xc1, 0xdf, 0x86, 0x72, 0x64, 0x1f, 0xba, 0x34, 0xb2, 0xa2, 0xb3, 0x09, 0xad, 0x67, 0x37,
0x54, 0xb6, 0xaa, 0xbb, 0x6b, 0x3b, 0xc9, 0x78, 0x26, 0x57, 0x9a, 0x67, 0x13, 0x4a, 0x20, 0x4a, 0x95, 0xad, 0xea, 0xee, 0xda, 0x4e, 0x32, 0x9e, 0xc9, 0x95, 0xe6, 0xd9, 0x84, 0x12, 0x88, 0x92,
0xca, 0x18, 0x43, 0x6e, 0x40, 0x5d, 0xb7, 0x9e, 0xe3, 0x7d, 0xf1, 0xb2, 0xba, 0x0f, 0xd5, 0x07, 0x32, 0xc6, 0x90, 0x1b, 0x50, 0xd7, 0xad, 0xe7, 0x78, 0x5f, 0xbc, 0xac, 0xee, 0x43, 0xf5, 0x81,
0xe6, 0x5d, 0x3b, 0xa2, 0x0d, 0xdb, 0x75, 0x69, 0xd0, 0xdc, 0x67, 0xd3, 0x99, 0x86, 0x34, 0xf0, 0x79, 0xd7, 0x8e, 0x68, 0xc3, 0x76, 0x5d, 0x1a, 0x34, 0xf7, 0xd9, 0x74, 0xa6, 0x21, 0x0d, 0x3c,
0xec, 0x71, 0x32, 0x9d, 0xb8, 0x8e, 0xaf, 0x42, 0x61, 0x14, 0xf8, 0xd3, 0x49, 0x58, 0xcf, 0x6c, 0x7b, 0x9c, 0x4c, 0x27, 0xae, 0xe3, 0xab, 0x50, 0x18, 0x05, 0xfe, 0x74, 0x12, 0xd6, 0x33, 0x9b,
0x66, 0xb7, 0x4a, 0x44, 0xd6, 0xd4, 0xef, 0x03, 0xe8, 0x27, 0xd4, 0x8b, 0x4c, 0xff, 0x98, 0x7a, 0xd9, 0xad, 0x12, 0x91, 0x35, 0xf5, 0xfb, 0x00, 0xfa, 0x09, 0xf5, 0x22, 0xd3, 0x3f, 0xa6, 0x1e,
0xf8, 0x0d, 0x28, 0x45, 0xce, 0x98, 0x86, 0x91, 0x3d, 0x9e, 0xf0, 0x2e, 0xb2, 0x64, 0x26, 0xf8, 0x7e, 0x03, 0x4a, 0x91, 0x33, 0xa6, 0x61, 0x64, 0x8f, 0x27, 0xbc, 0x8b, 0x2c, 0x99, 0x09, 0x3e,
0x14, 0x48, 0x1b, 0x50, 0x9c, 0xf8, 0xa1, 0x13, 0x39, 0xbe, 0xc7, 0xf1, 0x94, 0x48, 0x52, 0x57, 0x03, 0xd2, 0x06, 0x14, 0x27, 0x7e, 0xe8, 0x44, 0x8e, 0xef, 0x71, 0x3c, 0x25, 0x92, 0xd4, 0xd5,
0xbf, 0x03, 0xf9, 0x07, 0xb6, 0x3b, 0xa5, 0xf8, 0x6d, 0xc8, 0x71, 0xc0, 0x0a, 0x07, 0x5c, 0xde, 0x9f, 0x87, 0xfc, 0x03, 0xdb, 0x9d, 0x52, 0xfc, 0x36, 0xe4, 0x38, 0x60, 0x85, 0x03, 0x2e, 0xef,
0x11, 0xa4, 0x73, 0x9c, 0x5c, 0xc1, 0xfa, 0x3e, 0x61, 0x96, 0xbc, 0xef, 0x65, 0x22, 0x2a, 0xea, 0x08, 0xd2, 0x39, 0x4e, 0xae, 0x60, 0x7d, 0x9f, 0x30, 0x4b, 0xde, 0xf7, 0x32, 0x11, 0x15, 0xf5,
0x31, 0x2c, 0xef, 0x39, 0xde, 0xf0, 0x81, 0x1d, 0x38, 0x8c, 0x8c, 0x97, 0xec, 0x06, 0x7f, 0x05, 0x18, 0x96, 0xf7, 0x1c, 0x6f, 0xf8, 0xc0, 0x0e, 0x1c, 0x46, 0xc6, 0x4b, 0x76, 0x83, 0xbf, 0x06,
0x0a, 0xbc, 0x10, 0xd6, 0xb3, 0x9b, 0xd9, 0xad, 0xf2, 0xee, 0xb2, 0x6c, 0xc8, 0xe7, 0x46, 0xa4, 0x05, 0x5e, 0x08, 0xeb, 0xd9, 0xcd, 0xec, 0x56, 0x79, 0x77, 0x59, 0x36, 0xe4, 0x73, 0x23, 0x52,
0x4e, 0xfd, 0x7b, 0x05, 0x60, 0xcf, 0x9f, 0x7a, 0xc3, 0xfb, 0x4c, 0x89, 0x11, 0x64, 0xc3, 0x27, 0xa7, 0xfe, 0xbd, 0x02, 0xb0, 0xe7, 0x4f, 0xbd, 0xe1, 0x7d, 0xa6, 0xc4, 0x08, 0xb2, 0xe1, 0x13,
0xae, 0x24, 0x92, 0x15, 0xf1, 0x3d, 0xa8, 0x1e, 0x3a, 0xde, 0xd0, 0x3a, 0x91, 0xd3, 0x11, 0x5c, 0x57, 0x12, 0xc9, 0x8a, 0xf8, 0x1e, 0x54, 0x0f, 0x1d, 0x6f, 0x68, 0x9d, 0xc8, 0xe9, 0x08, 0x2e,
0x96, 0x77, 0xbf, 0x22, 0xbb, 0x9b, 0x35, 0xde, 0x49, 0xcf, 0x3a, 0xd4, 0xbd, 0x28, 0x38, 0x23, 0xcb, 0xbb, 0x5f, 0x93, 0xdd, 0xcd, 0x1a, 0xef, 0xa4, 0x67, 0x1d, 0xea, 0x5e, 0x14, 0x9c, 0x91,
0x95, 0xc3, 0xb4, 0x6c, 0xa3, 0x0f, 0xf8, 0xa2, 0x11, 0x1b, 0xf4, 0x98, 0x9e, 0xc5, 0x83, 0x1e, 0xca, 0x61, 0x5a, 0xb6, 0xd1, 0x07, 0x7c, 0xd1, 0x88, 0x0d, 0x7a, 0x4c, 0xcf, 0xe2, 0x41, 0x8f,
0xd3, 0x33, 0xfc, 0x33, 0x69, 0x44, 0xe5, 0xdd, 0x5a, 0x3c, 0x56, 0xaa, 0xad, 0x84, 0xf9, 0x7e, 0xe9, 0x19, 0xfe, 0xa9, 0x34, 0xa2, 0xf2, 0x6e, 0x2d, 0x1e, 0x2b, 0xd5, 0x56, 0xc2, 0x7c, 0x3f,
0xe6, 0xb6, 0xa2, 0xfe, 0x65, 0x01, 0xaa, 0xfa, 0x53, 0x3a, 0x98, 0x46, 0xb4, 0x33, 0x61, 0x3e, 0x73, 0x5b, 0x51, 0xff, 0xa2, 0x00, 0x55, 0xfd, 0x29, 0x1d, 0x4c, 0x23, 0xda, 0x99, 0x30, 0x1f,
0x08, 0xf1, 0x0e, 0xd4, 0x1c, 0x6f, 0xe0, 0x4e, 0x87, 0xd4, 0xa2, 0xcc, 0xd5, 0x56, 0xc4, 0x7c, 0x84, 0x78, 0x07, 0x6a, 0x8e, 0x37, 0x70, 0xa7, 0x43, 0x6a, 0x51, 0xe6, 0x6a, 0x2b, 0x62, 0xbe,
0xcd, 0xfb, 0x2b, 0x92, 0x55, 0xa9, 0x4a, 0x05, 0x81, 0x06, 0xb5, 0x81, 0x3f, 0x9e, 0xd8, 0xc1, 0xe6, 0xfd, 0x15, 0xc9, 0xaa, 0x54, 0xa5, 0x82, 0x40, 0x83, 0xda, 0xc0, 0x1f, 0x4f, 0xec, 0x60,
0xbc, 0x7d, 0x96, 0x8f, 0xbf, 0x2a, 0xc7, 0x9f, 0xd9, 0x93, 0x55, 0x69, 0x9d, 0xea, 0xa2, 0x0d, 0xde, 0x3e, 0xcb, 0xc7, 0x5f, 0x95, 0xe3, 0xcf, 0xec, 0xc9, 0xaa, 0xb4, 0x4e, 0x75, 0xd1, 0x86,
0x2b, 0xb2, 0xdf, 0xa1, 0xf5, 0xd8, 0xa1, 0xee, 0x30, 0xe4, 0xa1, 0x5b, 0x4d, 0xa8, 0x9a, 0x9f, 0x15, 0xd9, 0xef, 0xd0, 0x7a, 0xec, 0x50, 0x77, 0x18, 0xf2, 0xd0, 0xad, 0x26, 0x54, 0xcd, 0x4f,
0xe2, 0x4e, 0x53, 0x1a, 0x1f, 0x70, 0x5b, 0x52, 0x75, 0xe6, 0xea, 0x78, 0x1b, 0x56, 0x07, 0xae, 0x71, 0xa7, 0x29, 0x8d, 0x0f, 0xb8, 0x2d, 0xa9, 0x3a, 0x73, 0x75, 0xbc, 0x0d, 0xab, 0x03, 0xd7,
0xc3, 0xa6, 0xf2, 0x98, 0x51, 0x6c, 0x05, 0xfe, 0x69, 0x58, 0xcf, 0xf3, 0xf9, 0xaf, 0x08, 0xc5, 0x61, 0x53, 0x79, 0xcc, 0x28, 0xb6, 0x02, 0xff, 0x34, 0xac, 0xe7, 0xf9, 0xfc, 0x57, 0x84, 0xe2,
0x01, 0x93, 0x13, 0xff, 0x34, 0xc4, 0xef, 0x43, 0xf1, 0xd4, 0x0f, 0x8e, 0x5d, 0xdf, 0x1e, 0xd6, 0x80, 0xc9, 0x89, 0x7f, 0x1a, 0xe2, 0xf7, 0xa1, 0x78, 0xea, 0x07, 0xc7, 0xae, 0x6f, 0x0f, 0xeb,
0x0b, 0x7c, 0xcc, 0xb7, 0x16, 0x8f, 0xf9, 0x50, 0x5a, 0x91, 0xc4, 0x1e, 0x6f, 0x01, 0x0a, 0x9f, 0x05, 0x3e, 0xe6, 0x5b, 0x8b, 0xc7, 0x7c, 0x28, 0xad, 0x48, 0x62, 0x8f, 0xb7, 0x00, 0x85, 0x4f,
0xb8, 0x56, 0x48, 0x5d, 0x3a, 0x88, 0x2c, 0xd7, 0x19, 0x3b, 0x51, 0xbd, 0xc8, 0xbf, 0x82, 0x6a, 0x5c, 0x2b, 0xa4, 0x2e, 0x1d, 0x44, 0x96, 0xeb, 0x8c, 0x9d, 0xa8, 0x5e, 0xe4, 0x5f, 0x41, 0x35,
0xf8, 0xc4, 0xed, 0x71, 0x71, 0x8b, 0x49, 0xb1, 0x05, 0xeb, 0x51, 0x60, 0x7b, 0xa1, 0x3d, 0x60, 0x7c, 0xe2, 0xf6, 0xb8, 0xb8, 0xc5, 0xa4, 0xd8, 0x82, 0xf5, 0x28, 0xb0, 0xbd, 0xd0, 0x1e, 0xb0,
0x9d, 0x59, 0x4e, 0xe8, 0xbb, 0x36, 0xff, 0x02, 0x4a, 0x7c, 0xc8, 0xed, 0xc5, 0x43, 0x9a, 0xb3, 0xce, 0x2c, 0x27, 0xf4, 0x5d, 0x9b, 0x7f, 0x01, 0x25, 0x3e, 0xe4, 0xf6, 0xe2, 0x21, 0xcd, 0x59,
0x26, 0xcd, 0xb8, 0x05, 0x59, 0x8b, 0x16, 0x48, 0xf1, 0xbb, 0xb0, 0x1e, 0x1e, 0x3b, 0x13, 0x8b, 0x93, 0x66, 0xdc, 0x82, 0xac, 0x45, 0x0b, 0xa4, 0xf8, 0x5d, 0x58, 0x0f, 0x8f, 0x9d, 0x89, 0xc5,
0xf7, 0x63, 0x4d, 0x5c, 0xdb, 0xb3, 0x06, 0xf6, 0xe0, 0x88, 0xd6, 0x81, 0xc3, 0xc6, 0x4c, 0xc9, 0xfb, 0xb1, 0x26, 0xae, 0xed, 0x59, 0x03, 0x7b, 0x70, 0x44, 0xeb, 0xc0, 0x61, 0x63, 0xa6, 0xe4,
0x43, 0xad, 0xeb, 0xda, 0x5e, 0x83, 0x69, 0xd4, 0x6f, 0x41, 0x75, 0x9e, 0x47, 0xbc, 0x0a, 0x15, 0xa1, 0xd6, 0x75, 0x6d, 0xaf, 0xc1, 0x34, 0xea, 0x77, 0xa0, 0x3a, 0xcf, 0x23, 0x5e, 0x85, 0x8a,
0xf3, 0x51, 0x57, 0xb7, 0x34, 0x63, 0xdf, 0x32, 0xb4, 0xb6, 0x8e, 0xae, 0xe0, 0x0a, 0x94, 0xb8, 0xf9, 0xa8, 0xab, 0x5b, 0x9a, 0xb1, 0x6f, 0x19, 0x5a, 0x5b, 0x47, 0x57, 0x70, 0x05, 0x4a, 0x5c,
0xa8, 0x63, 0xb4, 0x1e, 0x21, 0x05, 0x2f, 0x41, 0x56, 0x6b, 0xb5, 0x50, 0x46, 0xbd, 0x0d, 0xc5, 0xd4, 0x31, 0x5a, 0x8f, 0x90, 0x82, 0x97, 0x20, 0xab, 0xb5, 0x5a, 0x28, 0xa3, 0xde, 0x86, 0x62,
0x98, 0x10, 0xbc, 0x02, 0xe5, 0xbe, 0xd1, 0xeb, 0xea, 0x8d, 0xe6, 0x41, 0x53, 0xdf, 0x47, 0x57, 0x4c, 0x08, 0x5e, 0x81, 0x72, 0xdf, 0xe8, 0x75, 0xf5, 0x46, 0xf3, 0xa0, 0xa9, 0xef, 0xa3, 0x2b,
0x70, 0x11, 0x72, 0x9d, 0x96, 0xd9, 0x45, 0x8a, 0x28, 0x69, 0x5d, 0x94, 0x61, 0x2d, 0xf7, 0xf7, 0xb8, 0x08, 0xb9, 0x4e, 0xcb, 0xec, 0x22, 0x45, 0x94, 0xb4, 0x2e, 0xca, 0xb0, 0x96, 0xfb, 0x7b,
0x34, 0x94, 0x55, 0xff, 0x46, 0x81, 0xb5, 0x45, 0xc0, 0x70, 0x19, 0x96, 0xf6, 0xf5, 0x03, 0xad, 0x1a, 0xca, 0xaa, 0x7f, 0xad, 0xc0, 0xda, 0x22, 0x60, 0xb8, 0x0c, 0x4b, 0xfb, 0xfa, 0x81, 0xd6,
0xdf, 0x32, 0xd1, 0x15, 0x5c, 0x83, 0x15, 0xa2, 0x77, 0x75, 0xcd, 0xd4, 0xf6, 0x5a, 0xba, 0x45, 0x6f, 0x99, 0xe8, 0x0a, 0xae, 0xc1, 0x0a, 0xd1, 0xbb, 0xba, 0x66, 0x6a, 0x7b, 0x2d, 0xdd, 0x22,
0x74, 0x6d, 0x1f, 0x29, 0x18, 0x43, 0x95, 0x95, 0xac, 0x46, 0xa7, 0xdd, 0x6e, 0x9a, 0xa6, 0xbe, 0xba, 0xb6, 0x8f, 0x14, 0x8c, 0xa1, 0xca, 0x4a, 0x56, 0xa3, 0xd3, 0x6e, 0x37, 0x4d, 0x53, 0xdf,
0x8f, 0x32, 0x78, 0x0d, 0x10, 0x97, 0xf5, 0x8d, 0x99, 0x34, 0x8b, 0x11, 0x2c, 0xf7, 0x74, 0xd2, 0x47, 0x19, 0xbc, 0x06, 0x88, 0xcb, 0xfa, 0xc6, 0x4c, 0x9a, 0xc5, 0x08, 0x96, 0x7b, 0x3a, 0x69,
0xd4, 0x5a, 0xcd, 0x0f, 0x59, 0x07, 0x28, 0x87, 0xbf, 0x04, 0x6f, 0x36, 0x3a, 0x46, 0xaf, 0xd9, 0x6a, 0xad, 0xe6, 0x47, 0xac, 0x03, 0x94, 0xc3, 0x5f, 0x81, 0x37, 0x1b, 0x1d, 0xa3, 0xd7, 0xec,
0x33, 0x75, 0xc3, 0xb4, 0x7a, 0x86, 0xd6, 0xed, 0x7d, 0xd0, 0x31, 0x79, 0xcf, 0x02, 0x5c, 0x1e, 0x99, 0xba, 0x61, 0x5a, 0x3d, 0x43, 0xeb, 0xf6, 0x3e, 0xe8, 0x98, 0xbc, 0x67, 0x01, 0x2e, 0x8f,
0x57, 0x01, 0xb4, 0xbe, 0xd9, 0x11, 0xfd, 0xa0, 0xc2, 0x77, 0x73, 0x45, 0x05, 0x65, 0xd4, 0x8f, 0xab, 0x00, 0x5a, 0xdf, 0xec, 0x88, 0x7e, 0x50, 0xe1, 0xc3, 0x5c, 0x51, 0x41, 0x19, 0xf5, 0x93,
0x33, 0x90, 0xe7, 0xfc, 0xb0, 0xac, 0x9a, 0xca, 0x95, 0xbc, 0x9c, 0x64, 0x98, 0xcc, 0x67, 0x64, 0x0c, 0xe4, 0x39, 0x3f, 0x2c, 0xab, 0xa6, 0x72, 0x25, 0x2f, 0x27, 0x19, 0x26, 0xf3, 0x39, 0x19,
0x18, 0x9e, 0x98, 0x65, 0xae, 0x13, 0x15, 0xfc, 0x3a, 0x94, 0xfc, 0x60, 0x64, 0x09, 0x8d, 0xc8, 0x86, 0x27, 0x66, 0x99, 0xeb, 0x44, 0x05, 0xbf, 0x0e, 0x25, 0x3f, 0x18, 0x59, 0x42, 0x23, 0xb2,
0xd2, 0x45, 0x3f, 0x18, 0xf1, 0x74, 0xce, 0x32, 0x24, 0x4b, 0xee, 0x87, 0x76, 0x48, 0x79, 0xd4, 0x74, 0xd1, 0x0f, 0x46, 0x3c, 0x9d, 0xb3, 0x0c, 0xc9, 0x92, 0xfb, 0xa1, 0x1d, 0x52, 0x1e, 0xb5,
0x96, 0x48, 0x52, 0xc7, 0xaf, 0x01, 0xb3, 0xb3, 0xf8, 0x3c, 0x0a, 0x5c, 0xb7, 0xe4, 0x07, 0x23, 0x25, 0x92, 0xd4, 0xf1, 0x6b, 0xc0, 0xec, 0x2c, 0x3e, 0x8f, 0x02, 0xd7, 0x2d, 0xf9, 0xc1, 0xc8,
0x83, 0x4d, 0xe5, 0xcb, 0x50, 0x19, 0xf8, 0xee, 0x74, 0xec, 0x59, 0x2e, 0xf5, 0x46, 0xd1, 0x51, 0x60, 0x53, 0xf9, 0x2a, 0x54, 0x06, 0xbe, 0x3b, 0x1d, 0x7b, 0x96, 0x4b, 0xbd, 0x51, 0x74, 0x54,
0x7d, 0x69, 0x53, 0xd9, 0xaa, 0x90, 0x65, 0x21, 0x6c, 0x71, 0x19, 0xae, 0xc3, 0xd2, 0xe0, 0xc8, 0x5f, 0xda, 0x54, 0xb6, 0x2a, 0x64, 0x59, 0x08, 0x5b, 0x5c, 0x86, 0xeb, 0xb0, 0x34, 0x38, 0xb2,
0x0e, 0x42, 0x2a, 0x22, 0xb5, 0x42, 0xe2, 0x2a, 0x1f, 0x95, 0x0e, 0x9c, 0xb1, 0xed, 0x86, 0x3c, 0x83, 0x90, 0x8a, 0x48, 0xad, 0x90, 0xb8, 0xca, 0x47, 0xa5, 0x03, 0x67, 0x6c, 0xbb, 0x21, 0x8f,
0x2a, 0x2b, 0x24, 0xa9, 0x33, 0x10, 0x8f, 0x5d, 0x7b, 0x14, 0xf2, 0x68, 0xaa, 0x10, 0x51, 0x51, 0xca, 0x0a, 0x49, 0xea, 0x0c, 0xc4, 0x63, 0xd7, 0x1e, 0x85, 0x3c, 0x9a, 0x2a, 0x44, 0x54, 0xd4,
0x7f, 0x0e, 0xb2, 0xc4, 0x3f, 0x65, 0x5d, 0x8a, 0x01, 0xc3, 0xba, 0xb2, 0x99, 0xdd, 0xc2, 0x24, 0x9f, 0x81, 0x2c, 0xf1, 0x4f, 0x59, 0x97, 0x62, 0xc0, 0xb0, 0xae, 0x6c, 0x66, 0xb7, 0x30, 0x89,
0xae, 0xb2, 0x45, 0x44, 0xe6, 0x51, 0x91, 0x5e, 0xe3, 0xcc, 0xf9, 0x7d, 0x58, 0x26, 0x34, 0x9c, 0xab, 0x6c, 0x11, 0x91, 0x79, 0x54, 0xa4, 0xd7, 0x38, 0x73, 0x7e, 0x1f, 0x96, 0x09, 0x0d, 0xa7,
0xba, 0x91, 0xfe, 0x34, 0x0a, 0xec, 0x10, 0xef, 0x42, 0x39, 0x9d, 0x39, 0x94, 0x4f, 0xcb, 0x1c, 0x6e, 0xa4, 0x3f, 0x8d, 0x02, 0x3b, 0xc4, 0xbb, 0x50, 0x4e, 0x67, 0x0e, 0xe5, 0xb3, 0x32, 0x07,
0x40, 0x67, 0x29, 0xa3, 0x0e, 0x4b, 0x8f, 0x03, 0x1a, 0x1e, 0xd1, 0x40, 0x66, 0xa6, 0xb8, 0xca, 0xd0, 0x59, 0xca, 0xa8, 0xc3, 0xd2, 0xe3, 0x80, 0x86, 0x47, 0x34, 0x90, 0x99, 0x29, 0xae, 0xb2,
0xf2, 0x72, 0x99, 0x87, 0xba, 0x18, 0x83, 0x65, 0x73, 0x99, 0x53, 0x94, 0xb9, 0x6c, 0xce, 0x9d, 0xbc, 0x5c, 0xe6, 0xa1, 0x2e, 0xc6, 0x60, 0xd9, 0x5c, 0xe6, 0x14, 0x65, 0x2e, 0x9b, 0x73, 0xa7,
0x4a, 0xa4, 0x8e, 0xb1, 0xc7, 0xd2, 0x84, 0x65, 0x3f, 0x7e, 0x4c, 0x07, 0x11, 0x15, 0x8b, 0x56, 0x12, 0xa9, 0x63, 0xec, 0xb1, 0x34, 0x61, 0xd9, 0x8f, 0x1f, 0xd3, 0x41, 0x44, 0xc5, 0xa2, 0x95,
0x8e, 0x2c, 0x33, 0xa1, 0x26, 0x65, 0xcc, 0x6d, 0x8e, 0x17, 0xd2, 0x20, 0xb2, 0x9c, 0x21, 0x77, 0x23, 0xcb, 0x4c, 0xa8, 0x49, 0x19, 0x73, 0x9b, 0xe3, 0x85, 0x34, 0x88, 0x2c, 0x67, 0xc8, 0x1d,
0x68, 0x8e, 0x14, 0x85, 0xa0, 0x39, 0xc4, 0x6f, 0x41, 0x8e, 0x27, 0x9a, 0x1c, 0x1f, 0x05, 0xe4, 0x9a, 0x23, 0x45, 0x21, 0x68, 0x0e, 0xf1, 0x5b, 0x90, 0xe3, 0x89, 0x26, 0xc7, 0x47, 0x01, 0x39,
0x28, 0xc4, 0x3f, 0x25, 0x5c, 0x8e, 0xbf, 0x0e, 0x05, 0xca, 0xf1, 0x72, 0xa7, 0xce, 0x52, 0x73, 0x0a, 0xf1, 0x4f, 0x09, 0x97, 0xe3, 0x6f, 0x42, 0x81, 0x72, 0xbc, 0xdc, 0xa9, 0xb3, 0xd4, 0x9c,
0x9a, 0x0a, 0x22, 0x4d, 0xd4, 0x6f, 0xc3, 0x32, 0xc7, 0xf0, 0xd0, 0x0e, 0x3c, 0xc7, 0x1b, 0xf1, 0xa6, 0x82, 0x48, 0x13, 0xf5, 0xbb, 0xb0, 0xcc, 0x31, 0x3c, 0xb4, 0x03, 0xcf, 0xf1, 0x46, 0x7c,
0x15, 0xdd, 0x1f, 0x8a, 0xd8, 0xab, 0x10, 0x5e, 0x66, 0x14, 0x8c, 0x69, 0x18, 0xda, 0x23, 0x2a, 0x45, 0xf7, 0x87, 0x22, 0xf6, 0x2a, 0x84, 0x97, 0x19, 0x05, 0x63, 0x1a, 0x86, 0xf6, 0x88, 0xca,
0x57, 0xd8, 0xb8, 0xaa, 0xfe, 0x55, 0x16, 0xca, 0xbd, 0x28, 0xa0, 0xf6, 0x98, 0xb3, 0x87, 0xbf, 0x15, 0x36, 0xae, 0xaa, 0x7f, 0x99, 0x85, 0x72, 0x2f, 0x0a, 0xa8, 0x3d, 0xe6, 0xec, 0xe1, 0xef,
0x0d, 0x10, 0x46, 0x76, 0x44, 0xc7, 0xd4, 0x8b, 0x62, 0x1a, 0xde, 0x90, 0xc3, 0xa7, 0xec, 0x76, 0x02, 0x84, 0x91, 0x1d, 0xd1, 0x31, 0xf5, 0xa2, 0x98, 0x86, 0x37, 0xe4, 0xf0, 0x29, 0xbb, 0x9d,
0x7a, 0xb1, 0x11, 0x49, 0xd9, 0x9f, 0x77, 0x4f, 0xe6, 0x05, 0xdc, 0xb3, 0xf1, 0x49, 0x06, 0x4a, 0x5e, 0x6c, 0x44, 0x52, 0xf6, 0xe7, 0xdd, 0x93, 0x79, 0x01, 0xf7, 0x6c, 0x7c, 0x9a, 0x81, 0x52,
0x49, 0x6f, 0x58, 0x83, 0xe2, 0xc0, 0x8e, 0xe8, 0xc8, 0x0f, 0xce, 0xe4, 0x5a, 0xfc, 0xce, 0x67, 0xd2, 0x1b, 0xd6, 0xa0, 0x38, 0xb0, 0x23, 0x3a, 0xf2, 0x83, 0x33, 0xb9, 0x16, 0xbf, 0xf3, 0x79,
0x8d, 0xbe, 0xd3, 0x90, 0xc6, 0x24, 0x69, 0x86, 0xdf, 0x04, 0xb1, 0xc1, 0x11, 0xa1, 0x2f, 0xf0, 0xa3, 0xef, 0x34, 0xa4, 0x31, 0x49, 0x9a, 0xe1, 0x37, 0x41, 0x6c, 0x70, 0x44, 0xe8, 0x0b, 0xbc,
0x96, 0xb8, 0x84, 0x07, 0xff, 0xfb, 0x80, 0x27, 0x81, 0x33, 0xb6, 0x83, 0x33, 0xeb, 0x98, 0x9e, 0x25, 0x2e, 0xe1, 0xc1, 0xff, 0x3e, 0xe0, 0x49, 0xe0, 0x8c, 0xed, 0xe0, 0xcc, 0x3a, 0xa6, 0x67,
0xc5, 0x8b, 0x48, 0x76, 0x81, 0xc3, 0x91, 0xb4, 0xbb, 0x47, 0xcf, 0x64, 0xda, 0xbb, 0x3d, 0xdf, 0xf1, 0x22, 0x92, 0x5d, 0xe0, 0x70, 0x24, 0xed, 0xee, 0xd1, 0x33, 0x99, 0xf6, 0x6e, 0xcf, 0xb7,
0x56, 0x86, 0xec, 0x45, 0x37, 0xa6, 0x5a, 0xf2, 0x9d, 0x40, 0x18, 0xaf, 0xf9, 0x79, 0x1e, 0xdd, 0x95, 0x21, 0x7b, 0xd1, 0x8d, 0xa9, 0x96, 0x7c, 0x27, 0x10, 0xc6, 0x6b, 0x7e, 0x9e, 0x47, 0x37,
0xac, 0xa8, 0x7e, 0x0d, 0x8a, 0xf1, 0xe4, 0x71, 0x09, 0xf2, 0x7a, 0x10, 0xf8, 0x01, 0xba, 0xc2, 0x2b, 0xaa, 0xdf, 0x80, 0x62, 0x3c, 0x79, 0x5c, 0x82, 0xbc, 0x1e, 0x04, 0x7e, 0x80, 0xae, 0xf0,
0xb3, 0x5f, 0xbb, 0x25, 0x12, 0xe8, 0xfe, 0x3e, 0x4b, 0xa0, 0x7f, 0x97, 0x49, 0x16, 0x5e, 0x42, 0xec, 0xd7, 0x6e, 0x89, 0x04, 0xba, 0xbf, 0xcf, 0x12, 0xe8, 0xdf, 0x65, 0x92, 0x85, 0x97, 0xd0,
0x9f, 0x4c, 0x69, 0x18, 0xe1, 0x5f, 0x84, 0x1a, 0xe5, 0x91, 0xe6, 0x9c, 0x50, 0x6b, 0xc0, 0x77, 0x27, 0x53, 0x1a, 0x46, 0xf8, 0x17, 0xa0, 0x46, 0x79, 0xa4, 0x39, 0x27, 0xd4, 0x1a, 0xf0, 0x5d,
0x69, 0x2c, 0xce, 0xc4, 0xe7, 0xb0, 0xb2, 0x23, 0x36, 0x95, 0xf1, 0xee, 0x8d, 0xac, 0x26, 0xb6, 0x1a, 0x8b, 0x33, 0xf1, 0x39, 0xac, 0xec, 0x88, 0x4d, 0x65, 0xbc, 0x7b, 0x23, 0xab, 0x89, 0xad,
0x52, 0x34, 0xc4, 0x3a, 0xd4, 0x9c, 0xf1, 0x98, 0x0e, 0x1d, 0x3b, 0x4a, 0x77, 0x20, 0x1c, 0xb6, 0x14, 0x0d, 0xb1, 0x0e, 0x35, 0x67, 0x3c, 0xa6, 0x43, 0xc7, 0x8e, 0xd2, 0x1d, 0x08, 0x87, 0xad,
0x1e, 0x6f, 0x62, 0xe6, 0x36, 0x81, 0x64, 0x35, 0x69, 0x91, 0x74, 0xf3, 0x0e, 0x14, 0x22, 0xbe, 0xc7, 0x9b, 0x98, 0xb9, 0x4d, 0x20, 0x59, 0x4d, 0x5a, 0x24, 0xdd, 0xbc, 0x03, 0x85, 0x88, 0x6f,
0x61, 0x95, 0x6b, 0x78, 0x25, 0xce, 0x6a, 0x5c, 0x48, 0xa4, 0x12, 0x7f, 0x0d, 0xc4, 0xf6, 0x97, 0x58, 0xe5, 0x1a, 0x5e, 0x89, 0xb3, 0x1a, 0x17, 0x12, 0xa9, 0xc4, 0xdf, 0x00, 0xb1, 0xfd, 0xe5,
0xe7, 0xaf, 0x59, 0x40, 0xcc, 0x76, 0x35, 0x44, 0xe8, 0xf1, 0x3b, 0x50, 0x9d, 0x5b, 0xfc, 0x86, 0xf9, 0x6b, 0x16, 0x10, 0xb3, 0x5d, 0x0d, 0x11, 0x7a, 0xfc, 0x0e, 0x54, 0xe7, 0x16, 0xbf, 0x21,
0x9c, 0xb0, 0x2c, 0xa9, 0xa4, 0x57, 0xb2, 0x21, 0xbe, 0x0e, 0x4b, 0xbe, 0x58, 0xf8, 0x78, 0x66, 0x27, 0x2c, 0x4b, 0x2a, 0xe9, 0x95, 0x6c, 0x88, 0xaf, 0xc3, 0x92, 0x2f, 0x16, 0x3e, 0x9e, 0xd9,
0x9b, 0xcd, 0x78, 0x7e, 0x55, 0x24, 0xb1, 0x95, 0xfa, 0x0b, 0xb0, 0x92, 0x30, 0x18, 0x4e, 0x7c, 0x66, 0x33, 0x9e, 0x5f, 0x15, 0x49, 0x6c, 0xa5, 0xfe, 0x1c, 0xac, 0x24, 0x0c, 0x86, 0x13, 0xdf,
0x2f, 0xa4, 0x78, 0x1b, 0x0a, 0x01, 0xff, 0x9c, 0x24, 0x6b, 0x58, 0x76, 0x91, 0xca, 0x07, 0x44, 0x0b, 0x29, 0xde, 0x86, 0x42, 0xc0, 0x3f, 0x27, 0xc9, 0x1a, 0x96, 0x5d, 0xa4, 0xf2, 0x01, 0x91,
0x5a, 0xa8, 0x43, 0x58, 0x11, 0x92, 0x87, 0x4e, 0x74, 0xc4, 0x1d, 0x85, 0xdf, 0x81, 0x3c, 0x65, 0x16, 0xea, 0x10, 0x56, 0x84, 0xe4, 0xa1, 0x13, 0x1d, 0x71, 0x47, 0xe1, 0x77, 0x20, 0x4f, 0x59,
0x85, 0x73, 0x9c, 0x93, 0x6e, 0x83, 0xeb, 0x89, 0xd0, 0xa6, 0x46, 0xc9, 0x3c, 0x77, 0x94, 0xff, 0xe1, 0x1c, 0xe7, 0xa4, 0xdb, 0xe0, 0x7a, 0x22, 0xb4, 0xa9, 0x51, 0x32, 0xcf, 0x1d, 0xe5, 0x3f,
0xca, 0x40, 0x4d, 0xce, 0x72, 0xcf, 0x8e, 0x06, 0x47, 0x97, 0xd4, 0xd9, 0x5f, 0x87, 0x25, 0x26, 0x33, 0x50, 0x93, 0xb3, 0xdc, 0xb3, 0xa3, 0xc1, 0xd1, 0x25, 0x75, 0xf6, 0x37, 0x61, 0x89, 0xc9,
0x77, 0x92, 0x0f, 0x63, 0x81, 0xbb, 0x63, 0x0b, 0xe6, 0x70, 0x3b, 0xb4, 0x52, 0xde, 0x95, 0x9b, 0x9d, 0xe4, 0xc3, 0x58, 0xe0, 0xee, 0xd8, 0x82, 0x39, 0xdc, 0x0e, 0xad, 0x94, 0x77, 0xe5, 0xe6,
0xaf, 0x8a, 0x1d, 0xa6, 0x56, 0xfe, 0x05, 0x71, 0x51, 0x78, 0x4e, 0x5c, 0x2c, 0xbd, 0x50, 0x5c, 0xab, 0x62, 0x87, 0xa9, 0x95, 0x7f, 0x41, 0x5c, 0x14, 0x9e, 0x13, 0x17, 0x4b, 0x2f, 0x14, 0x17,
0xec, 0xc3, 0xda, 0x3c, 0xe3, 0x32, 0x38, 0xbe, 0x01, 0x4b, 0xc2, 0x29, 0x71, 0x0a, 0x5c, 0xe4, 0xfb, 0xb0, 0x36, 0xcf, 0xb8, 0x0c, 0x8e, 0x6f, 0xc1, 0x92, 0x70, 0x4a, 0x9c, 0x02, 0x17, 0xf9,
0xb7, 0xd8, 0x44, 0xfd, 0x87, 0x0c, 0xac, 0xc9, 0xec, 0xf4, 0xf9, 0xf8, 0x4c, 0x53, 0x3c, 0xe7, 0x2d, 0x36, 0x51, 0xff, 0x21, 0x03, 0x6b, 0x32, 0x3b, 0x7d, 0x31, 0x3e, 0xd3, 0x14, 0xcf, 0xf9,
0x5f, 0x84, 0xe7, 0x17, 0xf4, 0x9f, 0xda, 0x80, 0xf5, 0x73, 0x3c, 0xbe, 0xc4, 0xc7, 0xfa, 0x63, 0x17, 0xe1, 0xf9, 0x05, 0xfd, 0xa7, 0x36, 0x60, 0xfd, 0x1c, 0x8f, 0x2f, 0xf1, 0xb1, 0xfe, 0x58,
0x05, 0x96, 0xf7, 0xe8, 0xc8, 0xf1, 0x2e, 0xa9, 0x17, 0x52, 0xe4, 0xe6, 0x5e, 0x28, 0x88, 0x6f, 0x81, 0xe5, 0x3d, 0x3a, 0x72, 0xbc, 0x4b, 0xea, 0x85, 0x14, 0xb9, 0xb9, 0x17, 0x0a, 0xe2, 0x5b,
0x41, 0x45, 0xe2, 0x95, 0x6c, 0x5d, 0x64, 0x5b, 0x59, 0xc4, 0xf6, 0x7f, 0x28, 0x50, 0x69, 0xf8, 0x50, 0x91, 0x78, 0x25, 0x5b, 0x17, 0xd9, 0x56, 0x16, 0xb1, 0xfd, 0xef, 0x0a, 0x54, 0x1a, 0xfe,
0xe3, 0xb1, 0x13, 0x5d, 0x52, 0xa6, 0x2e, 0xe2, 0xcc, 0x2d, 0xc2, 0x89, 0xa0, 0x1a, 0xc3, 0x14, 0x78, 0xec, 0x44, 0x97, 0x94, 0xa9, 0x8b, 0x38, 0x73, 0x8b, 0x70, 0x22, 0xa8, 0xc6, 0x30, 0x05,
0x04, 0xa9, 0xff, 0xa9, 0xc0, 0x0a, 0xf1, 0x5d, 0xf7, 0xd0, 0x1e, 0x1c, 0xbf, 0xda, 0xd8, 0x31, 0x41, 0xea, 0x7f, 0x28, 0xb0, 0x42, 0x7c, 0xd7, 0x3d, 0xb4, 0x07, 0xc7, 0xaf, 0x36, 0x76, 0x0c,
0xa0, 0x19, 0x50, 0x89, 0xfe, 0x7f, 0x14, 0xa8, 0x76, 0x03, 0xca, 0x7e, 0xac, 0x5f, 0x69, 0xf0, 0x68, 0x06, 0x54, 0xa2, 0xff, 0x6f, 0x05, 0xaa, 0xdd, 0x80, 0xb2, 0x1f, 0xeb, 0x57, 0x1a, 0x3c,
0x6c, 0x27, 0x3c, 0x8c, 0xe4, 0x1e, 0xa2, 0x44, 0x78, 0x59, 0x5d, 0x85, 0x95, 0x04, 0xbb, 0xe4, 0xdb, 0x09, 0x0f, 0x23, 0xb9, 0x87, 0x28, 0x11, 0x5e, 0x56, 0x57, 0x61, 0x25, 0xc1, 0x2e, 0xf9,
0xe3, 0x5f, 0x14, 0x58, 0x17, 0x01, 0x22, 0x35, 0xc3, 0x4b, 0x4a, 0x4b, 0x8c, 0x37, 0x97, 0xc2, 0xf8, 0x17, 0x05, 0xd6, 0x45, 0x80, 0x48, 0xcd, 0xf0, 0x92, 0xd2, 0x12, 0xe3, 0xcd, 0xa5, 0xf0,
0x5b, 0x87, 0xab, 0xe7, 0xb1, 0x49, 0xd8, 0x3f, 0xc8, 0xc0, 0xb5, 0x38, 0x36, 0x2e, 0x39, 0xf0, 0xd6, 0xe1, 0xea, 0x79, 0x6c, 0x12, 0xf6, 0x0f, 0x32, 0x70, 0x2d, 0x8e, 0x8d, 0x4b, 0x0e, 0xfc,
0xff, 0x47, 0x3c, 0x6c, 0x40, 0xfd, 0x22, 0x09, 0x92, 0xa1, 0x8f, 0x32, 0x50, 0x6f, 0x04, 0xd4, 0xff, 0x10, 0x0f, 0x1b, 0x50, 0xbf, 0x48, 0x82, 0x64, 0xe8, 0xe3, 0x0c, 0xd4, 0x1b, 0x01, 0xb5,
0x8e, 0x68, 0x6a, 0x2f, 0xf2, 0xea, 0xc4, 0x06, 0x7e, 0x17, 0x96, 0x27, 0x76, 0x10, 0x39, 0x03, 0x23, 0x9a, 0xda, 0x8b, 0xbc, 0x3a, 0xb1, 0x81, 0xdf, 0x85, 0xe5, 0x89, 0x1d, 0x44, 0xce, 0xc0,
0x67, 0x62, 0xb3, 0xbf, 0xbd, 0x3c, 0xdf, 0xea, 0x9c, 0xeb, 0x60, 0xce, 0x44, 0x7d, 0x1d, 0x5e, 0x99, 0xd8, 0xec, 0x6f, 0x2f, 0xcf, 0xb7, 0x3a, 0xe7, 0x3a, 0x98, 0x33, 0x51, 0x5f, 0x87, 0xd7,
0x5b, 0xc0, 0x88, 0xe4, 0xeb, 0x7f, 0x15, 0xc0, 0xbd, 0xc8, 0x0e, 0xa2, 0xcf, 0xc1, 0xaa, 0xb2, 0x16, 0x30, 0x22, 0xf9, 0xfa, 0x1f, 0x05, 0x70, 0x2f, 0xb2, 0x83, 0xe8, 0x0b, 0xb0, 0xaa, 0x2c,
0x30, 0x98, 0xd6, 0xa1, 0x36, 0x87, 0x3f, 0xcd, 0x0b, 0x8d, 0x3e, 0x17, 0x2b, 0xce, 0xa7, 0xf2, 0x0c, 0xa6, 0x75, 0xa8, 0xcd, 0xe1, 0x4f, 0xf3, 0x42, 0xa3, 0x2f, 0xc4, 0x8a, 0xf3, 0x99, 0xbc,
0x92, 0xc6, 0x2f, 0x79, 0xf9, 0x37, 0x05, 0x36, 0x1a, 0xbe, 0x38, 0x58, 0x7c, 0x25, 0xbf, 0x30, 0xa4, 0xf1, 0x4b, 0x5e, 0xfe, 0x4d, 0x81, 0x8d, 0x86, 0x2f, 0x0e, 0x16, 0x5f, 0xc9, 0x2f, 0x4c,
0xf5, 0x4d, 0x78, 0x7d, 0x21, 0x40, 0x49, 0xc0, 0xbf, 0x2a, 0x70, 0x95, 0x50, 0x7b, 0xf8, 0x6a, 0x7d, 0x13, 0x5e, 0x5f, 0x08, 0x50, 0x12, 0xf0, 0xaf, 0x0a, 0x5c, 0x25, 0xd4, 0x1e, 0xbe, 0x9a,
0x82, 0xbf, 0x0f, 0xd7, 0x2e, 0x80, 0x93, 0x3b, 0xd4, 0x5b, 0x50, 0x1c, 0xd3, 0xc8, 0x1e, 0xda, 0xe0, 0xef, 0xc3, 0xb5, 0x0b, 0xe0, 0xe4, 0x0e, 0xf5, 0x16, 0x14, 0xc7, 0x34, 0xb2, 0x87, 0x76,
0x91, 0x2d, 0x21, 0x6d, 0xc4, 0xfd, 0xce, 0xac, 0xdb, 0xd2, 0x82, 0x24, 0xb6, 0xea, 0x27, 0x19, 0x64, 0x4b, 0x48, 0x1b, 0x71, 0xbf, 0x33, 0xeb, 0xb6, 0xb4, 0x20, 0x89, 0xad, 0xfa, 0x69, 0x06,
0xa8, 0xf1, 0xbd, 0xee, 0x17, 0x3f, 0x5a, 0x8b, 0xff, 0x05, 0x3e, 0x52, 0x60, 0x6d, 0x9e, 0xa0, 0x6a, 0x7c, 0xaf, 0xfb, 0xe5, 0x8f, 0xd6, 0xe2, 0x7f, 0x81, 0x8f, 0x15, 0x58, 0x9b, 0x27, 0x28,
0xe4, 0x9f, 0xe0, 0xa7, 0x7d, 0x5e, 0xb1, 0x20, 0x21, 0x64, 0x17, 0x6d, 0x41, 0xff, 0x31, 0x03, 0xf9, 0x27, 0xf8, 0xff, 0x3e, 0xaf, 0x58, 0x90, 0x10, 0xb2, 0x8b, 0xb6, 0xa0, 0xff, 0x98, 0x81,
0xf5, 0xf4, 0x94, 0xbe, 0x38, 0xdb, 0x98, 0x3f, 0xdb, 0xf8, 0x89, 0x0f, 0xb3, 0x3e, 0x56, 0xe0, 0x7a, 0x7a, 0x4a, 0x5f, 0x9e, 0x6d, 0xcc, 0x9f, 0x6d, 0xfc, 0xc4, 0x87, 0x59, 0x9f, 0x28, 0xf0,
0xb5, 0x05, 0x84, 0xfe, 0x64, 0x8e, 0x4e, 0x9d, 0x70, 0x64, 0x9e, 0x7b, 0xc2, 0xf1, 0xa2, 0xae, 0xda, 0x02, 0x42, 0x7f, 0x32, 0x47, 0xa7, 0x4e, 0x38, 0x32, 0xcf, 0x3d, 0xe1, 0x78, 0x51, 0x57,
0xfe, 0x67, 0x05, 0xd6, 0xda, 0xe2, 0x60, 0x59, 0xfc, 0xc7, 0x5f, 0xde, 0x6c, 0xc6, 0xcf, 0x8e, 0xff, 0xb3, 0x02, 0x6b, 0x6d, 0x71, 0xb0, 0x2c, 0xfe, 0xe3, 0x2f, 0x6f, 0x36, 0xe3, 0x67, 0xc7,
0x73, 0xb3, 0xeb, 0x1b, 0xb5, 0x01, 0xeb, 0xe7, 0xa0, 0xbd, 0xc4, 0xd9, 0xc4, 0x7f, 0x2b, 0xb0, 0xb9, 0xd9, 0xf5, 0x8d, 0xda, 0x80, 0xf5, 0x73, 0xd0, 0x5e, 0xe2, 0x6c, 0xe2, 0xbf, 0x14, 0x58,
0x2a, 0x7b, 0xd1, 0x2e, 0xed, 0x46, 0x60, 0x01, 0x3b, 0xf8, 0x2d, 0xc8, 0x3a, 0xc3, 0x78, 0x07, 0x95, 0xbd, 0x68, 0x97, 0x76, 0x23, 0xb0, 0x80, 0x1d, 0xfc, 0x16, 0x64, 0x9d, 0x61, 0xbc, 0x83,
0x39, 0x7f, 0x09, 0xce, 0x14, 0xea, 0x1d, 0xc0, 0x69, 0xdc, 0x2f, 0x41, 0xdd, 0x3f, 0x65, 0x61, 0x9c, 0xbf, 0x04, 0x67, 0x0a, 0xf5, 0x0e, 0xe0, 0x34, 0xee, 0x97, 0xa0, 0xee, 0x9f, 0xb2, 0xb0,
0xb5, 0x37, 0x71, 0x9d, 0x48, 0x2a, 0x5f, 0xed, 0xc4, 0xff, 0x25, 0x58, 0x0e, 0x19, 0x58, 0x4b, 0xda, 0x9b, 0xb8, 0x4e, 0x24, 0x95, 0xaf, 0x76, 0xe2, 0xff, 0x0a, 0x2c, 0x87, 0x0c, 0xac, 0x25,
0x5c, 0xc9, 0x71, 0x62, 0x4b, 0xa4, 0xcc, 0x65, 0x0d, 0x2e, 0xc2, 0x6f, 0x43, 0x39, 0x36, 0x99, 0xae, 0xe4, 0x38, 0xb1, 0x25, 0x52, 0xe6, 0xb2, 0x06, 0x17, 0xe1, 0xb7, 0xa1, 0x1c, 0x9b, 0x4c,
0x7a, 0x91, 0x3c, 0x50, 0x03, 0x69, 0x31, 0xf5, 0x22, 0x7c, 0x13, 0xae, 0x79, 0xd3, 0x31, 0xbf, 0xbd, 0x48, 0x1e, 0xa8, 0x81, 0xb4, 0x98, 0x7a, 0x11, 0xbe, 0x09, 0xd7, 0xbc, 0xe9, 0x98, 0x5f,
0xd2, 0xb6, 0x26, 0x34, 0x88, 0x2f, 0x7c, 0xed, 0x20, 0xbe, 0x7a, 0xae, 0x79, 0xd3, 0x31, 0xf1, 0x69, 0x5b, 0x13, 0x1a, 0xc4, 0x17, 0xbe, 0x76, 0x10, 0x5f, 0x3d, 0xd7, 0xbc, 0xe9, 0x98, 0xf8,
0x4f, 0xc3, 0x2e, 0x0d, 0xc4, 0x85, 0xaf, 0x1d, 0x44, 0xf8, 0x0e, 0x94, 0x6c, 0x77, 0xe4, 0x07, 0xa7, 0x61, 0x97, 0x06, 0xe2, 0xc2, 0xd7, 0x0e, 0x22, 0x7c, 0x07, 0x4a, 0xb6, 0x3b, 0xf2, 0x03,
0x4e, 0x74, 0x34, 0x96, 0x77, 0xce, 0x6a, 0x7c, 0x03, 0x73, 0x9e, 0xfe, 0x1d, 0x2d, 0xb6, 0x24, 0x27, 0x3a, 0x1a, 0xcb, 0x3b, 0x67, 0x35, 0xbe, 0x81, 0x39, 0x4f, 0xff, 0x8e, 0x16, 0x5b, 0x92,
0xb3, 0x46, 0xea, 0x37, 0xa0, 0x94, 0xc8, 0x31, 0x82, 0x65, 0xfd, 0x7e, 0x5f, 0x6b, 0x59, 0xbd, 0x59, 0x23, 0xf5, 0x5b, 0x50, 0x4a, 0xe4, 0x18, 0xc1, 0xb2, 0x7e, 0xbf, 0xaf, 0xb5, 0xac, 0x5e,
0x6e, 0xab, 0x69, 0xf6, 0xc4, 0x3d, 0xf1, 0x41, 0xbf, 0xd5, 0xb2, 0x7a, 0x0d, 0xcd, 0x40, 0x8a, 0xb7, 0xd5, 0x34, 0x7b, 0xe2, 0x9e, 0xf8, 0xa0, 0xdf, 0x6a, 0x59, 0xbd, 0x86, 0x66, 0x20, 0x45,
0x4a, 0x00, 0x78, 0x97, 0xbc, 0xf3, 0x19, 0x41, 0xca, 0x73, 0x08, 0x7a, 0x1d, 0x4a, 0x81, 0x7f, 0x25, 0x00, 0xbc, 0x4b, 0xde, 0xf9, 0x8c, 0x20, 0xe5, 0x39, 0x04, 0xbd, 0x0e, 0xa5, 0xc0, 0x3f,
0x2a, 0xb1, 0x67, 0x38, 0x9c, 0x62, 0xe0, 0x9f, 0x72, 0xe4, 0xaa, 0x06, 0x38, 0x3d, 0x57, 0x19, 0x95, 0xd8, 0x33, 0x1c, 0x4e, 0x31, 0xf0, 0x4f, 0x39, 0x72, 0x55, 0x03, 0x9c, 0x9e, 0xab, 0x8c,
0x6d, 0xa9, 0xe4, 0xad, 0xcc, 0x25, 0xef, 0xd9, 0xf8, 0x49, 0xf2, 0x16, 0x5b, 0x79, 0xf6, 0x9d, 0xb6, 0x54, 0xf2, 0x56, 0xe6, 0x92, 0xf7, 0x6c, 0xfc, 0x24, 0x79, 0x8b, 0xad, 0x3c, 0xfb, 0xce,
0x7f, 0x40, 0x6d, 0x37, 0x8a, 0xd7, 0x2b, 0xf5, 0xaf, 0x33, 0x50, 0x21, 0x4c, 0xe2, 0x8c, 0x69, 0x3f, 0xa0, 0xb6, 0x1b, 0xc5, 0xeb, 0x95, 0xfa, 0x57, 0x19, 0xa8, 0x10, 0x26, 0x71, 0xc6, 0xb4,
0x2f, 0xb2, 0xa3, 0x90, 0x79, 0xea, 0x88, 0x9b, 0x58, 0xb3, 0xb4, 0x5b, 0x22, 0x65, 0x21, 0x13, 0x17, 0xd9, 0x51, 0xc8, 0x3c, 0x75, 0xc4, 0x4d, 0xac, 0x59, 0xda, 0x2d, 0x91, 0xb2, 0x90, 0x89,
0x77, 0x05, 0xbb, 0xb0, 0x1e, 0xd2, 0x81, 0xef, 0x0d, 0x43, 0xeb, 0x90, 0x1e, 0x39, 0xde, 0xd0, 0xbb, 0x82, 0x5d, 0x58, 0x0f, 0xe9, 0xc0, 0xf7, 0x86, 0xa1, 0x75, 0x48, 0x8f, 0x1c, 0x6f, 0x68,
0x1a, 0xdb, 0x61, 0x24, 0xaf, 0x23, 0x2b, 0xa4, 0x26, 0x95, 0x7b, 0x5c, 0xd7, 0xe6, 0x2a, 0x7c, 0x8d, 0xed, 0x30, 0x92, 0xd7, 0x91, 0x15, 0x52, 0x93, 0xca, 0x3d, 0xae, 0x6b, 0x73, 0x15, 0xbe,
0x03, 0xd6, 0x0e, 0x1d, 0xcf, 0xf5, 0x47, 0xd6, 0xc4, 0xb5, 0xcf, 0x68, 0x10, 0x4a, 0xa8, 0x2c, 0x01, 0x6b, 0x87, 0x8e, 0xe7, 0xfa, 0x23, 0x6b, 0xe2, 0xda, 0x67, 0x34, 0x08, 0x25, 0x54, 0x16,
0xbc, 0xf2, 0x04, 0x0b, 0x5d, 0x57, 0xa8, 0x84, 0xbb, 0x3f, 0x84, 0xed, 0x85, 0xa3, 0x58, 0x8f, 0x5e, 0x79, 0x82, 0x85, 0xae, 0x2b, 0x54, 0xc2, 0xdd, 0x1f, 0xc1, 0xf6, 0xc2, 0x51, 0xac, 0xc7,
0x1d, 0x37, 0xa2, 0x01, 0x1d, 0x5a, 0x01, 0x9d, 0xb8, 0xce, 0x40, 0xbc, 0x26, 0x10, 0x7b, 0xf7, 0x8e, 0x1b, 0xd1, 0x80, 0x0e, 0xad, 0x80, 0x4e, 0x5c, 0x67, 0x20, 0x5e, 0x13, 0x88, 0xbd, 0xfb,
0xaf, 0x2e, 0x18, 0xfa, 0x40, 0x9a, 0x93, 0x99, 0x35, 0x63, 0x7b, 0x30, 0x99, 0x5a, 0x53, 0x7e, 0xd7, 0x17, 0x0c, 0x7d, 0x20, 0xcd, 0xc9, 0xcc, 0x9a, 0xb1, 0x3d, 0x98, 0x4c, 0xad, 0x29, 0xbf,
0x83, 0xc8, 0x56, 0x31, 0x85, 0x14, 0x07, 0x93, 0x69, 0x9f, 0xd5, 0x31, 0x82, 0xec, 0x93, 0x89, 0x41, 0x64, 0xab, 0x98, 0x42, 0x8a, 0x83, 0xc9, 0xb4, 0xcf, 0xea, 0x18, 0x41, 0xf6, 0xc9, 0x44,
0x58, 0xbc, 0x14, 0xc2, 0x8a, 0xea, 0x8f, 0x15, 0xa8, 0x6a, 0xa3, 0x51, 0x40, 0x47, 0x76, 0x24, 0x2c, 0x5e, 0x0a, 0x61, 0x45, 0xf5, 0xc7, 0x0a, 0x54, 0xb5, 0xd1, 0x28, 0xa0, 0x23, 0x3b, 0x92,
0x69, 0xba, 0x01, 0x6b, 0x82, 0x92, 0x33, 0x4b, 0x3e, 0x53, 0x12, 0x78, 0x14, 0x81, 0x47, 0xea, 0x34, 0xdd, 0x80, 0x35, 0x41, 0xc9, 0x99, 0x25, 0x9f, 0x29, 0x09, 0x3c, 0x8a, 0xc0, 0x23, 0x75,
0xc4, 0x23, 0xa5, 0x38, 0x7c, 0xaf, 0x4e, 0xbd, 0x85, 0x6d, 0x32, 0xbc, 0xcd, 0x5a, 0xa2, 0x4d, 0xe2, 0x91, 0x52, 0x1c, 0xbe, 0x57, 0xa7, 0xde, 0xc2, 0x36, 0x19, 0xde, 0x66, 0x2d, 0xd1, 0xa6,
0xb7, 0xfa, 0x79, 0x78, 0x6d, 0x31, 0x0b, 0x63, 0x47, 0x3c, 0x34, 0xa9, 0x90, 0xab, 0x0b, 0x40, 0x5b, 0xfd, 0x2c, 0xbc, 0xb6, 0x98, 0x85, 0xb1, 0x23, 0x1e, 0x9a, 0x54, 0xc8, 0xd5, 0x05, 0xa0,
0xb7, 0x1d, 0xef, 0x33, 0x9a, 0xda, 0x4f, 0x39, 0x5f, 0x9f, 0xd2, 0xd4, 0x7e, 0xaa, 0xfe, 0x7b, 0xdb, 0x8e, 0xf7, 0x39, 0x4d, 0xed, 0xa7, 0x9c, 0xaf, 0xcf, 0x68, 0x6a, 0x3f, 0x55, 0xff, 0x26,
0x72, 0x03, 0x10, 0x87, 0x4b, 0xb2, 0x1a, 0xc7, 0x79, 0x41, 0xf9, 0xac, 0xbc, 0x50, 0x87, 0xa5, 0xb9, 0x01, 0x88, 0xc3, 0x25, 0x59, 0x8d, 0xe3, 0xbc, 0xa0, 0x7c, 0x5e, 0x5e, 0xa8, 0xc3, 0x52,
0x90, 0x06, 0x27, 0x8e, 0x37, 0x8a, 0xaf, 0xa8, 0x65, 0x15, 0xf7, 0xe0, 0xab, 0x12, 0x3b, 0x7d, 0x48, 0x83, 0x13, 0xc7, 0x1b, 0xc5, 0x57, 0xd4, 0xb2, 0x8a, 0x7b, 0xf0, 0x75, 0x89, 0x9d, 0x3e,
0x1a, 0xd1, 0xc0, 0xb3, 0x5d, 0xf7, 0xcc, 0x12, 0x07, 0x15, 0x5e, 0x44, 0x87, 0xd6, 0xec, 0x51, 0x8d, 0x68, 0xe0, 0xd9, 0xae, 0x7b, 0x66, 0x89, 0x83, 0x0a, 0x2f, 0xa2, 0x43, 0x6b, 0xf6, 0xa8,
0x95, 0x58, 0x91, 0xbf, 0x2c, 0xac, 0xf5, 0xc4, 0x98, 0x24, 0xb6, 0x66, 0xf2, 0xdc, 0xea, 0x5b, 0x4a, 0xac, 0xc8, 0x5f, 0x15, 0xd6, 0x7a, 0x62, 0x4c, 0x12, 0x5b, 0x33, 0x79, 0x6e, 0xf5, 0x1d,
0x50, 0x0d, 0x64, 0x10, 0x5b, 0x21, 0x73, 0x8f, 0xcc, 0x47, 0x6b, 0xc9, 0x3d, 0x73, 0x2a, 0xc2, 0xa8, 0x06, 0x32, 0x88, 0xad, 0x90, 0xb9, 0x47, 0xe6, 0xa3, 0xb5, 0xe4, 0x9e, 0x39, 0x15, 0xe1,
0x49, 0x25, 0x98, 0x0b, 0xf8, 0xef, 0xc0, 0x8a, 0x1d, 0xfb, 0x56, 0xb6, 0x9e, 0xdf, 0xb7, 0xcc, 0xa4, 0x12, 0xcc, 0x05, 0xfc, 0x6d, 0x58, 0x96, 0x33, 0xb2, 0x5d, 0xc7, 0x9e, 0x6d, 0x4c, 0xcf,
0x7b, 0x9e, 0x54, 0xed, 0xf9, 0x48, 0xb8, 0x0d, 0xcb, 0x12, 0x91, 0xed, 0x3a, 0xf6, 0x6c, 0x63, 0xbd, 0x34, 0xd3, 0x98, 0x92, 0xc8, 0x37, 0x69, 0xbc, 0xf2, 0x61, 0xae, 0x58, 0x40, 0x4b, 0xec,
0x7b, 0xee, 0xa5, 0x9a, 0xc6, 0x94, 0x44, 0xbe, 0x69, 0xe3, 0x15, 0xf6, 0x1f, 0x5d, 0xeb, 0x4f, 0x6f, 0xb8, 0xd6, 0x9f, 0x0c, 0x79, 0x64, 0x5c, 0xe2, 0x3d, 0x42, 0xfa, 0x71, 0x5a, 0x6e, 0xfe,
0x86, 0xbc, 0xa7, 0x4b, 0xbc, 0xbb, 0x48, 0x3f, 0x6b, 0xcb, 0xcd, 0x3f, 0x6b, 0x9b, 0x7f, 0x26, 0x71, 0xda, 0xfc, 0x63, 0xb7, 0xfc, 0xb9, 0xc7, 0x6e, 0xea, 0x1d, 0x58, 0x9b, 0xc7, 0x2f, 0x63,
0x97, 0x3f, 0xf7, 0x4c, 0x4e, 0xbd, 0x03, 0x6b, 0xf3, 0xf8, 0x65, 0x94, 0x6d, 0x41, 0x9e, 0x5f, 0x65, 0x0b, 0xf2, 0xfc, 0x5a, 0xfc, 0xdc, 0x62, 0x98, 0xba, 0xf7, 0x26, 0xc2, 0x40, 0xfd, 0x5b,
0xa8, 0x9f, 0x5b, 0x46, 0x53, 0x37, 0xe6, 0x44, 0x18, 0xa8, 0x7f, 0xab, 0x40, 0x6d, 0xc1, 0x2f, 0x05, 0x6a, 0x0b, 0x7e, 0x94, 0x92, 0xbf, 0x30, 0x25, 0x75, 0xc8, 0xf3, 0xd3, 0x90, 0xe7, 0x17,
0x56, 0xf2, 0xff, 0xa6, 0xa4, 0x8e, 0x87, 0x7e, 0x16, 0xf2, 0xfc, 0x6a, 0x5f, 0xbe, 0x58, 0xb9, 0xf4, 0xf2, 0xdd, 0xc9, 0xb5, 0x8b, 0xff, 0x59, 0xfc, 0x32, 0x9d, 0x08, 0x2b, 0x96, 0xce, 0x78,
0x76, 0xf1, 0x0f, 0x8d, 0x5f, 0xc3, 0x13, 0x61, 0xc5, 0x12, 0x21, 0x0f, 0xa8, 0x01, 0x3f, 0x1f, 0x58, 0x0c, 0xf8, 0x29, 0x4f, 0xbc, 0xcf, 0x2b, 0x33, 0x99, 0x38, 0xf8, 0xb9, 0x78, 0x6c, 0x94,
0x8a, 0x77, 0x88, 0x65, 0x26, 0x13, 0x47, 0x46, 0x17, 0x0f, 0x9c, 0x72, 0xcf, 0x3d, 0x70, 0xda, 0x7b, 0xee, 0xb1, 0xd1, 0xf6, 0xef, 0x67, 0xa1, 0xd4, 0x3e, 0xeb, 0x3d, 0x71, 0x0f, 0x5c, 0x7b,
0xfe, 0x83, 0x2c, 0x94, 0xda, 0x67, 0xbd, 0x27, 0xee, 0x81, 0x6b, 0x8f, 0xf8, 0x3d, 0x79, 0xbb, 0xc4, 0x6f, 0xbb, 0xdb, 0x5d, 0xf3, 0x11, 0xba, 0x82, 0x57, 0xa1, 0x62, 0x74, 0x4c, 0xcb, 0x60,
0x6b, 0x3e, 0x42, 0x57, 0xf0, 0x2a, 0x54, 0x8c, 0x8e, 0x69, 0x19, 0x6c, 0x29, 0x39, 0x68, 0x69, 0x0b, 0xc2, 0x41, 0x4b, 0xbb, 0x8b, 0x14, 0xb6, 0x62, 0x74, 0x49, 0xd3, 0xba, 0xa7, 0x3f, 0x12,
0x77, 0x91, 0xc2, 0xd6, 0x9a, 0x2e, 0x69, 0x5a, 0xf7, 0xf4, 0x47, 0x42, 0x92, 0xc1, 0x35, 0x58, 0x92, 0x0c, 0xae, 0xc1, 0x4a, 0xdf, 0x68, 0xde, 0xef, 0xeb, 0x33, 0x61, 0x0e, 0xaf, 0xc3, 0x6a,
0xe9, 0x1b, 0xcd, 0xfb, 0x7d, 0x7d, 0x26, 0xcc, 0xe1, 0x75, 0x58, 0x6d, 0xf7, 0x5b, 0x66, 0xb3, 0xbb, 0xdf, 0x32, 0x9b, 0xdd, 0x56, 0x4a, 0x5c, 0x64, 0xab, 0xcb, 0x5e, 0xab, 0xb3, 0x27, 0xaa,
0xdb, 0x4a, 0x89, 0x8b, 0x6c, 0x5d, 0xda, 0x6b, 0x75, 0xf6, 0x44, 0x15, 0xb1, 0xfe, 0xfb, 0x46, 0x88, 0xf5, 0xdf, 0x37, 0x7a, 0xcd, 0xbb, 0x86, 0xbe, 0x2f, 0x44, 0x9b, 0x4c, 0xf4, 0x91, 0x4e,
0xaf, 0x79, 0xd7, 0xd0, 0xf7, 0x85, 0x68, 0x93, 0x89, 0x3e, 0xd4, 0x49, 0xe7, 0xa0, 0x19, 0x0f, 0x3a, 0x07, 0xcd, 0x78, 0xc8, 0x3b, 0x18, 0x41, 0x79, 0xaf, 0x69, 0x68, 0x44, 0xf6, 0xf2, 0x4c,
0x79, 0x07, 0x23, 0x28, 0xef, 0x35, 0x0d, 0x8d, 0xc8, 0x5e, 0x9e, 0x29, 0xb8, 0x0a, 0x25, 0xdd, 0xc1, 0x55, 0x28, 0xe9, 0x46, 0xbf, 0x2d, 0xeb, 0x19, 0x5c, 0x87, 0x9a, 0xd6, 0x37, 0x3b, 0x56,
0xe8, 0xb7, 0x65, 0x3d, 0x83, 0xeb, 0x50, 0xd3, 0xfa, 0x66, 0xc7, 0x6a, 0x1a, 0x0d, 0xa2, 0xb7, 0xd3, 0x68, 0x10, 0xbd, 0xad, 0x1b, 0xa6, 0xd4, 0xe4, 0x70, 0x0d, 0xaa, 0x66, 0xb3, 0xad, 0xf7,
0x75, 0xc3, 0x94, 0x9a, 0x1c, 0xae, 0x41, 0xd5, 0x6c, 0xb6, 0xf5, 0x9e, 0xa9, 0xb5, 0xbb, 0x52, 0x4c, 0xad, 0xdd, 0x95, 0x42, 0x36, 0x8b, 0x62, 0x4f, 0x8f, 0x6d, 0x10, 0xde, 0x80, 0x75, 0xa3,
0xc8, 0x66, 0x51, 0xec, 0xe9, 0xb1, 0x0d, 0xc2, 0x1b, 0xb0, 0x6e, 0x74, 0x2c, 0xf9, 0xd8, 0xc9, 0x63, 0xc9, 0x27, 0x4b, 0xd6, 0x03, 0xad, 0xd5, 0xd7, 0xa5, 0x6e, 0x13, 0x5f, 0x03, 0xdc, 0x31,
0x7a, 0xa0, 0xb5, 0xfa, 0xba, 0xd4, 0x6d, 0xe2, 0x6b, 0x80, 0x3b, 0x86, 0xd5, 0xef, 0xee, 0x6b, 0xac, 0x7e, 0x77, 0x5f, 0x33, 0x75, 0xcb, 0xe8, 0x3c, 0x94, 0x8a, 0x3b, 0xb8, 0x0a, 0xc5, 0xd9,
0xa6, 0x6e, 0x19, 0x9d, 0x87, 0x52, 0x71, 0x07, 0x57, 0xa1, 0x38, 0x9b, 0xc1, 0x33, 0xc6, 0x42, 0x0c, 0x9e, 0x31, 0x16, 0x2a, 0x5d, 0x8d, 0x98, 0x33, 0xb0, 0xcf, 0x9e, 0x31, 0xb2, 0xe0, 0x2e,
0xa5, 0xab, 0x11, 0x73, 0x06, 0xf6, 0xd9, 0x33, 0x46, 0x16, 0xdc, 0x25, 0x9d, 0x7e, 0x77, 0x66, 0xe9, 0xf4, 0xbb, 0x33, 0xb3, 0x55, 0x28, 0x4b, 0xb2, 0xa4, 0x28, 0xc7, 0x44, 0x7b, 0x4d, 0xa3,
0xb6, 0x0a, 0x65, 0x49, 0x96, 0x14, 0xe5, 0x98, 0x68, 0xaf, 0x69, 0x34, 0x92, 0xf9, 0x3d, 0x2b, 0x91, 0xcc, 0xef, 0x59, 0x71, 0x23, 0x83, 0x94, 0xed, 0x63, 0xc8, 0x71, 0x77, 0x14, 0x21, 0x67,
0x6e, 0x64, 0x90, 0xb2, 0x7d, 0x0c, 0x39, 0xee, 0x8e, 0x22, 0xe4, 0x8c, 0x8e, 0xa1, 0xa3, 0x2b, 0x74, 0x0c, 0x1d, 0x5d, 0xc1, 0x2b, 0x00, 0xcd, 0x5e, 0xd3, 0x30, 0xf5, 0xbb, 0x44, 0x6b, 0x31,
0x78, 0x05, 0xa0, 0xd9, 0x6b, 0x1a, 0xa6, 0x7e, 0x97, 0x68, 0x2d, 0x06, 0x9b, 0x0b, 0x62, 0x02, 0xd8, 0x5c, 0x10, 0x13, 0xc8, 0xd0, 0x2e, 0xc3, 0x52, 0xb3, 0x77, 0xd0, 0xea, 0x68, 0xa6, 0x84,
0x19, 0xda, 0x65, 0x58, 0x6a, 0xf6, 0x0e, 0x5a, 0x1d, 0xcd, 0x94, 0x30, 0x9b, 0xbd, 0xfb, 0xfd, 0xd9, 0xec, 0xdd, 0xef, 0x77, 0x4c, 0xa6, 0x44, 0xb8, 0x0c, 0x85, 0x66, 0xcf, 0xd4, 0xbf, 0x67,
0x8e, 0xc9, 0x94, 0x08, 0x97, 0xa1, 0xd0, 0xec, 0x99, 0xfa, 0xf7, 0x4c, 0x86, 0x8b, 0xeb, 0x04, 0x32, 0x5c, 0x5c, 0x27, 0x58, 0x45, 0xcf, 0xee, 0x6c, 0xff, 0x28, 0x0b, 0x39, 0xfe, 0xe0, 0xb4,
0xab, 0xe8, 0xd9, 0x9d, 0xed, 0x1f, 0x65, 0x21, 0xc7, 0x9f, 0xaa, 0x56, 0xa0, 0xc4, 0xbd, 0x6d, 0x02, 0x25, 0xee, 0x6d, 0xf3, 0x51, 0x97, 0x0d, 0x59, 0x82, 0x5c, 0xd3, 0x30, 0x6f, 0xa3, 0x5f,
0x3e, 0xea, 0xb2, 0x21, 0x4b, 0x90, 0x6b, 0x1a, 0xe6, 0x6d, 0xf4, 0x4b, 0x19, 0x0c, 0x90, 0xef, 0xcc, 0x60, 0x80, 0x7c, 0x9f, 0x97, 0x7f, 0xa9, 0xc0, 0xca, 0x4d, 0xc3, 0x7c, 0xf7, 0x16, 0xfa,
0xf3, 0xf2, 0x2f, 0x17, 0x58, 0xb9, 0x69, 0x98, 0xef, 0xde, 0x42, 0x3f, 0xc8, 0xb0, 0x6e, 0xfb, 0x41, 0x86, 0x75, 0xdb, 0x17, 0x95, 0x5f, 0x8e, 0x15, 0xbb, 0x37, 0xd1, 0x0f, 0x13, 0xc5, 0xee,
0xa2, 0xf2, 0x2b, 0xb1, 0x62, 0xf7, 0x26, 0xfa, 0x61, 0xa2, 0xd8, 0xbd, 0x89, 0x7e, 0x35, 0x56, 0x4d, 0xf4, 0x2b, 0xb1, 0xe2, 0xbd, 0x5d, 0xf4, 0xab, 0x89, 0xe2, 0xbd, 0x5d, 0xf4, 0x6b, 0xb1,
0xbc, 0xb7, 0x8b, 0x7e, 0x2d, 0x51, 0xbc, 0xb7, 0x8b, 0x7e, 0x3d, 0x56, 0xdc, 0xba, 0x89, 0x7e, 0xe2, 0xd6, 0x4d, 0xf4, 0xeb, 0x89, 0xe2, 0xd6, 0x4d, 0xf4, 0x1b, 0x05, 0x86, 0x85, 0x23, 0x79,
0x23, 0x51, 0xdc, 0xba, 0x89, 0x7e, 0xb3, 0xc0, 0xb0, 0x70, 0x24, 0xef, 0xed, 0xa2, 0xdf, 0x2a, 0x6f, 0x17, 0xfd, 0x66, 0x31, 0xa9, 0xdd, 0xba, 0x89, 0x7e, 0xab, 0xc8, 0xfc, 0x9f, 0x78, 0x15,
0x26, 0xb5, 0x5b, 0x37, 0xd1, 0x6f, 0x17, 0x99, 0xff, 0x13, 0xaf, 0xa2, 0xdf, 0x41, 0x6c, 0x9a, 0xfd, 0x36, 0x62, 0xd3, 0x64, 0x0e, 0x42, 0xbf, 0xc3, 0x8b, 0x4c, 0x85, 0x7e, 0x17, 0x31, 0x8c,
0xcc, 0x41, 0xe8, 0x77, 0x79, 0x91, 0xa9, 0xd0, 0xef, 0x21, 0x86, 0x91, 0x49, 0x79, 0xf5, 0x23, 0x4c, 0xca, 0xab, 0x1f, 0x73, 0xcd, 0x23, 0x5d, 0x23, 0xe8, 0xf7, 0x0a, 0xe2, 0x85, 0x5a, 0xa3,
0xae, 0x79, 0xa4, 0x6b, 0x04, 0xfd, 0x7e, 0x41, 0xbc, 0x6d, 0x6b, 0x34, 0xdb, 0x5a, 0x0b, 0x61, 0xd9, 0xd6, 0x5a, 0x08, 0xf3, 0x16, 0x8c, 0x95, 0x3f, 0xb8, 0xc1, 0x8a, 0x2c, 0x3c, 0xd1, 0x1f,
0xde, 0x82, 0xb1, 0xf2, 0x87, 0x37, 0x58, 0x91, 0x85, 0x27, 0xfa, 0xa3, 0x2e, 0x1b, 0xf0, 0x81, 0x76, 0xd9, 0x80, 0x0f, 0x34, 0xd2, 0xf8, 0x40, 0x23, 0xe8, 0x8f, 0x6e, 0xb0, 0x01, 0x1f, 0x68,
0x46, 0x1a, 0x1f, 0x68, 0x04, 0xfd, 0xf1, 0x0d, 0x36, 0xe0, 0x03, 0x8d, 0x48, 0xbe, 0xfe, 0xa4, 0x44, 0xf2, 0xf5, 0xc7, 0x5d, 0x66, 0xc8, 0x55, 0x9f, 0xdc, 0x60, 0x93, 0x96, 0xf2, 0x3f, 0xe9,
0xcb, 0x0c, 0xb9, 0xea, 0xe3, 0x1b, 0x6c, 0xd2, 0x52, 0xfe, 0xa7, 0x5d, 0x5c, 0x84, 0xec, 0x5e, 0xe2, 0x22, 0x64, 0xf7, 0x9a, 0x26, 0xfa, 0x11, 0x1f, 0x8d, 0x85, 0x28, 0xfa, 0x53, 0xc4, 0x84,
0xd3, 0x44, 0x3f, 0xe2, 0xa3, 0xb1, 0x10, 0x45, 0x7f, 0x86, 0x98, 0xb0, 0xa7, 0x9b, 0xe8, 0xcf, 0x3d, 0xdd, 0x44, 0x7f, 0xc6, 0x84, 0x79, 0xb3, 0xdf, 0x6d, 0xe9, 0xe8, 0x0d, 0x36, 0xb9, 0xbb,
0x99, 0x30, 0x6f, 0xf6, 0xbb, 0x2d, 0x1d, 0xbd, 0xc1, 0x26, 0x77, 0x57, 0xef, 0xb4, 0x75, 0x93, 0x7a, 0xa7, 0xad, 0x9b, 0xe4, 0x11, 0xfa, 0x73, 0x6e, 0xfe, 0x61, 0xaf, 0x63, 0xa0, 0x4f, 0x11,
0x3c, 0x42, 0x7f, 0xc1, 0xcd, 0xbf, 0xdb, 0xeb, 0x18, 0xe8, 0x13, 0x84, 0xab, 0x00, 0xfa, 0xf7, 0xae, 0x02, 0xe8, 0xdf, 0xeb, 0x12, 0xbd, 0xd7, 0x6b, 0x76, 0x0c, 0xf4, 0xf6, 0xf6, 0x01, 0xa0,
0xba, 0x44, 0xef, 0xf5, 0x9a, 0x1d, 0x03, 0xbd, 0xbd, 0x7d, 0x00, 0xe8, 0x7c, 0x3a, 0x60, 0x00, 0xf3, 0xe9, 0x80, 0x01, 0xe8, 0x1b, 0xf7, 0x8c, 0xce, 0x43, 0x03, 0x5d, 0x61, 0x95, 0x2e, 0xd1,
0xfa, 0xc6, 0x3d, 0xa3, 0xf3, 0xd0, 0x40, 0x57, 0x58, 0xa5, 0x4b, 0xf4, 0xae, 0x46, 0x74, 0xa4, 0xbb, 0x1a, 0xd1, 0x91, 0x82, 0x01, 0x0a, 0xf2, 0xdd, 0x5b, 0x06, 0x2f, 0x43, 0x91, 0x74, 0x5a,
0x60, 0x80, 0x82, 0x7c, 0x31, 0x97, 0xc1, 0xcb, 0x50, 0x24, 0x9d, 0x56, 0x6b, 0x4f, 0x6b, 0xdc, 0xad, 0x3d, 0xad, 0x71, 0x0f, 0x65, 0xf7, 0xbe, 0x0d, 0x2b, 0x8e, 0xbf, 0x73, 0xe2, 0x44, 0x34,
0x43, 0xd9, 0xbd, 0x6f, 0xc2, 0x8a, 0xe3, 0xef, 0x9c, 0x38, 0x11, 0x0d, 0x43, 0xf1, 0x18, 0xfa, 0x0c, 0xc5, 0x93, 0xe6, 0x8f, 0x54, 0x59, 0x73, 0xfc, 0xeb, 0xa2, 0x74, 0x7d, 0xe4, 0x5f, 0x3f,
0x43, 0x55, 0xd6, 0x1c, 0xff, 0xba, 0x28, 0x5d, 0x1f, 0xf9, 0xd7, 0x4f, 0xa2, 0xeb, 0x5c, 0x7b, 0x89, 0xae, 0x73, 0xed, 0x75, 0x9e, 0x31, 0x0e, 0x0b, 0xbc, 0xf2, 0xde, 0xff, 0x06, 0x00, 0x00,
0x9d, 0x67, 0x8c, 0xc3, 0x02, 0xaf, 0xbc, 0xf7, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x5b, 0xff, 0xff, 0x40, 0x99, 0x5d, 0x63, 0x30, 0x2d, 0x00, 0x00,
0xfa, 0xe7, 0x6a, 0x2d, 0x00, 0x00,
} }
...@@ -288,10 +288,20 @@ type Tablet struct { ...@@ -288,10 +288,20 @@ type Tablet struct {
// MySQL port. Use topoproto.MysqlPort and topoproto.SetMysqlPort // MySQL port. Use topoproto.MysqlPort and topoproto.SetMysqlPort
// to access this variable. The functions provide support // to access this variable. The functions provide support
// for legacy behavior. // for legacy behavior.
MysqlPort int32 `protobuf:"varint,13,opt,name=mysql_port,json=mysqlPort,proto3" json:"mysql_port,omitempty"` MysqlPort int32 `protobuf:"varint,13,opt,name=mysql_port,json=mysqlPort,proto3" json:"mysql_port,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` // master_term_start_time is the time (in UTC) at which the current term of
XXX_unrecognized []byte `json:"-"` // the current tablet began as master. If this tablet is not currently the
XXX_sizecache int32 `json:"-"` // master, this value is ignored.
//
// A new master term begins any time an authoritative decision is communicated
// about which tablet should be the master, such as via Vitess
// replication-management commands like PlannedReparentShard,
// EmergencyReparentShard, and TabletExternallyReparented.
//
MasterTermStartTime *vttime.Time `protobuf:"bytes,14,opt,name=master_term_start_time,json=masterTermStartTime,proto3" json:"master_term_start_time,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *Tablet) Reset() { *m = Tablet{} } func (m *Tablet) Reset() { *m = Tablet{} }
...@@ -396,14 +406,36 @@ func (m *Tablet) GetMysqlPort() int32 { ...@@ -396,14 +406,36 @@ func (m *Tablet) GetMysqlPort() int32 {
return 0 return 0
} }
func (m *Tablet) GetMasterTermStartTime() *vttime.Time {
if m != nil {
return m.MasterTermStartTime
}
return nil
}
// A Shard contains data about a subset of the data whithin a keyspace. // A Shard contains data about a subset of the data whithin a keyspace.
type Shard struct { type Shard struct {
// master_alias is the tablet alias of the master for the shard.
// If it is unset, then there is no master in this shard yet.
// No lock is necessary to update this field, when for instance // No lock is necessary to update this field, when for instance
// TabletExternallyReparented updates this. However, we lock the // TabletExternallyReparented updates this. However, we lock the
// shard for reparenting operations (InitShardMaster, // shard for reparenting operations (InitShardMaster,
// PlannedReparentShard,EmergencyReparentShard), to guarantee // PlannedReparentShard,EmergencyReparentShard), to guarantee
// exclusive operation. // exclusive operation.
MasterAlias *TabletAlias `protobuf:"bytes,1,opt,name=master_alias,json=masterAlias,proto3" json:"master_alias,omitempty"` MasterAlias *TabletAlias `protobuf:"bytes,1,opt,name=master_alias,json=masterAlias,proto3" json:"master_alias,omitempty"`
// master_term_start_time is the time (in UTC) at which the current term of
// the master specified in master_alias began.
//
// A new master term begins any time an authoritative decision is communicated
// about which tablet should be the master, such as via Vitess
// replication-management commands like PlannedReparentShard,
// EmergencyReparentShard, and TabletExternallyReparented.
//
// The master_alias should only ever be changed if the new master's term began
// at a later time than this. Note that a new term can start for the tablet
// that is already the master. In that case, the master_term_start_time would
// be increased without changing the master_alias.
MasterTermStartTime *vttime.Time `protobuf:"bytes,8,opt,name=master_term_start_time,json=masterTermStartTime,proto3" json:"master_term_start_time,omitempty"`
// key_range is the KeyRange for this shard. It can be unset if: // key_range is the KeyRange for this shard. It can be unset if:
// - we are not using range-based sharding in this shard. // - we are not using range-based sharding in this shard.
// - the shard covers the entire keyrange. // - the shard covers the entire keyrange.
...@@ -462,6 +494,13 @@ func (m *Shard) GetMasterAlias() *TabletAlias { ...@@ -462,6 +494,13 @@ func (m *Shard) GetMasterAlias() *TabletAlias {
return nil return nil
} }
func (m *Shard) GetMasterTermStartTime() *vttime.Time {
if m != nil {
return m.MasterTermStartTime
}
return nil
}
func (m *Shard) GetKeyRange() *KeyRange { func (m *Shard) GetKeyRange() *KeyRange {
if m != nil { if m != nil {
return m.KeyRange return m.KeyRange
...@@ -1337,88 +1376,90 @@ func init() { ...@@ -1337,88 +1376,90 @@ func init() {
func init() { proto.RegisterFile("topodata.proto", fileDescriptor_52c350cb619f972e) } func init() { proto.RegisterFile("topodata.proto", fileDescriptor_52c350cb619f972e) }
var fileDescriptor_52c350cb619f972e = []byte{ var fileDescriptor_52c350cb619f972e = []byte{
// 1314 bytes of a gzipped FileDescriptorProto // 1349 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xe1, 0x6e, 0x1b, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6e, 0xdb, 0x46,
0x10, 0xee, 0xd9, 0x67, 0xe7, 0x3c, 0x3e, 0x27, 0xd7, 0x25, 0xad, 0x4e, 0x07, 0x15, 0x91, 0x51, 0x13, 0x0f, 0xf5, 0xcf, 0xd4, 0x88, 0x92, 0x99, 0x8d, 0x63, 0x10, 0xfa, 0xbe, 0xa0, 0x86, 0x8a,
0x85, 0x15, 0x84, 0x03, 0x69, 0x0b, 0x51, 0x11, 0x52, 0x5d, 0xc7, 0xa5, 0x69, 0x12, 0xc7, 0x5a, 0xa0, 0x82, 0x8b, 0xca, 0xad, 0x93, 0xb4, 0x46, 0x8a, 0x02, 0x51, 0x64, 0xa5, 0x71, 0x6c, 0xcb,
0x3b, 0x82, 0xf2, 0xe7, 0x74, 0xb1, 0x37, 0xe9, 0x29, 0xe7, 0x3b, 0xf7, 0x76, 0x63, 0xc9, 0xbc, 0xc2, 0x4a, 0x46, 0x9b, 0x5e, 0x08, 0x5a, 0x5a, 0x3b, 0x84, 0x25, 0x52, 0xd9, 0x5d, 0x0b, 0x50,
0x02, 0x3f, 0x80, 0xbf, 0xbc, 0x01, 0x8f, 0xc0, 0xbb, 0xf0, 0x07, 0x9e, 0x04, 0xed, 0xec, 0xdd, 0x5f, 0xa1, 0x87, 0xf6, 0xdc, 0x37, 0xe8, 0xfb, 0xf4, 0xd8, 0x4b, 0xfb, 0x1c, 0x3d, 0x14, 0x3b,
0xf9, 0x6c, 0xb7, 0x25, 0x45, 0xf9, 0xb7, 0x33, 0x3b, 0x33, 0x37, 0xf3, 0xcd, 0xcc, 0xb7, 0x36, 0x4b, 0x52, 0x94, 0x14, 0xa7, 0x4e, 0xe1, 0xdb, 0xcc, 0xec, 0xcc, 0x70, 0xe6, 0xb7, 0xbf, 0x99,
0xac, 0x8b, 0x68, 0x12, 0x8d, 0x3c, 0xe1, 0x35, 0x27, 0x71, 0x24, 0x22, 0x62, 0xa4, 0xb2, 0x03, 0x95, 0xa0, 0x22, 0xc3, 0x49, 0x38, 0xf4, 0xa4, 0xd7, 0x98, 0xf0, 0x50, 0x86, 0xc4, 0x8c, 0xf5,
0xc2, 0x1f, 0x33, 0xa5, 0xad, 0xef, 0x82, 0x71, 0xc8, 0x66, 0xd4, 0x0b, 0x2f, 0x18, 0xd9, 0x84, 0xaa, 0x35, 0x95, 0xd2, 0x1f, 0x33, 0x6d, 0xaf, 0xed, 0x82, 0x79, 0xc8, 0x66, 0xd4, 0x0b, 0x2e,
0x12, 0x17, 0x5e, 0x2c, 0x6c, 0x6d, 0x4b, 0x6b, 0x98, 0x54, 0x09, 0xc4, 0x82, 0x22, 0x0b, 0x47, 0x18, 0xd9, 0x80, 0xbc, 0x90, 0x1e, 0x97, 0x8e, 0xb1, 0x65, 0xd4, 0x2d, 0xaa, 0x15, 0x62, 0x43,
0x76, 0x01, 0x75, 0xf2, 0x58, 0x7f, 0x00, 0xd5, 0x81, 0x77, 0x16, 0x30, 0xd1, 0x0a, 0x7c, 0x8f, 0x96, 0x05, 0x43, 0x27, 0x83, 0x36, 0x25, 0xd6, 0x1e, 0x41, 0xa9, 0xef, 0x9d, 0x8d, 0x98, 0x6c,
0x13, 0x02, 0xfa, 0x90, 0x05, 0x01, 0x7a, 0x55, 0x28, 0x9e, 0xa5, 0xd3, 0x95, 0xaf, 0x9c, 0x6a, 0x8e, 0x7c, 0x4f, 0x10, 0x02, 0xb9, 0x01, 0x1b, 0x8d, 0x30, 0xaa, 0x48, 0x51, 0x56, 0x41, 0x57,
0x54, 0x1e, 0xeb, 0x7f, 0xea, 0x50, 0x56, 0x5e, 0xe4, 0x33, 0x28, 0x79, 0xd2, 0x13, 0x3d, 0xaa, 0xbe, 0x0e, 0x2a, 0x53, 0x25, 0xd6, 0xfe, 0xce, 0x41, 0x41, 0x47, 0x91, 0x4f, 0x21, 0xef, 0xa9,
0xbb, 0x77, 0x9a, 0x59, 0xa6, 0xb9, 0xb0, 0x54, 0xd9, 0x10, 0x07, 0x8c, 0x57, 0x11, 0x17, 0xa1, 0x48, 0x8c, 0x28, 0xed, 0xde, 0x6f, 0x24, 0xb5, 0xa6, 0xd2, 0x52, 0xed, 0x43, 0xaa, 0x60, 0xbe,
0x37, 0x66, 0x18, 0xae, 0x42, 0x33, 0x99, 0xec, 0x81, 0x31, 0x89, 0x62, 0xe1, 0x8e, 0xbd, 0x89, 0x09, 0x85, 0x0c, 0xbc, 0x31, 0xc3, 0x74, 0x45, 0x9a, 0xe8, 0x64, 0x0f, 0xcc, 0x49, 0xc8, 0xa5,
0xad, 0x6f, 0x15, 0x1b, 0xd5, 0xdd, 0x7b, 0xcb, 0xb1, 0x9a, 0xbd, 0x28, 0x16, 0xc7, 0xde, 0xa4, 0x3b, 0xf6, 0x26, 0x4e, 0x6e, 0x2b, 0x5b, 0x2f, 0xed, 0x3e, 0x58, 0xce, 0xd5, 0xe8, 0x86, 0x5c,
0x13, 0x8a, 0x78, 0x46, 0xd7, 0x26, 0x4a, 0x92, 0x51, 0x2f, 0xd9, 0x8c, 0x4f, 0xbc, 0x21, 0xb3, 0x1e, 0x7b, 0x93, 0x76, 0x20, 0xf9, 0x8c, 0xae, 0x4d, 0xb4, 0xa6, 0xb2, 0x5e, 0xb2, 0x99, 0x98,
0x4b, 0x2a, 0x6a, 0x2a, 0x23, 0x0c, 0xaf, 0xbc, 0x78, 0x64, 0x97, 0xf1, 0x42, 0x09, 0x64, 0x07, 0x78, 0x03, 0xe6, 0xe4, 0x75, 0xd6, 0x58, 0x47, 0x18, 0xde, 0x78, 0x7c, 0xe8, 0x14, 0xf0, 0x40,
0x2a, 0x97, 0x6c, 0xe6, 0xc6, 0x12, 0x29, 0x7b, 0x0d, 0x13, 0x27, 0xf3, 0x8f, 0xa5, 0x18, 0x62, 0x2b, 0x64, 0x07, 0x8a, 0x97, 0x6c, 0xe6, 0x72, 0x85, 0x94, 0xb3, 0x86, 0x85, 0x93, 0xf9, 0xc7,
0x18, 0x85, 0x66, 0x03, 0x74, 0x31, 0x9b, 0x30, 0xdb, 0xd8, 0xd2, 0x1a, 0xeb, 0xbb, 0x9b, 0xcb, 0x62, 0x0c, 0x31, 0x8d, 0x46, 0xb3, 0x0e, 0x39, 0x39, 0x9b, 0x30, 0xc7, 0xdc, 0x32, 0xea, 0x95,
0x89, 0x0d, 0x66, 0x13, 0x46, 0xd1, 0x82, 0x34, 0xc0, 0x1a, 0x9d, 0xb9, 0xb2, 0x22, 0x37, 0x9a, 0xdd, 0x8d, 0xe5, 0xc2, 0xfa, 0xb3, 0x09, 0xa3, 0xe8, 0x41, 0xea, 0x60, 0x0f, 0xcf, 0x5c, 0xd5,
0xb2, 0x38, 0xf6, 0x47, 0xcc, 0xae, 0xe0, 0xb7, 0xd7, 0x47, 0x67, 0x5d, 0x6f, 0xcc, 0x4e, 0x12, 0x91, 0x1b, 0x4e, 0x19, 0xe7, 0xfe, 0x90, 0x39, 0x45, 0xfc, 0x76, 0x65, 0x78, 0xd6, 0xf1, 0xc6,
0x2d, 0x69, 0x82, 0x2e, 0xbc, 0x0b, 0x6e, 0x03, 0x16, 0xeb, 0xac, 0x14, 0x3b, 0xf0, 0x2e, 0xb8, 0xec, 0x24, 0xb2, 0x92, 0x06, 0xe4, 0xa4, 0x77, 0x21, 0x1c, 0xc0, 0x66, 0xab, 0x2b, 0xcd, 0xf6,
0xaa, 0x14, 0xed, 0xc8, 0x7d, 0x58, 0x1f, 0xcf, 0xf8, 0xeb, 0xc0, 0xcd, 0x20, 0x34, 0x31, 0x6e, 0xbd, 0x0b, 0xa1, 0x3b, 0x45, 0x3f, 0xf2, 0x10, 0x2a, 0xe3, 0x99, 0x78, 0x3b, 0x72, 0x13, 0x08,
0x0d, 0xb5, 0xcf, 0x53, 0x1c, 0xef, 0x01, 0x28, 0x33, 0x09, 0x8f, 0x5d, 0xdb, 0xd2, 0x1a, 0x25, 0x2d, 0xcc, 0x5b, 0x46, 0xeb, 0xcb, 0x18, 0xc7, 0x07, 0x00, 0xda, 0x4d, 0xc1, 0xe3, 0x94, 0xb7,
0x5a, 0x41, 0x8d, 0x44, 0xcf, 0x79, 0x0c, 0x66, 0x1e, 0x45, 0xd9, 0xdc, 0x4b, 0x36, 0x4b, 0xfa, 0x8c, 0x7a, 0x9e, 0x16, 0xd1, 0xa2, 0xd0, 0x23, 0x4d, 0xd8, 0x1c, 0x7b, 0x42, 0x32, 0xee, 0x4a,
0x2d, 0x8f, 0x12, 0xb2, 0xa9, 0x17, 0x5c, 0xa9, 0x0e, 0x95, 0xa8, 0x12, 0x1e, 0x17, 0xf6, 0x34, 0xc6, 0xc7, 0x2e, 0xd2, 0xc2, 0x55, 0x1c, 0x72, 0x2a, 0x88, 0x83, 0xd5, 0x88, 0x28, 0xd5, 0xf7,
0xe7, 0x6b, 0xa8, 0x64, 0x49, 0xfd, 0x97, 0x63, 0x25, 0xe7, 0xf8, 0x42, 0x37, 0x8a, 0x96, 0xfe, 0xc7, 0x8c, 0xde, 0xd3, 0xbe, 0x7d, 0xc6, 0xc7, 0x3d, 0xe5, 0xa9, 0x8c, 0xd5, 0xa7, 0x60, 0xa5,
0x42, 0x37, 0xaa, 0x96, 0x59, 0xff, 0xad, 0x0c, 0xa5, 0x3e, 0x76, 0x61, 0x0f, 0xcc, 0xb1, 0xc7, 0x2f, 0x42, 0xf1, 0xe3, 0x92, 0xcd, 0x22, 0xca, 0x28, 0x51, 0xa1, 0x3e, 0xf5, 0x46, 0x57, 0xfa,
0x05, 0x8b, 0xdd, 0x6b, 0x4c, 0x50, 0x55, 0x99, 0xaa, 0x29, 0x5d, 0xe8, 0x5f, 0xe1, 0x1a, 0xfd, 0x92, 0xf3, 0x54, 0x2b, 0x4f, 0x33, 0x7b, 0x46, 0xf5, 0x2b, 0x28, 0x26, 0x7d, 0xfd, 0x5b, 0x60,
0xfb, 0x16, 0x4c, 0xce, 0xe2, 0x29, 0x1b, 0xb9, 0xb2, 0x49, 0xdc, 0x2e, 0x2e, 0x63, 0x8e, 0x19, 0x31, 0x15, 0xf8, 0x2a, 0x67, 0x66, 0xed, 0xdc, 0xab, 0x9c, 0x59, 0xb2, 0xad, 0xda, 0xef, 0x05,
0x35, 0xfb, 0x68, 0x83, 0xdd, 0xac, 0xf2, 0xec, 0xcc, 0xc9, 0x13, 0xa8, 0xf1, 0xe8, 0x2a, 0x1e, 0xc8, 0xf7, 0xf0, 0x22, 0xf7, 0xc0, 0x8a, 0xba, 0xb9, 0x01, 0x09, 0x4b, 0xda, 0x55, 0x13, 0xfd,
0x32, 0x17, 0xe7, 0x87, 0x27, 0x03, 0xfa, 0xe1, 0x8a, 0x3f, 0x1a, 0xe1, 0x99, 0x9a, 0x7c, 0x2e, 0x7a, 0x1c, 0xcc, 0x1b, 0xe2, 0xb0, 0xc8, 0xa2, 0xcc, 0x0d, 0x58, 0xf4, 0x0d, 0x58, 0x82, 0xf1,
0x70, 0xf2, 0x0c, 0x36, 0x04, 0x56, 0xe3, 0x0e, 0xa3, 0x50, 0xc4, 0x51, 0xc0, 0xed, 0xf2, 0xf2, 0x29, 0x1b, 0xba, 0x8a, 0x2a, 0xc2, 0xc9, 0x2e, 0xdf, 0x3c, 0x36, 0xd5, 0xe8, 0xa1, 0x0f, 0x72,
0x90, 0xab, 0x18, 0xaa, 0xe8, 0xb6, 0xb2, 0xa2, 0xeb, 0x22, 0x2f, 0x72, 0xb2, 0x0d, 0xb7, 0x7d, 0xaa, 0x24, 0x12, 0x59, 0x90, 0x67, 0x50, 0x16, 0xe1, 0x15, 0x1f, 0x30, 0x17, 0x59, 0x2c, 0xa2,
0xee, 0x26, 0xb0, 0xc9, 0x14, 0xfd, 0xf0, 0x02, 0x27, 0xd8, 0xa0, 0x1b, 0x3e, 0x3f, 0x46, 0x7d, 0x31, 0xf9, 0xdf, 0x4a, 0x3c, 0x3a, 0xa1, 0x4c, 0x2d, 0x31, 0x57, 0x04, 0x79, 0x01, 0xeb, 0x12,
0x5f, 0xa9, 0x9d, 0x97, 0x00, 0xf3, 0x82, 0xc8, 0x23, 0xa8, 0x26, 0x19, 0xe0, 0x24, 0x6b, 0xef, 0x01, 0x71, 0x07, 0x61, 0x20, 0x79, 0x38, 0x12, 0x4e, 0x61, 0x79, 0xd4, 0x74, 0x0e, 0x8d, 0x5b,
0x98, 0x64, 0x10, 0xd9, 0x59, 0x36, 0x55, 0x92, 0x00, 0xb7, 0x0b, 0x5b, 0x45, 0xd9, 0x54, 0x14, 0x4b, 0x7b, 0xd1, 0x8a, 0x4c, 0xab, 0x82, 0x6c, 0xc3, 0x5d, 0x5f, 0xb8, 0x11, 0x7e, 0xaa, 0x44,
0x9c, 0xdf, 0x35, 0xa8, 0xe6, 0x8a, 0x4d, 0x29, 0x42, 0xcb, 0x28, 0x62, 0x61, 0x29, 0x0b, 0x6f, 0x3f, 0xb8, 0xc0, 0x39, 0x32, 0xe9, 0xba, 0x2f, 0x8e, 0xd1, 0xde, 0xd3, 0xe6, 0xea, 0x6b, 0x80,
0x5b, 0xca, 0xe2, 0x5b, 0x97, 0x52, 0xbf, 0x46, 0x53, 0xef, 0x42, 0x19, 0x13, 0xe5, 0x76, 0x09, 0x79, 0x43, 0xe4, 0x09, 0x94, 0xa2, 0x0a, 0x70, 0x9e, 0x8c, 0xf7, 0xcc, 0x13, 0xc8, 0x44, 0x56,
0x73, 0x4b, 0x24, 0xe7, 0x0f, 0x0d, 0x6a, 0x0b, 0x28, 0xde, 0x68, 0xed, 0xe4, 0x73, 0x20, 0x67, 0xbc, 0x50, 0xab, 0x48, 0x38, 0x99, 0xad, 0xac, 0xe2, 0x05, 0x2a, 0xd5, 0x5f, 0x0d, 0x28, 0xa5,
0x81, 0x37, 0xbc, 0x0c, 0x7c, 0x2e, 0xe4, 0x40, 0xa9, 0x14, 0x74, 0x34, 0xb9, 0x9d, 0xbb, 0xc1, 0x9a, 0x8d, 0x17, 0x95, 0x91, 0x2c, 0xaa, 0x85, 0xd5, 0x90, 0xb9, 0x6e, 0x35, 0x64, 0xaf, 0x5d,
0xa0, 0x5c, 0x66, 0x79, 0x1e, 0x47, 0x3f, 0xb1, 0x10, 0xb9, 0xc9, 0xa0, 0x89, 0x94, 0xed, 0x44, 0x0d, 0xb9, 0x1b, 0x5c, 0xea, 0x26, 0x14, 0xb0, 0x50, 0xe1, 0xe4, 0xb1, 0xb6, 0x48, 0xab, 0xfe,
0xc9, 0x2a, 0xd7, 0xff, 0x2a, 0x22, 0x73, 0x2b, 0x74, 0xbe, 0x80, 0x4d, 0x04, 0xc4, 0x0f, 0x2f, 0x66, 0x40, 0x79, 0x01, 0xc5, 0x5b, 0xed, 0x9d, 0x7c, 0x06, 0xe4, 0x6c, 0xe4, 0x0d, 0x2e, 0x47,
0xdc, 0x61, 0x14, 0x5c, 0x8d, 0x43, 0xa4, 0x93, 0x64, 0xd3, 0x48, 0x7a, 0xd7, 0xc6, 0x2b, 0xc9, 0xbe, 0x90, 0x8a, 0x50, 0xba, 0x84, 0x1c, 0xba, 0xdc, 0x4d, 0x9d, 0x60, 0x52, 0xa1, 0xaa, 0x3c,
0x28, 0xe4, 0xc5, 0xaa, 0x07, 0xd6, 0x59, 0xc0, 0x3a, 0xed, 0x05, 0x10, 0xf1, 0x1b, 0x07, 0x6a, 0xe7, 0xe1, 0x8f, 0x2c, 0xc0, 0x0d, 0x69, 0xd2, 0x48, 0x4b, 0xc6, 0x2a, 0x6f, 0x17, 0x6a, 0x7f,
0xc6, 0x97, 0x62, 0x61, 0xcd, 0x4f, 0xb2, 0x4d, 0x39, 0x8f, 0xa3, 0x31, 0x5f, 0xa5, 0xe2, 0x34, 0x64, 0xf1, 0xfd, 0xd0, 0xe8, 0x7c, 0x0e, 0x1b, 0x08, 0x88, 0x1f, 0x5c, 0xb8, 0x83, 0x70, 0x74,
0x46, 0xb2, 0x2c, 0xcf, 0xe2, 0x68, 0x9c, 0x2e, 0x8b, 0x3c, 0x73, 0xf2, 0x0d, 0xd4, 0xd2, 0x4e, 0x35, 0x0e, 0x70, 0xa9, 0x45, 0xc3, 0x4a, 0xe2, 0xb3, 0x16, 0x1e, 0xa9, 0xbd, 0x46, 0x5e, 0xad,
0xab, 0x34, 0x4a, 0x98, 0xc6, 0xdd, 0xd5, 0x10, 0x98, 0x84, 0x79, 0x99, 0x93, 0xc8, 0x27, 0x50, 0x46, 0x60, 0x9f, 0x19, 0xec, 0xd3, 0x59, 0x00, 0x11, 0xbf, 0x71, 0xa0, 0x39, 0xbe, 0x94, 0x0b,
0x3b, 0xf3, 0x38, 0x73, 0xb3, 0xd9, 0x51, 0xbc, 0x6d, 0x4a, 0x65, 0x86, 0xd0, 0x97, 0x50, 0xe3, 0x7b, 0x7e, 0x96, 0x4c, 0xca, 0x39, 0x0f, 0xc7, 0x62, 0xf5, 0x41, 0x88, 0x73, 0x44, 0xc3, 0xf2,
0xa1, 0x37, 0xe1, 0xaf, 0x22, 0xe1, 0xca, 0xe7, 0x2f, 0xa1, 0x70, 0xb3, 0x39, 0x15, 0xf8, 0x1a, 0x82, 0x87, 0xe3, 0x78, 0x58, 0x94, 0x2c, 0xc8, 0xd7, 0x50, 0x8e, 0x6f, 0x5a, 0x97, 0x91, 0xc7,
0x0e, 0xfc, 0x31, 0xa3, 0x66, 0x6a, 0x22, 0x25, 0xe7, 0x2a, 0xdd, 0x05, 0x99, 0xe3, 0xcd, 0xce, 0x32, 0x36, 0x57, 0x53, 0x60, 0x11, 0xd6, 0x65, 0x4a, 0x23, 0x1f, 0x43, 0xf9, 0xcc, 0x13, 0xcc,
0x43, 0x7e, 0xd2, 0x8b, 0x8b, 0x93, 0xae, 0x9a, 0x5c, 0xff, 0x59, 0x03, 0x4b, 0x91, 0x02, 0x9b, 0x4d, 0xb8, 0xa3, 0x5f, 0x0f, 0x4b, 0x19, 0x13, 0x84, 0xbe, 0x80, 0xb2, 0x08, 0xbc, 0x89, 0x78,
0x04, 0xfe, 0xd0, 0x13, 0x7e, 0x14, 0x92, 0x47, 0x50, 0x0a, 0xa3, 0x11, 0x93, 0xb4, 0x27, 0x11, 0x13, 0x46, 0x8b, 0x63, 0xed, 0x1d, 0x8b, 0xc3, 0x8a, 0x5d, 0x70, 0x73, 0x5e, 0xc5, 0xb3, 0xa0,
0xfe, 0x78, 0x89, 0x07, 0x72, 0xa6, 0xcd, 0x6e, 0x34, 0x62, 0x54, 0x59, 0x3b, 0x4f, 0x40, 0x97, 0x6a, 0xbc, 0x5d, 0x3e, 0xa4, 0x99, 0x9e, 0x5d, 0x64, 0xba, 0xbe, 0xe4, 0xda, 0x4f, 0x06, 0xd8,
0xa2, 0x24, 0xcf, 0xa4, 0x84, 0xeb, 0x90, 0xa7, 0x98, 0x0b, 0xf5, 0x53, 0x58, 0x4f, 0xbe, 0x70, 0x7a, 0x29, 0xb0, 0xc9, 0xc8, 0x1f, 0x78, 0xd2, 0x0f, 0x03, 0xf2, 0x04, 0xf2, 0x41, 0x38, 0x64,
0xce, 0x62, 0x16, 0x0e, 0x99, 0x7c, 0xf4, 0x73, 0x13, 0x86, 0xe7, 0xf7, 0xa6, 0xd8, 0xfa, 0x2f, 0x6a, 0x73, 0x2a, 0x84, 0x3f, 0x5a, 0xda, 0x03, 0x29, 0xd7, 0x46, 0x27, 0x1c, 0x32, 0xaa, 0xbd,
0x1a, 0x10, 0x8c, 0xbb, 0xb8, 0x7a, 0x37, 0x11, 0x9b, 0x3c, 0x84, 0xbb, 0xaf, 0xaf, 0x58, 0x3c, 0xab, 0xcf, 0x20, 0xa7, 0x54, 0xb5, 0x7f, 0xa3, 0x16, 0x6e, 0xb2, 0x7f, 0xe5, 0x5c, 0xa9, 0x9d,
0x53, 0x8c, 0x37, 0x64, 0xee, 0xc8, 0xe7, 0xf2, 0x2b, 0x8a, 0x41, 0x0c, 0xba, 0x89, 0xb7, 0x7d, 0x42, 0x25, 0xfa, 0xc2, 0x39, 0xe3, 0x2c, 0x18, 0x30, 0xf5, 0xd3, 0x23, 0xc5, 0x30, 0x94, 0x3f,
0x75, 0xb9, 0x9f, 0xdc, 0xd5, 0xff, 0xd1, 0xa1, 0xda, 0x8f, 0xa7, 0xd9, 0xd8, 0x7c, 0x07, 0x30, 0x78, 0xc5, 0xd6, 0x7e, 0x36, 0x80, 0x60, 0xde, 0xc5, 0xd1, 0xbb, 0x8d, 0xdc, 0xe4, 0x31, 0x6c,
0xf1, 0x62, 0xe1, 0x4b, 0x4c, 0x53, 0xd8, 0x3f, 0xcd, 0xc1, 0x3e, 0x37, 0xcd, 0x26, 0xb4, 0x97, 0xbe, 0xbd, 0x62, 0x7c, 0xa6, 0x37, 0xde, 0x80, 0xb9, 0x43, 0x5f, 0xa8, 0xaf, 0xe8, 0x0d, 0x62,
0xda, 0xd3, 0x9c, 0xeb, 0x5b, 0x37, 0xb4, 0xf0, 0xde, 0x1b, 0x5a, 0xfc, 0x1f, 0x1b, 0xda, 0x82, 0xd2, 0x0d, 0x3c, 0xed, 0xe9, 0xc3, 0xfd, 0xe8, 0xac, 0xf6, 0x57, 0x0e, 0x4a, 0x3d, 0x3e, 0x4d,
0x6a, 0x6e, 0x43, 0x93, 0x05, 0xdd, 0x7a, 0x73, 0x1d, 0xb9, 0x1d, 0x85, 0xf9, 0x8e, 0x3a, 0x7f, 0x68, 0xf3, 0x2d, 0xc0, 0xc4, 0xe3, 0xd2, 0x57, 0x98, 0xc6, 0xb0, 0x7f, 0x92, 0x82, 0x7d, 0xee,
0x6b, 0x70, 0x7b, 0xa5, 0x44, 0xb9, 0x15, 0xb9, 0x47, 0xf2, 0xdd, 0x5b, 0x31, 0x7f, 0x1d, 0x49, 0x9a, 0x30, 0xb4, 0x1b, 0xfb, 0xd3, 0x54, 0xe8, 0xb5, 0x13, 0x9a, 0xf9, 0xe0, 0x09, 0xcd, 0xfe,
0x1b, 0x2c, 0xcc, 0xd2, 0x8d, 0xd3, 0x81, 0x52, 0x0b, 0x52, 0xcd, 0xd7, 0xb5, 0x38, 0x71, 0x74, 0x87, 0x09, 0x6d, 0x42, 0x29, 0x35, 0xa1, 0xd1, 0x80, 0x6e, 0xbd, 0xbb, 0x8f, 0xd4, 0x8c, 0xc2,
0x83, 0x2f, 0xc8, 0x9c, 0xf4, 0xe0, 0x8e, 0x0a, 0xb2, 0xfc, 0x4a, 0xaa, 0x97, 0xfa, 0xa3, 0xa5, 0x7c, 0x46, 0xab, 0x7f, 0x1a, 0x70, 0x77, 0xa5, 0x45, 0x35, 0x15, 0xa9, 0x47, 0xf2, 0xfd, 0x53,
0x48, 0x8b, 0x8f, 0xe4, 0x07, 0x7c, 0x45, 0xc7, 0x1d, 0xf7, 0x26, 0x36, 0xfe, 0x1d, 0xaf, 0x58, 0x31, 0x7f, 0x1d, 0x49, 0x0b, 0x6c, 0xac, 0xd2, 0xe5, 0x31, 0xa1, 0xf4, 0x80, 0x94, 0xd2, 0x7d,
0x42, 0xdd, 0x87, 0x60, 0xb4, 0x59, 0x10, 0x1c, 0x84, 0xe7, 0x91, 0xfc, 0x85, 0x86, 0xb8, 0xc4, 0x2d, 0x32, 0x8e, 0xae, 0x8b, 0x05, 0x5d, 0x90, 0x2e, 0xdc, 0xd7, 0x49, 0x96, 0x5f, 0x49, 0xfd,
0xae, 0x37, 0x1a, 0xc5, 0x8c, 0xf3, 0x64, 0xea, 0x6b, 0x4a, 0xdb, 0x52, 0x4a, 0xb9, 0x12, 0x71, 0x52, 0xff, 0x7f, 0x29, 0xd3, 0xe2, 0x23, 0x79, 0x4f, 0xac, 0xd8, 0x44, 0xd5, 0xbd, 0x8d, 0x89,
0x14, 0x89, 0x24, 0x20, 0x9e, 0x13, 0xa2, 0xa8, 0x03, 0xc8, 0x60, 0x5c, 0xfd, 0xca, 0x79, 0x23, 0x7f, 0xcf, 0x2b, 0x16, 0xad, 0xee, 0x43, 0x30, 0x5b, 0x6c, 0x34, 0x3a, 0x08, 0xce, 0x43, 0xf5,
0xdd, 0x6c, 0x37, 0xc0, 0xcc, 0xf3, 0x27, 0x01, 0x28, 0x77, 0x4f, 0xe8, 0x71, 0xeb, 0xc8, 0xba, 0x3b, 0x11, 0x71, 0xe1, 0xae, 0x37, 0x1c, 0x72, 0x26, 0x44, 0xc4, 0xfa, 0xb2, 0xb6, 0x36, 0xb5,
0x45, 0x4c, 0x30, 0xfa, 0xdd, 0x56, 0xaf, 0xff, 0xfc, 0x64, 0x60, 0x69, 0xdb, 0xbb, 0xb0, 0xbe, 0x51, 0x8d, 0x04, 0x0f, 0x43, 0x19, 0x25, 0x44, 0x39, 0x5a, 0x14, 0x35, 0x00, 0x95, 0x4c, 0xe8,
0x38, 0x4e, 0xa4, 0x02, 0xa5, 0xd3, 0x6e, 0xbf, 0x33, 0xb0, 0x6e, 0x49, 0xb7, 0xd3, 0x83, 0xee, 0x1f, 0x4a, 0xef, 0x5c, 0x37, 0xdb, 0x75, 0xb0, 0xd2, 0xfb, 0x93, 0x00, 0x14, 0x3a, 0x27, 0xf4,
0xe0, 0xab, 0x87, 0x96, 0x26, 0xd5, 0x4f, 0x5f, 0x0e, 0x3a, 0x7d, 0xab, 0xb0, 0xfd, 0xab, 0x06, 0xb8, 0x79, 0x64, 0xdf, 0x21, 0x16, 0x98, 0xbd, 0x4e, 0xb3, 0xdb, 0x7b, 0x79, 0xd2, 0xb7, 0x8d,
0x30, 0xc7, 0x82, 0x54, 0x61, 0xed, 0xb4, 0x7b, 0xd8, 0x3d, 0xf9, 0xbe, 0xab, 0x5c, 0x8e, 0x5b, 0xed, 0x5d, 0xa8, 0x2c, 0xd2, 0x89, 0x14, 0x21, 0x7f, 0xda, 0xe9, 0xb5, 0xfb, 0xf6, 0x1d, 0x15,
0xfd, 0x41, 0x87, 0x5a, 0x9a, 0xbc, 0xa0, 0x9d, 0xde, 0xd1, 0x41, 0xbb, 0x65, 0x15, 0xe4, 0x05, 0x76, 0x7a, 0xd0, 0xe9, 0x7f, 0xf9, 0xd8, 0x36, 0x94, 0xf9, 0xf9, 0xeb, 0x7e, 0xbb, 0x67, 0x67,
0xdd, 0x3f, 0xe9, 0x1e, 0xbd, 0xb4, 0x8a, 0x18, 0xab, 0x35, 0x68, 0x3f, 0x57, 0xc7, 0x7e, 0xaf, 0xb6, 0x7f, 0x31, 0x00, 0xe6, 0x58, 0x90, 0x12, 0xac, 0x9d, 0x76, 0x0e, 0x3b, 0x27, 0xdf, 0x75,
0x45, 0x3b, 0x96, 0x4e, 0x2c, 0x30, 0x3b, 0x3f, 0xf4, 0x3a, 0xf4, 0xe0, 0xb8, 0xd3, 0x1d, 0xb4, 0x74, 0xc8, 0x71, 0xb3, 0xd7, 0x6f, 0x53, 0xdb, 0x50, 0x07, 0xb4, 0xdd, 0x3d, 0x3a, 0x68, 0x35,
0x8e, 0xac, 0x92, 0xf4, 0x79, 0xda, 0x6a, 0x1f, 0x9e, 0xf6, 0xac, 0xb2, 0x0a, 0xd6, 0x1f, 0x9c, 0xed, 0x8c, 0x3a, 0xa0, 0xfb, 0x27, 0x9d, 0xa3, 0xd7, 0x76, 0x16, 0x73, 0x35, 0xfb, 0xad, 0x97,
0xd0, 0x8e, 0xb5, 0x26, 0x85, 0x7d, 0xda, 0x3a, 0xe8, 0x76, 0xf6, 0x2d, 0xc3, 0x29, 0x58, 0xda, 0x5a, 0xec, 0x75, 0x9b, 0xb4, 0x6d, 0xe7, 0x88, 0x0d, 0x56, 0xfb, 0xfb, 0x6e, 0x9b, 0x1e, 0x1c,
0xd3, 0x3d, 0xd8, 0xf0, 0xa3, 0xe6, 0xd4, 0x17, 0x8c, 0x73, 0xf5, 0x47, 0xe7, 0xc7, 0xfb, 0x89, 0xb7, 0x3b, 0xfd, 0xe6, 0x91, 0x9d, 0x57, 0x31, 0xcf, 0x9b, 0xad, 0xc3, 0xd3, 0xae, 0x5d, 0xd0,
0xe4, 0x47, 0x3b, 0xea, 0xb4, 0x73, 0x11, 0xed, 0x4c, 0xc5, 0x0e, 0xde, 0xee, 0xa4, 0x4d, 0x3d, 0xc9, 0x7a, 0xfd, 0x13, 0xda, 0xb6, 0xd7, 0x94, 0xb2, 0x4f, 0x9b, 0x07, 0x9d, 0xf6, 0xbe, 0x6d,
0x2b, 0xa3, 0xfc, 0xe0, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x5c, 0xc8, 0x21, 0x3e, 0x0d, 0x56, 0x33, 0xb6, 0xf1, 0x7c, 0x0f, 0xd6, 0xfd, 0xb0, 0x31, 0xf5, 0x25, 0x13, 0x42, 0xff, 0xdd,
0x00, 0x00, 0xfa, 0xe1, 0x61, 0xa4, 0xf9, 0xe1, 0x8e, 0x96, 0x76, 0x2e, 0xc2, 0x9d, 0xa9, 0xdc, 0xc1, 0xd3,
0x9d, 0xf8, 0x52, 0xcf, 0x0a, 0xa8, 0x3f, 0xfa, 0x27, 0x00, 0x00, 0xff, 0xff, 0x51, 0xac, 0x2b,
0xc1, 0xc6, 0x0d, 0x00, 0x00,
} }
...@@ -5,8 +5,9 @@ package vtgate ...@@ -5,8 +5,9 @@ package vtgate
import ( import (
fmt "fmt" fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math" math "math"
proto "github.com/golang/protobuf/proto"
binlogdata "vitess.io/vitess/go/vt/proto/binlogdata" binlogdata "vitess.io/vitess/go/vt/proto/binlogdata"
query "vitess.io/vitess/go/vt/proto/query" query "vitess.io/vitess/go/vt/proto/query"
topodata "vitess.io/vitess/go/vt/proto/topodata" topodata "vitess.io/vitess/go/vt/proto/topodata"
...@@ -134,10 +135,12 @@ type Session struct { ...@@ -134,10 +135,12 @@ type Session struct {
// pre_sessions contains sessions that have to be committed first. // pre_sessions contains sessions that have to be committed first.
PreSessions []*Session_ShardSession `protobuf:"bytes,9,rep,name=pre_sessions,json=preSessions,proto3" json:"pre_sessions,omitempty"` PreSessions []*Session_ShardSession `protobuf:"bytes,9,rep,name=pre_sessions,json=preSessions,proto3" json:"pre_sessions,omitempty"`
// post_sessions contains sessions that have to be committed last. // post_sessions contains sessions that have to be committed last.
PostSessions []*Session_ShardSession `protobuf:"bytes,10,rep,name=post_sessions,json=postSessions,proto3" json:"post_sessions,omitempty"` PostSessions []*Session_ShardSession `protobuf:"bytes,10,rep,name=post_sessions,json=postSessions,proto3" json:"post_sessions,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` // last_insert_id keeps track of the last seen insert_id for this session
XXX_unrecognized []byte `json:"-"` LastInsertId uint64 `protobuf:"varint,11,opt,name=last_insert_id,json=lastInsertId,proto3" json:"last_insert_id,omitempty"`
XXX_sizecache int32 `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *Session) Reset() { *m = Session{} } func (m *Session) Reset() { *m = Session{} }
...@@ -235,6 +238,13 @@ func (m *Session) GetPostSessions() []*Session_ShardSession { ...@@ -235,6 +238,13 @@ func (m *Session) GetPostSessions() []*Session_ShardSession {
return nil return nil
} }
func (m *Session) GetLastInsertId() uint64 {
if m != nil {
return m.LastInsertId
}
return 0
}
type Session_ShardSession struct { type Session_ShardSession struct {
Target *query.Target `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` Target *query.Target `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"`
TransactionId int64 `protobuf:"varint,2,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` TransactionId int64 `protobuf:"varint,2,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"`
...@@ -3685,133 +3695,135 @@ func init() { ...@@ -3685,133 +3695,135 @@ func init() {
func init() { proto.RegisterFile("vtgate.proto", fileDescriptor_aab96496ceaf1ebb) } func init() { proto.RegisterFile("vtgate.proto", fileDescriptor_aab96496ceaf1ebb) }
var fileDescriptor_aab96496ceaf1ebb = []byte{ var fileDescriptor_aab96496ceaf1ebb = []byte{
// 2041 bytes of a gzipped FileDescriptorProto // 2067 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0xcd, 0x8f, 0x23, 0x47, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0xcd, 0x8f, 0x23, 0x47,
0x15, 0x4f, 0x77, 0xfb, 0xf3, 0xf9, 0x73, 0x6b, 0xbc, 0x1b, 0xc7, 0x19, 0x76, 0x26, 0x1d, 0x46, 0x15, 0x4f, 0x77, 0xfb, 0xf3, 0xf9, 0x73, 0x6b, 0xbc, 0xbb, 0x8e, 0x33, 0xec, 0x38, 0x9d, 0x8c,
0xeb, 0x6c, 0x56, 0x1e, 0xe2, 0x40, 0x40, 0x28, 0x28, 0xcc, 0x78, 0x27, 0x2b, 0x2b, 0x3b, 0x1f, 0xd6, 0xd9, 0xac, 0x3c, 0xc4, 0x81, 0x80, 0x50, 0x50, 0x98, 0xf1, 0x4e, 0x56, 0x56, 0x76, 0x3e,
0x94, 0xbd, 0xb3, 0x80, 0x88, 0x5a, 0x3d, 0x76, 0xe1, 0x6d, 0xc6, 0xee, 0x76, 0xba, 0xca, 0x5e, 0x28, 0x7b, 0x67, 0x01, 0x11, 0xb5, 0x7a, 0xec, 0xc2, 0xdb, 0x8c, 0xdd, 0xed, 0x74, 0x95, 0xbd,
0x86, 0x03, 0xca, 0x7f, 0x10, 0x71, 0x40, 0x42, 0x11, 0x12, 0x42, 0x42, 0xe2, 0xc4, 0x15, 0x09, 0x0c, 0x07, 0x94, 0x0b, 0xe7, 0x88, 0x03, 0x12, 0x8a, 0x90, 0x10, 0x12, 0x12, 0x27, 0xae, 0x48,
0xb8, 0x70, 0x43, 0xe2, 0x82, 0x38, 0x71, 0x44, 0xe2, 0x1f, 0x40, 0xe2, 0x2f, 0x40, 0x5d, 0x55, 0xc0, 0x85, 0x1b, 0x12, 0x17, 0xc4, 0x89, 0x3b, 0xff, 0x00, 0x12, 0x7f, 0x41, 0xd4, 0x55, 0xd5,
0xfd, 0xe1, 0x9e, 0x2f, 0x8f, 0x67, 0x67, 0xe5, 0xbd, 0x58, 0x5d, 0xf5, 0x5e, 0x55, 0xbd, 0xf7, 0x1f, 0xf6, 0x7c, 0x79, 0x3c, 0x3b, 0x23, 0xef, 0xc5, 0xea, 0xaa, 0xf7, 0xea, 0xd5, 0xab, 0xdf,
0x7b, 0xbf, 0x7a, 0xf5, 0xba, 0xdc, 0x90, 0x9f, 0xb2, 0x81, 0xc9, 0x48, 0x63, 0xec, 0x3a, 0xcc, 0xfb, 0xd5, 0xab, 0xd7, 0xe5, 0x86, 0xec, 0x84, 0xf5, 0x4d, 0x46, 0xea, 0x23, 0xd7, 0x61, 0x0e,
0x41, 0x29, 0xd1, 0xaa, 0x95, 0x8f, 0x2c, 0x7b, 0xe8, 0x0c, 0xfa, 0x26, 0x33, 0x85, 0xa4, 0x96, 0x4a, 0x88, 0x56, 0xa5, 0x78, 0x68, 0xd9, 0x03, 0xa7, 0xdf, 0x33, 0x99, 0x29, 0x24, 0x95, 0xcc,
0xfb, 0x6c, 0x42, 0xdc, 0x13, 0xd9, 0x28, 0x32, 0x67, 0xec, 0x44, 0x85, 0x53, 0xe6, 0x8e, 0x7b, 0x67, 0x63, 0xe2, 0x1e, 0xcb, 0x46, 0x9e, 0x39, 0x23, 0x27, 0x2a, 0x9c, 0x30, 0x77, 0xd4, 0x15,
0xa2, 0xa1, 0xff, 0x3b, 0x01, 0xe9, 0x0e, 0xa1, 0xd4, 0x72, 0x6c, 0xb4, 0x01, 0x45, 0xcb, 0x36, 0x0d, 0xfd, 0x97, 0x71, 0x48, 0xb6, 0x09, 0xa5, 0x96, 0x63, 0xa3, 0x75, 0xc8, 0x5b, 0xb6, 0xc1,
0x98, 0x6b, 0xda, 0xd4, 0xec, 0x31, 0xcb, 0xb1, 0xab, 0xca, 0xba, 0x52, 0xcf, 0xe0, 0x82, 0x65, 0x5c, 0xd3, 0xa6, 0x66, 0x97, 0x59, 0x8e, 0x5d, 0x56, 0xaa, 0x4a, 0x2d, 0x85, 0x73, 0x96, 0xdd,
0x77, 0xc3, 0x4e, 0xd4, 0x82, 0x22, 0x7d, 0x66, 0xba, 0x7d, 0x83, 0x8a, 0x71, 0xb4, 0xaa, 0xae, 0x09, 0x3b, 0x51, 0x13, 0xf2, 0xf4, 0xb9, 0xe9, 0xf6, 0x0c, 0x2a, 0xc6, 0xd1, 0xb2, 0x5a, 0xd5,
0x6b, 0xf5, 0x5c, 0x73, 0xb5, 0x21, 0xad, 0x93, 0xf3, 0x35, 0x3a, 0x9e, 0x96, 0x6c, 0xe0, 0x02, 0x6a, 0x99, 0xc6, 0x6a, 0x5d, 0x7a, 0x27, 0xed, 0xd5, 0xdb, 0x9e, 0x96, 0x6c, 0xe0, 0x1c, 0x8d,
0x8d, 0xb4, 0x28, 0x7a, 0x13, 0xb2, 0xd4, 0xb2, 0x07, 0x43, 0x62, 0xf4, 0x8f, 0xaa, 0x1a, 0x5f, 0xb4, 0x28, 0x7a, 0x03, 0xd2, 0xd4, 0xb2, 0xfb, 0x03, 0x62, 0xf4, 0x0e, 0xcb, 0x1a, 0x9f, 0x26,
0x26, 0x23, 0x3a, 0x1e, 0x1e, 0xa1, 0xbb, 0x00, 0xe6, 0x84, 0x39, 0x3d, 0x67, 0x34, 0xb2, 0x58, 0x25, 0x3a, 0x1e, 0x1d, 0xa2, 0x7b, 0x00, 0xe6, 0x98, 0x39, 0x5d, 0x67, 0x38, 0xb4, 0x58, 0x39,
0x35, 0xc1, 0xa5, 0x91, 0x1e, 0xf4, 0x36, 0x14, 0x98, 0xe9, 0x0e, 0x08, 0x33, 0x28, 0x73, 0x2d, 0xc6, 0xa5, 0x91, 0x1e, 0xf4, 0x16, 0xe4, 0x98, 0xe9, 0xf6, 0x09, 0x33, 0x28, 0x73, 0x2d, 0xbb,
0x7b, 0x50, 0x4d, 0xae, 0x2b, 0xf5, 0x2c, 0xce, 0x8b, 0xce, 0x0e, 0xef, 0x43, 0x9b, 0x90, 0x76, 0x5f, 0x8e, 0x57, 0x95, 0x5a, 0x1a, 0x67, 0x45, 0x67, 0x9b, 0xf7, 0xa1, 0x0d, 0x48, 0x3a, 0x23,
0xc6, 0x8c, 0xdb, 0x97, 0x5a, 0x57, 0xea, 0xb9, 0xe6, 0xed, 0x86, 0x40, 0x65, 0xe7, 0xa7, 0xa4, 0xc6, 0xfd, 0x4b, 0x54, 0x95, 0x5a, 0xa6, 0x71, 0xbb, 0x2e, 0x50, 0xd9, 0xfe, 0x19, 0xe9, 0x8e,
0x37, 0x61, 0x64, 0x5f, 0x08, 0xb1, 0xaf, 0x85, 0xb6, 0xa1, 0x1c, 0xf1, 0xdd, 0x18, 0x39, 0x7d, 0x19, 0xd9, 0x13, 0x42, 0xec, 0x6b, 0xa1, 0x2d, 0x28, 0x46, 0xd6, 0x6e, 0x0c, 0x9d, 0x1e, 0x29,
0x52, 0x4d, 0xaf, 0x2b, 0xf5, 0x62, 0xf3, 0x75, 0xdf, 0xb3, 0x08, 0x0c, 0xbb, 0x4e, 0x9f, 0xe0, 0x27, 0xab, 0x4a, 0x2d, 0xdf, 0xb8, 0xeb, 0xaf, 0x2c, 0x02, 0xc3, 0x8e, 0xd3, 0x23, 0xb8, 0xc0,
0x12, 0x9b, 0xed, 0x40, 0x9b, 0x90, 0x79, 0x6e, 0xba, 0xb6, 0x65, 0x0f, 0x68, 0x35, 0xc3, 0x51, 0xa6, 0x3b, 0xd0, 0x06, 0xa4, 0x5e, 0x98, 0xae, 0x6d, 0xd9, 0x7d, 0x5a, 0x4e, 0x71, 0x54, 0x56,
0x59, 0x91, 0xab, 0x7e, 0xcf, 0xfb, 0x7d, 0x2a, 0x64, 0x38, 0x50, 0x42, 0x1f, 0x41, 0x7e, 0xec, 0xe4, 0xac, 0xdf, 0xf7, 0x7e, 0x9f, 0x09, 0x19, 0x0e, 0x94, 0xd0, 0x47, 0x90, 0x1d, 0xb9, 0x24,
0x92, 0x10, 0xca, 0xec, 0x1c, 0x50, 0xe6, 0xc6, 0x2e, 0x09, 0x80, 0xdc, 0x82, 0xc2, 0xd8, 0xa1, 0x84, 0x32, 0x3d, 0x07, 0x94, 0x99, 0x91, 0x4b, 0x02, 0x20, 0x37, 0x21, 0x37, 0x72, 0x28, 0x0b,
0x2c, 0x9c, 0x01, 0xe6, 0x98, 0x21, 0xef, 0x0d, 0xf1, 0xa7, 0xa8, 0xfd, 0x08, 0xf2, 0x51, 0x29, 0x2d, 0xc0, 0x1c, 0x16, 0xb2, 0xde, 0x90, 0xc0, 0xc4, 0xdb, 0x90, 0x1f, 0x98, 0x94, 0x19, 0x96,
0xda, 0x80, 0x94, 0x40, 0x92, 0xc7, 0x3f, 0xd7, 0x2c, 0x48, 0x17, 0xba, 0xbc, 0x13, 0x4b, 0xa1, 0x4d, 0x89, 0xcb, 0x0c, 0xab, 0x57, 0xce, 0x54, 0x95, 0x5a, 0x0c, 0x67, 0xbd, 0xde, 0x16, 0xef,
0x47, 0x97, 0x28, 0x5e, 0x56, 0xbf, 0xaa, 0xae, 0x2b, 0x75, 0x0d, 0x17, 0x22, 0xbd, 0xed, 0xbe, 0x6c, 0xf5, 0x2a, 0x3f, 0x86, 0x6c, 0xd4, 0x06, 0x5a, 0x87, 0x84, 0xc0, 0x9b, 0xb3, 0x24, 0xd3,
0xfe, 0x0f, 0x15, 0x8a, 0x12, 0x72, 0x4c, 0x3e, 0x9b, 0x10, 0xca, 0xd0, 0x03, 0xc8, 0xf6, 0xcc, 0xc8, 0xc9, 0x85, 0x76, 0x78, 0x27, 0x96, 0x42, 0x8f, 0x54, 0x51, 0x54, 0xad, 0x5e, 0x59, 0xad,
0xe1, 0x90, 0xb8, 0xde, 0x20, 0xb1, 0x46, 0xa9, 0x21, 0x58, 0xd9, 0xe2, 0xfd, 0xed, 0x87, 0x38, 0x2a, 0x35, 0x0d, 0xe7, 0x22, 0xbd, 0xad, 0x9e, 0xfe, 0x2f, 0x15, 0xf2, 0x32, 0x30, 0x98, 0x7c,
0x23, 0x34, 0xda, 0x7d, 0xf4, 0x0e, 0xa4, 0xa5, 0x73, 0x7c, 0x01, 0xa1, 0x1b, 0xf5, 0x0d, 0xfb, 0x36, 0x26, 0x94, 0xa1, 0x87, 0x90, 0xee, 0x9a, 0x83, 0x01, 0x71, 0xbd, 0x41, 0x62, 0x8e, 0x42,
0x72, 0x74, 0x0f, 0x92, 0xdc, 0x54, 0xce, 0xa8, 0x5c, 0xf3, 0x96, 0x34, 0x7c, 0xdb, 0x99, 0xd8, 0x5d, 0x70, 0xb7, 0xc9, 0xfb, 0x5b, 0x8f, 0x70, 0x4a, 0x68, 0xb4, 0x7a, 0xe8, 0x1d, 0x48, 0x4a,
0x7d, 0x1e, 0x00, 0x2c, 0xe4, 0xe8, 0x1b, 0x90, 0x63, 0xe6, 0xd1, 0x90, 0x30, 0x83, 0x9d, 0x8c, 0x08, 0xf8, 0x04, 0x42, 0x37, 0x8a, 0x00, 0xf6, 0xe5, 0xe8, 0x3e, 0xc4, 0xb9, 0xab, 0x9c, 0x77,
0x09, 0xa7, 0x58, 0xb1, 0x59, 0x69, 0x04, 0x3b, 0xa5, 0xcb, 0x85, 0xdd, 0x93, 0x31, 0xc1, 0xc0, 0x99, 0xc6, 0x2d, 0xe9, 0xf8, 0x96, 0x33, 0xb6, 0x7b, 0x3c, 0x4c, 0x58, 0xc8, 0xd1, 0x37, 0x21,
0x82, 0x67, 0xf4, 0x00, 0x90, 0xed, 0x30, 0x23, 0xb6, 0x4b, 0x92, 0x9c, 0xa0, 0x65, 0xdb, 0x61, 0xc3, 0xcc, 0xc3, 0x01, 0x61, 0x06, 0x3b, 0x1e, 0x11, 0x4e, 0xc4, 0x7c, 0xa3, 0x54, 0x0f, 0xf6,
0xed, 0x99, 0x8d, 0xb2, 0x01, 0xc5, 0x63, 0x72, 0x42, 0xc7, 0x66, 0x8f, 0x18, 0x9c, 0xfd, 0x9c, 0x53, 0x87, 0x0b, 0x3b, 0xc7, 0x23, 0x82, 0x81, 0x05, 0xcf, 0xe8, 0x21, 0x20, 0xdb, 0xf1, 0xe0,
0x88, 0x59, 0x5c, 0xf0, 0x7b, 0x39, 0xea, 0x51, 0xa2, 0xa6, 0xe7, 0x21, 0xaa, 0xfe, 0x85, 0x02, 0x9c, 0xda, 0x4b, 0x71, 0x4e, 0xe3, 0xa2, 0xed, 0xb0, 0xd6, 0xd4, 0x76, 0x5a, 0x87, 0xfc, 0x11,
0xa5, 0x00, 0x51, 0x3a, 0x76, 0x6c, 0x4a, 0xd0, 0x06, 0x24, 0x89, 0xeb, 0x3a, 0x6e, 0x0c, 0x4e, 0x39, 0xa6, 0x23, 0xb3, 0x4b, 0x0c, 0xbe, 0x47, 0x38, 0x5d, 0xd3, 0x38, 0xe7, 0xf7, 0x72, 0xd4,
0x7c, 0xd0, 0xda, 0xf1, 0xba, 0xb1, 0x90, 0x5e, 0x05, 0xcb, 0xfb, 0x90, 0x72, 0x09, 0x9d, 0x0c, 0xa3, 0x74, 0x4e, 0xce, 0x43, 0x67, 0xfd, 0x0b, 0x05, 0x0a, 0x01, 0xa2, 0x74, 0xe4, 0xd8, 0x94,
0x99, 0x04, 0x13, 0x45, 0x89, 0x8c, 0xb9, 0x04, 0x4b, 0x0d, 0xfd, 0x3f, 0x2a, 0x54, 0xa4, 0x45, 0xa0, 0x75, 0x88, 0x13, 0xd7, 0x75, 0xdc, 0x19, 0x38, 0xf1, 0x7e, 0x73, 0xdb, 0xeb, 0xc6, 0x42,
0xdc, 0x27, 0xba, 0x3c, 0x91, 0xae, 0x41, 0xc6, 0x87, 0x9b, 0x87, 0x39, 0x8b, 0x83, 0x36, 0xba, 0x7a, 0x19, 0x2c, 0x1f, 0x40, 0xc2, 0x25, 0x74, 0x3c, 0x60, 0x12, 0x4c, 0x14, 0xa5, 0x3b, 0xe6,
0x03, 0x29, 0x1e, 0x17, 0x5a, 0x4d, 0xae, 0x6b, 0xf5, 0x2c, 0x96, 0xad, 0x38, 0x3b, 0x52, 0xd7, 0x12, 0x2c, 0x35, 0xf4, 0xff, 0xaa, 0x50, 0x92, 0x1e, 0xf1, 0x35, 0xd1, 0xe5, 0x89, 0x74, 0x05,
0x62, 0x47, 0xfa, 0x1c, 0x76, 0x44, 0xc2, 0x9e, 0x99, 0x2b, 0xec, 0xbf, 0x54, 0xe0, 0x76, 0x0c, 0x52, 0x3e, 0xdc, 0x3c, 0xcc, 0x69, 0x1c, 0xb4, 0xd1, 0x1d, 0x48, 0xf0, 0xb8, 0xd0, 0x72, 0xbc,
0xe4, 0xa5, 0x08, 0xfe, 0xff, 0x54, 0x78, 0x43, 0xda, 0xf5, 0x89, 0x44, 0xb6, 0xfd, 0xaa, 0x30, 0xaa, 0xd5, 0xd2, 0x58, 0xb6, 0x66, 0xd9, 0x91, 0xb8, 0x12, 0x3b, 0x92, 0x67, 0xb0, 0x23, 0x12,
0xe0, 0x2d, 0xc8, 0x07, 0x5b, 0xd4, 0x92, 0x3c, 0xc8, 0xe3, 0xdc, 0x71, 0xe8, 0xc7, 0x92, 0x92, 0xf6, 0xd4, 0x5c, 0x61, 0xff, 0xb5, 0x02, 0xb7, 0x67, 0x40, 0x5e, 0x8a, 0xe0, 0xff, 0x5f, 0x85,
0xe1, 0x4b, 0x05, 0x6a, 0x67, 0x81, 0xbe, 0x14, 0x8c, 0xf8, 0x5c, 0x83, 0xd7, 0x43, 0xe3, 0xb0, 0xd7, 0xa5, 0x5f, 0x9f, 0x48, 0x64, 0x5b, 0xaf, 0x0a, 0x03, 0xde, 0x84, 0x6c, 0xb0, 0x45, 0x2d,
0x69, 0x0f, 0xc8, 0x2b, 0xc2, 0x87, 0xf7, 0x00, 0x8e, 0xc9, 0x89, 0xe1, 0x72, 0x93, 0x39, 0x1b, 0xc9, 0x83, 0x2c, 0xce, 0x1c, 0x85, 0xeb, 0x58, 0x52, 0x32, 0x7c, 0xa9, 0x40, 0xe5, 0x34, 0xd0,
0x3c, 0x4f, 0x83, 0x58, 0xfb, 0xde, 0xe0, 0xec, 0xb1, 0xef, 0xd7, 0x92, 0xf2, 0xe3, 0x57, 0x0a, 0x97, 0x82, 0x11, 0x9f, 0x6b, 0x70, 0x37, 0x74, 0x0e, 0x9b, 0x76, 0x9f, 0xbc, 0x22, 0x7c, 0x78,
0x54, 0x4f, 0x87, 0x60, 0x29, 0xd8, 0xf1, 0xa7, 0x44, 0xc0, 0x8e, 0x1d, 0x9b, 0x59, 0xec, 0xe4, 0x0f, 0xe0, 0x88, 0x1c, 0x1b, 0x2e, 0x77, 0x99, 0xb3, 0xc1, 0x5b, 0x69, 0x10, 0x6b, 0x7f, 0x35,
0x95, 0xc9, 0x16, 0x0f, 0x00, 0x11, 0x6e, 0xb1, 0xd1, 0x73, 0x86, 0x93, 0x91, 0x6d, 0xd8, 0xe6, 0x38, 0x7d, 0xe4, 0xaf, 0x6b, 0x49, 0xf9, 0xf1, 0x1b, 0x05, 0xca, 0x27, 0x43, 0xb0, 0x14, 0xec,
0x88, 0xc8, 0xe2, 0xb3, 0x2c, 0x24, 0x2d, 0x2e, 0xd8, 0x33, 0x47, 0x04, 0x7d, 0x1f, 0x56, 0xa4, 0xf8, 0x4b, 0x2c, 0x60, 0xc7, 0xb6, 0xcd, 0x2c, 0x76, 0xfc, 0xca, 0x64, 0x8b, 0x87, 0x80, 0x08,
0xf6, 0x4c, 0x8a, 0x49, 0x71, 0x52, 0xd5, 0x7d, 0x4b, 0xcf, 0x41, 0xa2, 0xe1, 0x77, 0xe0, 0x5b, 0xf7, 0xd8, 0xe8, 0x3a, 0x83, 0xf1, 0xd0, 0x36, 0x6c, 0x73, 0x48, 0x64, 0x89, 0x5a, 0x14, 0x92,
0x62, 0x92, 0x4f, 0xce, 0x4f, 0x49, 0xe9, 0x6b, 0x51, 0x2e, 0x73, 0x39, 0xe5, 0xb2, 0xf3, 0x50, 0x26, 0x17, 0xec, 0x9a, 0x43, 0x82, 0x7e, 0x00, 0x2b, 0x52, 0x7b, 0x2a, 0xc5, 0x24, 0x38, 0xa9,
0xae, 0x76, 0x04, 0x19, 0xdf, 0x68, 0xb4, 0x06, 0x09, 0x6e, 0x9a, 0xc2, 0x4d, 0xcb, 0xf9, 0x05, 0x6a, 0xbe, 0xa7, 0x67, 0x20, 0x51, 0xf7, 0x3b, 0xf0, 0x2d, 0x61, 0xe4, 0x93, 0xb3, 0x53, 0x52,
0xa4, 0x67, 0x11, 0x17, 0xa0, 0x0a, 0x24, 0xa7, 0xe6, 0x70, 0x42, 0x78, 0xe0, 0xf2, 0x58, 0x34, 0xf2, 0x4a, 0x94, 0x4b, 0x5d, 0x4c, 0xb9, 0xf4, 0x3c, 0x94, 0xab, 0x1c, 0x42, 0xca, 0x77, 0x1a,
0xd0, 0x1a, 0xe4, 0x22, 0x58, 0xf1, 0x58, 0xe5, 0x31, 0x84, 0xd9, 0x38, 0x4a, 0xeb, 0x08, 0x62, 0xad, 0x41, 0x8c, 0xbb, 0xa6, 0x70, 0xd7, 0x32, 0x7e, 0x01, 0xe9, 0x79, 0xc4, 0x05, 0xa8, 0x04,
0x4b, 0x41, 0xeb, 0x7f, 0xaa, 0xb0, 0x22, 0x4d, 0xdb, 0x36, 0x59, 0xef, 0xd9, 0x8d, 0x53, 0xfa, 0xf1, 0x89, 0x39, 0x18, 0x13, 0x1e, 0xb8, 0x2c, 0x16, 0x0d, 0xb4, 0x06, 0x99, 0x08, 0x56, 0x3c,
0x5d, 0x48, 0x7b, 0xd6, 0x58, 0x84, 0x56, 0x35, 0xce, 0xa9, 0x33, 0x48, 0xed, 0x6b, 0x2c, 0x5a, 0x56, 0x59, 0x0c, 0x61, 0x36, 0x8e, 0xd2, 0x3a, 0x82, 0xd8, 0x52, 0xd0, 0xfa, 0xdf, 0x2a, 0xac,
0xf0, 0x6e, 0x40, 0xd1, 0xa4, 0x67, 0x14, 0xbb, 0x05, 0x93, 0xbe, 0x8c, 0x4a, 0xf7, 0x4b, 0x25, 0x48, 0xd7, 0xb6, 0x4c, 0xd6, 0x7d, 0x7e, 0xed, 0x94, 0x7e, 0x17, 0x92, 0x9e, 0x37, 0x16, 0xa1,
0xa8, 0x2b, 0x25, 0xa6, 0x37, 0x16, 0xea, 0xaf, 0x41, 0x5a, 0x04, 0xd2, 0x47, 0xf3, 0x8e, 0xb4, 0x65, 0x8d, 0x73, 0xea, 0x14, 0x52, 0xfb, 0x1a, 0x8b, 0x16, 0xbc, 0xeb, 0x90, 0x37, 0xe9, 0x29,
0x4d, 0x84, 0xf9, 0xa9, 0xc5, 0x9e, 0x89, 0xa9, 0x7d, 0x35, 0xdd, 0x86, 0x12, 0x47, 0x9a, 0xfb, 0xc5, 0x6e, 0xce, 0xa4, 0x37, 0x51, 0xe9, 0x7e, 0xa9, 0x04, 0x75, 0xa5, 0xc4, 0xf4, 0xda, 0x42,
0xc6, 0xe1, 0x0e, 0xb3, 0x8c, 0x72, 0x85, 0x2c, 0xa3, 0x9e, 0x5b, 0x95, 0x6a, 0xd1, 0xaa, 0x54, 0xfd, 0x75, 0x48, 0x8a, 0x40, 0xfa, 0x68, 0xde, 0x91, 0xbe, 0x89, 0x30, 0x3f, 0xb3, 0xd8, 0x73,
0xff, 0x63, 0x58, 0x67, 0x71, 0x30, 0x5e, 0x52, 0xa5, 0xfd, 0x5e, 0x9c, 0x66, 0xc1, 0xdb, 0x70, 0x61, 0xda, 0x57, 0xd3, 0x6d, 0x28, 0x70, 0xa4, 0xf9, 0xda, 0x38, 0xdc, 0x61, 0x96, 0x51, 0x2e,
0xcc, 0xfb, 0x97, 0x45, 0xb6, 0xab, 0xbe, 0xd8, 0xeb, 0xbf, 0x0e, 0x6b, 0xa5, 0x19, 0xe0, 0x6e, 0x91, 0x65, 0xd4, 0x33, 0xab, 0x52, 0x2d, 0x5a, 0x95, 0xea, 0x7f, 0x0e, 0xeb, 0x2c, 0x0e, 0xc6,
0x8c, 0x4b, 0x0f, 0xe2, 0x5c, 0x3a, 0x2b, 0x6f, 0x04, 0x3c, 0xfa, 0x39, 0x54, 0x38, 0x92, 0x61, 0x0d, 0x55, 0xda, 0xef, 0xcd, 0xd2, 0x2c, 0x78, 0x67, 0x9e, 0x59, 0xfd, 0x4d, 0x91, 0xed, 0xb2,
0x86, 0x7f, 0x81, 0x64, 0x8a, 0x17, 0xb8, 0xda, 0xa9, 0x02, 0x57, 0xff, 0xab, 0x0a, 0x77, 0xa3, 0xaf, 0xff, 0xfa, 0x6f, 0xc3, 0x5a, 0x69, 0x0a, 0xb8, 0x6b, 0xe3, 0xd2, 0xc3, 0x59, 0x2e, 0x9d,
0xf0, 0xbc, 0xcc, 0x22, 0xfe, 0x83, 0x38, 0xb9, 0x56, 0x67, 0xc8, 0x15, 0x83, 0x64, 0x69, 0x19, 0x96, 0x37, 0x02, 0x1e, 0xfd, 0x02, 0x4a, 0x1c, 0xc9, 0x30, 0xc3, 0xbf, 0x44, 0x32, 0xcd, 0x16,
0xf6, 0x5b, 0x05, 0xd6, 0xce, 0x85, 0x70, 0x49, 0x68, 0xf6, 0x7b, 0x15, 0x2a, 0x1d, 0xe6, 0x12, 0xb8, 0xda, 0x89, 0x02, 0x57, 0xff, 0xbb, 0x0a, 0xf7, 0xa2, 0xf0, 0xdc, 0x64, 0x11, 0xff, 0xc1,
0x73, 0x74, 0xad, 0xdb, 0x98, 0x80, 0x95, 0xea, 0xd5, 0xae, 0x58, 0xb4, 0xf9, 0x43, 0x14, 0x3b, 0x2c, 0xb9, 0x56, 0xa7, 0xc8, 0x35, 0x03, 0xc9, 0xd2, 0x32, 0xec, 0xf7, 0x0a, 0xac, 0x9d, 0x09,
0x4a, 0x12, 0x97, 0x1c, 0x25, 0xc9, 0xb9, 0x6e, 0xf7, 0x22, 0xb8, 0xa6, 0x2e, 0xc6, 0x55, 0x6f, 0xe1, 0x92, 0xd0, 0xec, 0x8f, 0x2a, 0x94, 0xda, 0xcc, 0x25, 0xe6, 0xf0, 0x4a, 0xb7, 0x31, 0x01,
0xc1, 0xed, 0x18, 0x50, 0x32, 0x84, 0x61, 0x39, 0xa0, 0x5c, 0x5a, 0x0e, 0x7c, 0xa1, 0x42, 0x6d, 0x2b, 0xd5, 0xcb, 0x5d, 0xb1, 0x68, 0xf3, 0x87, 0x68, 0xe6, 0x28, 0x89, 0x5d, 0x70, 0x94, 0xc4,
0x66, 0x96, 0xeb, 0xa4, 0xeb, 0xb9, 0x41, 0x8f, 0xa6, 0x02, 0xed, 0xdc, 0x73, 0x25, 0x71, 0xd1, 0xe7, 0xba, 0x03, 0x8c, 0xe0, 0x9a, 0x38, 0x1f, 0x57, 0xbd, 0x09, 0xb7, 0x67, 0x80, 0x92, 0x21,
0x6d, 0x47, 0x72, 0xce, 0x40, 0x5d, 0x79, 0x93, 0xb4, 0xe1, 0xcd, 0x33, 0x01, 0x59, 0x00, 0xdc, 0x0c, 0xcb, 0x01, 0xe5, 0xc2, 0x72, 0xe0, 0x0b, 0x15, 0x2a, 0x53, 0x56, 0xae, 0x92, 0xae, 0xe7,
0xdf, 0xa8, 0xb0, 0x36, 0x33, 0xd7, 0xb5, 0x73, 0xd6, 0x0b, 0x41, 0x38, 0x9e, 0x6c, 0x13, 0x97, 0x06, 0x3d, 0x9a, 0x0a, 0xb4, 0x33, 0xcf, 0x95, 0xd8, 0x79, 0xb7, 0x1d, 0xf1, 0x39, 0x03, 0x75,
0xde, 0x26, 0xdc, 0x18, 0xd8, 0x7b, 0xb0, 0x7e, 0x3e, 0x40, 0x0b, 0x20, 0xfe, 0x07, 0x15, 0xbe, 0xe9, 0x4d, 0xd2, 0x82, 0x37, 0x4e, 0x05, 0x64, 0x01, 0x70, 0x7f, 0xa7, 0xc2, 0xda, 0x94, 0xad,
0x12, 0x9f, 0xf0, 0x3a, 0x2f, 0xf6, 0x2f, 0x04, 0xef, 0xd9, 0xb7, 0xf5, 0xc4, 0x02, 0x6f, 0xeb, 0x2b, 0xe7, 0xac, 0x97, 0x82, 0xf0, 0x6c, 0xb2, 0x8d, 0x5d, 0x78, 0x9b, 0x70, 0x6d, 0x60, 0xef,
0x37, 0x86, 0xff, 0x63, 0xb8, 0x7b, 0x1e, 0x5c, 0x0b, 0xa0, 0xff, 0x03, 0xc8, 0x6f, 0x93, 0x81, 0x42, 0xf5, 0x6c, 0x80, 0x16, 0x40, 0xfc, 0x4f, 0x2a, 0x7c, 0x6d, 0xd6, 0xe0, 0x55, 0x5e, 0xec,
0x65, 0x2f, 0x86, 0xf5, 0xcc, 0x7f, 0x2d, 0xea, 0xec, 0x7f, 0x2d, 0xfa, 0xb7, 0xa1, 0x20, 0xa7, 0x5f, 0x0a, 0xde, 0xd3, 0x6f, 0xeb, 0xb1, 0x05, 0xde, 0xd6, 0xaf, 0x0d, 0xff, 0x27, 0x70, 0xef,
0x96, 0x76, 0x45, 0x12, 0xa5, 0x72, 0x49, 0xa2, 0xfc, 0x5c, 0x81, 0x42, 0x8b, 0xff, 0x25, 0x73, 0x2c, 0xb8, 0x16, 0x40, 0xff, 0x87, 0x90, 0xdd, 0x22, 0x7d, 0xcb, 0x5e, 0x0c, 0xeb, 0xa9, 0x7f,
0xe3, 0x85, 0xc2, 0x1d, 0x48, 0x99, 0xcc, 0x19, 0x59, 0x3d, 0xf9, 0x67, 0x91, 0x6c, 0xe9, 0x65, 0x64, 0xd4, 0xe9, 0x7f, 0x64, 0xf4, 0xef, 0x40, 0x4e, 0x9a, 0x96, 0x7e, 0x45, 0x12, 0xa5, 0x72,
0x28, 0xfa, 0x16, 0x08, 0xfb, 0xf5, 0x9f, 0x40, 0x09, 0x3b, 0xc3, 0xe1, 0x91, 0xd9, 0x3b, 0xbe, 0x41, 0xa2, 0xfc, 0x5c, 0x81, 0x5c, 0x93, 0xff, 0x71, 0x73, 0xed, 0x85, 0xc2, 0x1d, 0x48, 0x98,
0x69, 0xab, 0x74, 0x04, 0xe5, 0x70, 0x2d, 0xb9, 0xfe, 0xa7, 0xf0, 0x06, 0x26, 0xd4, 0x19, 0x4e, 0xcc, 0x19, 0x5a, 0x5d, 0xf9, 0x97, 0x92, 0x6c, 0xe9, 0x45, 0xc8, 0xfb, 0x1e, 0x08, 0xff, 0xf5,
0x49, 0xa4, 0xa4, 0x58, 0xcc, 0x12, 0x04, 0x89, 0x3e, 0x93, 0xff, 0xab, 0x64, 0x31, 0x7f, 0xd6, 0x9f, 0x42, 0x01, 0x3b, 0x83, 0xc1, 0xa1, 0xd9, 0x3d, 0xba, 0x6e, 0xaf, 0x74, 0x04, 0xc5, 0x70,
0xff, 0xa2, 0x40, 0x65, 0x97, 0x50, 0x6a, 0x0e, 0x88, 0x20, 0xd8, 0x62, 0x53, 0x5f, 0x54, 0x33, 0x2e, 0x39, 0xff, 0xa7, 0xf0, 0x3a, 0x26, 0xd4, 0x19, 0x4c, 0x48, 0xa4, 0xa4, 0x58, 0xcc, 0x13,
0x56, 0x20, 0x29, 0x4e, 0x5e, 0xb1, 0xdf, 0x44, 0x03, 0x6d, 0x42, 0x36, 0xd8, 0x6c, 0xfc, 0x4c, 0x04, 0xb1, 0x1e, 0x93, 0xff, 0xab, 0xa4, 0x31, 0x7f, 0xd6, 0xff, 0xa6, 0x40, 0x69, 0x87, 0x50,
0x3e, 0x7b, 0xaf, 0x65, 0xfc, 0xbd, 0xe6, 0x59, 0x1f, 0xb9, 0x1f, 0xe1, 0xcf, 0xfa, 0x2f, 0x14, 0x6a, 0xf6, 0x89, 0x20, 0xd8, 0x62, 0xa6, 0xcf, 0xab, 0x19, 0x4b, 0x10, 0x17, 0x27, 0xaf, 0xd8,
0xb8, 0x25, 0xad, 0xdf, 0x5a, 0x34, 0x3e, 0x17, 0x99, 0xee, 0xaf, 0xa9, 0x85, 0x6b, 0xa2, 0xbb, 0x6f, 0xa2, 0x81, 0x36, 0x20, 0x1d, 0x6c, 0x36, 0x7e, 0x26, 0x9f, 0xbe, 0xd7, 0x52, 0xfe, 0x5e,
0xa0, 0xf9, 0xc9, 0x38, 0xd7, 0xcc, 0xcb, 0x5d, 0x76, 0x68, 0x0e, 0x27, 0x04, 0x7b, 0x02, 0x7d, 0xf3, 0xbc, 0x8f, 0xdc, 0x8f, 0xf0, 0x67, 0xfd, 0x57, 0x0a, 0xdc, 0x92, 0xde, 0x6f, 0x2e, 0x1a,
0x17, 0xf2, 0xed, 0x48, 0xa5, 0x89, 0x56, 0x41, 0x0d, 0xcc, 0x98, 0x55, 0x57, 0xad, 0x7e, 0xfc, 0x9f, 0xf3, 0x5c, 0xf7, 0xe7, 0xd4, 0xc2, 0x39, 0xd1, 0x3d, 0xd0, 0xfc, 0x64, 0x9c, 0x69, 0x64,
0x8a, 0x42, 0x3d, 0x75, 0x45, 0xf1, 0x67, 0x05, 0x56, 0x43, 0x17, 0xaf, 0x7d, 0x30, 0x5d, 0xd5, 0xe5, 0x2e, 0x3b, 0x30, 0x07, 0x63, 0x82, 0x3d, 0x81, 0xbe, 0x03, 0xd9, 0x56, 0xa4, 0xd2, 0x44,
0xdb, 0x0f, 0xa1, 0x64, 0xf5, 0x8d, 0x53, 0xc7, 0x50, 0xae, 0x59, 0xf1, 0x59, 0x1c, 0x75, 0x16, 0xab, 0xa0, 0x06, 0x6e, 0x4c, 0xab, 0xab, 0x56, 0x6f, 0xf6, 0x8a, 0x42, 0x3d, 0x71, 0x45, 0xf1,
0x17, 0xac, 0x48, 0x8b, 0xea, 0xab, 0x50, 0x3b, 0x8b, 0xbc, 0x92, 0xda, 0xff, 0x55, 0xe1, 0x56, 0x57, 0x05, 0x56, 0xc3, 0x25, 0x5e, 0xf9, 0x60, 0xba, 0xec, 0x6a, 0x3f, 0x84, 0x82, 0xd5, 0x33,
0x67, 0x3c, 0xb4, 0x98, 0xcc, 0x51, 0x2f, 0xda, 0x9f, 0xb9, 0x2f, 0xe9, 0xde, 0x82, 0x3c, 0xf5, 0x4e, 0x1c, 0x43, 0x99, 0x46, 0xc9, 0x67, 0x71, 0x74, 0xb1, 0x38, 0x67, 0x45, 0x5a, 0x54, 0x5f,
0xec, 0x90, 0xf7, 0x70, 0xb2, 0xa0, 0xc9, 0xf1, 0x3e, 0x71, 0x03, 0xe7, 0xc5, 0xc9, 0x57, 0x99, 0x85, 0xca, 0x69, 0xe4, 0x95, 0xd4, 0xfe, 0x9f, 0x0a, 0xb7, 0xda, 0xa3, 0x81, 0xc5, 0x64, 0x8e,
0xd8, 0x8c, 0x93, 0x50, 0xc3, 0x20, 0x35, 0x26, 0x36, 0x43, 0x5f, 0x87, 0xd7, 0xed, 0xc9, 0xc8, 0x7a, 0xd9, 0xeb, 0x99, 0xfb, 0x92, 0xee, 0x4d, 0xc8, 0x52, 0xcf, 0x0f, 0x79, 0x0f, 0x27, 0x0b,
0x70, 0x9d, 0xe7, 0xd4, 0x18, 0x13, 0xd7, 0xe0, 0x33, 0x1b, 0x63, 0xd3, 0x65, 0x3c, 0xc5, 0x6b, 0x9a, 0x0c, 0xef, 0x13, 0x37, 0x70, 0x5e, 0x9c, 0x7c, 0x95, 0xb1, 0xcd, 0x38, 0x09, 0x35, 0x0c,
0x78, 0xc5, 0x9e, 0x8c, 0xb0, 0xf3, 0x9c, 0x1e, 0x10, 0x97, 0x2f, 0x7e, 0x60, 0xba, 0x0c, 0x7d, 0x52, 0x63, 0x6c, 0x33, 0xf4, 0x0d, 0xb8, 0x6b, 0x8f, 0x87, 0x86, 0xeb, 0xbc, 0xa0, 0xc6, 0x88,
0x17, 0xb2, 0xe6, 0x70, 0xe0, 0xb8, 0x16, 0x7b, 0x36, 0x92, 0x17, 0x6f, 0xba, 0x34, 0xf3, 0x14, 0xb8, 0x06, 0xb7, 0x6c, 0x8c, 0x4c, 0x97, 0xf1, 0x14, 0xaf, 0xe1, 0x15, 0x7b, 0x3c, 0xc4, 0xce,
0x32, 0x8d, 0x2d, 0x5f, 0x13, 0x87, 0x83, 0xd0, 0xbb, 0x80, 0x26, 0x94, 0x18, 0xc2, 0x38, 0xb1, 0x0b, 0xba, 0x4f, 0x5c, 0x3e, 0xf9, 0xbe, 0xe9, 0x32, 0xf4, 0x3d, 0x48, 0x9b, 0x83, 0xbe, 0xe3,
0xe8, 0xb4, 0x29, 0x6f, 0xe1, 0x4a, 0x13, 0x4a, 0xc2, 0x69, 0x0e, 0x9b, 0xfa, 0xdf, 0x34, 0x40, 0x5a, 0xec, 0xf9, 0x50, 0x5e, 0xbc, 0xe9, 0xd2, 0xcd, 0x13, 0xc8, 0xd4, 0x37, 0x7d, 0x4d, 0x1c,
0xd1, 0x79, 0x65, 0x8e, 0xfe, 0x26, 0xa4, 0xf8, 0x78, 0x5a, 0x55, 0x78, 0x6c, 0xd7, 0x82, 0x0c, 0x0e, 0x42, 0xef, 0x02, 0x1a, 0x53, 0x62, 0x08, 0xe7, 0xc4, 0xa4, 0x93, 0x86, 0xbc, 0x85, 0x2b,
0x75, 0x4a, 0xb7, 0xe1, 0x99, 0x8d, 0xa5, 0x7a, 0xed, 0x53, 0xc8, 0xfb, 0x3b, 0x95, 0xbb, 0x13, 0x8c, 0x29, 0x09, 0xcd, 0x1c, 0x34, 0xf4, 0x7f, 0x68, 0x80, 0xa2, 0x76, 0x65, 0x8e, 0xfe, 0x16,
0x8d, 0x86, 0x72, 0xe1, 0xe9, 0xaa, 0xce, 0x71, 0xba, 0xd6, 0x3e, 0x82, 0x2c, 0xaf, 0xea, 0x2e, 0x24, 0xf8, 0x78, 0x5a, 0x56, 0x78, 0x6c, 0xd7, 0x82, 0x0c, 0x75, 0x42, 0xb7, 0xee, 0xb9, 0x8d,
0x9d, 0x3b, 0xac, 0x45, 0xd5, 0x68, 0x2d, 0x5a, 0xfb, 0x97, 0x02, 0x09, 0x3e, 0x78, 0xee, 0x97, 0xa5, 0x7a, 0xe5, 0x53, 0xc8, 0xfa, 0x3b, 0x95, 0x2f, 0x27, 0x1a, 0x0d, 0xe5, 0xdc, 0xd3, 0x55,
0xdf, 0x5d, 0xfe, 0xbe, 0x20, 0xac, 0x14, 0xd1, 0x13, 0x49, 0xfb, 0xde, 0x05, 0x90, 0x44, 0x21, 0x9d, 0xe3, 0x74, 0xad, 0x7c, 0x04, 0x69, 0x5e, 0xd5, 0x5d, 0x68, 0x3b, 0xac, 0x45, 0xd5, 0x68,
0xc0, 0xf9, 0xe3, 0x28, 0x20, 0x2d, 0x00, 0xf1, 0x71, 0x03, 0x9f, 0x4a, 0xf0, 0xf0, 0xab, 0x17, 0x2d, 0x5a, 0xf9, 0x8f, 0x02, 0x31, 0x3e, 0x78, 0xee, 0x97, 0xdf, 0x1d, 0xfe, 0xbe, 0x20, 0xbc,
0x4c, 0x15, 0xb8, 0x8b, 0xb3, 0x34, 0xf0, 0x1c, 0x41, 0x82, 0x5a, 0x3f, 0x13, 0x59, 0x52, 0xc3, 0x14, 0xd1, 0x13, 0x49, 0xfb, 0xfe, 0x39, 0x90, 0x44, 0x21, 0xc0, 0xd9, 0xa3, 0x28, 0x20, 0x4d,
0xfc, 0x59, 0x7f, 0x1f, 0x6e, 0x3f, 0x22, 0xac, 0xe3, 0x4e, 0xfd, 0xed, 0xe6, 0x6f, 0x9f, 0x0b, 0x00, 0xf1, 0x09, 0x04, 0x37, 0x25, 0x78, 0xf8, 0xf6, 0x39, 0xa6, 0x82, 0xe5, 0xe2, 0x34, 0x0d,
0x60, 0xd2, 0x31, 0xdc, 0x89, 0x0f, 0x92, 0x0c, 0xf8, 0x16, 0xe4, 0xa9, 0x3b, 0x35, 0x66, 0x46, 0x56, 0x8e, 0x20, 0x46, 0xad, 0x9f, 0x8b, 0x2c, 0xa9, 0x61, 0xfe, 0xac, 0xbf, 0x0f, 0xb7, 0x1f,
0x7a, 0x55, 0x49, 0x10, 0x9e, 0xe8, 0xa0, 0x1c, 0x0d, 0x1b, 0xfa, 0xdf, 0x15, 0x28, 0x1e, 0x5e, 0x13, 0xd6, 0x76, 0x27, 0xfe, 0x76, 0xf3, 0xb7, 0xcf, 0x39, 0x30, 0xe9, 0x18, 0xee, 0xcc, 0x0e,
0xe7, 0xe8, 0x88, 0x95, 0x50, 0xea, 0x9c, 0x25, 0xd4, 0x3d, 0x48, 0x4e, 0x07, 0x4c, 0xde, 0xea, 0x92, 0x0c, 0xf8, 0x36, 0x64, 0xa9, 0x3b, 0x31, 0xa6, 0x46, 0x7a, 0x55, 0x49, 0x10, 0x9e, 0xe8,
0x7a, 0x11, 0x8d, 0x7c, 0xb5, 0x72, 0xf8, 0x88, 0x59, 0x7d, 0x2c, 0xe4, 0x5e, 0x61, 0xf4, 0x63, 0xa0, 0x0c, 0x0d, 0x1b, 0xfa, 0x3f, 0x15, 0xc8, 0x1f, 0x5c, 0xe5, 0xe8, 0x98, 0x29, 0xa1, 0xd4,
0x6b, 0xc8, 0x88, 0x1b, 0x9c, 0x32, 0x11, 0xcd, 0x8f, 0xb9, 0x04, 0x4b, 0x0d, 0xfd, 0x3b, 0x50, 0x39, 0x4b, 0xa8, 0xfb, 0x10, 0x9f, 0xf4, 0x99, 0xbc, 0xd5, 0xf5, 0x22, 0x1a, 0xf9, 0xb6, 0xe5,
0x0a, 0x7c, 0x09, 0xeb, 0x2a, 0x32, 0x25, 0x76, 0xb0, 0x37, 0x66, 0x86, 0x1f, 0xee, 0x78, 0x22, 0xe0, 0x31, 0xb3, 0x7a, 0x58, 0xc8, 0xbd, 0xc2, 0xe8, 0x27, 0xd6, 0x80, 0x11, 0x37, 0x38, 0x65,
0x2c, 0x35, 0xf4, 0xdf, 0xa9, 0xb0, 0xf2, 0x64, 0xdc, 0x37, 0xd9, 0xb2, 0x9f, 0xa5, 0x0b, 0x96, 0x22, 0x9a, 0x1f, 0x73, 0x09, 0x96, 0x1a, 0xfa, 0x77, 0xa1, 0x10, 0xac, 0x25, 0xac, 0xab, 0xc8,
0xad, 0xab, 0x90, 0x65, 0xd6, 0x88, 0x50, 0x66, 0x8e, 0xc6, 0x32, 0xab, 0x85, 0x1d, 0x5e, 0x44, 0x84, 0xd8, 0xc1, 0xde, 0x98, 0x1a, 0x7e, 0xb0, 0xed, 0x89, 0xb0, 0xd4, 0xd0, 0xff, 0xa0, 0xc2,
0x38, 0x0e, 0xf2, 0x32, 0xd6, 0xdf, 0x63, 0x1c, 0xa2, 0xae, 0x73, 0x4c, 0x6c, 0x2c, 0xe4, 0xfa, 0xca, 0xd3, 0x51, 0xcf, 0x64, 0xcb, 0x7e, 0x96, 0x2e, 0x58, 0xb6, 0xae, 0x42, 0x9a, 0x59, 0x43,
0x31, 0x54, 0x66, 0x51, 0x92, 0x50, 0xd7, 0xfd, 0x09, 0x66, 0x2b, 0x58, 0x59, 0xf8, 0x72, 0xa4, 0x42, 0x99, 0x39, 0x1c, 0xc9, 0xac, 0x16, 0x76, 0x78, 0x11, 0xe1, 0x38, 0xc8, 0xcb, 0x58, 0x7f,
0x85, 0x02, 0x7a, 0x07, 0xca, 0x5e, 0x29, 0x3b, 0x22, 0x46, 0x68, 0x8f, 0xf8, 0x5a, 0xa4, 0x24, 0x8f, 0x71, 0x88, 0x3a, 0xce, 0x11, 0xb1, 0xb1, 0x90, 0xeb, 0x47, 0x50, 0x9a, 0x46, 0x49, 0x42,
0xfa, 0xbb, 0x7e, 0xf7, 0xfd, 0x87, 0x50, 0x8a, 0x7d, 0x66, 0x83, 0x4a, 0x90, 0x7b, 0xb2, 0xd7, 0x5d, 0xf3, 0x0d, 0x4c, 0x57, 0xb0, 0xb2, 0xf0, 0xe5, 0x48, 0x0b, 0x05, 0xf4, 0x0e, 0x14, 0xbd,
0x39, 0xd8, 0x69, 0xb5, 0x3f, 0x6e, 0xef, 0x3c, 0x2c, 0xbf, 0x86, 0x00, 0x52, 0x9d, 0xf6, 0xde, 0x52, 0x76, 0x48, 0x8c, 0xd0, 0x1f, 0xf1, 0xb5, 0x48, 0x41, 0xf4, 0x77, 0xfc, 0xee, 0x07, 0x8f,
0xa3, 0xc7, 0x3b, 0x65, 0x05, 0x65, 0x21, 0xb9, 0xfb, 0xe4, 0x71, 0xb7, 0x5d, 0x56, 0xbd, 0xc7, 0xa0, 0x30, 0xf3, 0x31, 0x0e, 0x2a, 0x40, 0xe6, 0xe9, 0x6e, 0x7b, 0x7f, 0xbb, 0xd9, 0xfa, 0xb8,
0xee, 0xd3, 0xfd, 0x83, 0x56, 0x59, 0xbb, 0xff, 0x21, 0xe4, 0x44, 0x5d, 0xb8, 0xef, 0xf6, 0x89, 0xb5, 0xfd, 0xa8, 0xf8, 0x1a, 0x02, 0x48, 0xb4, 0x5b, 0xbb, 0x8f, 0x9f, 0x6c, 0x17, 0x15, 0x94,
0xeb, 0x0d, 0xd8, 0xdb, 0xc7, 0xbb, 0x5b, 0x8f, 0xcb, 0xaf, 0xa1, 0x34, 0x68, 0x07, 0xd8, 0x1b, 0x86, 0xf8, 0xce, 0xd3, 0x27, 0x9d, 0x56, 0x51, 0xf5, 0x1e, 0x3b, 0xcf, 0xf6, 0xf6, 0x9b, 0x45,
0x99, 0x81, 0xc4, 0xc1, 0x7e, 0xa7, 0x5b, 0x56, 0x51, 0x11, 0x60, 0xeb, 0x49, 0x77, 0xbf, 0xb5, 0xed, 0xc1, 0x87, 0x90, 0x11, 0x75, 0xe1, 0x9e, 0xdb, 0x23, 0xae, 0x37, 0x60, 0x77, 0x0f, 0xef,
0xbf, 0xbb, 0xdb, 0xee, 0x96, 0xb5, 0xed, 0x0f, 0xa0, 0x64, 0x39, 0x8d, 0xa9, 0xc5, 0x08, 0xa5, 0x6c, 0x3e, 0x29, 0xbe, 0x86, 0x92, 0xa0, 0xed, 0x63, 0x6f, 0x64, 0x0a, 0x62, 0xfb, 0x7b, 0xed,
0xe2, 0x43, 0xa9, 0x1f, 0xbe, 0x2d, 0x5b, 0x96, 0xb3, 0x29, 0x9e, 0x36, 0x07, 0xce, 0xe6, 0x94, 0x4e, 0x51, 0x45, 0x79, 0x80, 0xcd, 0xa7, 0x9d, 0xbd, 0xe6, 0xde, 0xce, 0x4e, 0xab, 0x53, 0xd4,
0x6d, 0x72, 0xe9, 0xa6, 0x48, 0x10, 0x47, 0x29, 0xde, 0x7a, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xb6, 0x3e, 0x80, 0x82, 0xe5, 0xd4, 0x27, 0x16, 0x23, 0x94, 0x8a, 0xcf, 0xa9, 0x7e, 0xf4, 0x96,
0xff, 0x4b, 0xc0, 0xed, 0xac, 0xa8, 0x25, 0x00, 0x00, 0x6c, 0x59, 0xce, 0x86, 0x78, 0xda, 0xe8, 0x3b, 0x1b, 0x13, 0xb6, 0xc1, 0xa5, 0x1b, 0x22, 0x41,
0x1c, 0x26, 0x78, 0xeb, 0xfd, 0xaf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x03, 0xdd, 0xba, 0xce,
0x25, 0x00, 0x00,
} }
...@@ -5,8 +5,9 @@ package vtrpc ...@@ -5,8 +5,9 @@ package vtrpc
import ( import (
fmt "fmt" fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math" math "math"
proto "github.com/golang/protobuf/proto"
) )
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
......
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// source: time.proto // source: vttime.proto
package vttime package vttime
import ( import (
fmt "fmt" fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math" math "math"
proto "github.com/golang/protobuf/proto"
) )
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
...@@ -34,7 +35,7 @@ func (m *Time) Reset() { *m = Time{} } ...@@ -34,7 +35,7 @@ func (m *Time) Reset() { *m = Time{} }
func (m *Time) String() string { return proto.CompactTextString(m) } func (m *Time) String() string { return proto.CompactTextString(m) }
func (*Time) ProtoMessage() {} func (*Time) ProtoMessage() {}
func (*Time) Descriptor() ([]byte, []int) { func (*Time) Descriptor() ([]byte, []int) {
return fileDescriptor_49a92d779a28c7fd, []int{0} return fileDescriptor_bbeb0d3434911dee, []int{0}
} }
func (m *Time) XXX_Unmarshal(b []byte) error { func (m *Time) XXX_Unmarshal(b []byte) error {
...@@ -73,16 +74,16 @@ func init() { ...@@ -73,16 +74,16 @@ func init() {
proto.RegisterType((*Time)(nil), "vttime.Time") proto.RegisterType((*Time)(nil), "vttime.Time")
} }
func init() { proto.RegisterFile("time.proto", fileDescriptor_49a92d779a28c7fd) } func init() { proto.RegisterFile("vttime.proto", fileDescriptor_bbeb0d3434911dee) }
var fileDescriptor_49a92d779a28c7fd = []byte{ var fileDescriptor_bbeb0d3434911dee = []byte{
// 120 bytes of a gzipped FileDescriptorProto // 120 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xc9, 0xcc, 0x4d, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x2b, 0x29, 0xc9,
0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2b, 0x2b, 0x01, 0xf1, 0x94, 0x9c, 0xb8, 0x58, 0xcc, 0x4d, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0x94, 0x9c, 0xb8, 0x58,
0x42, 0x32, 0x73, 0x53, 0x85, 0x24, 0xb8, 0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x42, 0x32, 0x73, 0x53, 0x85, 0x24, 0xb8, 0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25,
0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60, 0x5c, 0x21, 0x05, 0x2e, 0xee, 0xbc, 0xc4, 0xbc, 0x7c, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60, 0x5c, 0x21, 0x05, 0x2e, 0xee, 0xbc, 0xc4, 0xbc, 0x7c,
0x98, 0x2c, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0xb2, 0x90, 0x93, 0x6a, 0x94, 0x72, 0x59, 0x66, 0x98, 0x2c, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0xb2, 0x90, 0x93, 0x6a, 0x94, 0x72, 0x59, 0x66,
0x49, 0x6a, 0x71, 0xb1, 0x5e, 0x66, 0xbe, 0x3e, 0x84, 0xa5, 0x9f, 0x9e, 0xaf, 0x5f, 0x56, 0xa2, 0x49, 0x6a, 0x71, 0xb1, 0x5e, 0x66, 0xbe, 0x3e, 0x84, 0xa5, 0x9f, 0x9e, 0xaf, 0x5f, 0x56, 0xa2,
0x0f, 0xb6, 0x4b, 0x1f, 0x62, 0x55, 0x12, 0x1b, 0x98, 0x67, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xb6, 0x4b, 0x1f, 0x62, 0x55, 0x12, 0x1b, 0x98, 0x67, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff,
0xb4, 0x42, 0xf5, 0xf7, 0x87, 0x00, 0x00, 0x00, 0x35, 0x46, 0xf4, 0x16, 0x89, 0x00, 0x00, 0x00,
} }
# Copyright 2017 Google Inc. # Copyright 2019 The Vitess Authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -175,6 +175,31 @@ func SplitAndExpression(filters []Expr, node Expr) []Expr { ...@@ -175,6 +175,31 @@ func SplitAndExpression(filters []Expr, node Expr) []Expr {
return append(filters, node) return append(filters, node)
} }
// TableFromStatement returns the qualified table name for the query.
// This works only for select statements.
func TableFromStatement(sql string) (TableName, error) {
stmt, err := Parse(sql)
if err != nil {
return TableName{}, err
}
sel, ok := stmt.(*Select)
if !ok {
return TableName{}, fmt.Errorf("unrecognized statement: %s", sql)
}
if len(sel.From) != 1 {
return TableName{}, fmt.Errorf("table expression is complex")
}
aliased, ok := sel.From[0].(*AliasedTableExpr)
if !ok {
return TableName{}, fmt.Errorf("table expression is complex")
}
tableName, ok := aliased.Expr.(TableName)
if !ok {
return TableName{}, fmt.Errorf("table expression is complex")
}
return tableName, nil
}
// GetTableName returns the table name from the SimpleTableExpr // GetTableName returns the table name from the SimpleTableExpr
// only if it's a simple expression. Otherwise, it returns "". // only if it's a simple expression. Otherwise, it returns "".
func GetTableName(node SimpleTableExpr) TableIdent { func GetTableName(node SimpleTableExpr) TableIdent {
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -123,7 +123,9 @@ func SplitMarginComments(sql string) (query string, comments MarginComments) { ...@@ -123,7 +123,9 @@ func SplitMarginComments(sql string) (query string, comments MarginComments) {
Leading: strings.TrimLeftFunc(sql[:leadingEnd], unicode.IsSpace), Leading: strings.TrimLeftFunc(sql[:leadingEnd], unicode.IsSpace),
Trailing: strings.TrimRightFunc(sql[trailingStart:], unicode.IsSpace), Trailing: strings.TrimRightFunc(sql[trailingStart:], unicode.IsSpace),
} }
return strings.TrimFunc(sql[leadingEnd:trailingStart], unicode.IsSpace), comments return strings.TrimFunc(sql[leadingEnd:trailingStart], func(c rune) bool {
return unicode.IsSpace(c) || c == ';'
}), comments
} }
// StripLeadingComments trims the SQL string and removes any leading comments // StripLeadingComments trims the SQL string and removes any leading comments
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -7,7 +7,7 @@ You may obtain a copy of the License at ...@@ -7,7 +7,7 @@ You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreedto in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -173,7 +173,7 @@ func skipToEnd(yylex interface{}) { ...@@ -173,7 +173,7 @@ func skipToEnd(yylex interface{}) {
%token <bytes> BIT TINYINT SMALLINT MEDIUMINT INT INTEGER BIGINT INTNUM %token <bytes> BIT TINYINT SMALLINT MEDIUMINT INT INTEGER BIGINT INTNUM
%token <bytes> REAL DOUBLE FLOAT_TYPE DECIMAL NUMERIC %token <bytes> REAL DOUBLE FLOAT_TYPE DECIMAL NUMERIC
%token <bytes> TIME TIMESTAMP DATETIME YEAR %token <bytes> TIME TIMESTAMP DATETIME YEAR
%token <bytes> CHAR VARCHAR BOOL CHARACTER VARBINARY NCHAR %token <bytes> CHAR VARCHAR BOOL CHARACTER VARBINARY NCHAR
%token <bytes> TEXT TINYTEXT MEDIUMTEXT LONGTEXT %token <bytes> TEXT TINYTEXT MEDIUMTEXT LONGTEXT
%token <bytes> BLOB TINYBLOB MEDIUMBLOB LONGBLOB JSON ENUM %token <bytes> BLOB TINYBLOB MEDIUMBLOB LONGBLOB JSON ENUM
%token <bytes> GEOMETRY POINT LINESTRING POLYGON GEOMETRYCOLLECTION MULTIPOINT MULTILINESTRING MULTIPOLYGON %token <bytes> GEOMETRY POINT LINESTRING POLYGON GEOMETRYCOLLECTION MULTIPOINT MULTILINESTRING MULTIPOLYGON
...@@ -201,7 +201,13 @@ func skipToEnd(yylex interface{}) { ...@@ -201,7 +201,13 @@ func skipToEnd(yylex interface{}) {
%token <bytes> MATCH AGAINST BOOLEAN LANGUAGE WITH QUERY EXPANSION %token <bytes> MATCH AGAINST BOOLEAN LANGUAGE WITH QUERY EXPANSION
// MySQL reserved words that are unused by this grammar will map to this token. // MySQL reserved words that are unused by this grammar will map to this token.
%token <bytes> UNUSED %token <bytes> UNUSED ARRAY CUME_DIST DESCRIPTION DENSE_RANK EMPTY EXCEPT FIRST_VALUE GROUPING GROUPS JSON_TABLE LAG LAST_VALUE LATERAL LEAD MEMBER
%token <bytes> NTH_VALUE NTILE OF OVER PERCENT_RANK RANK RECURSIVE ROW_NUMBER SYSTEM WINDOW
%token <bytes> ACTIVE ADMIN BUCKETS CLONE COMPONENT DEFINITION ENFORCED EXCLUDE FOLLOWING GEOMCOLLECTION GET_MASTER_PUBLIC_KEY HISTOGRAM HISTORY
%token <bytes> INACTIVE INVISIBLE LOCKED MASTER_COMPRESSION_ALGORITHMS MASTER_PUBLIC_KEY_PATH MASTER_TLS_CIPHERSUITES MASTER_ZSTD_COMPRESSION_LEVEL
%token <bytes> NESTED NETWORK_NAMESPACE NOWAIT NULLS OJ OLD OPTIONAL ORDINALITY ORGANIZATION OTHERS PATH PERSIST PERSIST_ONLY PRECEDING PRIVILEGE_CHECKS_USER PROCESS
%token <bytes> RANDOM REFERENCE REQUIRE_ROW_FORMAT RESOURCE RESPECT RESTART RETAIN REUSE ROLE SECONDARY SECONDARY_ENGINE SECONDARY_LOAD SECONDARY_UNLOAD SKIP SRID
%token <bytes> THREAD_PRIORITY TIES UNBOUNDED VCPU VISIBLE
%type <statement> command %type <statement> command
%type <selStmt> select_statement base_select union_lhs union_rhs %type <selStmt> select_statement base_select union_lhs union_rhs
...@@ -3210,6 +3216,7 @@ reserved_table_id: ...@@ -3210,6 +3216,7 @@ reserved_table_id:
*/ */
reserved_keyword: reserved_keyword:
ADD ADD
| ARRAY
| AND | AND
| AS | AS
| ASC | ASC
...@@ -3222,6 +3229,7 @@ reserved_keyword: ...@@ -3222,6 +3229,7 @@ reserved_keyword:
| CONVERT | CONVERT
| CREATE | CREATE
| CROSS | CROSS
| CUME_DIST
| CURRENT_DATE | CURRENT_DATE
| CURRENT_TIME | CURRENT_TIME
| CURRENT_TIMESTAMP | CURRENT_TIMESTAMP
...@@ -3231,6 +3239,7 @@ reserved_keyword: ...@@ -3231,6 +3239,7 @@ reserved_keyword:
| DATABASES | DATABASES
| DEFAULT | DEFAULT
| DELETE | DELETE
| DENSE_RANK
| DESC | DESC
| DESCRIBE | DESCRIBE
| DISTINCT | DISTINCT
...@@ -3242,10 +3251,13 @@ reserved_keyword: ...@@ -3242,10 +3251,13 @@ reserved_keyword:
| EXISTS | EXISTS
| EXPLAIN | EXPLAIN
| FALSE | FALSE
| FIRST_VALUE
| FOR | FOR
| FORCE | FORCE
| FROM | FROM
| GROUP | GROUP
| GROUPING
| GROUPS
| HAVING | HAVING
| IF | IF
| IGNORE | IGNORE
...@@ -3257,35 +3269,50 @@ reserved_keyword: ...@@ -3257,35 +3269,50 @@ reserved_keyword:
| INTO | INTO
| IS | IS
| JOIN | JOIN
| JSON_TABLE
| KEY | KEY
| LAG
| LAST_VALUE
| LATERAL
| LEAD
| LEFT | LEFT
| LIKE | LIKE
| LIMIT | LIMIT
| LOCALTIME | LOCALTIME
| LOCALTIMESTAMP | LOCALTIMESTAMP
| LOCK | LOCK
| MEMBER
| MATCH | MATCH
| MAXVALUE | MAXVALUE
| MOD | MOD
| NATURAL | NATURAL
| NEXT // next should be doable as non-reserved, but is not due to the special `select next num_val` query that vitess supports | NEXT // next should be doable as non-reserved, but is not due to the special `select next num_val` query that vitess supports
| NOT | NOT
| NTH_VALUE
| NTILE
| NULL | NULL
| OF
| OFF | OFF
| ON | ON
| OR | OR
| ORDER | ORDER
| OUTER | OUTER
| OVER
| PERCENT_RANK
| RANK
| RECURSIVE
| REGEXP | REGEXP
| RENAME | RENAME
| REPLACE | REPLACE
| RIGHT | RIGHT
| ROW_NUMBER
| SCHEMA | SCHEMA
| SELECT | SELECT
| SEPARATOR | SEPARATOR
| SET | SET
| SHOW | SHOW
| STRAIGHT_JOIN | STRAIGHT_JOIN
| SYSTEM
| TABLE | TABLE
| THEN | THEN
| TIMESTAMPADD | TIMESTAMPADD
...@@ -3304,6 +3331,7 @@ reserved_keyword: ...@@ -3304,6 +3331,7 @@ reserved_keyword:
| VALUES | VALUES
| WHEN | WHEN
| WHERE | WHERE
| WINDOW
/* /*
These are non-reserved Vitess, because they don't cause conflicts in the grammar. These are non-reserved Vitess, because they don't cause conflicts in the grammar.
...@@ -3315,40 +3343,56 @@ reserved_keyword: ...@@ -3315,40 +3343,56 @@ reserved_keyword:
non_reserved_keyword: non_reserved_keyword:
AGAINST AGAINST
| ACTION | ACTION
| ACTIVE
| ADMIN
| BEGIN | BEGIN
| BIGINT | BIGINT
| BIT | BIT
| BLOB | BLOB
| BOOL | BOOL
| BOOLEAN | BOOLEAN
| BUCKETS
| CASCADE | CASCADE
| CHAR | CHAR
| CHARACTER | CHARACTER
| CHARSET | CHARSET
| CHECK | CHECK
| CLONE
| COLLATION | COLLATION
| COLUMNS | COLUMNS
| COMMENT_KEYWORD | COMMENT_KEYWORD
| COMMIT | COMMIT
| COMMITTED | COMMITTED
| COMPONENT
| DATE | DATE
| DATETIME | DATETIME
| DECIMAL | DECIMAL
| DEFINITION
| DESCRIPTION
| DOUBLE | DOUBLE
| DUPLICATE | DUPLICATE
| ENFORCED
| ENGINES | ENGINES
| ENUM | ENUM
| EXCLUDE
| EXPANSION | EXPANSION
| FLOAT_TYPE | FLOAT_TYPE
| FIELDS | FIELDS
| FLUSH | FLUSH
| FOLLOWING
| FOREIGN | FOREIGN
| FULLTEXT | FULLTEXT
| GEOMCOLLECTION
| GEOMETRY | GEOMETRY
| GEOMETRYCOLLECTION | GEOMETRYCOLLECTION
| GET_MASTER_PUBLIC_KEY
| GLOBAL | GLOBAL
| HISTOGRAM
| HISTORY
| INACTIVE
| INT | INT
| INTEGER | INTEGER
| INVISIBLE
| ISOLATION | ISOLATION
| JSON | JSON
| KEY_BLOCK_SIZE | KEY_BLOCK_SIZE
...@@ -3358,8 +3402,13 @@ non_reserved_keyword: ...@@ -3358,8 +3402,13 @@ non_reserved_keyword:
| LESS | LESS
| LEVEL | LEVEL
| LINESTRING | LINESTRING
| LOCKED
| LONGBLOB | LONGBLOB
| LONGTEXT | LONGTEXT
| MASTER_COMPRESSION_ALGORITHMS
| MASTER_PUBLIC_KEY_PATH
| MASTER_TLS_CIPHERSUITES
| MASTER_ZSTD_COMPRESSION_LEVEL
| MEDIUMBLOB | MEDIUMBLOB
| MEDIUMINT | MEDIUMINT
| MEDIUMTEXT | MEDIUMTEXT
...@@ -3369,38 +3418,71 @@ non_reserved_keyword: ...@@ -3369,38 +3418,71 @@ non_reserved_keyword:
| MULTIPOLYGON | MULTIPOLYGON
| NAMES | NAMES
| NCHAR | NCHAR
| NESTED
| NETWORK_NAMESPACE
| NOWAIT
| NO | NO
| NULLS
| NUMERIC | NUMERIC
| OFFSET | OFFSET
| OJ
| OLD
| OPTIONAL
| ORDINALITY
| ORGANIZATION
| ONLY | ONLY
| OPTIMIZE | OPTIMIZE
| OTHERS
| PARTITION | PARTITION
| PATH
| PERSIST
| PERSIST_ONLY
| PRECEDING
| PRIVILEGE_CHECKS_USER
| PROCESS
| PLUGINS | PLUGINS
| POINT | POINT
| POLYGON | POLYGON
| PRIMARY | PRIMARY
| PROCEDURE | PROCEDURE
| QUERY | QUERY
| RANDOM
| READ | READ
| REAL | REAL
| REFERENCE
| REFERENCES | REFERENCES
| REORGANIZE | REORGANIZE
| REPAIR | REPAIR
| REPEATABLE | REPEATABLE
| RESTRICT | RESTRICT
| REQUIRE_ROW_FORMAT
| RESOURCE
| RESPECT
| RESTART
| RETAIN
| REUSE
| ROLE
| ROLLBACK | ROLLBACK
| SECONDARY
| SECONDARY_ENGINE
| SECONDARY_LOAD
| SECONDARY_UNLOAD
| SEQUENCE | SEQUENCE
| SESSION | SESSION
| SERIALIZABLE | SERIALIZABLE
| SHARE | SHARE
| SIGNED | SIGNED
| SKIP
| SMALLINT | SMALLINT
| SPATIAL | SPATIAL
| SRID
| START | START
| STATUS | STATUS
| TABLES | TABLES
| TEXT | TEXT
| THAN | THAN
| THREAD_PRIORITY
| TIES
| TIME | TIME
| TIMESTAMP | TIMESTAMP
| TINYBLOB | TINYBLOB
...@@ -3409,15 +3491,18 @@ non_reserved_keyword: ...@@ -3409,15 +3491,18 @@ non_reserved_keyword:
| TRANSACTION | TRANSACTION
| TRIGGER | TRIGGER
| TRUNCATE | TRUNCATE
| UNBOUNDED
| UNCOMMITTED | UNCOMMITTED
| UNSIGNED | UNSIGNED
| UNUSED | UNUSED
| VARBINARY | VARBINARY
| VARCHAR | VARCHAR
| VARIABLES | VARIABLES
| VCPU
| VIEW | VIEW
| VINDEX | VINDEX
| VINDEXES | VINDEXES
| VISIBLE
| VITESS_METADATA | VITESS_METADATA
| VSCHEMA | VSCHEMA
| WARNINGS | WARNINGS
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
/* /*
Copyright 2017 Google Inc. Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册