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

daily update

上级 45a48465
...@@ -257,7 +257,7 @@ func parseDSN(odbc string, d *dsn) *dsn { ...@@ -257,7 +257,7 @@ func parseDSN(odbc string, d *dsn) *dsn {
if d != nil { if d != nil {
// 原来有个判断,后来判断条件被删除了就导致第一次addr无论如何都会被修改。所以这边先注释掉 // 原来有个判断,后来判断条件被删除了就导致第一次addr无论如何都会被修改。所以这边先注释掉
//addr = d.Addr // addr = d.Addr
user = d.User user = d.User
password = d.Password password = d.Password
schema = d.Schema schema = d.Schema
...@@ -273,27 +273,24 @@ func parseDSN(odbc string, d *dsn) *dsn { ...@@ -273,27 +273,24 @@ func parseDSN(odbc string, d *dsn) *dsn {
var userInfo, hostInfo, query string var userInfo, hostInfo, query string
// DSN 格式匹配 // DSN 格式匹配
// userInfo@hostInfo/database if res := regexp.MustCompile(`^(.*)@(.*?)/(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 5 {
if res := regexp.MustCompile( `^(.*)@(.*?)/(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 5 { // userInfo@hostInfo/database
userInfo = res[1] userInfo = res[1]
hostInfo = res[2] hostInfo = res[2]
schema = res[3] schema = res[3]
query = res[5] query = res[5]
// hostInfo/database
} else if res := regexp.MustCompile(`^(.*)/(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 4 { } else if res := regexp.MustCompile(`^(.*)/(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 4 {
// hostInfo/database
hostInfo = res[1] hostInfo = res[1]
schema = res[2] schema = res[2]
query = res[4] query = res[4]
// userInfo@hostInfo
} else if res := regexp.MustCompile(`^(.*)@(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 4 { } else if res := regexp.MustCompile(`^(.*)@(.*?)($|\?)(.*)`).FindStringSubmatch(odbc); len(res) > 4 {
// userInfo@hostInfo
userInfo = res[1] userInfo = res[1]
hostInfo = res[2] hostInfo = res[2]
query = res[4] query = res[4]
// hostInfo
} else { } else {
// hostInfo
hostInfo = odbc hostInfo = odbc
} }
...@@ -301,7 +298,7 @@ func parseDSN(odbc string, d *dsn) *dsn { ...@@ -301,7 +298,7 @@ func parseDSN(odbc string, d *dsn) *dsn {
if userInfo != "" { if userInfo != "" {
user = strings.Split(userInfo, ":")[0] user = strings.Split(userInfo, ":")[0]
// 防止密码中含有与用户名相同的字符, 所以用正则替换, 剩下的就是密码 // 防止密码中含有与用户名相同的字符, 所以用正则替换, 剩下的就是密码
password = strings.TrimLeft(regexp.MustCompile("^" + user).ReplaceAllString(userInfo, ""), ":") password = strings.TrimLeft(regexp.MustCompile("^"+user).ReplaceAllString(userInfo, ""), ":")
} }
// 解析主机信息 // 解析主机信息
...@@ -310,13 +307,13 @@ func parseDSN(odbc string, d *dsn) *dsn { ...@@ -310,13 +307,13 @@ func parseDSN(odbc string, d *dsn) *dsn {
if host == "" { if host == "" {
host = "127.0.0.1" host = "127.0.0.1"
} }
if port == ""{ if port == "" {
port = "3306" port = "3306"
} }
addr = host + ":" + port addr = host + ":" + port
// 解析查询字符串 // 解析查询字符串
if (query != "") { if query != "" {
params := strings.Split(query, "&") params := strings.Split(query, "&")
for _, f := range params { for _, f := range params {
attr := strings.Split(f, "=") attr := strings.Split(f, "=")
......
...@@ -17,7 +17,6 @@ package ast ...@@ -17,7 +17,6 @@ package ast
import ( import (
"io" "io"
"strings"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
"github.com/pingcap/parser/types" "github.com/pingcap/parser/types"
...@@ -27,7 +26,7 @@ import ( ...@@ -27,7 +26,7 @@ import (
// Interfaces embed Node should have 'Node' name suffix. // Interfaces embed Node should have 'Node' name suffix.
type Node interface { type Node interface {
// Restore returns the sql text from ast tree // Restore returns the sql text from ast tree
Restore(sb *strings.Builder) error Restore(ctx *RestoreCtx) error
// Accept accepts Visitor to visit itself. // Accept accepts Visitor to visit itself.
// The returned node should replace original node. // The returned node should replace original node.
// ok returns false to stop visiting. // ok returns false to stop visiting.
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
package ast package ast
import ( import (
"strings"
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/auth" "github.com/pingcap/parser/auth"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
...@@ -65,15 +63,17 @@ type DatabaseOption struct { ...@@ -65,15 +63,17 @@ type DatabaseOption struct {
Value string Value string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DatabaseOption) Restore(sb *strings.Builder) error { func (n *DatabaseOption) Restore(ctx *RestoreCtx) error {
switch n.Tp { switch n.Tp {
case DatabaseOptionCharset: case DatabaseOptionCharset:
sb.WriteString("CHARACTER SET = ") ctx.WriteKeyWord("CHARACTER SET")
sb.WriteString(n.Value) ctx.WritePlain(" = ")
ctx.WritePlain(n.Value)
case DatabaseOptionCollate: case DatabaseOptionCollate:
sb.WriteString("COLLATE = ") ctx.WriteKeyWord("COLLATE")
sb.WriteString(n.Value) ctx.WritePlain(" = ")
ctx.WritePlain(n.Value)
default: default:
return errors.Errorf("invalid DatabaseOptionType: %d", n.Tp) return errors.Errorf("invalid DatabaseOptionType: %d", n.Tp)
} }
...@@ -90,16 +90,16 @@ type CreateDatabaseStmt struct { ...@@ -90,16 +90,16 @@ type CreateDatabaseStmt struct {
Options []*DatabaseOption Options []*DatabaseOption
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *CreateDatabaseStmt) Restore(sb *strings.Builder) error { func (n *CreateDatabaseStmt) Restore(ctx *RestoreCtx) error {
sb.WriteString("CREATE DATABASE ") ctx.WriteKeyWord("CREATE DATABASE ")
if n.IfNotExists { if n.IfNotExists {
sb.WriteString("IF NOT EXISTS ") ctx.WriteKeyWord("IF NOT EXISTS ")
} }
WriteName(sb, n.Name) ctx.WriteName(n.Name)
for _, option := range n.Options { for _, option := range n.Options {
sb.WriteString(" ") ctx.WritePlain(" ")
err := option.Restore(sb) err := option.Restore(ctx)
if err != nil { if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
...@@ -126,13 +126,13 @@ type DropDatabaseStmt struct { ...@@ -126,13 +126,13 @@ type DropDatabaseStmt struct {
Name string Name string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DropDatabaseStmt) Restore(sb *strings.Builder) error { func (n *DropDatabaseStmt) Restore(ctx *RestoreCtx) error {
sb.WriteString("DROP DATABASE ") ctx.WriteKeyWord("DROP DATABASE ")
if n.IfExists { if n.IfExists {
sb.WriteString("IF EXISTS ") ctx.WriteKeyWord("IF EXISTS ")
} }
WriteName(sb, n.Name) ctx.WriteName(n.Name)
return nil return nil
} }
...@@ -154,8 +154,8 @@ type IndexColName struct { ...@@ -154,8 +154,8 @@ type IndexColName struct {
Length int Length int
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *IndexColName) Restore(sb *strings.Builder) error { func (n *IndexColName) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -185,8 +185,8 @@ type ReferenceDef struct { ...@@ -185,8 +185,8 @@ type ReferenceDef struct {
OnUpdate *OnUpdateOpt OnUpdate *OnUpdateOpt
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ReferenceDef) Restore(sb *strings.Builder) error { func (n *ReferenceDef) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -255,8 +255,8 @@ type OnDeleteOpt struct { ...@@ -255,8 +255,8 @@ type OnDeleteOpt struct {
ReferOpt ReferOptionType ReferOpt ReferOptionType
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *OnDeleteOpt) Restore(sb *strings.Builder) error { func (n *OnDeleteOpt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -276,8 +276,8 @@ type OnUpdateOpt struct { ...@@ -276,8 +276,8 @@ type OnUpdateOpt struct {
ReferOpt ReferOptionType ReferOpt ReferOptionType
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *OnUpdateOpt) Restore(sb *strings.Builder) error { func (n *OnUpdateOpt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -325,8 +325,8 @@ type ColumnOption struct { ...@@ -325,8 +325,8 @@ type ColumnOption struct {
Refer *ReferenceDef Refer *ReferenceDef
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ColumnOption) Restore(sb *strings.Builder) error { func (n *ColumnOption) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -361,8 +361,8 @@ type IndexOption struct { ...@@ -361,8 +361,8 @@ type IndexOption struct {
Comment string Comment string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *IndexOption) Restore(sb *strings.Builder) error { func (n *IndexOption) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -406,8 +406,8 @@ type Constraint struct { ...@@ -406,8 +406,8 @@ type Constraint struct {
Option *IndexOption // Index Options Option *IndexOption // Index Options
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *Constraint) Restore(sb *strings.Builder) error { func (n *Constraint) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -451,8 +451,8 @@ type ColumnDef struct { ...@@ -451,8 +451,8 @@ type ColumnDef struct {
Options []*ColumnOption Options []*ColumnOption
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ColumnDef) Restore(sb *strings.Builder) error { func (n *ColumnDef) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -494,8 +494,8 @@ type CreateTableStmt struct { ...@@ -494,8 +494,8 @@ type CreateTableStmt struct {
Select ResultSetNode Select ResultSetNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *CreateTableStmt) Restore(sb *strings.Builder) error { func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -553,8 +553,8 @@ type DropTableStmt struct { ...@@ -553,8 +553,8 @@ type DropTableStmt struct {
IsView bool IsView bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DropTableStmt) Restore(sb *strings.Builder) error { func (n *DropTableStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -588,8 +588,8 @@ type RenameTableStmt struct { ...@@ -588,8 +588,8 @@ type RenameTableStmt struct {
TableToTables []*TableToTable TableToTables []*TableToTable
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *RenameTableStmt) Restore(sb *strings.Builder) error { func (n *RenameTableStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -629,8 +629,8 @@ type TableToTable struct { ...@@ -629,8 +629,8 @@ type TableToTable struct {
NewTable *TableName NewTable *TableName
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *TableToTable) Restore(sb *strings.Builder) error { func (n *TableToTable) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -669,8 +669,8 @@ type CreateViewStmt struct { ...@@ -669,8 +669,8 @@ type CreateViewStmt struct {
CheckOption model.ViewCheckOption CheckOption model.ViewCheckOption
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *CreateViewStmt) Restore(sb *strings.Builder) error { func (n *CreateViewStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -706,8 +706,8 @@ type CreateIndexStmt struct { ...@@ -706,8 +706,8 @@ type CreateIndexStmt struct {
IndexOption *IndexOption IndexOption *IndexOption
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *CreateIndexStmt) Restore(sb *strings.Builder) error { func (n *CreateIndexStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -750,8 +750,8 @@ type DropIndexStmt struct { ...@@ -750,8 +750,8 @@ type DropIndexStmt struct {
Table *TableName Table *TableName
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DropIndexStmt) Restore(sb *strings.Builder) error { func (n *DropIndexStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -843,8 +843,8 @@ type ColumnPosition struct { ...@@ -843,8 +843,8 @@ type ColumnPosition struct {
RelativeColumn *ColumnName RelativeColumn *ColumnName
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ColumnPosition) Restore(sb *strings.Builder) error { func (n *ColumnPosition) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -925,8 +925,8 @@ type AlterTableSpec struct { ...@@ -925,8 +925,8 @@ type AlterTableSpec struct {
Num uint64 Num uint64
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *AlterTableSpec) Restore(sb *strings.Builder) error { func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -984,8 +984,8 @@ type AlterTableStmt struct { ...@@ -984,8 +984,8 @@ type AlterTableStmt struct {
Specs []*AlterTableSpec Specs []*AlterTableSpec
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *AlterTableStmt) Restore(sb *strings.Builder) error { func (n *AlterTableStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1019,8 +1019,8 @@ type TruncateTableStmt struct { ...@@ -1019,8 +1019,8 @@ type TruncateTableStmt struct {
Table *TableName Table *TableName
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *TruncateTableStmt) Restore(sb *strings.Builder) error { func (n *TruncateTableStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
package ast package ast
import ( import (
"strings"
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/auth" "github.com/pingcap/parser/auth"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
...@@ -85,8 +83,8 @@ type Join struct { ...@@ -85,8 +83,8 @@ type Join struct {
StraightJoin bool StraightJoin bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *Join) Restore(sb *strings.Builder) error { func (n *Join) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -133,16 +131,16 @@ type TableName struct { ...@@ -133,16 +131,16 @@ type TableName struct {
IndexHints []*IndexHint IndexHints []*IndexHint
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *TableName) Restore(sb *strings.Builder) error { func (n *TableName) Restore(ctx *RestoreCtx) error {
if n.Schema.String() != "" { if n.Schema.String() != "" {
WriteName(sb, n.Schema.String()) ctx.WriteName(n.Schema.String())
sb.WriteString(".") ctx.WritePlain(".")
} }
WriteName(sb, n.Name.String()) ctx.WriteName(n.Name.String())
for _, value := range n.IndexHints { for _, value := range n.IndexHints {
sb.WriteString(" ") ctx.WritePlain(" ")
if err := value.Restore(sb); err != nil { if err := value.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing IndexHints") return errors.Annotate(err, "An error occurred while splicing IndexHints")
} }
} }
...@@ -178,7 +176,7 @@ type IndexHint struct { ...@@ -178,7 +176,7 @@ type IndexHint struct {
} }
// IndexHint Restore (The const field uses switch to facilitate understanding) // IndexHint Restore (The const field uses switch to facilitate understanding)
func (n *IndexHint) Restore(sb *strings.Builder) error { func (n *IndexHint) Restore(ctx *RestoreCtx) error {
indexHintType := "" indexHintType := ""
switch n.HintType { switch n.HintType {
case 1: case 1:
...@@ -204,17 +202,16 @@ func (n *IndexHint) Restore(sb *strings.Builder) error { ...@@ -204,17 +202,16 @@ func (n *IndexHint) Restore(sb *strings.Builder) error {
default: // Prevent accidents default: // Prevent accidents
return errors.New("IndexHintScope has an error while matching") return errors.New("IndexHintScope has an error while matching")
} }
ctx.WriteKeyWord(indexHintType)
sb.WriteString(indexHintType) ctx.WriteKeyWord(indexHintScope)
sb.WriteString(indexHintScope) ctx.WritePlain(" (")
sb.WriteString(" (")
for i, value := range n.IndexNames { for i, value := range n.IndexNames {
if i > 0 { if i > 0 {
sb.WriteString(", ") ctx.WritePlain(", ")
} }
WriteName(sb, value.O) ctx.WriteName(value.O)
} }
sb.WriteString(")") ctx.WritePlain(")")
return nil return nil
} }
...@@ -235,8 +232,8 @@ type DeleteTableList struct { ...@@ -235,8 +232,8 @@ type DeleteTableList struct {
Tables []*TableName Tables []*TableName
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DeleteTableList) Restore(sb *strings.Builder) error { func (n *DeleteTableList) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -266,8 +263,8 @@ type OnCondition struct { ...@@ -266,8 +263,8 @@ type OnCondition struct {
Expr ExprNode Expr ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *OnCondition) Restore(sb *strings.Builder) error { func (n *OnCondition) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -298,8 +295,8 @@ type TableSource struct { ...@@ -298,8 +295,8 @@ type TableSource struct {
AsName model.CIStr AsName model.CIStr
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *TableSource) Restore(sb *strings.Builder) error { func (n *TableSource) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -349,8 +346,8 @@ type WildCardField struct { ...@@ -349,8 +346,8 @@ type WildCardField struct {
Schema model.CIStr Schema model.CIStr
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *WildCardField) Restore(sb *strings.Builder) error { func (n *WildCardField) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -384,8 +381,8 @@ type SelectField struct { ...@@ -384,8 +381,8 @@ type SelectField struct {
Auxiliary bool Auxiliary bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *SelectField) Restore(sb *strings.Builder) error { func (n *SelectField) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -413,8 +410,8 @@ type FieldList struct { ...@@ -413,8 +410,8 @@ type FieldList struct {
Fields []*SelectField Fields []*SelectField
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *FieldList) Restore(sb *strings.Builder) error { func (n *FieldList) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -442,8 +439,8 @@ type TableRefsClause struct { ...@@ -442,8 +439,8 @@ type TableRefsClause struct {
TableRefs *Join TableRefs *Join
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *TableRefsClause) Restore(sb *strings.Builder) error { func (n *TableRefsClause) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -470,8 +467,8 @@ type ByItem struct { ...@@ -470,8 +467,8 @@ type ByItem struct {
Desc bool Desc bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ByItem) Restore(sb *strings.Builder) error { func (n *ByItem) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -496,8 +493,8 @@ type GroupByClause struct { ...@@ -496,8 +493,8 @@ type GroupByClause struct {
Items []*ByItem Items []*ByItem
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *GroupByClause) Restore(sb *strings.Builder) error { func (n *GroupByClause) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -524,8 +521,8 @@ type HavingClause struct { ...@@ -524,8 +521,8 @@ type HavingClause struct {
Expr ExprNode Expr ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *HavingClause) Restore(sb *strings.Builder) error { func (n *HavingClause) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -551,8 +548,8 @@ type OrderByClause struct { ...@@ -551,8 +548,8 @@ type OrderByClause struct {
ForUnion bool ForUnion bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *OrderByClause) Restore(sb *strings.Builder) error { func (n *OrderByClause) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -609,8 +606,8 @@ type SelectStmt struct { ...@@ -609,8 +606,8 @@ type SelectStmt struct {
IsInBraces bool IsInBraces bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *SelectStmt) Restore(sb *strings.Builder) error { func (n *SelectStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -708,8 +705,8 @@ type UnionSelectList struct { ...@@ -708,8 +705,8 @@ type UnionSelectList struct {
Selects []*SelectStmt Selects []*SelectStmt
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *UnionSelectList) Restore(sb *strings.Builder) error { func (n *UnionSelectList) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -741,8 +738,8 @@ type UnionStmt struct { ...@@ -741,8 +738,8 @@ type UnionStmt struct {
Limit *Limit Limit *Limit
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *UnionStmt) Restore(sb *strings.Builder) error { func (n *UnionStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -786,8 +783,8 @@ type Assignment struct { ...@@ -786,8 +783,8 @@ type Assignment struct {
Expr ExprNode Expr ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *Assignment) Restore(sb *strings.Builder) error { func (n *Assignment) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -825,8 +822,8 @@ type LoadDataStmt struct { ...@@ -825,8 +822,8 @@ type LoadDataStmt struct {
IgnoreLines uint64 IgnoreLines uint64
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *LoadDataStmt) Restore(sb *strings.Builder) error { func (n *LoadDataStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -883,8 +880,8 @@ type InsertStmt struct { ...@@ -883,8 +880,8 @@ type InsertStmt struct {
Select ResultSetNode Select ResultSetNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *InsertStmt) Restore(sb *strings.Builder) error { func (n *InsertStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -964,8 +961,8 @@ type DeleteStmt struct { ...@@ -964,8 +961,8 @@ type DeleteStmt struct {
TableHints []*TableOptimizerHint TableHints []*TableOptimizerHint
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DeleteStmt) Restore(sb *strings.Builder) error { func (n *DeleteStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1029,8 +1026,8 @@ type UpdateStmt struct { ...@@ -1029,8 +1026,8 @@ type UpdateStmt struct {
TableHints []*TableOptimizerHint TableHints []*TableOptimizerHint
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *UpdateStmt) Restore(sb *strings.Builder) error { func (n *UpdateStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1085,8 +1082,8 @@ type Limit struct { ...@@ -1085,8 +1082,8 @@ type Limit struct {
Offset ExprNode Offset ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *Limit) Restore(sb *strings.Builder) error { func (n *Limit) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1170,8 +1167,8 @@ type ShowStmt struct { ...@@ -1170,8 +1167,8 @@ type ShowStmt struct {
Where ExprNode Where ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ShowStmt) Restore(sb *strings.Builder) error { func (n *ShowStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1235,8 +1232,8 @@ type WindowSpec struct { ...@@ -1235,8 +1232,8 @@ type WindowSpec struct {
Frame *FrameClause Frame *FrameClause
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *WindowSpec) Restore(sb *strings.Builder) error { func (n *WindowSpec) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1278,8 +1275,8 @@ type PartitionByClause struct { ...@@ -1278,8 +1275,8 @@ type PartitionByClause struct {
Items []*ByItem Items []*ByItem
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *PartitionByClause) Restore(sb *strings.Builder) error { func (n *PartitionByClause) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1319,8 +1316,8 @@ type FrameClause struct { ...@@ -1319,8 +1316,8 @@ type FrameClause struct {
Extent FrameExtent Extent FrameExtent
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *FrameClause) Restore(sb *strings.Builder) error { func (n *FrameClause) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1372,8 +1369,8 @@ type FrameBound struct { ...@@ -1372,8 +1369,8 @@ type FrameBound struct {
Unit ExprNode Unit ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *FrameBound) Restore(sb *strings.Builder) error { func (n *FrameBound) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
......
...@@ -79,9 +79,24 @@ type BetweenExpr struct { ...@@ -79,9 +79,24 @@ type BetweenExpr struct {
Not bool Not bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *BetweenExpr) Restore(sb *strings.Builder) error { func (n *BetweenExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore BetweenExpr.Expr")
}
if n.Not {
ctx.WriteKeyWord(" NOT BETWEEN ")
} else {
ctx.WriteKeyWord(" BETWEEN ")
}
if err := n.Left.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore BetweenExpr.Left")
}
ctx.WriteKeyWord(" AND ")
if err := n.Right.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore BetweenExpr.Right ")
}
return nil
} }
// Format the ExprNode into a Writer. // Format the ExprNode into a Writer.
...@@ -137,8 +152,8 @@ type BinaryOperationExpr struct { ...@@ -137,8 +152,8 @@ type BinaryOperationExpr struct {
R ExprNode R ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *BinaryOperationExpr) Restore(sb *strings.Builder) error { func (n *BinaryOperationExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -183,8 +198,8 @@ type WhenClause struct { ...@@ -183,8 +198,8 @@ type WhenClause struct {
Result ExprNode Result ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *WhenClause) Restore(sb *strings.Builder) error { func (n *WhenClause) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -221,8 +236,8 @@ type CaseExpr struct { ...@@ -221,8 +236,8 @@ type CaseExpr struct {
ElseClause ExprNode ElseClause ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *CaseExpr) Restore(sb *strings.Builder) error { func (n *CaseExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -290,8 +305,8 @@ type SubqueryExpr struct { ...@@ -290,8 +305,8 @@ type SubqueryExpr struct {
Exists bool Exists bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *SubqueryExpr) Restore(sb *strings.Builder) error { func (n *SubqueryExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -331,8 +346,8 @@ type CompareSubqueryExpr struct { ...@@ -331,8 +346,8 @@ type CompareSubqueryExpr struct {
All bool All bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *CompareSubqueryExpr) Restore(sb *strings.Builder) error { func (n *CompareSubqueryExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -369,17 +384,17 @@ type ColumnName struct { ...@@ -369,17 +384,17 @@ type ColumnName struct {
Name model.CIStr Name model.CIStr
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ColumnName) Restore(sb *strings.Builder) error { func (n *ColumnName) Restore(ctx *RestoreCtx) error {
if n.Schema.O != "" { if n.Schema.O != "" {
WriteName(sb, n.Schema.O) ctx.WriteName(n.Schema.O)
sb.WriteString(".") ctx.WritePlain(".")
} }
if n.Table.O != "" { if n.Table.O != "" {
WriteName(sb, n.Table.O) ctx.WriteName(n.Table.O)
sb.WriteString(".") ctx.WritePlain(".")
} }
WriteName(sb, n.Name.O) ctx.WriteName(n.Name.O)
return nil return nil
} }
...@@ -431,10 +446,9 @@ type ColumnNameExpr struct { ...@@ -431,10 +446,9 @@ type ColumnNameExpr struct {
Refer *ResultField Refer *ResultField
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ColumnNameExpr) Restore(sb *strings.Builder) error { func (n *ColumnNameExpr) Restore(ctx *RestoreCtx) error {
err := n.Name.Restore(sb) if err := n.Name.Restore(ctx); err != nil {
if err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
return nil return nil
...@@ -468,8 +482,8 @@ type DefaultExpr struct { ...@@ -468,8 +482,8 @@ type DefaultExpr struct {
Name *ColumnName Name *ColumnName
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DefaultExpr) Restore(sb *strings.Builder) error { func (n *DefaultExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -505,8 +519,8 @@ type ExistsSubqueryExpr struct { ...@@ -505,8 +519,8 @@ type ExistsSubqueryExpr struct {
Not bool Not bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ExistsSubqueryExpr) Restore(sb *strings.Builder) error { func (n *ExistsSubqueryExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -543,8 +557,8 @@ type PatternInExpr struct { ...@@ -543,8 +557,8 @@ type PatternInExpr struct {
Sel ExprNode Sel ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *PatternInExpr) Restore(sb *strings.Builder) error { func (n *PatternInExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -603,9 +617,16 @@ type IsNullExpr struct { ...@@ -603,9 +617,16 @@ type IsNullExpr struct {
Not bool Not bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *IsNullExpr) Restore(sb *strings.Builder) error { func (n *IsNullExpr) Restore(ctx *RestoreCtx) error {
n.Format(sb) if err := n.Expr.Restore(ctx); err != nil {
return errors.Trace(err)
}
if n.Not {
ctx.WriteKeyWord(" IS NOT NULL")
} else {
ctx.WriteKeyWord(" IS NULL")
}
return nil return nil
} }
...@@ -645,8 +666,8 @@ type IsTruthExpr struct { ...@@ -645,8 +666,8 @@ type IsTruthExpr struct {
True int64 True int64
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *IsTruthExpr) Restore(sb *strings.Builder) error { func (n *IsTruthExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -696,8 +717,8 @@ type PatternLikeExpr struct { ...@@ -696,8 +717,8 @@ type PatternLikeExpr struct {
PatTypes []byte PatTypes []byte
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *PatternLikeExpr) Restore(sb *strings.Builder) error { func (n *PatternLikeExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -754,8 +775,8 @@ type ParenthesesExpr struct { ...@@ -754,8 +775,8 @@ type ParenthesesExpr struct {
Expr ExprNode Expr ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ParenthesesExpr) Restore(sb *strings.Builder) error { func (n *ParenthesesExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -796,8 +817,8 @@ type PositionExpr struct { ...@@ -796,8 +817,8 @@ type PositionExpr struct {
Refer *ResultField Refer *ResultField
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *PositionExpr) Restore(sb *strings.Builder) error { func (n *PositionExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -839,8 +860,8 @@ type PatternRegexpExpr struct { ...@@ -839,8 +860,8 @@ type PatternRegexpExpr struct {
Sexpr *string Sexpr *string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *PatternRegexpExpr) Restore(sb *strings.Builder) error { func (n *PatternRegexpExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -883,8 +904,8 @@ type RowExpr struct { ...@@ -883,8 +904,8 @@ type RowExpr struct {
Values []ExprNode Values []ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *RowExpr) Restore(sb *strings.Builder) error { func (n *RowExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -919,9 +940,14 @@ type UnaryOperationExpr struct { ...@@ -919,9 +940,14 @@ type UnaryOperationExpr struct {
V ExprNode V ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *UnaryOperationExpr) Restore(sb *strings.Builder) error { func (n *UnaryOperationExpr) Restore(ctx *RestoreCtx) error {
n.Format(sb) if err := n.Op.Restore(ctx.In); err != nil {
return errors.Trace(err)
}
if err := n.V.Restore(ctx); err != nil {
return errors.Trace(err)
}
return nil return nil
} }
...@@ -953,8 +979,8 @@ type ValuesExpr struct { ...@@ -953,8 +979,8 @@ type ValuesExpr struct {
Column *ColumnNameExpr Column *ColumnNameExpr
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ValuesExpr) Restore(sb *strings.Builder) error { func (n *ValuesExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -995,8 +1021,8 @@ type VariableExpr struct { ...@@ -995,8 +1021,8 @@ type VariableExpr struct {
Value ExprNode Value ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *VariableExpr) Restore(sb *strings.Builder) error { func (n *VariableExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -1029,8 +1055,8 @@ type MaxValueExpr struct { ...@@ -1029,8 +1055,8 @@ type MaxValueExpr struct {
exprNode exprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *MaxValueExpr) Restore(sb *strings.Builder) error { func (n *MaxValueExpr) Restore(ctx *RestoreCtx) error {
panic("Not implemented") panic("Not implemented")
} }
......
...@@ -16,7 +16,6 @@ package ast ...@@ -16,7 +16,6 @@ package ast
import ( import (
"fmt" "fmt"
"io" "io"
"strings"
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
...@@ -329,8 +328,8 @@ type FuncCallExpr struct { ...@@ -329,8 +328,8 @@ type FuncCallExpr struct {
Args []ExprNode Args []ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *FuncCallExpr) Restore(sb *strings.Builder) error { func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -406,8 +405,8 @@ type FuncCastExpr struct { ...@@ -406,8 +405,8 @@ type FuncCastExpr struct {
FunctionType CastFunctionType FunctionType CastFunctionType
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *FuncCastExpr) Restore(sb *strings.Builder) error { func (n *FuncCastExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -519,8 +518,8 @@ type AggregateFuncExpr struct { ...@@ -519,8 +518,8 @@ type AggregateFuncExpr struct {
Distinct bool Distinct bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *AggregateFuncExpr) Restore(sb *strings.Builder) error { func (n *AggregateFuncExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -592,8 +591,8 @@ type WindowFuncExpr struct { ...@@ -592,8 +591,8 @@ type WindowFuncExpr struct {
Spec WindowSpec Spec WindowSpec
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *WindowFuncExpr) Restore(sb *strings.Builder) error { func (n *WindowFuncExpr) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
......
...@@ -98,8 +98,8 @@ type TraceStmt struct { ...@@ -98,8 +98,8 @@ type TraceStmt struct {
Format string Format string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *TraceStmt) Restore(sb *strings.Builder) error { func (n *TraceStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -129,8 +129,8 @@ type ExplainStmt struct { ...@@ -129,8 +129,8 @@ type ExplainStmt struct {
Analyze bool Analyze bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ExplainStmt) Restore(sb *strings.Builder) error { func (n *ExplainStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -160,8 +160,8 @@ type PrepareStmt struct { ...@@ -160,8 +160,8 @@ type PrepareStmt struct {
SQLVar *VariableExpr SQLVar *VariableExpr
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *PrepareStmt) Restore(sb *strings.Builder) error { func (n *PrepareStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -190,8 +190,8 @@ type DeallocateStmt struct { ...@@ -190,8 +190,8 @@ type DeallocateStmt struct {
Name string Name string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DeallocateStmt) Restore(sb *strings.Builder) error { func (n *DeallocateStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -223,8 +223,8 @@ type ExecuteStmt struct { ...@@ -223,8 +223,8 @@ type ExecuteStmt struct {
ExecID uint32 ExecID uint32
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ExecuteStmt) Restore(sb *strings.Builder) error { func (n *ExecuteStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -251,8 +251,8 @@ type BeginStmt struct { ...@@ -251,8 +251,8 @@ type BeginStmt struct {
stmtNode stmtNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *BeginStmt) Restore(sb *strings.Builder) error { func (n *BeginStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -274,8 +274,8 @@ type BinlogStmt struct { ...@@ -274,8 +274,8 @@ type BinlogStmt struct {
Str string Str string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *BinlogStmt) Restore(sb *strings.Builder) error { func (n *BinlogStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -295,8 +295,8 @@ type CommitStmt struct { ...@@ -295,8 +295,8 @@ type CommitStmt struct {
stmtNode stmtNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *CommitStmt) Restore(sb *strings.Builder) error { func (n *CommitStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -316,8 +316,8 @@ type RollbackStmt struct { ...@@ -316,8 +316,8 @@ type RollbackStmt struct {
stmtNode stmtNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *RollbackStmt) Restore(sb *strings.Builder) error { func (n *RollbackStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -339,10 +339,10 @@ type UseStmt struct { ...@@ -339,10 +339,10 @@ type UseStmt struct {
DBName string DBName string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *UseStmt) Restore(sb *strings.Builder) error { func (n *UseStmt) Restore(ctx *RestoreCtx) error {
sb.WriteString("USE ") ctx.WriteKeyWord("USE ")
WriteName(sb, n.DBName) ctx.WriteName(n.DBName)
return nil return nil
} }
...@@ -377,8 +377,8 @@ type VariableAssignment struct { ...@@ -377,8 +377,8 @@ type VariableAssignment struct {
ExtendValue ValueExpr ExtendValue ValueExpr
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *VariableAssignment) Restore(sb *strings.Builder) error { func (n *VariableAssignment) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -418,8 +418,8 @@ type FlushStmt struct { ...@@ -418,8 +418,8 @@ type FlushStmt struct {
ReadLock bool ReadLock bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *FlushStmt) Restore(sb *strings.Builder) error { func (n *FlushStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -453,8 +453,8 @@ type KillStmt struct { ...@@ -453,8 +453,8 @@ type KillStmt struct {
TiDBExtension bool TiDBExtension bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *KillStmt) Restore(sb *strings.Builder) error { func (n *KillStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -475,8 +475,8 @@ type SetStmt struct { ...@@ -475,8 +475,8 @@ type SetStmt struct {
Variables []*VariableAssignment Variables []*VariableAssignment
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *SetStmt) Restore(sb *strings.Builder) error { func (n *SetStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -527,8 +527,8 @@ type SetPwdStmt struct { ...@@ -527,8 +527,8 @@ type SetPwdStmt struct {
Password string Password string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *SetPwdStmt) Restore(sb *strings.Builder) error { func (n *SetPwdStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -595,8 +595,8 @@ type CreateUserStmt struct { ...@@ -595,8 +595,8 @@ type CreateUserStmt struct {
Specs []*UserSpec Specs []*UserSpec
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *CreateUserStmt) Restore(sb *strings.Builder) error { func (n *CreateUserStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -631,8 +631,8 @@ type AlterUserStmt struct { ...@@ -631,8 +631,8 @@ type AlterUserStmt struct {
Specs []*UserSpec Specs []*UserSpec
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *AlterUserStmt) Restore(sb *strings.Builder) error { func (n *AlterUserStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -666,8 +666,8 @@ type DropUserStmt struct { ...@@ -666,8 +666,8 @@ type DropUserStmt struct {
UserList []*auth.UserIdentity UserList []*auth.UserIdentity
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DropUserStmt) Restore(sb *strings.Builder) error { func (n *DropUserStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -688,8 +688,8 @@ type DoStmt struct { ...@@ -688,8 +688,8 @@ type DoStmt struct {
Exprs []ExprNode Exprs []ExprNode
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DoStmt) Restore(sb *strings.Builder) error { func (n *DoStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -780,8 +780,8 @@ type AdminStmt struct { ...@@ -780,8 +780,8 @@ type AdminStmt struct {
ShowSlow *ShowSlow ShowSlow *ShowSlow
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *AdminStmt) Restore(sb *strings.Builder) error { func (n *AdminStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -812,8 +812,8 @@ type PrivElem struct { ...@@ -812,8 +812,8 @@ type PrivElem struct {
Cols []*ColumnName Cols []*ColumnName
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *PrivElem) Restore(sb *strings.Builder) error { func (n *PrivElem) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -875,8 +875,8 @@ type RevokeStmt struct { ...@@ -875,8 +875,8 @@ type RevokeStmt struct {
Users []*UserSpec Users []*UserSpec
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *RevokeStmt) Restore(sb *strings.Builder) error { func (n *RevokeStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -908,8 +908,8 @@ type GrantStmt struct { ...@@ -908,8 +908,8 @@ type GrantStmt struct {
WithGrant bool WithGrant bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *GrantStmt) Restore(sb *strings.Builder) error { func (n *GrantStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -978,8 +978,8 @@ type TableOptimizerHint struct { ...@@ -978,8 +978,8 @@ type TableOptimizerHint struct {
MaxExecutionTime uint64 MaxExecutionTime uint64
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *TableOptimizerHint) Restore(sb *strings.Builder) error { func (n *TableOptimizerHint) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
package ast package ast
import ( import (
"strings"
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
) )
...@@ -39,8 +37,8 @@ type AnalyzeTableStmt struct { ...@@ -39,8 +37,8 @@ type AnalyzeTableStmt struct {
IndexFlag bool IndexFlag bool
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *AnalyzeTableStmt) Restore(sb *strings.Builder) error { func (n *AnalyzeTableStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -68,8 +66,8 @@ type DropStatsStmt struct { ...@@ -68,8 +66,8 @@ type DropStatsStmt struct {
Table *TableName Table *TableName
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *DropStatsStmt) Restore(sb *strings.Builder) error { func (n *DropStatsStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
...@@ -95,8 +93,8 @@ type LoadStatsStmt struct { ...@@ -95,8 +93,8 @@ type LoadStatsStmt struct {
Path string Path string
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *LoadStatsStmt) Restore(sb *strings.Builder) error { func (n *LoadStatsStmt) Restore(ctx *RestoreCtx) error {
return errors.New("Not implemented") return errors.New("Not implemented")
} }
......
...@@ -13,7 +13,11 @@ ...@@ -13,7 +13,11 @@
package ast package ast
import "strings" import (
"fmt"
"io"
"strings"
)
// 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 {
...@@ -62,14 +66,150 @@ func (checker *readOnlyChecker) Leave(in Node) (out Node, ok bool) { ...@@ -62,14 +66,150 @@ func (checker *readOnlyChecker) Leave(in Node) (out Node, ok bool) {
return in, checker.readOnly return in, checker.readOnly
} }
// WriteName append escaped `name` with back quote to `sb`. //RestoreFlag mark the Restore format
func WriteName(sb *strings.Builder, name string) { type RestoreFlags uint64
sb.WriteString("`")
sb.WriteString(EscapeName(name)) // Mutually exclusive group of `RestoreFlags`:
sb.WriteString("`") // [RestoreStringSingleQuotes, RestoreStringDoubleQuotes]
// [RestoreKeyWordUppercase, RestoreKeyWordLowercase]
// [RestoreNameUppercase, RestoreNameLowercase]
// [RestoreNameDoubleQuotes, RestoreNameBackQuotes]
// The flag with the left position in each group has a higher priority.
const (
RestoreStringSingleQuotes RestoreFlags = 1 << iota
RestoreStringDoubleQuotes
RestoreStringEscapeBackslash
RestoreKeyWordUppercase
RestoreKeyWordLowercase
RestoreNameUppercase
RestoreNameLowercase
RestoreNameDoubleQuotes
RestoreNameBackQuotes
)
const (
DefaultRestoreFlags = RestoreStringSingleQuotes | RestoreKeyWordUppercase | RestoreNameBackQuotes
)
func (rf RestoreFlags) has(flag RestoreFlags) bool {
return rf&flag != 0
}
// HasStringSingleQuotesFlag returns a boolean indicating when `rf` has `RestoreStringSingleQuotes` flag.
func (rf RestoreFlags) HasStringSingleQuotesFlag() bool {
return rf.has(RestoreStringSingleQuotes)
}
// HasStringDoubleQuotesFlag returns a boolean indicating whether `rf` has `RestoreStringDoubleQuotes` flag.
func (rf RestoreFlags) HasStringDoubleQuotesFlag() bool {
return rf.has(RestoreStringDoubleQuotes)
}
// HasStringEscapeBackslashFlag returns a boolean indicating whether `rf` has `RestoreStringEscapeBackslash` flag.
func (rf RestoreFlags) HasStringEscapeBackslashFlag() bool {
return rf.has(RestoreStringEscapeBackslash)
}
// HasKeyWordUppercaseFlag returns a boolean indicating whether `rf` has `RestoreKeyWordUppercase` flag.
func (rf RestoreFlags) HasKeyWordUppercaseFlag() bool {
return rf.has(RestoreKeyWordUppercase)
}
// HasKeyWordLowercaseFlag returns a boolean indicating whether `rf` has `RestoreKeyWordLowercase` flag.
func (rf RestoreFlags) HasKeyWordLowercaseFlag() bool {
return rf.has(RestoreKeyWordLowercase)
}
// HasNameUppercaseFlag returns a boolean indicating whether `rf` has `RestoreNameUppercase` flag.
func (rf RestoreFlags) HasNameUppercaseFlag() bool {
return rf.has(RestoreNameUppercase)
}
// HasNameLowercaseFlag returns a boolean indicating whether `rf` has `RestoreNameLowercase` flag.
func (rf RestoreFlags) HasNameLowercaseFlag() bool {
return rf.has(RestoreNameLowercase)
}
// HasNameDoubleQuotesFlag returns a boolean indicating whether `rf` has `RestoreNameDoubleQuotes` flag.
func (rf RestoreFlags) HasNameDoubleQuotesFlag() bool {
return rf.has(RestoreNameDoubleQuotes)
}
// HasNameBackQuotesFlag returns a boolean indicating whether `rf` has `RestoreNameBackQuotes` flag.
func (rf RestoreFlags) HasNameBackQuotesFlag() bool {
return rf.has(RestoreNameBackQuotes)
}
// RestoreCtx is `Restore` context to hold flags and writer.
type RestoreCtx struct {
Flags RestoreFlags
In io.Writer
}
// NewRestoreCtx returns a new `RestoreCtx`.
func NewRestoreCtx(flags RestoreFlags, in io.Writer) *RestoreCtx {
return &RestoreCtx{flags, in}
}
// WriteKeyWord writes the `keyWord` into writer.
// `keyWord` will be converted format(uppercase and lowercase for now) according to `RestoreFlags`.
func (ctx *RestoreCtx) WriteKeyWord(keyWord string) {
switch {
case ctx.Flags.HasKeyWordUppercaseFlag():
keyWord = strings.ToUpper(keyWord)
case ctx.Flags.HasKeyWordLowercaseFlag():
keyWord = strings.ToLower(keyWord)
}
fmt.Fprint(ctx.In, keyWord)
}
// WriteString writes the string into writer
// `str` may be wrapped in quotes and escaped according to RestoreFlags.
func (ctx *RestoreCtx) WriteString(str string) {
if ctx.Flags.HasStringEscapeBackslashFlag() {
str = strings.Replace(str, `\`, `\\`, -1)
}
quotes := ""
switch {
case ctx.Flags.HasStringSingleQuotesFlag():
str = strings.Replace(str, `'`, `''`, -1)
quotes = `'`
case ctx.Flags.HasStringDoubleQuotesFlag():
str = strings.Replace(str, `"`, `""`, -1)
quotes = `"`
}
fmt.Fprint(ctx.In, quotes, str, quotes)
}
// WriteName writes the name into writer
// `name` maybe wrapped in quotes and escaped according to RestoreFlags.
func (ctx *RestoreCtx) WriteName(name string) {
switch {
case ctx.Flags.HasNameUppercaseFlag():
name = strings.ToUpper(name)
case ctx.Flags.HasNameLowercaseFlag():
name = strings.ToLower(name)
}
quotes := ""
switch {
case ctx.Flags.HasNameDoubleQuotesFlag():
name = strings.Replace(name, `"`, `""`, -1)
quotes = `"`
case ctx.Flags.HasNameBackQuotesFlag():
name = strings.Replace(name, "`", "``", -1)
quotes = "`"
}
fmt.Fprint(ctx.In, quotes, name, quotes)
}
// WritePlain writes the plain text into writer without any handling.
func (ctx *RestoreCtx) WritePlain(plainText string) {
fmt.Fprint(ctx.In, plainText)
} }
// EscapeName escape the `name` // WritePlainf write the plain text into writer without any handling.
func EscapeName(name string) string { func (ctx *RestoreCtx) WritePlainf(format string, a ...interface{}) {
return strings.Replace(name, "`", "``", -1) fmt.Fprintf(ctx.In, format, a...)
} }
...@@ -7,11 +7,10 @@ require ( ...@@ -7,11 +7,10 @@ require (
github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65 github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65
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/pingcap/check v0.0.0-20171206051426-1c287c953996 github.com/pingcap/check v0.0.0-20181213055612-5c2b07721bdb
github.com/pingcap/errors v0.11.0 github.com/pingcap/errors v0.11.0
github.com/pingcap/tidb v0.0.0-20181203021530-741adcee43e2 github.com/pingcap/tidb v0.0.0-20181217070741-096bb68e6bef
github.com/pingcap/tipb v0.0.0-20181012112600-11e33c750323 github.com/pingcap/tipb v0.0.0-20181012112600-11e33c750323
github.com/sirupsen/logrus v1.2.0 github.com/sirupsen/logrus v1.2.0
golang.org/x/net v0.0.0-20181029044818-c44066c5c816
golang.org/x/text v0.3.0 golang.org/x/text v0.3.0
) )
...@@ -250,6 +250,14 @@ func (t *TableInfo) GetAutoIncrementColInfo() *ColumnInfo { ...@@ -250,6 +250,14 @@ func (t *TableInfo) GetAutoIncrementColInfo() *ColumnInfo {
return nil return nil
} }
func (t *TableInfo) IsAutoIncColUnsigned() bool {
col := t.GetAutoIncrementColInfo()
if col == nil {
return false
}
return mysql.HasUnsignedFlag(col.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))
......
...@@ -16,6 +16,8 @@ package opcode ...@@ -16,6 +16,8 @@ package opcode
import ( import (
"fmt" "fmt"
"io" "io"
"github.com/pingcap/errors"
) )
// Op is opcode type. // Op is opcode type.
...@@ -136,3 +138,12 @@ var opsLiteral = map[Op]string{ ...@@ -136,3 +138,12 @@ var opsLiteral = map[Op]string{
func (o Op) Format(w io.Writer) { func (o Op) Format(w io.Writer) {
fmt.Fprintf(w, "%s", opsLiteral[o]) fmt.Fprintf(w, "%s", opsLiteral[o])
} }
// Restore the Op into a Writer
func (o Op) Restore(w io.Writer) error {
if v, ok := opsLiteral[o]; ok {
fmt.Fprint(w, v)
return nil
}
return errors.Errorf("Invalid opcode type %d during restoring AST to SQL text", o)
}
...@@ -128,12 +128,24 @@ func DefaultParamTypeForValue(value interface{}, tp *FieldType) { ...@@ -128,12 +128,24 @@ func DefaultParamTypeForValue(value interface{}, tp *FieldType) {
tp.Decimal = UnspecifiedLength tp.Decimal = UnspecifiedLength
default: default:
DefaultTypeForValue(value, tp) DefaultTypeForValue(value, tp)
if hasVariantFieldLength(tp) {
tp.Flen = UnspecifiedLength
}
if tp.Tp == mysql.TypeUnspecified { if tp.Tp == mysql.TypeUnspecified {
tp.Tp = mysql.TypeVarString tp.Tp = mysql.TypeVarString
} }
} }
} }
func hasVariantFieldLength(tp *FieldType) bool {
switch tp.Tp {
case mysql.TypeLonglong, mysql.TypeVarString, mysql.TypeDouble, mysql.TypeBlob,
mysql.TypeBit, mysql.TypeDuration, mysql.TypeNewDecimal, mysql.TypeEnum, mysql.TypeSet:
return true
}
return false
}
// DefaultTypeForValue returns the default FieldType for the value. // DefaultTypeForValue returns the default FieldType for the value.
func DefaultTypeForValue(value interface{}, tp *FieldType) { func DefaultTypeForValue(value interface{}, tp *FieldType) {
switch x := value.(type) { switch x := value.(type) {
......
...@@ -17,7 +17,6 @@ import ( ...@@ -17,7 +17,6 @@ import (
"fmt" "fmt"
"io" "io"
"strconv" "strconv"
"strings"
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/ast" "github.com/pingcap/parser/ast"
...@@ -69,11 +68,45 @@ type ValueExpr struct { ...@@ -69,11 +68,45 @@ type ValueExpr struct {
projectionOffset int projectionOffset int
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ValueExpr) Restore(sb *strings.Builder) error { func (n *ValueExpr) Restore(ctx *ast.RestoreCtx) error {
err := n.format(sb) switch n.Kind() {
if err != nil { case types.KindNull:
return errors.Trace(err) ctx.WriteKeyWord("NULL")
case types.KindInt64:
if n.Type.Flag&mysql.IsBooleanFlag != 0 {
if n.GetInt64() > 0 {
ctx.WriteKeyWord("TRUE")
} else {
ctx.WriteKeyWord("FALSE")
}
} else {
ctx.WritePlain(strconv.FormatInt(n.GetInt64(), 10))
}
case types.KindUint64:
ctx.WritePlain(strconv.FormatUint(n.GetUint64(), 10))
case types.KindFloat32:
ctx.WritePlain(strconv.FormatFloat(n.GetFloat64(), 'e', -1, 32))
case types.KindFloat64:
ctx.WritePlain(strconv.FormatFloat(n.GetFloat64(), 'e', -1, 64))
case types.KindString, types.KindBytes:
ctx.WriteString(n.GetString())
case types.KindMysqlDecimal:
ctx.WritePlain(n.GetMysqlDecimal().String())
case types.KindBinaryLiteral:
if n.Type.Flag&mysql.UnsignedFlag != 0 {
ctx.WritePlainf("x'%x'", n.GetBytes())
} else {
ctx.WritePlain(n.GetBinaryLiteral().ToBitLiteralString(true))
}
case types.KindMysqlDuration, types.KindMysqlEnum,
types.KindMysqlBit, types.KindMysqlSet, types.KindMysqlTime,
types.KindInterface, types.KindMinNotNull, types.KindMaxValue,
types.KindRaw, types.KindMysqlJSON:
// TODO implement Restore function
return errors.New("Not implemented")
default:
return errors.New("can't format to string")
} }
return nil return nil
} }
...@@ -84,7 +117,7 @@ func (n *ValueExpr) GetDatumString() string { ...@@ -84,7 +117,7 @@ func (n *ValueExpr) GetDatumString() string {
} }
// Format the ExprNode into a Writer. // Format the ExprNode into a Writer.
func (n *ValueExpr) format(w io.Writer) error { func (n *ValueExpr) Format(w io.Writer) {
var s string var s string
switch n.Kind() { switch n.Kind() {
case types.KindNull: case types.KindNull:
...@@ -116,18 +149,9 @@ func (n *ValueExpr) format(w io.Writer) error { ...@@ -116,18 +149,9 @@ func (n *ValueExpr) format(w io.Writer) error {
s = n.GetBinaryLiteral().ToBitLiteralString(true) s = n.GetBinaryLiteral().ToBitLiteralString(true)
} }
default: default:
return errors.New("can't format to string")
}
fmt.Fprint(w, s)
return nil
}
// Format the ExprNode into a Writer.
func (n *ValueExpr) Format(w io.Writer) {
err := n.format(w)
if err != nil {
panic("Can't format to string") panic("Can't format to string")
} }
fmt.Fprint(w, s)
} }
// newValueExpr creates a ValueExpr with value, and sets default field type. // newValueExpr creates a ValueExpr with value, and sets default field type.
...@@ -170,9 +194,9 @@ type ParamMarkerExpr struct { ...@@ -170,9 +194,9 @@ type ParamMarkerExpr struct {
Order int Order int
} }
// Restore implements Recoverable interface. // Restore implements Node interface.
func (n *ParamMarkerExpr) Restore(sb *strings.Builder) error { func (n *ParamMarkerExpr) Restore(ctx *ast.RestoreCtx) error {
sb.WriteString("?") ctx.WritePlain("?")
return nil return nil
} }
......
...@@ -105,106 +105,106 @@ ...@@ -105,106 +105,106 @@
"revisionTime": "2018-10-24T15:10:47Z" "revisionTime": "2018-10-24T15:10:47Z"
}, },
{ {
"checksumSHA1": "xbV0lm0Qw8rFC82Dttxbf5ypBjA=", "checksumSHA1": "fjZ4hf54cBBlV260wsAMZJ5T3po=",
"path": "github.com/pingcap/parser", "path": "github.com/pingcap/parser",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "RosqMriA/39ZEtqGgNU+bOfRBVc=", "checksumSHA1": "nRo2Z/Gyb1ziK+CKQi1OAOMa4hc=",
"path": "github.com/pingcap/parser/ast", "path": "github.com/pingcap/parser/ast",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "skWGV4FNvD3vr+5olepaPPnylUw=", "checksumSHA1": "skWGV4FNvD3vr+5olepaPPnylUw=",
"path": "github.com/pingcap/parser/auth", "path": "github.com/pingcap/parser/auth",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "t4UHo966WzU9Z0IJkyGHRp0loOk=", "checksumSHA1": "t4UHo966WzU9Z0IJkyGHRp0loOk=",
"path": "github.com/pingcap/parser/charset", "path": "github.com/pingcap/parser/charset",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "SInoXbsRe0tnBwmatmtZYfSFbdk=", "checksumSHA1": "SInoXbsRe0tnBwmatmtZYfSFbdk=",
"path": "github.com/pingcap/parser/format", "path": "github.com/pingcap/parser/format",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "reRV2qecd6NpB7tIW3JeK46K/sk=", "checksumSHA1": "WZYTGDMnc1UfTdjdZoBbISsnpRY=",
"path": "github.com/pingcap/parser/model", "path": "github.com/pingcap/parser/model",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "QBa9yiMDQNl2cLLwqlRoNTpCPNg=", "checksumSHA1": "QBa9yiMDQNl2cLLwqlRoNTpCPNg=",
"path": "github.com/pingcap/parser/mysql", "path": "github.com/pingcap/parser/mysql",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "oNBCSwJRykKuzIKgPCttatB9hAo=", "checksumSHA1": "+O6CYIE0jT8pIDxWRP9FtKwFZjI=",
"path": "github.com/pingcap/parser/opcode", "path": "github.com/pingcap/parser/opcode",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "XvnUllvwMYd6HrMvMiKnn4cGN2M=", "checksumSHA1": "XvnUllvwMYd6HrMvMiKnn4cGN2M=",
"path": "github.com/pingcap/parser/terror", "path": "github.com/pingcap/parser/terror",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "YoDiJ3sniNqxkP5X/BDkx6efteA=", "checksumSHA1": "YoDiJ3sniNqxkP5X/BDkx6efteA=",
"path": "github.com/pingcap/parser/types", "path": "github.com/pingcap/parser/types",
"revision": "f20218bc290343c2752c4926c1bf4264343bbef4", "revision": "b7f4816358997259f649a06fd126db3542b644c8",
"revisionTime": "2018-12-12T04:21:31Z" "revisionTime": "2018-12-17T08:17:10Z"
}, },
{ {
"checksumSHA1": "fWqL/7jTYOiqDNmiUcQi3u45Hw0=", "checksumSHA1": "fWqL/7jTYOiqDNmiUcQi3u45Hw0=",
"path": "github.com/pingcap/tidb/sessionctx/stmtctx", "path": "github.com/pingcap/tidb/sessionctx/stmtctx",
"revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", "revision": "ab88f0b1c3b6db829f3e553963673a9bf7752899",
"revisionTime": "2018-12-13T09:52:39Z" "revisionTime": "2018-12-17T12:08:05Z"
}, },
{ {
"checksumSHA1": "0CCq+3fAyaXs9XU+xWaRvbbtSOQ=", "checksumSHA1": "kXyszfR2fQ6bHvuCCFlHRkt1mF0=",
"path": "github.com/pingcap/tidb/types", "path": "github.com/pingcap/tidb/types",
"revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", "revision": "ab88f0b1c3b6db829f3e553963673a9bf7752899",
"revisionTime": "2018-12-13T09:52:39Z" "revisionTime": "2018-12-17T12:08:05Z"
}, },
{ {
"checksumSHA1": "DWVD7+ygtT66IQ+cqXmMJ5OVqUk=", "checksumSHA1": "DWVD7+ygtT66IQ+cqXmMJ5OVqUk=",
"path": "github.com/pingcap/tidb/types/json", "path": "github.com/pingcap/tidb/types/json",
"revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", "revision": "ab88f0b1c3b6db829f3e553963673a9bf7752899",
"revisionTime": "2018-12-13T09:52:39Z" "revisionTime": "2018-12-17T12:08:05Z"
}, },
{ {
"checksumSHA1": "Zp5ME8OXNTmHnYTwJJUZlydN4/U=", "checksumSHA1": "6vi/eCZXqNTa5eAUpxDZet4LPlY=",
"path": "github.com/pingcap/tidb/types/parser_driver", "path": "github.com/pingcap/tidb/types/parser_driver",
"revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", "revision": "ab88f0b1c3b6db829f3e553963673a9bf7752899",
"revisionTime": "2018-12-13T09:52:39Z" "revisionTime": "2018-12-17T12:08:05Z"
}, },
{ {
"checksumSHA1": "s709bhSrG2Ec35406mGtrySid4s=", "checksumSHA1": "s709bhSrG2Ec35406mGtrySid4s=",
"path": "github.com/pingcap/tidb/util/execdetails", "path": "github.com/pingcap/tidb/util/execdetails",
"revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", "revision": "ab88f0b1c3b6db829f3e553963673a9bf7752899",
"revisionTime": "2018-12-13T09:52:39Z" "revisionTime": "2018-12-17T12:08:05Z"
}, },
{ {
"checksumSHA1": "nUC7zVoAMNR2a+z2iGqHoN2AkFE=", "checksumSHA1": "nUC7zVoAMNR2a+z2iGqHoN2AkFE=",
"path": "github.com/pingcap/tidb/util/hack", "path": "github.com/pingcap/tidb/util/hack",
"revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", "revision": "ab88f0b1c3b6db829f3e553963673a9bf7752899",
"revisionTime": "2018-12-13T09:52:39Z" "revisionTime": "2018-12-17T12:08:05Z"
}, },
{ {
"checksumSHA1": "xSyepiuqsoaaeDch7cXeumvVHKM=", "checksumSHA1": "xSyepiuqsoaaeDch7cXeumvVHKM=",
"path": "github.com/pingcap/tidb/util/memory", "path": "github.com/pingcap/tidb/util/memory",
"revision": "4ccd7456fcdc5e62e68f49a0a542cbcf88e38343", "revision": "ab88f0b1c3b6db829f3e553963673a9bf7752899",
"revisionTime": "2018-12-13T09:52:39Z" "revisionTime": "2018-12-17T12:08:05Z"
}, },
{ {
"checksumSHA1": "SmYeIK/fIYXNu8IKxD6HOVQVTuU=", "checksumSHA1": "SmYeIK/fIYXNu8IKxD6HOVQVTuU=",
...@@ -401,62 +401,62 @@ ...@@ -401,62 +401,62 @@
{ {
"checksumSHA1": "aKn1oKcY74N8TRLm3Ayt7Q4bbI4=", "checksumSHA1": "aKn1oKcY74N8TRLm3Ayt7Q4bbI4=",
"path": "vitess.io/vitess/go/bytes2", "path": "vitess.io/vitess/go/bytes2",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "JVCEN4UGRmg3TofIBdzZMZ3G0Ww=", "checksumSHA1": "JVCEN4UGRmg3TofIBdzZMZ3G0Ww=",
"path": "vitess.io/vitess/go/hack", "path": "vitess.io/vitess/go/hack",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "e1WJ7vCnVrlQQQlc6n/FewCDMso=", "checksumSHA1": "F5pcGq+2W1FHEjgktTdKOE6W8mk=",
"path": "vitess.io/vitess/go/sqltypes", "path": "vitess.io/vitess/go/sqltypes",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "ntFIQYkBS51G6y+FEkjFW40+HOU=", "checksumSHA1": "ntFIQYkBS51G6y+FEkjFW40+HOU=",
"path": "vitess.io/vitess/go/vt/log", "path": "vitess.io/vitess/go/vt/log",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "tPQFPwbMdjuX0qjNl4Zl8zc37JQ=", "checksumSHA1": "tPQFPwbMdjuX0qjNl4Zl8zc37JQ=",
"path": "vitess.io/vitess/go/vt/proto/query", "path": "vitess.io/vitess/go/vt/proto/query",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "o0tR/c7lgr0pLkxk7CdvjiNDAKU=", "checksumSHA1": "o0tR/c7lgr0pLkxk7CdvjiNDAKU=",
"path": "vitess.io/vitess/go/vt/proto/topodata", "path": "vitess.io/vitess/go/vt/proto/topodata",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "77UojBqi0yyeQvR70j7C3kcKclQ=", "checksumSHA1": "77UojBqi0yyeQvR70j7C3kcKclQ=",
"path": "vitess.io/vitess/go/vt/proto/vtgate", "path": "vitess.io/vitess/go/vt/proto/vtgate",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "QpWGhoVDwM+8+sgYLI/YU+95iGU=", "checksumSHA1": "QpWGhoVDwM+8+sgYLI/YU+95iGU=",
"path": "vitess.io/vitess/go/vt/proto/vtrpc", "path": "vitess.io/vitess/go/vt/proto/vtrpc",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "lENrUY/YyxwYFHYN+21TBH92P3U=", "checksumSHA1": "lENrUY/YyxwYFHYN+21TBH92P3U=",
"path": "vitess.io/vitess/go/vt/sqlparser", "path": "vitess.io/vitess/go/vt/sqlparser",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
}, },
{ {
"checksumSHA1": "oF4XzuOzwvj1iduX/lYqNSyY/HM=", "checksumSHA1": "Jx+gOh/kiBDSZxEIWHyYn9brjdo=",
"path": "vitess.io/vitess/go/vt/vterrors", "path": "vitess.io/vitess/go/vt/vterrors",
"revision": "eb5a5e0e435db30856600b794d8cff235fdf24b7", "revision": "935bf8ac1ad1e75bc8fd26a74fbfc906f15aa7d0",
"revisionTime": "2018-12-13T22:28:01Z" "revisionTime": "2018-12-17T04:01:44Z"
} }
], ],
"rootPath": "github.com/XiaoMi/soar" "rootPath": "github.com/XiaoMi/soar"
......
...@@ -16,7 +16,9 @@ limitations under the License. ...@@ -16,7 +16,9 @@ limitations under the License.
package sqltypes package sqltypes
import "reflect" import (
"vitess.io/vitess/go/vt/vterrors"
)
// QueryResponse represents a query response for ExecuteBatch. // QueryResponse represents a query response for ExecuteBatch.
type QueryResponse struct { type QueryResponse struct {
...@@ -34,7 +36,7 @@ func QueryResponsesEqual(r1, r2 []QueryResponse) bool { ...@@ -34,7 +36,7 @@ func QueryResponsesEqual(r1, r2 []QueryResponse) bool {
if !r.QueryResult.Equal(r2[i].QueryResult) { if !r.QueryResult.Equal(r2[i].QueryResult) {
return false return false
} }
if !reflect.DeepEqual(r.QueryError, r2[i].QueryError) { if !vterrors.Equals(r.QueryError, r2[i].QueryError) {
return false return false
} }
} }
......
Copyright (c) 2015, Dave Cheney <dave@cheney.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
Copyright 2017 Google 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 agreedto in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package vterrors provides helpers for propagating internal errors
// through the Vitess system (including across RPC boundaries) in a
// structured way.
package vterrors
/*
Vitess uses canonical error codes for error reporting. This is based
on years of industry experience with error reporting. This idea is
that errors should be classified into a small set of errors (10 or so)
with very specific meaning. Each error has a code, and a message. When
errors are passed around (even through RPCs), the code is
propagated. To handle errors, only the code should be looked at (and
not string-matching on the error message).
Vitess defines the error codes in /proto/vtrpc.proto. Along with an
RPCError message that can be used to transmit errors through RPCs, in
the message payloads. These codes match the names and numbers defined
by gRPC.
Vitess also defines a standardized error implementation that allows
you to build an error with an associated canonical code.
While sending an error through gRPC, these codes are transmitted
using gRPC's error propagation mechanism and decoded back to
the original code on the other end.
*/
package vterrors
/* This file is copied from https://github.com/pkg/errors/blob/v0.8.0/stack.go */
import (
"fmt"
"io"
"path"
"runtime"
"strings"
)
// Frame represents a program counter inside a stack frame.
type Frame uintptr
// pc returns the program counter for this frame;
// multiple frames may have the same PC value.
func (f Frame) pc() uintptr { return uintptr(f) - 1 }
// file returns the full path to the file that contains the
// function for this Frame's pc.
func (f Frame) file() string {
fn := runtime.FuncForPC(f.pc())
if fn == nil {
return "unknown"
}
file, _ := fn.FileLine(f.pc())
return file
}
// line returns the line number of source code of the
// function for this Frame's pc.
func (f Frame) line() int {
fn := runtime.FuncForPC(f.pc())
if fn == nil {
return 0
}
_, line := fn.FileLine(f.pc())
return line
}
// Format formats the frame according to the fmt.Formatter interface.
//
// %s source file
// %d source line
// %n function name
// %v equivalent to %s:%d
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+s path of source file relative to the compile time GOPATH
// %+v equivalent to %+s:%d
func (f Frame) Format(s fmt.State, verb rune) {
switch verb {
case 's':
switch {
case s.Flag('+'):
pc := f.pc()
fn := runtime.FuncForPC(pc)
if fn == nil {
io.WriteString(s, "unknown")
} else {
file, _ := fn.FileLine(pc)
fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
}
default:
io.WriteString(s, path.Base(f.file()))
}
case 'd':
fmt.Fprintf(s, "%d", f.line())
case 'n':
name := runtime.FuncForPC(f.pc()).Name()
io.WriteString(s, funcname(name))
case 'v':
f.Format(s, 's')
io.WriteString(s, ":")
f.Format(s, 'd')
}
}
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
type StackTrace []Frame
// Format format the stacktrace according to the fmt.Formatter interface.
//
// %s source file
// %d source line
// %n function name
// %v equivalent to %s:%d
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+s path of source file relative to the compile time GOPATH
// %+v equivalent to %+s:%d
func (st StackTrace) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case s.Flag('+'):
for _, f := range st {
fmt.Fprintf(s, "\n%+v", f)
}
case s.Flag('#'):
fmt.Fprintf(s, "%#v", []Frame(st))
default:
fmt.Fprintf(s, "%v", []Frame(st))
}
case 's':
fmt.Fprintf(s, "%s", []Frame(st))
}
}
// stack represents a stack of program counters.
type stack []uintptr
func (s *stack) Format(st fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case st.Flag('+'):
for _, pc := range *s {
f := Frame(pc)
fmt.Fprintf(st, "\n%+v", f)
}
}
}
}
func (s *stack) StackTrace() StackTrace {
f := make([]Frame, len(*s))
for i := 0; i < len(f); i++ {
f[i] = Frame((*s)[i])
}
return f
}
func callers() *stack {
const depth = 32
var pcs [depth]uintptr
n := runtime.Callers(3, pcs[:])
var st stack = pcs[0:n]
return &st
}
// funcname removes the path prefix component of a function's name reported by func.Name().
func funcname(name string) string {
i := strings.LastIndex(name, "/")
name = name[i+1:]
i = strings.Index(name, ".")
return name[i+1:]
}
func trimGOPATH(name, file string) string {
// Here we want to get the source file path relative to the compile time
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
// GOPATH at runtime, but we can infer the number of path segments in the
// GOPATH. We note that fn.Name() returns the function name qualified by
// the import path, which does not include the GOPATH. Thus we can trim
// segments from the beginning of the file path until the number of path
// separators remaining is one more than the number of path separators in
// the function name. For example, given:
//
// GOPATH /home/user
// file /home/user/src/pkg/sub/file.go
// fn.Name() pkg/sub.Type.Method
//
// We want to produce:
//
// pkg/sub/file.go
//
// From this we can easily see that fn.Name() has one less path separator
// than our desired output. We count separators from the end of the file
// path until it finds two more than in the function name and then move
// one character forward to preserve the initial path segment without a
// leading separator.
const sep = "/"
goal := strings.Count(name, sep) + 2
i := len(file)
for n := 0; n < goal; n++ {
i = strings.LastIndex(file[:i], sep)
if i == -1 {
// not enough separators found, set i so that the slice expression
// below leaves file unmodified
i = -len(sep)
break
}
}
// get back to 0 or trim the leading separator
file = file[i+len(sep):]
return file
}
/* // Package vterrors provides simple error handling primitives for Vitess
Copyright 2017 Google Inc. //
// In all Vitess code, errors should be propagated using vterrors.Wrapf()
Licensed under the Apache License, Version 2.0 (the "License"); // and not fmt.Errorf().
you may not use this file except in compliance with the License. //
You may obtain a copy of the License at // New errors should be created using vterrors.New
//
http://www.apache.org/licenses/LICENSE-2.0 // Vitess uses canonical error codes for error reporting. This is based
// on years of industry experience with error reporting. This idea is
Unless required by applicable law or agreedto in writing, software // that errors should be classified into a small set of errors (10 or so)
distributed under the License is distributed on an "AS IS" BASIS, // with very specific meaning. Each error has a code, and a message. When
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // errors are passed around (even through RPCs), the code is
See the License for the specific language governing permissions and // propagated. To handle errors, only the code should be looked at (and
limitations under the License. // not string-matching on the error message).
*/ //
// Error codes are defined in /proto/vtrpc.proto. Along with an
// RPCError message that can be used to transmit errors through RPCs, in
// the message payloads. These codes match the names and numbers defined
// by gRPC.
//
// A standardized error implementation that allows you to build an error
// with an associated canonical code is also defined.
// While sending an error through gRPC, these codes are transmitted
// using gRPC's error propagation mechanism and decoded back to
// the original code on the other end.
//
// Retrieving the cause of an error
//
// Using vterrors.Wrap constructs a stack of errors, adding context to the
// preceding error. Depending on the nature of the error it may be necessary
// to reverse the operation of errors.Wrap to retrieve the original error
// for inspection. Any error value which implements this interface
//
// type causer interface {
// Cause() error
// }
//
// can be inspected by vterrors.Cause and vterrors.RootCause.
//
// * vterrors.Cause will find the immediate cause if one is available, or nil
// if the error is not a `causer` or if no cause is available.
// * vterrors.RootCause will recursively retrieve
// the topmost error which does not implement causer, which is assumed to be
// the original cause. For example:
//
// switch err := errors.RootCause(err).(type) {
// case *MyError:
// // handle specifically
// default:
// // unknown error
// }
//
// causer interface is not exported by this package, but is considered a part
// of stable public API.
//
// Formatted printing of errors
//
// All error values returned from this package implement fmt.Formatter and can
// be formatted by the fmt package. The following verbs are supported
//
// %s print the error. If the error has a Cause it will be
// printed recursively
// %v see %s
// %+v extended format. Each Frame of the error's StackTrace will
// be printed in detail.
//
// Most but not all of the code in this file was originally copied from
// https://github.com/pkg/errors/blob/v0.8.0/errors.go
package vterrors package vterrors
import ( import (
"fmt" "fmt"
"golang.org/x/net/context" "golang.org/x/net/context"
"io"
vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
) )
type vtError struct { // New returns an error with the supplied message.
code vtrpcpb.Code // New also records the stack trace at the point it was called.
err string func New(code vtrpcpb.Code, message string) error {
return &fundamental{
msg: message,
code: code,
stack: callers(),
}
} }
// New creates a new error using the code and input string. // NewWithoutCode returns an error when no applicable error code is available
func New(code vtrpcpb.Code, in string) error { // It will record the stack trace when creating the error
if code == vtrpcpb.Code_OK { func NewWithoutCode(message string) error {
panic("OK is an invalid error code; use INTERNAL instead") return &fundamental{
} msg: message,
return &vtError{ code: vtrpcpb.Code_UNKNOWN,
code: code, stack: callers(),
err: in,
} }
} }
// Wrap wraps the given error, returning a new error with the given message as a prefix but with the same error code (if err was a vterror) and message of the passed error. // Errorf formats according to a format specifier and returns the string
func Wrap(err error, message string) error { // as a value that satisfies error.
return New(Code(err), fmt.Sprintf("%v: %v", message, err.Error())) // Errorf also records the stack trace at the point it was called.
func Errorf(code vtrpcpb.Code, format string, args ...interface{}) error {
return &fundamental{
msg: fmt.Sprintf(format, args...),
code: code,
stack: callers(),
}
} }
// Wrapf wraps the given error, returning a new error with the given format string as a prefix but with the same error code (if err was a vterror) and message of the passed error. // fundamental is an error that has a message and a stack, but no caller.
func Wrapf(err error, format string, args ...interface{}) error { type fundamental struct {
return Wrap(err, fmt.Sprintf(format, args...)) msg string
code vtrpcpb.Code
*stack
} }
// Errorf returns a new error built using Printf style arguments. func (f *fundamental) Error() string { return f.msg }
func Errorf(code vtrpcpb.Code, format string, args ...interface{}) error {
return New(code, fmt.Sprintf(format, args...))
}
func (e *vtError) Error() string { func (f *fundamental) Format(s fmt.State, verb rune) {
return e.err switch verb {
case 'v':
if s.Flag('+') {
io.WriteString(s, "Code: "+f.code.String()+"\n")
io.WriteString(s, f.msg+"\n")
f.stack.Format(s, verb)
return
}
fallthrough
case 's':
io.WriteString(s, f.msg)
case 'q':
fmt.Fprintf(s, "%q", f.msg)
}
} }
// Code returns the error code if it's a vtError. // Code returns the error code if it's a vtError.
// If err is nil, it returns ok. Otherwise, it returns unknown. // If err is nil, it returns ok.
func Code(err error) vtrpcpb.Code { func Code(err error) vtrpcpb.Code {
if err == nil { if err == nil {
return vtrpcpb.Code_OK return vtrpcpb.Code_OK
} }
if err, ok := err.(*vtError); ok { if err, ok := err.(*fundamental); ok {
return err.code return err.code
} }
cause := Cause(err)
if cause != err && cause != nil {
// If we did not find an error code at the outer level, let's find the cause and check it's code
return Code(cause)
}
// Handle some special cases. // Handle some special cases.
switch err { switch err {
case context.Canceled: case context.Canceled:
...@@ -78,16 +158,111 @@ func Code(err error) vtrpcpb.Code { ...@@ -78,16 +158,111 @@ func Code(err error) vtrpcpb.Code {
return vtrpcpb.Code_UNKNOWN return vtrpcpb.Code_UNKNOWN
} }
// Wrap returns an error annotating err with a stack trace
// at the point Wrap is called, and the supplied message.
// If err is nil, Wrap returns nil.
func Wrap(err error, message string) error {
if err == nil {
return nil
}
return &wrapping{
cause: err,
msg: message,
stack: callers(),
}
}
// Wrapf returns an error annotating err with a stack trace
// at the point Wrapf is call, and the format specifier.
// If err is nil, Wrapf returns nil.
func Wrapf(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}
return &wrapping{
cause: err,
msg: fmt.Sprintf(format, args...),
stack: callers(),
}
}
type wrapping struct {
cause error
msg string
stack *stack
}
func (w *wrapping) Error() string { return w.msg + ": " + w.cause.Error() }
func (w *wrapping) Cause() error { return w.cause }
func (w *wrapping) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
fmt.Fprintf(s, "%+v\n", w.Cause())
io.WriteString(s, w.msg)
w.stack.Format(s, verb)
return
}
fallthrough
case 's', 'q':
io.WriteString(s, w.Error())
}
}
// RootCause returns the underlying cause of the error, if possible.
// An error value has a cause if it implements the following
// interface:
//
// type causer interface {
// Cause() error
// }
//
// If the error does not implement Cause, the original error will
// be returned. If the error is nil, nil will be returned without further
// investigation.
func RootCause(err error) error {
for {
cause := Cause(err)
if cause == nil {
return err
}
err = cause
}
}
//
// Cause will return the immediate cause, if possible.
// An error value has a cause if it implements the following
// interface:
//
// type causer interface {
// Cause() error
// }
// If the error does not implement Cause, nil will be returned
func Cause(err error) error {
type causer interface {
Cause() error
}
causerObj, ok := err.(causer)
if !ok {
return nil
}
return causerObj.Cause()
}
// Equals returns true iff the error message and the code returned by Code() // Equals returns true iff the error message and the code returned by Code()
// is equal. // are equal.
func Equals(a, b error) bool { func Equals(a, b error) bool {
if a == nil && b == nil { if a == nil && b == nil {
// Both are nil. // Both are nil.
return true return true
} }
if a == nil && b != nil || a != nil && b == nil { if a == nil || b == nil {
// One of the two is nil. // One of the two is nil, since we know both are not nil.
return false return false
} }
...@@ -97,5 +272,5 @@ func Equals(a, b error) bool { ...@@ -97,5 +272,5 @@ func Equals(a, b error) bool {
// Print is meant to print the vtError object in test failures. // Print is meant to print the vtError object in test failures.
// For comparing two vterrors, use Equals() instead. // For comparing two vterrors, use Equals() instead.
func Print(err error) string { func Print(err error) string {
return fmt.Sprintf("%v: %v", Code(err), err.Error()) return fmt.Sprintf("%v: %v\n", Code(err), err.Error())
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册