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

update vendor & fix spell error

上级 6474f630
...@@ -17,7 +17,7 @@ VERSION_TAG := $(shell git describe --tags --always) ...@@ -17,7 +17,7 @@ VERSION_TAG := $(shell git describe --tags --always)
VERSION_VERSION := $(shell git log --date=iso --pretty=format:"%cd" -1) $(VERSION_TAG) VERSION_VERSION := $(shell git log --date=iso --pretty=format:"%cd" -1) $(VERSION_TAG)
VERSION_COMPILE := $(shell date +"%F %T %z") by $(shell go version) VERSION_COMPILE := $(shell date +"%F %T %z") by $(shell go version)
VERSION_BRANCH := $(shell git rev-parse --abbrev-ref HEAD) VERSION_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
VERSION_GIT_DIRTY := $(shell git diff --no-ext-diff 2>/dev/null | wc -l) VERSION_GIT_DIRTY := $(shell git diff --no-ext-diff 2>/dev/null | wc -l | awk '{print 1}')
VERSION_DEV_PATH:= $(shell pwd) VERSION_DEV_PATH:= $(shell pwd)
LDFLAGS=-ldflags="-s -w -X 'github.com/XiaoMi/soar/common.Version=$(VERSION_VERSION)' -X 'github.com/XiaoMi/soar/common.Compile=$(VERSION_COMPILE)' -X 'github.com/XiaoMi/soar/common.Branch=$(VERSION_BRANCH)' -X github.com/XiaoMi/soar/common.GitDirty=$(VERSION_GIT_DIRTY) -X github.com/XiaoMi/soar/common.DevPath=$(VERSION_DEV_PATH)" LDFLAGS=-ldflags="-s -w -X 'github.com/XiaoMi/soar/common.Version=$(VERSION_VERSION)' -X 'github.com/XiaoMi/soar/common.Compile=$(VERSION_COMPILE)' -X 'github.com/XiaoMi/soar/common.Branch=$(VERSION_BRANCH)' -X github.com/XiaoMi/soar/common.GitDirty=$(VERSION_GIT_DIRTY) -X github.com/XiaoMi/soar/common.DevPath=$(VERSION_DEV_PATH)"
......
...@@ -154,7 +154,7 @@ func SchemaMetaInfo(sql string, defaultDatabase string) []string { ...@@ -154,7 +154,7 @@ func SchemaMetaInfo(sql string, defaultDatabase string) []string {
tb := gjson.Get(table.String(), "Name.O") tb := gjson.Get(table.String(), "Name.O")
if db.String() == "" { if db.String() == "" {
if tb.String() != "" { if tb.String() != "" {
tables = append(tables, fmt.Sprintf("`%s`.%s`", defaultDatabase, tb.String())) tables = append(tables, fmt.Sprintf("`%s`.`%s`", defaultDatabase, tb.String()))
} }
} else { } else {
if tb.String() != "" { if tb.String() != "" {
...@@ -177,7 +177,7 @@ func SchemaMetaInfo(sql string, defaultDatabase string) []string { ...@@ -177,7 +177,7 @@ func SchemaMetaInfo(sql string, defaultDatabase string) []string {
tb := gjson.Get(table, "Name.O") tb := gjson.Get(table, "Name.O")
if db.String() == "" { if db.String() == "" {
if tb.String() != "" { if tb.String() != "" {
tables = append(tables, fmt.Sprintf("`%s`.%s`", defaultDatabase, tb.String())) tables = append(tables, fmt.Sprintf("`%s`.`%s`", defaultDatabase, tb.String()))
} }
} else { } else {
if tb.String() != "" { if tb.String() != "" {
......
# Parser # Parser - A MySQL Compatible SQL Parser
[![Go Report Card](https://goreportcard.com/badge/github.com/pingcap/parser)](https://goreportcard.com/report/github.com/pingcap/parser) [![CircleCI Status](https://circleci.com/gh/pingcap/parser.svg?style=shield)](https://circleci.com/gh/pingcap/parser) [![GoDoc](https://godoc.org/github.com/pingcap/parser?status.svg)](https://godoc.org/github.com/pingcap/parser) [![Go Report Card](https://goreportcard.com/badge/github.com/pingcap/parser)](https://goreportcard.com/report/github.com/pingcap/parser)
[![CircleCI Status](https://circleci.com/gh/pingcap/parser.svg?style=shield)](https://circleci.com/gh/pingcap/parser)
[![GoDoc](https://godoc.org/github.com/pingcap/parser?status.svg)](https://godoc.org/github.com/pingcap/parser)
[![codecov](https://codecov.io/gh/pingcap/parser/branch/master/graph/badge.svg)](https://codecov.io/gh/pingcap/parser) [![codecov](https://codecov.io/gh/pingcap/parser/branch/master/graph/badge.svg)](https://codecov.io/gh/pingcap/parser)
TiDB SQL Parser The goal of this project is to build a Golang parser that is fully compatible with MySQL syntax, easy to extend, and high performance. Currently, features supported by parser are as follows:
## How to use it - Highly compatible with MySQL: it supports almost all features of MySQL. For the complete details, see [parser.y](https://github.com/pingcap/parser/blob/master/parser.y) and [hintparser.y](https://github.com/pingcap/parser/blob/master/hintparser.y).
- Extensible: adding a new syntax requires only a few lines of Yacc and Golang code changes. As an example, see [PR-680](https://github.com/pingcap/parser/pull/680/files).
```go - Good performance: the parser is generated by goyacc in a bottom-up approach. It is efficient to build an AST tree with a state machine.
import (
"fmt"
"github.com/pingcap/parser"
_ "github.com/pingcap/tidb/types/parser_driver"
)
// This example show how to parse a text sql into ast.
func example() {
// 0. make sure import parser_driver implemented by TiDB(user also can implement own driver by self).
// and add `import _ "github.com/pingcap/tidb/types/parser_driver"` in the head of file.
// 1. Create a parser. The parser is NOT goroutine safe and should
// not be shared among multiple goroutines. However, parser is also
// heavy, so each goroutine should reuse its own local instance if
// possible.
p := parser.New()
// 2. Parse a text SQL into AST([]ast.StmtNode). ## How to use it
stmtNodes, _, err := p.Parse("select * from tbl where id = 1", "", "")
// 3. Use AST to do cool things.
fmt.Println(stmtNodes[0], err)
}
```
See [https://godoc.org/github.com/pingcap/parser](https://godoc.org/github.com/pingcap/parser)
## How to update parser for TiDB
Assuming that you want to file a PR (pull request) to TiDB, and your PR includes a change in the parser, follow these steps to update the parser in TiDB.
### Step 1: Make changes in your parser repository Please read the [quickstart](https://github.com/pingcap/parser/blob/master/docs/quickstart.md).
Fork this repository to your own account and commit the changes to your repository. ## Future
> **Note:** - Support more MySQL syntax
> - Optimize the code structure, make it easier to extend
> - Don't forget to run `make test` before you commit! - Improve performance and benchmark
> - Make sure `parser.go` is updated. - Improve the quality of code and comments
Suppose the forked repository is `https://github.com/your-repo/parser`. ## Getting Help
### Step 2: Make your parser changes take effect in TiDB and run CI - [GitHub Issue](https://github.com/pingcap/parser/issues)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/tidb)
- [User Group (Chinese)](https://asktug.com/)
1. In your TiDB repository, execute the `replace` instruction to make your parser changes take effect: If you have any questions, feel free to join and discuss in #sig-ddl channel of [Slack-community](https://pingcap.com/tidbslack/).
``` If you want to join as a special interest group member, see [DDL Special Interest Group](https://github.com/pingcap/community/tree/master/special-interest-groups/sig-ddl).
GO111MODULE=on go mod edit -replace github.com/pingcap/parser=github.com/your-repo/parser@your-branch
```
2. `make dev` to run CI in TiDB. ## Users
3. File a PR to TiDB. These projects use this parser. Please feel free to extend this list if you
found you are one of the users but not listed here:
### Step 3: Merge the PR about the parser to this repository - [pingcap/tidb](https://github.com/pingcap/tidb)
- [XiaoMi/soar](https://github.com/XiaoMi/soar)
- [XiaoMi/Gaea](https://github.com/XiaoMi/Gaea)
- [sql-machine-learning/sqlflow](https://github.com/sql-machine-learning/sqlflow)
File a PR to this repository. **Link the related PR in TiDB in your PR description or comment.** ## Contributing
This PR will be reviewed, and if everything goes well, it will be merged. Contributions are welcomed and greatly appreciated. See [CONTRIBUTING.md](https://github.com/pingcap/community/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
### Step 4: Update TiDB to use the latest parser Here is how to [update parser for TiDB](https://github.com/pingcap/parser/blob/master/docs/update-parser-for-tidb.md).
In your TiDB pull request, modify the `go.mod` file manually or use this command: ## Acknowledgments
``` Thanks [cznic](https://github.com/cznic) for providing some great open-source tools.
GO111MODULE=on go get -u github.com/pingcap/parser@master
```
Make sure the `replace` instruction is changed back to the `require` instruction and the version is the latest. ## License
Parser is under the Apache 2.0 license. See the LICENSE file for details.
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
package ast package ast
import ( import (
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
) )
var _ StmtNode = &IndexAdviseStmt{} var _ StmtNode = &IndexAdviseStmt{}
...@@ -31,7 +31,7 @@ type IndexAdviseStmt struct { ...@@ -31,7 +31,7 @@ type IndexAdviseStmt struct {
} }
// Restore implements Node Accept interface. // Restore implements Node Accept interface.
func (n *IndexAdviseStmt) Restore(ctx *RestoreCtx) error { func (n *IndexAdviseStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("INDEX ADVISE ") ctx.WriteKeyWord("INDEX ADVISE ")
if n.IsLocal { if n.IsLocal {
ctx.WriteKeyWord("LOCAL ") ctx.WriteKeyWord("LOCAL ")
...@@ -66,7 +66,7 @@ type MaxIndexNumClause struct { ...@@ -66,7 +66,7 @@ type MaxIndexNumClause struct {
} }
// Restore for max index num clause // Restore for max index num clause
func (n *MaxIndexNumClause) Restore(ctx *RestoreCtx) error { func (n *MaxIndexNumClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(" MAX_IDXNUM") ctx.WriteKeyWord(" MAX_IDXNUM")
if n.PerTable != UnspecifiedSize { if n.PerTable != UnspecifiedSize {
ctx.WriteKeyWord(" PER_TABLE ") ctx.WriteKeyWord(" PER_TABLE ")
......
...@@ -18,7 +18,7 @@ package ast ...@@ -18,7 +18,7 @@ package ast
import ( import (
"io" "io"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
"github.com/pingcap/parser/types" "github.com/pingcap/parser/types"
) )
...@@ -27,7 +27,7 @@ import ( ...@@ -27,7 +27,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(ctx *RestoreCtx) error Restore(ctx *format.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.
......
...@@ -16,7 +16,7 @@ package ast ...@@ -16,7 +16,7 @@ package ast
import ( import (
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/auth" "github.com/pingcap/parser/auth"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql" "github.com/pingcap/parser/mysql"
"github.com/pingcap/parser/terror" "github.com/pingcap/parser/terror"
...@@ -71,7 +71,7 @@ type DatabaseOption struct { ...@@ -71,7 +71,7 @@ type DatabaseOption struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DatabaseOption) Restore(ctx *RestoreCtx) error { func (n *DatabaseOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp { switch n.Tp {
case DatabaseOptionCharset: case DatabaseOptionCharset:
ctx.WriteKeyWord("CHARACTER SET") ctx.WriteKeyWord("CHARACTER SET")
...@@ -102,7 +102,7 @@ type CreateDatabaseStmt struct { ...@@ -102,7 +102,7 @@ type CreateDatabaseStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *CreateDatabaseStmt) Restore(ctx *RestoreCtx) error { func (n *CreateDatabaseStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CREATE DATABASE ") ctx.WriteKeyWord("CREATE DATABASE ")
if n.IfNotExists { if n.IfNotExists {
ctx.WriteKeyWord("IF NOT EXISTS ") ctx.WriteKeyWord("IF NOT EXISTS ")
...@@ -139,7 +139,7 @@ type AlterDatabaseStmt struct { ...@@ -139,7 +139,7 @@ type AlterDatabaseStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *AlterDatabaseStmt) Restore(ctx *RestoreCtx) error { func (n *AlterDatabaseStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ALTER DATABASE") ctx.WriteKeyWord("ALTER DATABASE")
if !n.AlterDefaultDatabase { if !n.AlterDefaultDatabase {
ctx.WritePlain(" ") ctx.WritePlain(" ")
...@@ -175,7 +175,7 @@ type DropDatabaseStmt struct { ...@@ -175,7 +175,7 @@ type DropDatabaseStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DropDatabaseStmt) Restore(ctx *RestoreCtx) error { func (n *DropDatabaseStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DROP DATABASE ") ctx.WriteKeyWord("DROP DATABASE ")
if n.IfExists { if n.IfExists {
ctx.WriteKeyWord("IF EXISTS ") ctx.WriteKeyWord("IF EXISTS ")
...@@ -204,7 +204,7 @@ type IndexPartSpecification struct { ...@@ -204,7 +204,7 @@ type IndexPartSpecification struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *IndexPartSpecification) Restore(ctx *RestoreCtx) error { func (n *IndexPartSpecification) Restore(ctx *format.RestoreCtx) error {
if n.Expr != nil { if n.Expr != nil {
ctx.WritePlain("(") ctx.WritePlain("(")
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
...@@ -269,7 +269,7 @@ type ReferenceDef struct { ...@@ -269,7 +269,7 @@ type ReferenceDef struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ReferenceDef) Restore(ctx *RestoreCtx) error { func (n *ReferenceDef) Restore(ctx *format.RestoreCtx) error {
if n.Table != nil { if n.Table != nil {
ctx.WriteKeyWord("REFERENCES ") ctx.WriteKeyWord("REFERENCES ")
if err := n.Table.Restore(ctx); err != nil { if err := n.Table.Restore(ctx); err != nil {
...@@ -385,7 +385,7 @@ type OnDeleteOpt struct { ...@@ -385,7 +385,7 @@ type OnDeleteOpt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *OnDeleteOpt) Restore(ctx *RestoreCtx) error { func (n *OnDeleteOpt) Restore(ctx *format.RestoreCtx) error {
if n.ReferOpt != ReferOptionNoOption { if n.ReferOpt != ReferOptionNoOption {
ctx.WriteKeyWord("ON DELETE ") ctx.WriteKeyWord("ON DELETE ")
ctx.WriteKeyWord(n.ReferOpt.String()) ctx.WriteKeyWord(n.ReferOpt.String())
...@@ -410,7 +410,7 @@ type OnUpdateOpt struct { ...@@ -410,7 +410,7 @@ type OnUpdateOpt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *OnUpdateOpt) Restore(ctx *RestoreCtx) error { func (n *OnUpdateOpt) Restore(ctx *format.RestoreCtx) error {
if n.ReferOpt != ReferOptionNoOption { if n.ReferOpt != ReferOptionNoOption {
ctx.WriteKeyWord("ON UPDATE ") ctx.WriteKeyWord("ON UPDATE ")
ctx.WriteKeyWord(n.ReferOpt.String()) ctx.WriteKeyWord(n.ReferOpt.String())
...@@ -480,7 +480,7 @@ type ColumnOption struct { ...@@ -480,7 +480,7 @@ type ColumnOption struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ColumnOption) Restore(ctx *RestoreCtx) error { func (n *ColumnOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp { switch n.Tp {
case ColumnOptionNoOption: case ColumnOptionNoOption:
return nil return nil
...@@ -606,7 +606,7 @@ type IndexOption struct { ...@@ -606,7 +606,7 @@ type IndexOption struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *IndexOption) Restore(ctx *RestoreCtx) error { func (n *IndexOption) Restore(ctx *format.RestoreCtx) error {
hasPrevOption := false hasPrevOption := false
if n.KeyBlockSize > 0 { if n.KeyBlockSize > 0 {
ctx.WriteKeyWord("KEY_BLOCK_SIZE") ctx.WriteKeyWord("KEY_BLOCK_SIZE")
...@@ -705,7 +705,7 @@ type Constraint struct { ...@@ -705,7 +705,7 @@ type Constraint struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *Constraint) Restore(ctx *RestoreCtx) error { func (n *Constraint) Restore(ctx *format.RestoreCtx) error {
switch n.Tp { switch n.Tp {
case ConstraintNoConstraint: case ConstraintNoConstraint:
return nil return nil
...@@ -833,7 +833,7 @@ type ColumnDef struct { ...@@ -833,7 +833,7 @@ type ColumnDef struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ColumnDef) Restore(ctx *RestoreCtx) error { func (n *ColumnDef) Restore(ctx *format.RestoreCtx) error {
if err := n.Name.Restore(ctx); err != nil { if err := n.Name.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing ColumnDef Name") return errors.Annotate(err, "An error occurred while splicing ColumnDef Name")
} }
...@@ -909,7 +909,7 @@ type CreateTableStmt struct { ...@@ -909,7 +909,7 @@ type CreateTableStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error { func (n *CreateTableStmt) Restore(ctx *format.RestoreCtx) error {
if n.IsTemporary { if n.IsTemporary {
ctx.WriteKeyWord("CREATE TEMPORARY TABLE ") ctx.WriteKeyWord("CREATE TEMPORARY TABLE ")
} else { } else {
...@@ -1047,7 +1047,7 @@ type DropTableStmt struct { ...@@ -1047,7 +1047,7 @@ type DropTableStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DropTableStmt) Restore(ctx *RestoreCtx) error { func (n *DropTableStmt) Restore(ctx *format.RestoreCtx) error {
if n.IsView { if n.IsView {
ctx.WriteKeyWord("DROP VIEW ") ctx.WriteKeyWord("DROP VIEW ")
} else { } else {
...@@ -1100,7 +1100,7 @@ type DropSequenceStmt struct { ...@@ -1100,7 +1100,7 @@ type DropSequenceStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DropSequenceStmt) Restore(ctx *RestoreCtx) error { func (n *DropSequenceStmt) Restore(ctx *format.RestoreCtx) error {
if n.IsTemporary { if n.IsTemporary {
ctx.WriteKeyWord("DROP TEMPORARY SEQUENCE ") ctx.WriteKeyWord("DROP TEMPORARY SEQUENCE ")
} else { } else {
...@@ -1152,7 +1152,7 @@ type RenameTableStmt struct { ...@@ -1152,7 +1152,7 @@ type RenameTableStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *RenameTableStmt) Restore(ctx *RestoreCtx) error { func (n *RenameTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("RENAME TABLE ") ctx.WriteKeyWord("RENAME TABLE ")
for index, table2table := range n.TableToTables { for index, table2table := range n.TableToTables {
if index != 0 { if index != 0 {
...@@ -1202,7 +1202,7 @@ type TableToTable struct { ...@@ -1202,7 +1202,7 @@ type TableToTable struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *TableToTable) Restore(ctx *RestoreCtx) error { func (n *TableToTable) Restore(ctx *format.RestoreCtx) error {
if err := n.OldTable.Restore(ctx); err != nil { if err := n.OldTable.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore TableToTable.OldTable") return errors.Annotate(err, "An error occurred while restore TableToTable.OldTable")
} }
...@@ -1250,7 +1250,7 @@ type CreateViewStmt struct { ...@@ -1250,7 +1250,7 @@ type CreateViewStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *CreateViewStmt) Restore(ctx *RestoreCtx) error { func (n *CreateViewStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CREATE ") ctx.WriteKeyWord("CREATE ")
if n.OrReplace { if n.OrReplace {
ctx.WriteKeyWord("OR REPLACE ") ctx.WriteKeyWord("OR REPLACE ")
...@@ -1340,7 +1340,7 @@ type CreateSequenceStmt struct { ...@@ -1340,7 +1340,7 @@ type CreateSequenceStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *CreateSequenceStmt) Restore(ctx *RestoreCtx) error { func (n *CreateSequenceStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CREATE ") ctx.WriteKeyWord("CREATE ")
if n.OrReplace { if n.OrReplace {
ctx.WriteKeyWord("OR REPLACE ") ctx.WriteKeyWord("OR REPLACE ")
...@@ -1394,7 +1394,7 @@ type IndexLockAndAlgorithm struct { ...@@ -1394,7 +1394,7 @@ type IndexLockAndAlgorithm struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *IndexLockAndAlgorithm) Restore(ctx *RestoreCtx) error { func (n *IndexLockAndAlgorithm) Restore(ctx *format.RestoreCtx) error {
hasPrevOption := false hasPrevOption := false
if n.AlgorithmTp != AlgorithmTypeDefault { if n.AlgorithmTp != AlgorithmTypeDefault {
ctx.WriteKeyWord("ALGORITHM") ctx.WriteKeyWord("ALGORITHM")
...@@ -1453,7 +1453,7 @@ type CreateIndexStmt struct { ...@@ -1453,7 +1453,7 @@ type CreateIndexStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *CreateIndexStmt) Restore(ctx *RestoreCtx) error { func (n *CreateIndexStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CREATE ") ctx.WriteKeyWord("CREATE ")
switch n.KeyType { switch n.KeyType {
case IndexKeyTypeUnique: case IndexKeyTypeUnique:
...@@ -1549,7 +1549,7 @@ type DropIndexStmt struct { ...@@ -1549,7 +1549,7 @@ type DropIndexStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DropIndexStmt) Restore(ctx *RestoreCtx) error { func (n *DropIndexStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DROP INDEX ") ctx.WriteKeyWord("DROP INDEX ")
if n.IfExists { if n.IfExists {
ctx.WriteKeyWord("IF EXISTS ") ctx.WriteKeyWord("IF EXISTS ")
...@@ -1624,7 +1624,7 @@ func (n *LockTablesStmt) Accept(v Visitor) (Node, bool) { ...@@ -1624,7 +1624,7 @@ func (n *LockTablesStmt) Accept(v Visitor) (Node, bool) {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *LockTablesStmt) Restore(ctx *RestoreCtx) error { func (n *LockTablesStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("LOCK TABLES ") ctx.WriteKeyWord("LOCK TABLES ")
for i, tl := range n.TableLocks { for i, tl := range n.TableLocks {
if i != 0 { if i != 0 {
...@@ -1650,7 +1650,7 @@ func (n *UnlockTablesStmt) Accept(v Visitor) (Node, bool) { ...@@ -1650,7 +1650,7 @@ func (n *UnlockTablesStmt) Accept(v Visitor) (Node, bool) {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *UnlockTablesStmt) Restore(ctx *RestoreCtx) error { func (n *UnlockTablesStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("UNLOCK TABLES") ctx.WriteKeyWord("UNLOCK TABLES")
return nil return nil
} }
...@@ -1680,7 +1680,7 @@ func (n *CleanupTableLockStmt) Accept(v Visitor) (Node, bool) { ...@@ -1680,7 +1680,7 @@ func (n *CleanupTableLockStmt) Accept(v Visitor) (Node, bool) {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *CleanupTableLockStmt) Restore(ctx *RestoreCtx) error { func (n *CleanupTableLockStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ADMIN CLEANUP TABLE LOCK ") ctx.WriteKeyWord("ADMIN CLEANUP TABLE LOCK ")
for i, v := range n.Tables { for i, v := range n.Tables {
if i != 0 { if i != 0 {
...@@ -1721,7 +1721,7 @@ func (n *RepairTableStmt) Accept(v Visitor) (Node, bool) { ...@@ -1721,7 +1721,7 @@ func (n *RepairTableStmt) Accept(v Visitor) (Node, bool) {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *RepairTableStmt) Restore(ctx *RestoreCtx) error { func (n *RepairTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ADMIN REPAIR TABLE ") ctx.WriteKeyWord("ADMIN REPAIR TABLE ")
if err := n.Table.Restore(ctx); err != nil { if err := n.Table.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore RepairTableStmt.table : [%v]", n.Table) return errors.Annotatef(err, "An error occurred while restore RepairTableStmt.table : [%v]", n.Table)
...@@ -1817,7 +1817,7 @@ type TableOption struct { ...@@ -1817,7 +1817,7 @@ type TableOption struct {
TableNames []*TableName TableNames []*TableName
} }
func (n *TableOption) Restore(ctx *RestoreCtx) error { func (n *TableOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp { switch n.Tp {
case TableOptionEngine: case TableOptionEngine:
ctx.WriteKeyWord("ENGINE ") ctx.WriteKeyWord("ENGINE ")
...@@ -2039,7 +2039,7 @@ type SequenceOption struct { ...@@ -2039,7 +2039,7 @@ type SequenceOption struct {
IntValue int64 IntValue int64
} }
func (n *SequenceOption) Restore(ctx *RestoreCtx) error { func (n *SequenceOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp { switch n.Tp {
case SequenceOptionIncrementBy: case SequenceOptionIncrementBy:
ctx.WriteKeyWord("INCREMENT BY ") ctx.WriteKeyWord("INCREMENT BY ")
...@@ -2096,7 +2096,7 @@ type ColumnPosition struct { ...@@ -2096,7 +2096,7 @@ type ColumnPosition struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ColumnPosition) Restore(ctx *RestoreCtx) error { func (n *ColumnPosition) Restore(ctx *format.RestoreCtx) error {
switch n.Tp { switch n.Tp {
case ColumnPositionNone: case ColumnPositionNone:
// do nothing // do nothing
...@@ -2290,7 +2290,7 @@ type AlterOrderItem struct { ...@@ -2290,7 +2290,7 @@ type AlterOrderItem struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *AlterOrderItem) Restore(ctx *RestoreCtx) error { func (n *AlterOrderItem) Restore(ctx *format.RestoreCtx) error {
if err := n.Column.Restore(ctx); err != nil { if err := n.Column.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore AlterOrderItem.Column") return errors.Annotate(err, "An error occurred while restore AlterOrderItem.Column")
} }
...@@ -2301,7 +2301,7 @@ func (n *AlterOrderItem) Restore(ctx *RestoreCtx) error { ...@@ -2301,7 +2301,7 @@ func (n *AlterOrderItem) Restore(ctx *RestoreCtx) error {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error { func (n *AlterTableSpec) Restore(ctx *format.RestoreCtx) error {
switch n.Tp { switch n.Tp {
case AlterTableSetTiFlashReplica: case AlterTableSetTiFlashReplica:
ctx.WriteKeyWord("SET TIFLASH REPLICA ") ctx.WriteKeyWord("SET TIFLASH REPLICA ")
...@@ -2697,7 +2697,7 @@ func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error { ...@@ -2697,7 +2697,7 @@ func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error {
case AlterTableAlterCheck: case AlterTableAlterCheck:
ctx.WriteKeyWord("ALTER CHECK ") ctx.WriteKeyWord("ALTER CHECK ")
ctx.WriteName(n.Constraint.Name) ctx.WriteName(n.Constraint.Name)
if n.Constraint.Enforced == false { if !n.Constraint.Enforced {
ctx.WriteKeyWord(" NOT") ctx.WriteKeyWord(" NOT")
} }
ctx.WriteKeyWord(" ENFORCED") ctx.WriteKeyWord(" ENFORCED")
...@@ -2786,7 +2786,7 @@ type AlterTableStmt struct { ...@@ -2786,7 +2786,7 @@ type AlterTableStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *AlterTableStmt) Restore(ctx *RestoreCtx) error { func (n *AlterTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ALTER TABLE ") ctx.WriteKeyWord("ALTER TABLE ")
if err := n.Table.Restore(ctx); err != nil { if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore AlterTableStmt.Table") return errors.Annotate(err, "An error occurred while restore AlterTableStmt.Table")
...@@ -2835,7 +2835,7 @@ type TruncateTableStmt struct { ...@@ -2835,7 +2835,7 @@ type TruncateTableStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *TruncateTableStmt) Restore(ctx *RestoreCtx) error { func (n *TruncateTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("TRUNCATE TABLE ") ctx.WriteKeyWord("TRUNCATE TABLE ")
if err := n.Table.Restore(ctx); err != nil { if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore TruncateTableStmt.Table") return errors.Annotate(err, "An error occurred while restore TruncateTableStmt.Table")
...@@ -2878,7 +2878,7 @@ type SubPartitionDefinition struct { ...@@ -2878,7 +2878,7 @@ type SubPartitionDefinition struct {
Options []*TableOption Options []*TableOption
} }
func (spd *SubPartitionDefinition) Restore(ctx *RestoreCtx) error { func (spd *SubPartitionDefinition) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("SUBPARTITION ") ctx.WriteKeyWord("SUBPARTITION ")
ctx.WriteName(spd.Name.O) ctx.WriteName(spd.Name.O)
for i, opt := range spd.Options { for i, opt := range spd.Options {
...@@ -2891,7 +2891,7 @@ func (spd *SubPartitionDefinition) Restore(ctx *RestoreCtx) error { ...@@ -2891,7 +2891,7 @@ func (spd *SubPartitionDefinition) Restore(ctx *RestoreCtx) error {
} }
type PartitionDefinitionClause interface { type PartitionDefinitionClause interface {
restore(ctx *RestoreCtx) error restore(ctx *format.RestoreCtx) error
acceptInPlace(v Visitor) bool acceptInPlace(v Visitor) bool
// Validate checks if the clause is consistent with the given options. // Validate checks if the clause is consistent with the given options.
// `pt` can be 0 and `columns` can be -1 to skip checking the clause against // `pt` can be 0 and `columns` can be -1 to skip checking the clause against
...@@ -2901,7 +2901,7 @@ type PartitionDefinitionClause interface { ...@@ -2901,7 +2901,7 @@ type PartitionDefinitionClause interface {
type PartitionDefinitionClauseNone struct{} type PartitionDefinitionClauseNone struct{}
func (n *PartitionDefinitionClauseNone) restore(ctx *RestoreCtx) error { func (n *PartitionDefinitionClauseNone) restore(ctx *format.RestoreCtx) error {
return nil return nil
} }
...@@ -2926,7 +2926,7 @@ type PartitionDefinitionClauseLessThan struct { ...@@ -2926,7 +2926,7 @@ type PartitionDefinitionClauseLessThan struct {
Exprs []ExprNode Exprs []ExprNode
} }
func (n *PartitionDefinitionClauseLessThan) restore(ctx *RestoreCtx) error { func (n *PartitionDefinitionClauseLessThan) restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(" VALUES LESS THAN ") ctx.WriteKeyWord(" VALUES LESS THAN ")
ctx.WritePlain("(") ctx.WritePlain("(")
for i, expr := range n.Exprs { for i, expr := range n.Exprs {
...@@ -2972,7 +2972,7 @@ type PartitionDefinitionClauseIn struct { ...@@ -2972,7 +2972,7 @@ type PartitionDefinitionClauseIn struct {
Values [][]ExprNode Values [][]ExprNode
} }
func (n *PartitionDefinitionClauseIn) restore(ctx *RestoreCtx) error { func (n *PartitionDefinitionClauseIn) restore(ctx *format.RestoreCtx) error {
// we special-case an empty list of values to mean MariaDB's "DEFAULT" clause. // we special-case an empty list of values to mean MariaDB's "DEFAULT" clause.
if len(n.Values) == 0 { if len(n.Values) == 0 {
ctx.WriteKeyWord(" DEFAULT") ctx.WriteKeyWord(" DEFAULT")
...@@ -3050,7 +3050,7 @@ type PartitionDefinitionClauseHistory struct { ...@@ -3050,7 +3050,7 @@ type PartitionDefinitionClauseHistory struct {
Current bool Current bool
} }
func (n *PartitionDefinitionClauseHistory) restore(ctx *RestoreCtx) error { func (n *PartitionDefinitionClauseHistory) restore(ctx *format.RestoreCtx) error {
if n.Current { if n.Current {
ctx.WriteKeyWord(" CURRENT") ctx.WriteKeyWord(" CURRENT")
} else { } else {
...@@ -3097,7 +3097,7 @@ func (n *PartitionDefinition) acceptInPlace(v Visitor) bool { ...@@ -3097,7 +3097,7 @@ func (n *PartitionDefinition) acceptInPlace(v Visitor) bool {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *PartitionDefinition) Restore(ctx *RestoreCtx) error { func (n *PartitionDefinition) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("PARTITION ") ctx.WriteKeyWord("PARTITION ")
ctx.WriteName(n.Name.O) ctx.WriteName(n.Name.O)
...@@ -3151,7 +3151,7 @@ type PartitionMethod struct { ...@@ -3151,7 +3151,7 @@ type PartitionMethod struct {
} }
// Restore implements the Node interface // Restore implements the Node interface
func (n *PartitionMethod) Restore(ctx *RestoreCtx) error { func (n *PartitionMethod) Restore(ctx *format.RestoreCtx) error {
if n.Linear { if n.Linear {
ctx.WriteKeyWord("LINEAR ") ctx.WriteKeyWord("LINEAR ")
} }
...@@ -3282,7 +3282,7 @@ func (n *PartitionOptions) Validate() error { ...@@ -3282,7 +3282,7 @@ func (n *PartitionOptions) Validate() error {
return nil return nil
} }
func (n *PartitionOptions) Restore(ctx *RestoreCtx) error { func (n *PartitionOptions) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("PARTITION BY ") ctx.WriteKeyWord("PARTITION BY ")
if err := n.PartitionMethod.Restore(ctx); err != nil { if err := n.PartitionMethod.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore PartitionOptions.PartitionMethod") return errors.Annotate(err, "An error occurred while restore PartitionOptions.PartitionMethod")
...@@ -3351,7 +3351,7 @@ type RecoverTableStmt struct { ...@@ -3351,7 +3351,7 @@ type RecoverTableStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *RecoverTableStmt) Restore(ctx *RestoreCtx) error { func (n *RecoverTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("RECOVER TABLE ") ctx.WriteKeyWord("RECOVER TABLE ")
if n.JobID != 0 { if n.JobID != 0 {
ctx.WriteKeyWord("BY JOB ") ctx.WriteKeyWord("BY JOB ")
...@@ -3390,20 +3390,15 @@ type FlashBackTableStmt struct { ...@@ -3390,20 +3390,15 @@ type FlashBackTableStmt struct {
ddlNode ddlNode
Table *TableName Table *TableName
Timestamp ValueExpr
NewName string NewName string
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *FlashBackTableStmt) Restore(ctx *RestoreCtx) error { func (n *FlashBackTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("FLASHBACK TABLE ") ctx.WriteKeyWord("FLASHBACK TABLE ")
if err := n.Table.Restore(ctx); err != nil { if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing RecoverTableStmt Table") return errors.Annotate(err, "An error occurred while splicing RecoverTableStmt Table")
} }
ctx.WriteKeyWord(" UNTIL TIMESTAMP ")
if err := n.Timestamp.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing FlashBackTableStmt Table")
}
if len(n.NewName) > 0 { if len(n.NewName) > 0 {
ctx.WriteKeyWord(" TO ") ctx.WriteKeyWord(" TO ")
ctx.WriteName(n.NewName) ctx.WriteName(n.NewName)
......
...@@ -16,7 +16,7 @@ package ast ...@@ -16,7 +16,7 @@ package ast
import ( import (
"github.com/pingcap/errors" "github.com/pingcap/errors"
"github.com/pingcap/parser/auth" "github.com/pingcap/parser/auth"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql" "github.com/pingcap/parser/mysql"
) )
...@@ -86,7 +86,7 @@ type Join struct { ...@@ -86,7 +86,7 @@ type Join struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *Join) Restore(ctx *RestoreCtx) error { func (n *Join) Restore(ctx *format.RestoreCtx) error {
if ctx.JoinLevel != 0 { if ctx.JoinLevel != 0 {
ctx.WritePlain("(") ctx.WritePlain("(")
defer ctx.WritePlain(")") defer ctx.WritePlain(")")
...@@ -187,7 +187,7 @@ type TableName struct { ...@@ -187,7 +187,7 @@ type TableName struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *TableName) restoreName(ctx *RestoreCtx) { func (n *TableName) restoreName(ctx *format.RestoreCtx) {
if n.Schema.String() != "" { if n.Schema.String() != "" {
ctx.WriteName(n.Schema.String()) ctx.WriteName(n.Schema.String())
ctx.WritePlain(".") ctx.WritePlain(".")
...@@ -195,7 +195,7 @@ func (n *TableName) restoreName(ctx *RestoreCtx) { ...@@ -195,7 +195,7 @@ func (n *TableName) restoreName(ctx *RestoreCtx) {
ctx.WriteName(n.Name.String()) ctx.WriteName(n.Name.String())
} }
func (n *TableName) restorePartitions(ctx *RestoreCtx) { func (n *TableName) restorePartitions(ctx *format.RestoreCtx) {
if len(n.PartitionNames) > 0 { if len(n.PartitionNames) > 0 {
ctx.WriteKeyWord(" PARTITION") ctx.WriteKeyWord(" PARTITION")
ctx.WritePlain("(") ctx.WritePlain("(")
...@@ -209,7 +209,7 @@ func (n *TableName) restorePartitions(ctx *RestoreCtx) { ...@@ -209,7 +209,7 @@ func (n *TableName) restorePartitions(ctx *RestoreCtx) {
} }
} }
func (n *TableName) restoreIndexHints(ctx *RestoreCtx) error { func (n *TableName) restoreIndexHints(ctx *format.RestoreCtx) error {
for _, value := range n.IndexHints { for _, value := range n.IndexHints {
ctx.WritePlain(" ") ctx.WritePlain(" ")
if err := value.Restore(ctx); err != nil { if err := value.Restore(ctx); err != nil {
...@@ -220,7 +220,7 @@ func (n *TableName) restoreIndexHints(ctx *RestoreCtx) error { ...@@ -220,7 +220,7 @@ func (n *TableName) restoreIndexHints(ctx *RestoreCtx) error {
return nil return nil
} }
func (n *TableName) Restore(ctx *RestoreCtx) error { func (n *TableName) Restore(ctx *format.RestoreCtx) error {
n.restoreName(ctx) n.restoreName(ctx)
n.restorePartitions(ctx) n.restorePartitions(ctx)
return n.restoreIndexHints(ctx) return n.restoreIndexHints(ctx)
...@@ -255,7 +255,7 @@ type IndexHint struct { ...@@ -255,7 +255,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(ctx *RestoreCtx) error { func (n *IndexHint) Restore(ctx *format.RestoreCtx) error {
indexHintType := "" indexHintType := ""
switch n.HintType { switch n.HintType {
case 1: case 1:
...@@ -312,7 +312,7 @@ type DeleteTableList struct { ...@@ -312,7 +312,7 @@ type DeleteTableList struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DeleteTableList) Restore(ctx *RestoreCtx) error { func (n *DeleteTableList) Restore(ctx *format.RestoreCtx) error {
for i, t := range n.Tables { for i, t := range n.Tables {
if i != 0 { if i != 0 {
ctx.WritePlain(",") ctx.WritePlain(",")
...@@ -351,7 +351,7 @@ type OnCondition struct { ...@@ -351,7 +351,7 @@ type OnCondition struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *OnCondition) Restore(ctx *RestoreCtx) error { func (n *OnCondition) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ON ") ctx.WriteKeyWord("ON ")
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore OnCondition.Expr") return errors.Annotate(err, "An error occurred while restore OnCondition.Expr")
...@@ -387,7 +387,7 @@ type TableSource struct { ...@@ -387,7 +387,7 @@ type TableSource struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *TableSource) Restore(ctx *RestoreCtx) error { func (n *TableSource) Restore(ctx *format.RestoreCtx) error {
needParen := false needParen := false
switch n.Source.(type) { switch n.Source.(type) {
case *SelectStmt, *UnionStmt: case *SelectStmt, *UnionStmt:
...@@ -482,7 +482,7 @@ type WildCardField struct { ...@@ -482,7 +482,7 @@ type WildCardField struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *WildCardField) Restore(ctx *RestoreCtx) error { func (n *WildCardField) Restore(ctx *format.RestoreCtx) error {
if schema := n.Schema.String(); schema != "" { if schema := n.Schema.String(); schema != "" {
ctx.WriteName(schema) ctx.WriteName(schema)
ctx.WritePlain(".") ctx.WritePlain(".")
...@@ -526,7 +526,7 @@ type SelectField struct { ...@@ -526,7 +526,7 @@ type SelectField struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *SelectField) Restore(ctx *RestoreCtx) error { func (n *SelectField) Restore(ctx *format.RestoreCtx) error {
if n.WildCard != nil { if n.WildCard != nil {
if err := n.WildCard.Restore(ctx); err != nil { if err := n.WildCard.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore SelectField.WildCard") return errors.Annotate(err, "An error occurred while restore SelectField.WildCard")
...@@ -569,7 +569,7 @@ type FieldList struct { ...@@ -569,7 +569,7 @@ type FieldList struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *FieldList) Restore(ctx *RestoreCtx) error { func (n *FieldList) Restore(ctx *format.RestoreCtx) error {
for i, v := range n.Fields { for i, v := range n.Fields {
if i != 0 { if i != 0 {
ctx.WritePlain(", ") ctx.WritePlain(", ")
...@@ -606,7 +606,7 @@ type TableRefsClause struct { ...@@ -606,7 +606,7 @@ type TableRefsClause struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *TableRefsClause) Restore(ctx *RestoreCtx) error { func (n *TableRefsClause) Restore(ctx *format.RestoreCtx) error {
if err := n.TableRefs.Restore(ctx); err != nil { if err := n.TableRefs.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore TableRefsClause.TableRefs") return errors.Annotate(err, "An error occurred while restore TableRefsClause.TableRefs")
} }
...@@ -637,7 +637,7 @@ type ByItem struct { ...@@ -637,7 +637,7 @@ type ByItem struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ByItem) Restore(ctx *RestoreCtx) error { func (n *ByItem) Restore(ctx *format.RestoreCtx) error {
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore ByItem.Expr") return errors.Annotate(err, "An error occurred while restore ByItem.Expr")
} }
...@@ -669,7 +669,7 @@ type GroupByClause struct { ...@@ -669,7 +669,7 @@ type GroupByClause struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *GroupByClause) Restore(ctx *RestoreCtx) error { func (n *GroupByClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("GROUP BY ") ctx.WriteKeyWord("GROUP BY ")
for i, v := range n.Items { for i, v := range n.Items {
if i != 0 { if i != 0 {
...@@ -706,7 +706,7 @@ type HavingClause struct { ...@@ -706,7 +706,7 @@ type HavingClause struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *HavingClause) Restore(ctx *RestoreCtx) error { func (n *HavingClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("HAVING ") ctx.WriteKeyWord("HAVING ")
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore HavingClause.Expr") return errors.Annotate(err, "An error occurred while restore HavingClause.Expr")
...@@ -737,7 +737,7 @@ type OrderByClause struct { ...@@ -737,7 +737,7 @@ type OrderByClause struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *OrderByClause) Restore(ctx *RestoreCtx) error { func (n *OrderByClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ORDER BY ") ctx.WriteKeyWord("ORDER BY ")
for i, item := range n.Items { for i, item := range n.Items {
if i != 0 { if i != 0 {
...@@ -803,10 +803,12 @@ type SelectStmt struct { ...@@ -803,10 +803,12 @@ type SelectStmt struct {
IsInBraces bool IsInBraces bool
// QueryBlockOffset indicates the order of this SelectStmt if counted from left to right in the sql text. // QueryBlockOffset indicates the order of this SelectStmt if counted from left to right in the sql text.
QueryBlockOffset int QueryBlockOffset int
// SelectIntoOpt is the select-into option.
SelectIntoOpt *SelectIntoOption
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *SelectStmt) Restore(ctx *RestoreCtx) error { func (n *SelectStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("SELECT ") ctx.WriteKeyWord("SELECT ")
if n.SelectStmtOpts.Priority > 0 { if n.SelectStmtOpts.Priority > 0 {
...@@ -922,6 +924,13 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error { ...@@ -922,6 +924,13 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error {
ctx.WritePlain(" ") ctx.WritePlain(" ")
ctx.WriteKeyWord(n.LockTp.String()) ctx.WriteKeyWord(n.LockTp.String())
} }
if n.SelectIntoOpt != nil {
ctx.WritePlain(" ")
if err := n.SelectIntoOpt.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore SelectStmt.SelectIntoOpt")
}
}
return nil return nil
} }
...@@ -1020,7 +1029,7 @@ type UnionSelectList struct { ...@@ -1020,7 +1029,7 @@ type UnionSelectList struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *UnionSelectList) Restore(ctx *RestoreCtx) error { func (n *UnionSelectList) Restore(ctx *format.RestoreCtx) error {
for i, selectStmt := range n.Selects { for i, selectStmt := range n.Selects {
if i != 0 { if i != 0 {
ctx.WriteKeyWord(" UNION ") ctx.WriteKeyWord(" UNION ")
...@@ -1070,7 +1079,7 @@ type UnionStmt struct { ...@@ -1070,7 +1079,7 @@ type UnionStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *UnionStmt) Restore(ctx *RestoreCtx) error { func (n *UnionStmt) Restore(ctx *format.RestoreCtx) error {
if err := n.SelectList.Restore(ctx); err != nil { if err := n.SelectList.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore UnionStmt.SelectList") return errors.Annotate(err, "An error occurred while restore UnionStmt.SelectList")
} }
...@@ -1132,7 +1141,7 @@ type Assignment struct { ...@@ -1132,7 +1141,7 @@ type Assignment struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *Assignment) Restore(ctx *RestoreCtx) error { func (n *Assignment) Restore(ctx *format.RestoreCtx) error {
if err := n.Column.Restore(ctx); err != nil { if err := n.Column.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore Assignment.Column") return errors.Annotate(err, "An error occurred while restore Assignment.Column")
} }
...@@ -1187,7 +1196,7 @@ type LoadDataStmt struct { ...@@ -1187,7 +1196,7 @@ type LoadDataStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *LoadDataStmt) Restore(ctx *RestoreCtx) error { func (n *LoadDataStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("LOAD DATA ") ctx.WriteKeyWord("LOAD DATA ")
if n.IsLocal { if n.IsLocal {
ctx.WriteKeyWord("LOCAL ") ctx.WriteKeyWord("LOCAL ")
...@@ -1287,6 +1296,7 @@ const ( ...@@ -1287,6 +1296,7 @@ const (
type FieldItem struct { type FieldItem struct {
Type int Type int
Value string Value string
OptEnclosed bool
} }
// FieldsClause represents fields references clause in load data statement. // FieldsClause represents fields references clause in load data statement.
...@@ -1294,10 +1304,11 @@ type FieldsClause struct { ...@@ -1294,10 +1304,11 @@ type FieldsClause struct {
Terminated string Terminated string
Enclosed byte Enclosed byte
Escaped byte Escaped byte
OptEnclosed bool
} }
// Restore for FieldsClause // Restore for FieldsClause
func (n *FieldsClause) Restore(ctx *RestoreCtx) error { func (n *FieldsClause) Restore(ctx *format.RestoreCtx) error {
if n.Terminated != "\t" || n.Escaped != '\\' { if n.Terminated != "\t" || n.Escaped != '\\' {
ctx.WriteKeyWord(" FIELDS") ctx.WriteKeyWord(" FIELDS")
if n.Terminated != "\t" { if n.Terminated != "\t" {
...@@ -1305,6 +1316,9 @@ func (n *FieldsClause) Restore(ctx *RestoreCtx) error { ...@@ -1305,6 +1316,9 @@ func (n *FieldsClause) Restore(ctx *RestoreCtx) error {
ctx.WriteString(n.Terminated) ctx.WriteString(n.Terminated)
} }
if n.Enclosed != 0 { if n.Enclosed != 0 {
if n.OptEnclosed {
ctx.WriteKeyWord(" OPTIONALLY")
}
ctx.WriteKeyWord(" ENCLOSED BY ") ctx.WriteKeyWord(" ENCLOSED BY ")
ctx.WriteString(string(n.Enclosed)) ctx.WriteString(string(n.Enclosed))
} }
...@@ -1327,7 +1341,7 @@ type LinesClause struct { ...@@ -1327,7 +1341,7 @@ type LinesClause struct {
} }
// Restore for LinesClause // Restore for LinesClause
func (n *LinesClause) Restore(ctx *RestoreCtx) error { func (n *LinesClause) Restore(ctx *format.RestoreCtx) error {
if n.Starting != "" || n.Terminated != "\n" { if n.Starting != "" || n.Terminated != "\n" {
ctx.WriteKeyWord(" LINES") ctx.WriteKeyWord(" LINES")
if n.Starting != "" { if n.Starting != "" {
...@@ -1359,7 +1373,7 @@ type InsertStmt struct { ...@@ -1359,7 +1373,7 @@ type InsertStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *InsertStmt) Restore(ctx *RestoreCtx) error { func (n *InsertStmt) Restore(ctx *format.RestoreCtx) error {
if n.IsReplace { if n.IsReplace {
ctx.WriteKeyWord("REPLACE ") ctx.WriteKeyWord("REPLACE ")
} else { } else {
...@@ -1522,7 +1536,7 @@ type DeleteStmt struct { ...@@ -1522,7 +1536,7 @@ type DeleteStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DeleteStmt) Restore(ctx *RestoreCtx) error { func (n *DeleteStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DELETE ") ctx.WriteKeyWord("DELETE ")
if n.TableHints != nil && len(n.TableHints) != 0 { if n.TableHints != nil && len(n.TableHints) != 0 {
...@@ -1664,7 +1678,7 @@ type UpdateStmt struct { ...@@ -1664,7 +1678,7 @@ type UpdateStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *UpdateStmt) Restore(ctx *RestoreCtx) error { func (n *UpdateStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("UPDATE ") ctx.WriteKeyWord("UPDATE ")
if n.TableHints != nil && len(n.TableHints) != 0 { if n.TableHints != nil && len(n.TableHints) != 0 {
...@@ -1784,7 +1798,7 @@ type Limit struct { ...@@ -1784,7 +1798,7 @@ type Limit struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *Limit) Restore(ctx *RestoreCtx) error { func (n *Limit) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("LIMIT ") ctx.WriteKeyWord("LIMIT ")
if n.Offset != nil { if n.Offset != nil {
if err := n.Offset.Restore(ctx); err != nil { if err := n.Offset.Restore(ctx); err != nil {
...@@ -1849,6 +1863,7 @@ const ( ...@@ -1849,6 +1863,7 @@ const (
ShowIndex ShowIndex
ShowProcessList ShowProcessList
ShowCreateDatabase ShowCreateDatabase
ShowConfig
ShowEvents ShowEvents
ShowStatsMeta ShowStatsMeta
ShowStatsHistograms ShowStatsHistograms
...@@ -1867,6 +1882,9 @@ const ( ...@@ -1867,6 +1882,9 @@ const (
ShowAnalyzeStatus ShowAnalyzeStatus
ShowRegions ShowRegions
ShowBuiltins ShowBuiltins
ShowTableNextRowId
ShowBackup
ShowRestore
) )
const ( const (
...@@ -1911,7 +1929,7 @@ type ShowStmt struct { ...@@ -1911,7 +1929,7 @@ type ShowStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ShowStmt) Restore(ctx *RestoreCtx) error { func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error {
restoreOptFull := func() { restoreOptFull := func() {
if n.Full { if n.Full {
ctx.WriteKeyWord("FULL ") ctx.WriteKeyWord("FULL ")
...@@ -2070,6 +2088,8 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error { ...@@ -2070,6 +2088,8 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error {
switch n.Tp { switch n.Tp {
case ShowEngines: case ShowEngines:
ctx.WriteKeyWord("ENGINES") ctx.WriteKeyWord("ENGINES")
case ShowConfig:
ctx.WriteKeyWord("CONFIG")
case ShowDatabases: case ShowDatabases:
ctx.WriteKeyWord("DATABASES") ctx.WriteKeyWord("DATABASES")
case ShowCharset: case ShowCharset:
...@@ -2154,6 +2174,17 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error { ...@@ -2154,6 +2174,17 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error {
return err return err
} }
return nil return nil
case ShowTableNextRowId:
ctx.WriteKeyWord("TABLE ")
if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore SplitIndexRegionStmt.Table")
}
ctx.WriteKeyWord(" NEXT_ROW_ID")
return nil
case ShowBackup:
ctx.WriteKeyWord("BACKUP")
case ShowRestore:
ctx.WriteKeyWord("RESTORE")
default: default:
return errors.New("Unknown ShowStmt type") return errors.New("Unknown ShowStmt type")
} }
...@@ -2227,7 +2258,7 @@ type WindowSpec struct { ...@@ -2227,7 +2258,7 @@ type WindowSpec struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *WindowSpec) Restore(ctx *RestoreCtx) error { func (n *WindowSpec) Restore(ctx *format.RestoreCtx) error {
if name := n.Name.String(); name != "" { if name := n.Name.String(); name != "" {
ctx.WriteName(name) ctx.WriteName(name)
if n.OnlyAlias { if n.OnlyAlias {
...@@ -2297,6 +2328,54 @@ func (n *WindowSpec) Accept(v Visitor) (Node, bool) { ...@@ -2297,6 +2328,54 @@ func (n *WindowSpec) Accept(v Visitor) (Node, bool) {
return v.Leave(n) return v.Leave(n)
} }
type SelectIntoType int
const (
SelectIntoOutfile SelectIntoType = iota + 1
SelectIntoDumpfile
SelectIntoVars
)
type SelectIntoOption struct {
node
Tp SelectIntoType
FileName string
FieldsInfo *FieldsClause
LinesInfo *LinesClause
}
// Restore implements Node interface.
func (n *SelectIntoOption) Restore(ctx *format.RestoreCtx) error {
if n.Tp != SelectIntoOutfile {
// only support SELECT ... INTO OUTFILE now
return errors.New("Unsupported SelectionInto type")
}
ctx.WriteKeyWord("INTO OUTFILE ")
ctx.WriteString(n.FileName)
if n.FieldsInfo != nil {
if err := n.FieldsInfo.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore SelectInto.FieldsInfo")
}
}
if n.LinesInfo != nil {
if err := n.LinesInfo.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore SelectInto.LinesInfo")
}
}
return nil
}
// Accept implements Node Accept interface.
func (n *SelectIntoOption) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
return v.Leave(n)
}
// PartitionByClause represents partition by clause. // PartitionByClause represents partition by clause.
type PartitionByClause struct { type PartitionByClause struct {
node node
...@@ -2305,7 +2384,7 @@ type PartitionByClause struct { ...@@ -2305,7 +2384,7 @@ type PartitionByClause struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *PartitionByClause) Restore(ctx *RestoreCtx) error { func (n *PartitionByClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("PARTITION BY ") ctx.WriteKeyWord("PARTITION BY ")
for i, v := range n.Items { for i, v := range n.Items {
if i != 0 { if i != 0 {
...@@ -2355,7 +2434,7 @@ type FrameClause struct { ...@@ -2355,7 +2434,7 @@ type FrameClause struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *FrameClause) Restore(ctx *RestoreCtx) error { func (n *FrameClause) Restore(ctx *format.RestoreCtx) error {
switch n.Type { switch n.Type {
case Rows: case Rows:
ctx.WriteKeyWord("ROWS") ctx.WriteKeyWord("ROWS")
...@@ -2425,7 +2504,7 @@ type FrameBound struct { ...@@ -2425,7 +2504,7 @@ type FrameBound struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *FrameBound) Restore(ctx *RestoreCtx) error { func (n *FrameBound) Restore(ctx *format.RestoreCtx) error {
if n.UnBounded { if n.UnBounded {
ctx.WriteKeyWord("UNBOUNDED") ctx.WriteKeyWord("UNBOUNDED")
} }
...@@ -2495,7 +2574,7 @@ type SplitSyntaxOption struct { ...@@ -2495,7 +2574,7 @@ type SplitSyntaxOption struct {
HasPartition bool HasPartition bool
} }
func (n *SplitRegionStmt) Restore(ctx *RestoreCtx) error { func (n *SplitRegionStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("SPLIT ") ctx.WriteKeyWord("SPLIT ")
if n.SplitSyntaxOpt != nil { if n.SplitSyntaxOpt != nil {
if n.SplitSyntaxOpt.HasRegionFor { if n.SplitSyntaxOpt.HasRegionFor {
...@@ -2571,7 +2650,7 @@ func (n *SplitRegionStmt) Accept(v Visitor) (Node, bool) { ...@@ -2571,7 +2650,7 @@ func (n *SplitRegionStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(n) return v.Leave(n)
} }
func (n *SplitOption) Restore(ctx *RestoreCtx) error { func (n *SplitOption) Restore(ctx *format.RestoreCtx) error {
if len(n.ValueLists) == 0 { if len(n.ValueLists) == 0 {
ctx.WriteKeyWord("BETWEEN ") ctx.WriteKeyWord("BETWEEN ")
ctx.WritePlain("(") ctx.WritePlain("(")
......
...@@ -20,7 +20,7 @@ import ( ...@@ -20,7 +20,7 @@ import (
"strings" "strings"
"github.com/pingcap/errors" "github.com/pingcap/errors"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
"github.com/pingcap/parser/opcode" "github.com/pingcap/parser/opcode"
) )
...@@ -30,6 +30,7 @@ var ( ...@@ -30,6 +30,7 @@ var (
_ ExprNode = &BinaryOperationExpr{} _ ExprNode = &BinaryOperationExpr{}
_ ExprNode = &CaseExpr{} _ ExprNode = &CaseExpr{}
_ ExprNode = &ColumnNameExpr{} _ ExprNode = &ColumnNameExpr{}
_ ExprNode = &TableNameExpr{}
_ ExprNode = &CompareSubqueryExpr{} _ ExprNode = &CompareSubqueryExpr{}
_ ExprNode = &DefaultExpr{} _ ExprNode = &DefaultExpr{}
_ ExprNode = &ExistsSubqueryExpr{} _ ExprNode = &ExistsSubqueryExpr{}
...@@ -46,6 +47,7 @@ var ( ...@@ -46,6 +47,7 @@ var (
_ ExprNode = &ValuesExpr{} _ ExprNode = &ValuesExpr{}
_ ExprNode = &VariableExpr{} _ ExprNode = &VariableExpr{}
_ ExprNode = &MatchAgainst{} _ ExprNode = &MatchAgainst{}
_ ExprNode = &SetCollationExpr{}
_ Node = &ColumnName{} _ Node = &ColumnName{}
_ Node = &WhenClause{} _ Node = &WhenClause{}
...@@ -63,7 +65,7 @@ type ValueExpr interface { ...@@ -63,7 +65,7 @@ type ValueExpr interface {
} }
// NewValueExpr creates a ValueExpr with value, and sets default field type. // NewValueExpr creates a ValueExpr with value, and sets default field type.
var NewValueExpr func(interface{}) ValueExpr var NewValueExpr func(value interface{}, charset string, collate string) ValueExpr
// NewParamMarkerExpr creates a ParamMarkerExpr. // NewParamMarkerExpr creates a ParamMarkerExpr.
var NewParamMarkerExpr func(offset int) ParamMarkerExpr var NewParamMarkerExpr func(offset int) ParamMarkerExpr
...@@ -82,7 +84,7 @@ type BetweenExpr struct { ...@@ -82,7 +84,7 @@ type BetweenExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *BetweenExpr) Restore(ctx *RestoreCtx) error { func (n *BetweenExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore BetweenExpr.Expr") return errors.Annotate(err, "An error occurred while restore BetweenExpr.Expr")
} }
...@@ -155,7 +157,7 @@ type BinaryOperationExpr struct { ...@@ -155,7 +157,7 @@ type BinaryOperationExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *BinaryOperationExpr) Restore(ctx *RestoreCtx) error { func (n *BinaryOperationExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.L.Restore(ctx); err != nil { if err := n.L.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred when restore BinaryOperationExpr.L") return errors.Annotate(err, "An error occurred when restore BinaryOperationExpr.L")
} }
...@@ -217,7 +219,7 @@ type WhenClause struct { ...@@ -217,7 +219,7 @@ type WhenClause struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *WhenClause) Restore(ctx *RestoreCtx) error { func (n *WhenClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("WHEN ") ctx.WriteKeyWord("WHEN ")
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore WhenClauses.Expr") return errors.Annotate(err, "An error occurred while restore WhenClauses.Expr")
...@@ -263,7 +265,7 @@ type CaseExpr struct { ...@@ -263,7 +265,7 @@ type CaseExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *CaseExpr) Restore(ctx *RestoreCtx) error { func (n *CaseExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CASE") ctx.WriteKeyWord("CASE")
if n.Value != nil { if n.Value != nil {
ctx.WritePlain(" ") ctx.WritePlain(" ")
...@@ -354,7 +356,7 @@ type SubqueryExpr struct { ...@@ -354,7 +356,7 @@ type SubqueryExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *SubqueryExpr) Restore(ctx *RestoreCtx) error { func (n *SubqueryExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WritePlain("(") ctx.WritePlain("(")
if err := n.Query.Restore(ctx); err != nil { if err := n.Query.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore SubqueryExpr.Query") return errors.Annotate(err, "An error occurred while restore SubqueryExpr.Query")
...@@ -400,7 +402,7 @@ type CompareSubqueryExpr struct { ...@@ -400,7 +402,7 @@ type CompareSubqueryExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *CompareSubqueryExpr) Restore(ctx *RestoreCtx) error { func (n *CompareSubqueryExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.L.Restore(ctx); err != nil { if err := n.L.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.L") return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.L")
} }
...@@ -443,6 +445,47 @@ func (n *CompareSubqueryExpr) Accept(v Visitor) (Node, bool) { ...@@ -443,6 +445,47 @@ func (n *CompareSubqueryExpr) Accept(v Visitor) (Node, bool) {
return v.Leave(n) return v.Leave(n)
} }
// TableNameExpr represents a table-level object name expression, such as sequence/table/view etc.
type TableNameExpr struct {
exprNode
// Name is the referenced object name expression.
Name *TableName
}
// Restore implements Node interface.
func (n *TableNameExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Name.Restore(ctx); err != nil {
return errors.Trace(err)
}
return nil
}
// Format the ExprNode into a Writer.
func (n *TableNameExpr) Format(w io.Writer) {
dbName, tbName := n.Name.Schema.L, n.Name.Name.L
if dbName == "" {
fmt.Fprintf(w, "`%s`", tbName)
} else {
fmt.Fprintf(w, "`%s`.`%s`", dbName, tbName)
}
}
// Accept implements Node Accept interface.
func (n *TableNameExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TableNameExpr)
node, ok := n.Name.Accept(v)
if !ok {
return n, false
}
n.Name = node.(*TableName)
return v.Leave(n)
}
// ColumnName represents column name. // ColumnName represents column name.
type ColumnName struct { type ColumnName struct {
node node
...@@ -452,7 +495,7 @@ type ColumnName struct { ...@@ -452,7 +495,7 @@ type ColumnName struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ColumnName) Restore(ctx *RestoreCtx) error { func (n *ColumnName) Restore(ctx *format.RestoreCtx) error {
if n.Schema.O != "" { if n.Schema.O != "" {
ctx.WriteName(n.Schema.O) ctx.WriteName(n.Schema.O)
ctx.WritePlain(".") ctx.WritePlain(".")
...@@ -514,7 +557,7 @@ type ColumnNameExpr struct { ...@@ -514,7 +557,7 @@ type ColumnNameExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ColumnNameExpr) Restore(ctx *RestoreCtx) error { func (n *ColumnNameExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Name.Restore(ctx); err != nil { if err := n.Name.Restore(ctx); err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
...@@ -550,7 +593,7 @@ type DefaultExpr struct { ...@@ -550,7 +593,7 @@ type DefaultExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DefaultExpr) Restore(ctx *RestoreCtx) error { func (n *DefaultExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DEFAULT") ctx.WriteKeyWord("DEFAULT")
if n.Name != nil { if n.Name != nil {
ctx.WritePlain("(") ctx.WritePlain("(")
...@@ -595,7 +638,7 @@ type ExistsSubqueryExpr struct { ...@@ -595,7 +638,7 @@ type ExistsSubqueryExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ExistsSubqueryExpr) Restore(ctx *RestoreCtx) error { func (n *ExistsSubqueryExpr) Restore(ctx *format.RestoreCtx) error {
if n.Not { if n.Not {
ctx.WriteKeyWord("NOT EXISTS ") ctx.WriteKeyWord("NOT EXISTS ")
} else { } else {
...@@ -641,7 +684,7 @@ type PatternInExpr struct { ...@@ -641,7 +684,7 @@ type PatternInExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *PatternInExpr) Restore(ctx *RestoreCtx) error { func (n *PatternInExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore PatternInExpr.Expr") return errors.Annotate(err, "An error occurred while restore PatternInExpr.Expr")
} }
...@@ -725,7 +768,7 @@ type IsNullExpr struct { ...@@ -725,7 +768,7 @@ type IsNullExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *IsNullExpr) Restore(ctx *RestoreCtx) error { func (n *IsNullExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
...@@ -774,7 +817,7 @@ type IsTruthExpr struct { ...@@ -774,7 +817,7 @@ type IsTruthExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *IsTruthExpr) Restore(ctx *RestoreCtx) error { func (n *IsTruthExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
...@@ -838,7 +881,7 @@ type PatternLikeExpr struct { ...@@ -838,7 +881,7 @@ type PatternLikeExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *PatternLikeExpr) Restore(ctx *RestoreCtx) error { func (n *PatternLikeExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore PatternLikeExpr.Expr") return errors.Annotate(err, "An error occurred while restore PatternLikeExpr.Expr")
} }
...@@ -916,7 +959,7 @@ type ParenthesesExpr struct { ...@@ -916,7 +959,7 @@ type ParenthesesExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ParenthesesExpr) Restore(ctx *RestoreCtx) error { func (n *ParenthesesExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WritePlain("(") ctx.WritePlain("(")
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred when restore ParenthesesExpr.Expr") return errors.Annotate(err, "An error occurred when restore ParenthesesExpr.Expr")
...@@ -963,7 +1006,7 @@ type PositionExpr struct { ...@@ -963,7 +1006,7 @@ type PositionExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *PositionExpr) Restore(ctx *RestoreCtx) error { func (n *PositionExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WritePlainf("%d", n.N) ctx.WritePlainf("%d", n.N)
return nil return nil
} }
...@@ -1007,7 +1050,7 @@ type PatternRegexpExpr struct { ...@@ -1007,7 +1050,7 @@ type PatternRegexpExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *PatternRegexpExpr) Restore(ctx *RestoreCtx) error { func (n *PatternRegexpExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Expr.Restore(ctx); err != nil { if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore PatternRegexpExpr.Expr") return errors.Annotate(err, "An error occurred while restore PatternRegexpExpr.Expr")
} }
...@@ -1065,7 +1108,7 @@ type RowExpr struct { ...@@ -1065,7 +1108,7 @@ type RowExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *RowExpr) Restore(ctx *RestoreCtx) error { func (n *RowExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ROW") ctx.WriteKeyWord("ROW")
ctx.WritePlain("(") ctx.WritePlain("(")
for i, v := range n.Values { for i, v := range n.Values {
...@@ -1112,7 +1155,7 @@ type UnaryOperationExpr struct { ...@@ -1112,7 +1155,7 @@ type UnaryOperationExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *UnaryOperationExpr) Restore(ctx *RestoreCtx) error { func (n *UnaryOperationExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Op.Restore(ctx); err != nil { if err := n.Op.Restore(ctx); err != nil {
return errors.Trace(err) return errors.Trace(err)
} }
...@@ -1151,7 +1194,7 @@ type ValuesExpr struct { ...@@ -1151,7 +1194,7 @@ type ValuesExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *ValuesExpr) Restore(ctx *RestoreCtx) error { func (n *ValuesExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("VALUES") ctx.WriteKeyWord("VALUES")
ctx.WritePlain("(") ctx.WritePlain("(")
if err := n.Column.Restore(ctx); err != nil { if err := n.Column.Restore(ctx); err != nil {
...@@ -1200,7 +1243,7 @@ type VariableExpr struct { ...@@ -1200,7 +1243,7 @@ type VariableExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *VariableExpr) Restore(ctx *RestoreCtx) error { func (n *VariableExpr) Restore(ctx *format.RestoreCtx) error {
if n.IsSystem { if n.IsSystem {
ctx.WritePlain("@@") ctx.WritePlain("@@")
if n.ExplicitScope { if n.ExplicitScope {
...@@ -1256,7 +1299,7 @@ type MaxValueExpr struct { ...@@ -1256,7 +1299,7 @@ type MaxValueExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *MaxValueExpr) Restore(ctx *RestoreCtx) error { func (n *MaxValueExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("MAXVALUE") ctx.WriteKeyWord("MAXVALUE")
return nil return nil
} }
...@@ -1286,7 +1329,7 @@ type MatchAgainst struct { ...@@ -1286,7 +1329,7 @@ type MatchAgainst struct {
Modifier FulltextSearchModifier Modifier FulltextSearchModifier
} }
func (n *MatchAgainst) Restore(ctx *RestoreCtx) error { func (n *MatchAgainst) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("MATCH") ctx.WriteKeyWord("MATCH")
ctx.WritePlain(" (") ctx.WritePlain(" (")
for i, v := range n.ColumnNames { for i, v := range n.ColumnNames {
...@@ -1354,3 +1397,43 @@ func (n *MatchAgainst) Accept(v Visitor) (Node, bool) { ...@@ -1354,3 +1397,43 @@ func (n *MatchAgainst) Accept(v Visitor) (Node, bool) {
n.Against = newAgainst.(ExprNode) n.Against = newAgainst.(ExprNode)
return v.Leave(n) return v.Leave(n)
} }
// SetCollationExpr is the expression for the `COLLATE collation_name` clause.
type SetCollationExpr struct {
exprNode
// Expr is the expression to be set.
Expr ExprNode
// Collate is the name of collation to set.
Collate string
}
// Restore implements Node interface.
func (n *SetCollationExpr) Restore(ctx *format.RestoreCtx) error {
if err := n.Expr.Restore(ctx); err != nil {
return errors.Trace(err)
}
ctx.WriteKeyWord(" COLLATE ")
ctx.WritePlain(n.Collate)
return nil
}
// Format the ExprNode into a Writer.
func (n *SetCollationExpr) Format(w io.Writer) {
n.Expr.Format(w)
fmt.Fprintf(w, " COLLATE %s", n.Collate)
}
// Accept implements Node Accept interface.
func (n *SetCollationExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SetCollationExpr)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
...@@ -17,9 +17,10 @@ import ( ...@@ -17,9 +17,10 @@ import (
"fmt" "fmt"
"io" "io"
"strings" "strings"
"time"
"github.com/pingcap/errors" "github.com/pingcap/errors"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
"github.com/pingcap/parser/types" "github.com/pingcap/parser/types"
) )
...@@ -226,6 +227,7 @@ const ( ...@@ -226,6 +227,7 @@ const (
CharLength = "char_length" CharLength = "char_length"
CharacterLength = "character_length" CharacterLength = "character_length"
FindInSet = "find_in_set" FindInSet = "find_in_set"
WeightString = "weight_string"
// information functions // information functions
Benchmark = "benchmark" Benchmark = "benchmark"
...@@ -247,6 +249,8 @@ const ( ...@@ -247,6 +249,8 @@ const (
TiDBVersion = "tidb_version" TiDBVersion = "tidb_version"
TiDBIsDDLOwner = "tidb_is_ddl_owner" TiDBIsDDLOwner = "tidb_is_ddl_owner"
TiDBDecodePlan = "tidb_decode_plan" TiDBDecodePlan = "tidb_decode_plan"
FormatBytes = "format_bytes"
FormatNanoTime = "format_nano_time"
// control functions // control functions
If = "if" If = "if"
...@@ -325,6 +329,11 @@ const ( ...@@ -325,6 +329,11 @@ const (
// TiDB internal function. // TiDB internal function.
TiDBDecodeKey = "tidb_decode_key" TiDBDecodeKey = "tidb_decode_key"
// Sequence function.
NextVal = "nextval"
LastVal = "lastval"
SetVal = "setval"
) )
// FuncCallExpr is for function expression. // FuncCallExpr is for function expression.
...@@ -337,7 +346,7 @@ type FuncCallExpr struct { ...@@ -337,7 +346,7 @@ type FuncCallExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error { func (n *FuncCallExpr) Restore(ctx *format.RestoreCtx) error {
var specialLiteral string var specialLiteral string
switch n.FnName.L { switch n.FnName.L {
case DateLiteral: case DateLiteral:
...@@ -415,6 +424,19 @@ func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error { ...@@ -415,6 +424,19 @@ func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error {
return errors.Annotatef(err, "An error occurred while restore FuncCallExpr.Args[0]") return errors.Annotatef(err, "An error occurred while restore FuncCallExpr.Args[0]")
} }
} }
case WeightString:
if err := n.Args[0].Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore FuncCallExpr.(WEIGHT_STRING).Args[0]")
}
if len(n.Args) == 3 {
ctx.WriteKeyWord(" AS ")
ctx.WriteKeyWord(n.Args[1].(ValueExpr).GetValue().(string))
ctx.WritePlain("(")
if err := n.Args[2].Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore FuncCallExpr.(WEIGHT_STRING).Args[2]")
}
ctx.WritePlain(")")
}
default: default:
for i, argv := range n.Args { for i, argv := range n.Args {
if i != 0 { if i != 0 {
...@@ -497,7 +519,7 @@ type FuncCastExpr struct { ...@@ -497,7 +519,7 @@ type FuncCastExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *FuncCastExpr) Restore(ctx *RestoreCtx) error { func (n *FuncCastExpr) Restore(ctx *format.RestoreCtx) error {
switch n.FunctionType { switch n.FunctionType {
case CastFunction: case CastFunction:
ctx.WriteKeyWord("CAST") ctx.WriteKeyWord("CAST")
...@@ -598,7 +620,7 @@ type TrimDirectionExpr struct { ...@@ -598,7 +620,7 @@ type TrimDirectionExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *TrimDirectionExpr) Restore(ctx *RestoreCtx) error { func (n *TrimDirectionExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.Direction.String()) ctx.WriteKeyWord(n.Direction.String())
return nil return nil
} }
...@@ -660,6 +682,8 @@ const ( ...@@ -660,6 +682,8 @@ const (
AggFuncStddevPop = "stddev_pop" AggFuncStddevPop = "stddev_pop"
// AggFuncStddevSamp is the name of stddev_samp function // AggFuncStddevSamp is the name of stddev_samp function
AggFuncStddevSamp = "stddev_samp" AggFuncStddevSamp = "stddev_samp"
// AggFuncJsonObjectAgg is the name of json_objectagg function
AggFuncJsonObjectAgg = "json_objectagg"
) )
// AggregateFuncExpr represents aggregate function expression. // AggregateFuncExpr represents aggregate function expression.
...@@ -676,7 +700,7 @@ type AggregateFuncExpr struct { ...@@ -676,7 +700,7 @@ type AggregateFuncExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *AggregateFuncExpr) Restore(ctx *RestoreCtx) error { func (n *AggregateFuncExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.F) ctx.WriteKeyWord(n.F)
ctx.WritePlain("(") ctx.WritePlain("(")
if n.Distinct { if n.Distinct {
...@@ -779,7 +803,7 @@ type WindowFuncExpr struct { ...@@ -779,7 +803,7 @@ type WindowFuncExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *WindowFuncExpr) Restore(ctx *RestoreCtx) error { func (n *WindowFuncExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.F) ctx.WriteKeyWord(n.F)
ctx.WritePlain("(") ctx.WritePlain("(")
for i, v := range n.Args { for i, v := range n.Args {
...@@ -930,6 +954,30 @@ func (unit TimeUnitType) String() string { ...@@ -930,6 +954,30 @@ func (unit TimeUnitType) String() string {
} }
} }
// Duration represented by this unit.
// Returns error if the time unit is not a fixed time interval (such as MONTH)
// or a composite unit (such as MINUTE_SECOND).
func (unit TimeUnitType) Duration() (time.Duration, error) {
switch unit {
case TimeUnitMicrosecond:
return time.Microsecond, nil
case TimeUnitSecond:
return time.Second, nil
case TimeUnitMinute:
return time.Minute, nil
case TimeUnitHour:
return time.Hour, nil
case TimeUnitDay:
return time.Hour * 24, nil
case TimeUnitWeek:
return time.Hour * 24 * 7, nil
case TimeUnitMonth, TimeUnitQuarter, TimeUnitYear:
return 0, errors.Errorf("%s is not a constant time interval and cannot be used here", unit)
default:
return 0, errors.Errorf("%s is a composite time unit and is not supported yet", unit)
}
}
// TimeUnitExpr is an expression representing a time or timestamp unit. // TimeUnitExpr is an expression representing a time or timestamp unit.
type TimeUnitExpr struct { type TimeUnitExpr struct {
exprNode exprNode
...@@ -938,7 +986,7 @@ type TimeUnitExpr struct { ...@@ -938,7 +986,7 @@ type TimeUnitExpr struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *TimeUnitExpr) Restore(ctx *RestoreCtx) error { func (n *TimeUnitExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.Unit.String()) ctx.WriteKeyWord(n.Unit.String())
return nil return nil
} }
...@@ -991,7 +1039,7 @@ func (selector GetFormatSelectorType) String() string { ...@@ -991,7 +1039,7 @@ func (selector GetFormatSelectorType) String() string {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *GetFormatSelectorExpr) Restore(ctx *RestoreCtx) error { func (n *GetFormatSelectorExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.Selector.String()) ctx.WriteKeyWord(n.Selector.String())
return nil return nil
} }
......
...@@ -15,7 +15,7 @@ package ast ...@@ -15,7 +15,7 @@ package ast
import ( import (
"github.com/pingcap/errors" "github.com/pingcap/errors"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
"github.com/pingcap/parser/model" "github.com/pingcap/parser/model"
) )
...@@ -67,7 +67,7 @@ type AnalyzeOpt struct { ...@@ -67,7 +67,7 @@ type AnalyzeOpt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *AnalyzeTableStmt) Restore(ctx *RestoreCtx) error { func (n *AnalyzeTableStmt) Restore(ctx *format.RestoreCtx) error {
if n.Incremental { if n.Incremental {
ctx.WriteKeyWord("ANALYZE INCREMENTAL TABLE ") ctx.WriteKeyWord("ANALYZE INCREMENTAL TABLE ")
} else { } else {
...@@ -139,7 +139,7 @@ type DropStatsStmt struct { ...@@ -139,7 +139,7 @@ type DropStatsStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *DropStatsStmt) Restore(ctx *RestoreCtx) error { func (n *DropStatsStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DROP STATS ") ctx.WriteKeyWord("DROP STATS ")
if err := n.Table.Restore(ctx); err != nil { if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while add table") return errors.Annotate(err, "An error occurred while add table")
...@@ -171,7 +171,7 @@ type LoadStatsStmt struct { ...@@ -171,7 +171,7 @@ type LoadStatsStmt struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *LoadStatsStmt) Restore(ctx *RestoreCtx) error { func (n *LoadStatsStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("LOAD STATS ") ctx.WriteKeyWord("LOAD STATS ")
ctx.WriteString(n.Path) ctx.WriteString(n.Path)
return nil return nil
......
...@@ -36,7 +36,14 @@ func IsReadOnly(node Node) bool { ...@@ -36,7 +36,14 @@ func IsReadOnly(node Node) bool {
return checker.readOnly return checker.readOnly
case *ExplainStmt: case *ExplainStmt:
return !st.Analyze || IsReadOnly(st.Stmt) return !st.Analyze || IsReadOnly(st.Stmt)
case *DoStmt: case *DoStmt, *ShowStmt:
return true
case *UnionStmt:
for _, sel := range node.(*UnionStmt).SelectList.Selects {
if !IsReadOnly(sel) {
return false
}
}
return true return true
default: default:
return false return false
......
...@@ -20,7 +20,7 @@ import ( ...@@ -20,7 +20,7 @@ import (
"fmt" "fmt"
"github.com/pingcap/errors" "github.com/pingcap/errors"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
"github.com/pingcap/parser/terror" "github.com/pingcap/parser/terror"
) )
...@@ -34,7 +34,7 @@ type UserIdentity struct { ...@@ -34,7 +34,7 @@ type UserIdentity struct {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (user *UserIdentity) Restore(ctx *RestoreCtx) error { func (user *UserIdentity) Restore(ctx *format.RestoreCtx) error {
if user.CurrentUser { if user.CurrentUser {
ctx.WriteKeyWord("CURRENT_USER") ctx.WriteKeyWord("CURRENT_USER")
} else { } else {
...@@ -67,7 +67,7 @@ type RoleIdentity struct { ...@@ -67,7 +67,7 @@ type RoleIdentity struct {
Hostname string Hostname string
} }
func (role *RoleIdentity) Restore(ctx *RestoreCtx) error { func (role *RoleIdentity) Restore(ctx *format.RestoreCtx) error {
ctx.WriteName(role.Username) ctx.WriteName(role.Username)
if role.Hostname != "" { if role.Hostname != "" {
ctx.WritePlain("@") ctx.WritePlain("@")
......
...@@ -105,11 +105,7 @@ func ValidCharsetAndCollation(cs string, co string) bool { ...@@ -105,11 +105,7 @@ func ValidCharsetAndCollation(cs string, co string) bool {
} }
co = strings.ToLower(co) co = strings.ToLower(co)
_, ok = c.Collations[co] _, ok = c.Collations[co]
if !ok { return ok
return false
}
return true
} }
// GetDefaultCollation returns the default collation for charset. // GetDefaultCollation returns the default collation for charset.
......
...@@ -114,14 +114,14 @@ func (d *sqlDigester) doDigest(sql string) (result string) { ...@@ -114,14 +114,14 @@ func (d *sqlDigester) doDigest(sql string) (result string) {
func (d *sqlDigester) doNormalize(sql string) (result string) { func (d *sqlDigester) doNormalize(sql string) (result string) {
d.normalize(sql) d.normalize(sql)
result = string(d.buffer.Bytes()) result = d.buffer.String()
d.buffer.Reset() d.buffer.Reset()
return return
} }
func (d *sqlDigester) doNormalizeDigest(sql string) (normalized, digest string) { func (d *sqlDigester) doNormalizeDigest(sql string) (normalized, digest string) {
d.normalize(sql) d.normalize(sql)
normalized = string(d.buffer.Bytes()) normalized = d.buffer.String()
d.hasher.Write(d.buffer.Bytes()) d.hasher.Write(d.buffer.Bytes())
d.buffer.Reset() d.buffer.Reset()
digest = fmt.Sprintf("%x", d.hasher.Sum(nil)) digest = fmt.Sprintf("%x", d.hasher.Sum(nil))
......
...@@ -78,7 +78,7 @@ import ( ...@@ -78,7 +78,7 @@ import (
/* TiDB hint names */ /* TiDB hint names */
hintAggToCop "AGG_TO_COP" hintAggToCop "AGG_TO_COP"
hintEnablePlanCache "ENABLE_PLAN_CACHE" hintIgnorePlanCache "IGNORE_PLAN_CACHE"
hintHashAgg "HASH_AGG" hintHashAgg "HASH_AGG"
hintIgnoreIndex "IGNORE_INDEX" hintIgnoreIndex "IGNORE_INDEX"
hintInlHashJoin "INL_HASH_JOIN" hintInlHashJoin "INL_HASH_JOIN"
...@@ -89,13 +89,15 @@ import ( ...@@ -89,13 +89,15 @@ import (
hintQueryType "QUERY_TYPE" hintQueryType "QUERY_TYPE"
hintReadConsistentReplica "READ_CONSISTENT_REPLICA" hintReadConsistentReplica "READ_CONSISTENT_REPLICA"
hintReadFromStorage "READ_FROM_STORAGE" hintReadFromStorage "READ_FROM_STORAGE"
hintSMJoin "SM_JOIN" hintSMJoin "MERGE_JOIN"
hintStreamAgg "STREAM_AGG" hintStreamAgg "STREAM_AGG"
hintSwapJoinInputs "SWAP_JOIN_INPUTS" hintSwapJoinInputs "SWAP_JOIN_INPUTS"
hintUseIndexMerge "USE_INDEX_MERGE" hintUseIndexMerge "USE_INDEX_MERGE"
hintUseIndex "USE_INDEX" hintUseIndex "USE_INDEX"
hintUsePlanCache "USE_PLAN_CACHE" hintUsePlanCache "USE_PLAN_CACHE"
hintUseToja "USE_TOJA" hintUseToja "USE_TOJA"
hintTimeRange "TIME_RANGE"
hintUseCascades "USE_CASCADES"
/* Other keywords */ /* Other keywords */
hintOLAP "OLAP" hintOLAP "OLAP"
...@@ -229,7 +231,7 @@ TableOptimizerHintOpt: ...@@ -229,7 +231,7 @@ TableOptimizerHintOpt:
$$ = &ast.TableOptimizerHint{ $$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1), HintName: model.NewCIStr($1),
QBName: model.NewCIStr($3), QBName: model.NewCIStr($3),
MaxExecutionTime: $4, HintData: $4,
} }
} }
| "SET_VAR" '(' Identifier '=' Value ')' | "SET_VAR" '(' Identifier '=' Value ')'
...@@ -255,7 +257,7 @@ TableOptimizerHintOpt: ...@@ -255,7 +257,7 @@ TableOptimizerHintOpt:
if $4 <= maxValue { if $4 <= maxValue {
$$ = &ast.TableOptimizerHint{ $$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1), HintName: model.NewCIStr($1),
MemoryQuota: int64($4 * $5), HintData: int64($4 * $5),
QBName: model.NewCIStr($3), QBName: model.NewCIStr($3),
} }
} else { } else {
...@@ -264,6 +266,16 @@ TableOptimizerHintOpt: ...@@ -264,6 +266,16 @@ TableOptimizerHintOpt:
$$ = nil $$ = nil
} }
} }
| "TIME_RANGE" '(' hintStringLit CommaOpt hintStringLit ')'
{
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
HintData: ast.HintTimeRange{
From: $3,
To: $5,
},
}
}
| BooleanHintName '(' QueryBlockOpt HintTrueOrFalse ')' | BooleanHintName '(' QueryBlockOpt HintTrueOrFalse ')'
{ {
h := $4 h := $4
...@@ -283,7 +295,7 @@ TableOptimizerHintOpt: ...@@ -283,7 +295,7 @@ TableOptimizerHintOpt:
$$ = &ast.TableOptimizerHint{ $$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1), HintName: model.NewCIStr($1),
QBName: model.NewCIStr($3), QBName: model.NewCIStr($3),
QueryType: model.NewCIStr($4), HintData: model.NewCIStr($4),
} }
} }
...@@ -314,7 +326,7 @@ HintStorageTypeAndTable: ...@@ -314,7 +326,7 @@ HintStorageTypeAndTable:
HintStorageType '[' HintTableList ']' HintStorageType '[' HintTableList ']'
{ {
h := $3 h := $3
h.StoreType = model.NewCIStr($1) h.HintData = model.NewCIStr($1)
$$ = h $$ = h
} }
...@@ -449,11 +461,11 @@ UnitOfBytes: ...@@ -449,11 +461,11 @@ UnitOfBytes:
HintTrueOrFalse: HintTrueOrFalse:
"TRUE" "TRUE"
{ {
$$ = &ast.TableOptimizerHint{HintFlag: true} $$ = &ast.TableOptimizerHint{HintData: true}
} }
| "FALSE" | "FALSE"
{ {
$$ = &ast.TableOptimizerHint{HintFlag: false} $$ = &ast.TableOptimizerHint{HintData: false}
} }
JoinOrderOptimizerHintName: JoinOrderOptimizerHintName:
...@@ -472,7 +484,7 @@ UnsupportedTableLevelOptimizerHintName: ...@@ -472,7 +484,7 @@ UnsupportedTableLevelOptimizerHintName:
| "NO_MERGE" | "NO_MERGE"
SupportedTableLevelOptimizerHintName: SupportedTableLevelOptimizerHintName:
"SM_JOIN" "MERGE_JOIN"
| "INL_JOIN" | "INL_JOIN"
| "INL_HASH_JOIN" | "INL_HASH_JOIN"
| "SWAP_JOIN_INPUTS" | "SWAP_JOIN_INPUTS"
...@@ -507,7 +519,7 @@ SubqueryStrategy: ...@@ -507,7 +519,7 @@ SubqueryStrategy:
BooleanHintName: BooleanHintName:
"USE_TOJA" "USE_TOJA"
| "ENABLE_PLAN_CACHE" | "USE_CASCADES"
NullaryHintName: NullaryHintName:
"USE_PLAN_CACHE" "USE_PLAN_CACHE"
...@@ -516,6 +528,7 @@ NullaryHintName: ...@@ -516,6 +528,7 @@ NullaryHintName:
| "AGG_TO_COP" | "AGG_TO_COP"
| "NO_INDEX_MERGE" | "NO_INDEX_MERGE"
| "READ_CONSISTENT_REPLICA" | "READ_CONSISTENT_REPLICA"
| "IGNORE_PLAN_CACHE"
HintQueryType: HintQueryType:
"OLAP" "OLAP"
...@@ -556,7 +569,7 @@ Identifier: ...@@ -556,7 +569,7 @@ Identifier:
| "QB_NAME" | "QB_NAME"
/* TiDB hint names */ /* TiDB hint names */
| "AGG_TO_COP" | "AGG_TO_COP"
| "ENABLE_PLAN_CACHE" | "IGNORE_PLAN_CACHE"
| "HASH_AGG" | "HASH_AGG"
| "IGNORE_INDEX" | "IGNORE_INDEX"
| "INL_HASH_JOIN" | "INL_HASH_JOIN"
...@@ -567,13 +580,15 @@ Identifier: ...@@ -567,13 +580,15 @@ Identifier:
| "QUERY_TYPE" | "QUERY_TYPE"
| "READ_CONSISTENT_REPLICA" | "READ_CONSISTENT_REPLICA"
| "READ_FROM_STORAGE" | "READ_FROM_STORAGE"
| "SM_JOIN" | "MERGE_JOIN"
| "STREAM_AGG" | "STREAM_AGG"
| "SWAP_JOIN_INPUTS" | "SWAP_JOIN_INPUTS"
| "USE_INDEX_MERGE" | "USE_INDEX_MERGE"
| "USE_INDEX" | "USE_INDEX"
| "USE_PLAN_CACHE" | "USE_PLAN_CACHE"
| "USE_TOJA" | "USE_TOJA"
| "TIME_RANGE"
| "USE_CASCADES"
/* other keywords */ /* other keywords */
| "OLAP" | "OLAP"
| "OLTP" | "OLTP"
......
...@@ -66,6 +66,8 @@ const ( ...@@ -66,6 +66,8 @@ const (
ActionCreateSequence ActionType = 34 ActionCreateSequence ActionType = 34
ActionAlterSequence ActionType = 35 ActionAlterSequence ActionType = 35
ActionDropSequence ActionType = 36 ActionDropSequence ActionType = 36
ActionAddColumns ActionType = 37
ActionDropColumns ActionType = 38
) )
const ( const (
...@@ -111,6 +113,8 @@ var actionMap = map[ActionType]string{ ...@@ -111,6 +113,8 @@ var actionMap = map[ActionType]string{
ActionCreateSequence: "create sequence", ActionCreateSequence: "create sequence",
ActionAlterSequence: "alter sequence", ActionAlterSequence: "alter sequence",
ActionDropSequence: "drop sequence", ActionDropSequence: "drop sequence",
ActionAddColumns: "add multi-columns",
ActionDropColumns: "drop multi-columns",
} }
// String return current ddl action in string // String return current ddl action in string
......
...@@ -23,7 +23,6 @@ import ( ...@@ -23,7 +23,6 @@ import (
"github.com/pingcap/parser/auth" "github.com/pingcap/parser/auth"
"github.com/pingcap/parser/mysql" "github.com/pingcap/parser/mysql"
"github.com/pingcap/parser/types" "github.com/pingcap/parser/types"
"github.com/pingcap/tipb/go-tipb"
) )
// SchemaState is the state for schema elements. // SchemaState is the state for schema elements.
...@@ -87,6 +86,8 @@ type ColumnInfo struct { ...@@ -87,6 +86,8 @@ type ColumnInfo struct {
OriginDefaultValue interface{} `json:"origin_default"` OriginDefaultValue interface{} `json:"origin_default"`
DefaultValue interface{} `json:"default"` DefaultValue interface{} `json:"default"`
DefaultValueBit []byte `json:"default_bit"` DefaultValueBit []byte `json:"default_bit"`
// DefaultIsExpr is indicates the default value string is expr.
DefaultIsExpr bool `json:"default_is_expr"`
GeneratedExprString string `json:"generated_expr_string"` GeneratedExprString string `json:"generated_expr_string"`
GeneratedStored bool `json:"generated_stored"` GeneratedStored bool `json:"generated_stored"`
Dependences map[string]struct{} `json:"dependences"` Dependences map[string]struct{} `json:"dependences"`
...@@ -350,6 +351,17 @@ type TiFlashReplicaInfo struct { ...@@ -350,6 +351,17 @@ type TiFlashReplicaInfo struct {
Count uint64 Count uint64
LocationLabels []string LocationLabels []string
Available bool Available bool
AvailablePartitionIDs []int64
}
// IsPartitionAvailable checks whether the partition table replica was available.
func (tr *TiFlashReplicaInfo) IsPartitionAvailable(pid int64) bool {
for _, id := range tr.AvailablePartitionIDs {
if id == pid {
return true
}
}
return false
} }
// GetPartitionInfo returns the partition information. // GetPartitionInfo returns the partition information.
...@@ -724,11 +736,12 @@ type IndexInfo struct { ...@@ -724,11 +736,12 @@ type IndexInfo struct {
Name CIStr `json:"idx_name"` // Index name. Name CIStr `json:"idx_name"` // Index name.
Table CIStr `json:"tbl_name"` // Table name. Table CIStr `json:"tbl_name"` // Table name.
Columns []*IndexColumn `json:"idx_cols"` // Index columns. Columns []*IndexColumn `json:"idx_cols"` // Index columns.
Unique bool `json:"is_unique"` // Whether the index is unique.
Primary bool `json:"is_primary"` // Whether the index is primary key.
State SchemaState `json:"state"` State SchemaState `json:"state"`
Comment string `json:"comment"` // Comment Comment string `json:"comment"` // Comment
Tp IndexType `json:"index_type"` // Index type: Btree, Hash or Rtree Tp IndexType `json:"index_type"` // Index type: Btree, Hash or Rtree
Unique bool `json:"is_unique"` // Whether the index is unique.
Primary bool `json:"is_primary"` // Whether the index is primary key.
Invisible bool `json:"is_invisible"` // Whether the index is invisible.
} }
// Clone clones IndexInfo. // Clone clones IndexInfo.
...@@ -840,75 +853,6 @@ func (cis *CIStr) UnmarshalJSON(b []byte) error { ...@@ -840,75 +853,6 @@ func (cis *CIStr) UnmarshalJSON(b []byte) error {
return nil return nil
} }
// ColumnsToProto converts a slice of model.ColumnInfo to a slice of tipb.ColumnInfo.
func ColumnsToProto(columns []*ColumnInfo, pkIsHandle bool) []*tipb.ColumnInfo {
cols := make([]*tipb.ColumnInfo, 0, len(columns))
for _, c := range columns {
col := ColumnToProto(c)
// TODO: Here `PkHandle`'s meaning is changed, we will change it to `IsHandle` when tikv's old select logic
// is abandoned.
if (pkIsHandle && mysql.HasPriKeyFlag(c.Flag)) || c.ID == ExtraHandleID {
col.PkHandle = true
} else {
col.PkHandle = false
}
cols = append(cols, col)
}
return cols
}
// IndexToProto converts a model.IndexInfo to a tipb.IndexInfo.
func IndexToProto(t *TableInfo, idx *IndexInfo) *tipb.IndexInfo {
pi := &tipb.IndexInfo{
TableId: t.ID,
IndexId: idx.ID,
Unique: idx.Unique,
}
cols := make([]*tipb.ColumnInfo, 0, len(idx.Columns)+1)
for _, c := range idx.Columns {
cols = append(cols, ColumnToProto(t.Columns[c.Offset]))
}
if t.PKIsHandle {
// Coprocessor needs to know PKHandle column info, so we need to append it.
for _, col := range t.Columns {
if mysql.HasPriKeyFlag(col.Flag) {
colPB := ColumnToProto(col)
colPB.PkHandle = true
cols = append(cols, colPB)
break
}
}
}
pi.Columns = cols
return pi
}
// ColumnToProto converts model.ColumnInfo to tipb.ColumnInfo.
func ColumnToProto(c *ColumnInfo) *tipb.ColumnInfo {
pc := &tipb.ColumnInfo{
ColumnId: c.ID,
Collation: collationToProto(c.FieldType.Collate),
ColumnLen: int32(c.FieldType.Flen),
Decimal: int32(c.FieldType.Decimal),
Flag: int32(c.Flag),
Elems: c.Elems,
}
pc.Tp = int32(c.FieldType.Tp)
return pc
}
// TODO: update it when more collate is supported.
func collationToProto(c string) int32 {
v := mysql.CollationNames[c]
if v == mysql.BinaryDefaultCollationID {
return int32(mysql.BinaryDefaultCollationID)
}
// We only support binary and utf8_bin collation.
// Setting other collations to utf8_bin for old data compatibility.
// For the data created when we didn't enforce utf8_bin collation in create table.
return int32(mysql.DefaultCollationID)
}
// TableColumnID is composed by table ID and column ID. // TableColumnID is composed by table ID and column ID.
type TableColumnID struct { type TableColumnID struct {
TableID int64 TableID int64
......
...@@ -18,7 +18,7 @@ import ( ...@@ -18,7 +18,7 @@ import (
"strings" "strings"
"github.com/pingcap/errors" "github.com/pingcap/errors"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
) )
func newInvalidModeErr(s string) error { func newInvalidModeErr(s string) error {
...@@ -779,7 +779,7 @@ func Str2Priority(val string) PriorityEnum { ...@@ -779,7 +779,7 @@ func Str2Priority(val string) PriorityEnum {
} }
// Restore implements Node interface. // Restore implements Node interface.
func (n *PriorityEnum) Restore(ctx *RestoreCtx) error { func (n *PriorityEnum) Restore(ctx *format.RestoreCtx) error {
switch *n { switch *n {
case NoPriority: case NoPriority:
return nil return nil
......
...@@ -900,6 +900,7 @@ const ( ...@@ -900,6 +900,7 @@ const (
ErrInvalidJSONPathWildcard = 3149 ErrInvalidJSONPathWildcard = 3149
ErrInvalidJSONContainsPathType = 3150 ErrInvalidJSONContainsPathType = 3150
ErrJSONUsedAsKey = 3152 ErrJSONUsedAsKey = 3152
ErrJSONDocumentNULLKey = 3158
ErrBadUser = 3162 ErrBadUser = 3162
ErrUserAlreadyExists = 3163 ErrUserAlreadyExists = 3163
ErrInvalidJSONPathArrayCell = 3165 ErrInvalidJSONPathArrayCell = 3165
...@@ -960,119 +961,12 @@ const ( ...@@ -960,119 +961,12 @@ const (
ErrSequenceInvalidTableStructure = 4141 ErrSequenceInvalidTableStructure = 4141
// TiDB self-defined errors. // TiDB self-defined errors.
ErrMemExceedThreshold = 8001
ErrForUpdateCantRetry = 8002
ErrAdminCheckTable = 8003
ErrTxnTooLarge = 8004
ErrWriteConflictInTiDB = 8005
ErrInvalidPluginID = 8101
ErrInvalidPluginManifest = 8102
ErrInvalidPluginName = 8103
ErrInvalidPluginVersion = 8104
ErrDuplicatePlugin = 8105
ErrInvalidPluginSysVarName = 8106
ErrRequireVersionCheckFail = 8107
ErrUnsupportedType = 8108
ErrAnalyzeMissIndex = 8109
ErrCartesianProductUnsupported = 8110
ErrPreparedStmtNotFound = 8111
ErrWrongParamCount = 8112
ErrSchemaChanged = 8113
ErrUnknownPlan = 8114
ErrPrepareMulti = 8115
ErrPrepareDDL = 8116
ErrResultIsEmpty = 8117
ErrBuildExecutor = 8118
ErrBatchInsertFail = 8119
ErrGetStartTS = 8120
ErrPrivilegeCheckFail = 8121
ErrInvalidWildCard = 8122
ErrMixOfGroupFuncAndFieldsIncompatible = 8123
ErrUnsupportedReloadPlugin = 8018
ErrUnsupportedReloadPluginVar = 8019
ErrTableLocked = 8020
ErrNotExist = 8021
ErrTxnRetryable = 8022
ErrCannotSetNilValue = 8023
ErrInvalidTxn = 8024
ErrEntryTooLarge = 8025
ErrNotImplemented = 8026
ErrInfoSchemaExpired = 8027
ErrInfoSchemaChanged = 8028
ErrBadNumber = 8029
ErrCastAsSignedOverflow = 8030
ErrCastNegIntAsUnsigned = 8031
ErrInvalidYearFormat = 8032
ErrInvalidYear = 8033
ErrIncorrectDatetimeValue = 8034
ErrInvalidTimeFormat = 8036
ErrInvalidWeekModeFormat = 8037
ErrFieldGetDefaultFailed = 8038
ErrIndexOutBound = 8039
ErrUnsupportedOp = 8040
ErrRowNotFound = 8041
ErrTableStateCantNone = 8042
ErrColumnStateNonPublic = 8043
ErrIndexStateCantNone = 8044
ErrInvalidRecordKey = 8045
ErrColumnStateCantNone = 8046
ErrUnsupportedValueForVar = 8047
ErrUnsupportedIsolationLevel = 8048
ErrLoadPrivilege = 8049
ErrInvalidPrivilegeType = 8050
ErrUnknownFieldType = 8051
ErrInvalidSequence = 8052
ErrCantGetValidID = 8053
ErrCantSetToNull = 8054
ErrSnapshotTooOld = 8055
ErrInvalidTableID = 8056
ErrInvalidType = 8057
ErrUnknownAllocatorType = 8058
ErrAutoRandReadFailed = 8059
ErrInvalidIncrementAndOffset = 8060
ErrWarnOptimizerHintUnsupportedHint = 8061 ErrWarnOptimizerHintUnsupportedHint = 8061
ErrWarnOptimizerHintInvalidToken = 8062 ErrWarnOptimizerHintInvalidToken = 8062
ErrWarnMemoryQuotaOverflow = 8063 ErrWarnMemoryQuotaOverflow = 8063
ErrWarnOptimizerHintParseError = 8064 ErrWarnOptimizerHintParseError = 8064
ErrWarnOptimizerHintInvalidInteger = 8065 ErrWarnOptimizerHintInvalidInteger = 8065
// Error codes used by TiDB ddl package // Stop adding error code here!
ErrUnsupportedDDLOperation = 8200 // They are moved to github.com/pingcap/tidb/errno
ErrNotOwner = 8201
ErrCantDecodeIndex = 8202
ErrInvalidDDLWorker = 8203
ErrInvalidDDLJob = 8204
ErrInvalidDDLJobFlag = 8205
ErrWaitReorgTimeout = 8206
ErrInvalidStoreVersion = 8207
ErrUnknownTypeLength = 8208
ErrUnknownFractionLength = 8209
ErrInvalidDDLState = 8210
ErrReorgPanic = 8211
ErrInvalidSplitRegionRanges = 8212
ErrInvalidDDLJobVersion = 8213
ErrCancelledDDLJob = 8214
ErrRepairTable = 8215
ErrInvalidAutoRandom = 8216
ErrInvalidHashKeyFlag = 8217
ErrInvalidListIndex = 8218
ErrInvalidListMetaData = 8219
ErrWriteOnSnapshot = 8220
ErrInvalidKey = 8221
ErrInvalidIndexKey = 8222
ErrDataInConsistent = 8223
ErrDDLJobNotFound = 8224
ErrCancelFinishedDDLJob = 8225
ErrCannotCancelDDLJob = 8226
ErrSequenceUnsupportedTableOption = 8227
// TiKV/PD errors.
ErrPDServerTimeout = 9001
ErrTiKVServerTimeout = 9002
ErrTiKVServerBusy = 9003
ErrResolveLockTimeout = 9004
ErrRegionUnavailable = 9005
ErrGCTooEarly = 9006
ErrWriteConflict = 9007
ErrTiKVStoreLimit = 9008
) )
...@@ -896,6 +896,7 @@ var MySQLErrName = map[uint16]string{ ...@@ -896,6 +896,7 @@ var MySQLErrName = map[uint16]string{
ErrInvalidJSONPathWildcard: "In this situation, path expressions may not contain the * and ** tokens.", ErrInvalidJSONPathWildcard: "In this situation, path expressions may not contain the * and ** tokens.",
ErrInvalidJSONContainsPathType: "The second argument can only be either 'one' or 'all'.", ErrInvalidJSONContainsPathType: "The second argument can only be either 'one' or 'all'.",
ErrJSONUsedAsKey: "JSON column '%-.192s' cannot be used in key specification.", ErrJSONUsedAsKey: "JSON column '%-.192s' cannot be used in key specification.",
ErrJSONDocumentNULLKey: "JSON documents may not contain NULL member names.",
ErrBadUser: "User %s does not exist.", ErrBadUser: "User %s does not exist.",
ErrUserAlreadyExists: "User %s already exists.", ErrUserAlreadyExists: "User %s already exists.",
ErrInvalidJSONPathArrayCell: "A path expression is not a path to a cell in an array.", ErrInvalidJSONPathArrayCell: "A path expression is not a path to a cell in an array.",
...@@ -957,119 +958,9 @@ var MySQLErrName = map[uint16]string{ ...@@ -957,119 +958,9 @@ var MySQLErrName = map[uint16]string{
ErrSequenceInvalidTableStructure: "Sequence '%-.64s.%-.64s' table structure is invalid (%s)", ErrSequenceInvalidTableStructure: "Sequence '%-.64s.%-.64s' table structure is invalid (%s)",
// TiDB errors. // TiDB errors.
ErrMemExceedThreshold: "%s holds %dB memory, exceeds threshold %dB.%s",
ErrForUpdateCantRetry: "[%d] can not retry select for update statement",
ErrAdminCheckTable: "TiDB admin check table failed.",
ErrTxnTooLarge: "Transaction is too large, size: %d",
ErrWriteConflictInTiDB: "Write conflict, txnStartTS %d is stale",
ErrInvalidPluginID: "Wrong plugin id: %s, valid plugin id is [name]-[version], both name and version should not contain '-'",
ErrInvalidPluginManifest: "Cannot read plugin %s's manifest",
ErrInvalidPluginName: "Plugin load with %s but got wrong name %s",
ErrInvalidPluginVersion: "Plugin load with %s but got %s",
ErrDuplicatePlugin: "Plugin [%s] is redeclared",
ErrInvalidPluginSysVarName: "Plugin %s's sysVar %s must start with its plugin name %s",
ErrRequireVersionCheckFail: "Plugin %s require %s be %v but got %v",
ErrUnsupportedReloadPlugin: "Plugin %s isn't loaded so cannot be reloaded",
ErrUnsupportedReloadPluginVar: "Reload plugin with different sysVar is unsupported %v",
ErrTableLocked: "Table '%s' was locked in %s by %v",
ErrNotExist: "Error: key not exist",
ErrTxnRetryable: "Error: KV error safe to retry %s ",
ErrCannotSetNilValue: "can not set nil value",
ErrInvalidTxn: "invalid transaction",
ErrEntryTooLarge: "entry too large, the max entry size is %d, the size of data is %d",
ErrNotImplemented: "not implemented",
ErrInfoSchemaExpired: "Information schema is out of date: schema failed to update in 1 lease, please make sure TiDB can connect to TiKV",
ErrInfoSchemaChanged: "Information schema is changed during the execution of the statement(for example, table definition may be updated by other DDL ran in parallel). If you see this error often, try increasing `tidb_max_delta_schema_count`",
ErrBadNumber: "Bad Number",
ErrCastAsSignedOverflow: "Cast to signed converted positive out-of-range integer to it's negative complement",
ErrCastNegIntAsUnsigned: "Cast to unsigned converted negative integer to it's positive complement",
ErrInvalidYearFormat: "invalid year format",
ErrInvalidYear: "invalid year",
ErrIncorrectDatetimeValue: "Incorrect datetime value: '%s'",
ErrInvalidTimeFormat: "invalid time format: '%v'",
ErrInvalidWeekModeFormat: "invalid week mode format: '%v'",
ErrFieldGetDefaultFailed: "Field '%s' get default value fail",
ErrIndexOutBound: "Index column %s offset out of bound, offset: %d, row: %v",
ErrUnsupportedOp: "operation not supported",
ErrRowNotFound: "can not find the row: %s",
ErrTableStateCantNone: "table %s can't be in none state",
ErrColumnStateCantNone: "column %s can't be in none state",
ErrColumnStateNonPublic: "can not use non-public column",
ErrIndexStateCantNone: "index %s can't be in none state",
ErrInvalidRecordKey: "invalid record key",
ErrUnsupportedValueForVar: "variable '%s' does not yet support value: %s",
ErrUnsupportedIsolationLevel: "The isolation level '%s' is not supported. Set tidb_skip_isolation_level_check=1 to skip this error",
ErrInvalidDDLWorker: "Invalid DDL worker",
ErrUnsupportedDDLOperation: "Unsupported %s",
ErrNotOwner: "TiDB server is not a DDL owner",
ErrCantDecodeIndex: "Cannot decode index value, because %s",
ErrInvalidDDLJob: "Invalid DDL job",
ErrInvalidDDLJobFlag: "Invalid DDL job flag",
ErrWaitReorgTimeout: "Timeout waiting for data reorganization",
ErrInvalidStoreVersion: "Invalid storage current version: %d",
ErrUnknownTypeLength: "Unknown length for type %d",
ErrUnknownFractionLength: "Unknown length for type %d and fraction %d",
ErrInvalidDDLJobVersion: "Version %d of DDL job is greater than current one: %d",
ErrInvalidSplitRegionRanges: "Failed to split region ranges",
ErrReorgPanic: "Reorg worker panic",
ErrInvalidDDLState: "Invalid %s state: %v",
ErrCancelledDDLJob: "Cancelled DDL job",
ErrRepairTable: "Failed to repair table: %s",
ErrLoadPrivilege: "Load privilege table fail: %s",
ErrInvalidPrivilegeType: "unknown privilege type %s",
ErrUnknownFieldType: "unknown field type",
ErrInvalidSequence: "invalid sequence",
ErrInvalidType: "invalid type",
ErrCantGetValidID: "cannot get valid auto-increment id in retry",
ErrCantSetToNull: "cannot set variable to null",
ErrSnapshotTooOld: "snapshot is older than GC safe point %s",
ErrInvalidTableID: "invalid TableID",
ErrInvalidAutoRandom: "Invalid auto random: %s",
ErrInvalidHashKeyFlag: "invalid encoded hash key flag",
ErrInvalidListIndex: "invalid list index",
ErrInvalidListMetaData: "invalid list meta data",
ErrWriteOnSnapshot: "write on snapshot",
ErrInvalidKey: "invalid key",
ErrInvalidIndexKey: "invalid index key",
ErrDataInConsistent: "data isn't equal",
ErrDDLJobNotFound: "DDL Job:%v not found",
ErrCancelFinishedDDLJob: "This job:%v is finished, so can't be cancelled",
ErrCannotCancelDDLJob: "This job:%v is almost finished, can't be cancelled now",
ErrUnknownAllocatorType: "Invalid allocator type",
ErrAutoRandReadFailed: "Failed to read auto-random value from storage engine",
ErrInvalidIncrementAndOffset: "Invalid auto_increment settings: auto_increment_increment: %d, auto_increment_offset: %d, both of them must be in range [1..65535]",
ErrWarnOptimizerHintInvalidInteger: "integer value is out of range in '%s'", ErrWarnOptimizerHintInvalidInteger: "integer value is out of range in '%s'",
ErrWarnOptimizerHintUnsupportedHint: "Optimizer hint %s is not supported by TiDB and is ignored", ErrWarnOptimizerHintUnsupportedHint: "Optimizer hint %s is not supported by TiDB and is ignored",
ErrWarnOptimizerHintInvalidToken: "Cannot use %s '%s' (tok = %d) in an optimizer hint", ErrWarnOptimizerHintInvalidToken: "Cannot use %s '%s' (tok = %d) in an optimizer hint",
ErrWarnMemoryQuotaOverflow: "Max value of MEMORY_QUOTA is %d bytes, ignore this invalid limit", ErrWarnMemoryQuotaOverflow: "Max value of MEMORY_QUOTA is %d bytes, ignore this invalid limit",
ErrWarnOptimizerHintParseError: "Optimizer hint syntax error at %v", ErrWarnOptimizerHintParseError: "Optimizer hint syntax error at %v",
ErrSequenceUnsupportedTableOption: "Unsupported sequence table-option %s",
ErrUnsupportedType: "Unsupported type %T",
ErrAnalyzeMissIndex: "Index '%s' in field list does not exist in table '%s'",
ErrCartesianProductUnsupported: "Cartesian product is unsupported",
ErrPreparedStmtNotFound: "Prepared statement not found",
ErrWrongParamCount: "Wrong parameter count",
ErrSchemaChanged: "Schema has changed",
ErrUnknownPlan: "Unknown plan",
ErrPrepareMulti: "Can not prepare multiple statements",
ErrPrepareDDL: "Can not prepare DDL statements with parameters",
ErrResultIsEmpty: "Result is empty",
ErrBuildExecutor: "Failed to build executor",
ErrBatchInsertFail: "Batch insert failed, please clean the table and try again.",
ErrGetStartTS: "Can not get start ts",
ErrPrivilegeCheckFail: "privilege check fail", // this error message should begin lowercased to be compatible with the test
ErrInvalidWildCard: "Wildcard fields without any table name appears in wrong place",
ErrMixOfGroupFuncAndFieldsIncompatible: "In aggregated query without GROUP BY, expression #%d of SELECT list contains nonaggregated column '%s'; this is incompatible with sql_mode=only_full_group_by",
// TiKV/PD errors.
ErrPDServerTimeout: "PD server timeout",
ErrTiKVServerTimeout: "TiKV server timeout",
ErrTiKVServerBusy: "TiKV server is busy",
ErrResolveLockTimeout: "Resolve lock timeout",
ErrRegionUnavailable: "Region is unavailable",
ErrGCTooEarly: "GC life time is shorter than transaction duration, transaction starts at %v, GC safe point is %v",
ErrWriteConflict: "Write conflict, txnStartTS=%d, conflictStartTS=%d, conflictCommitTS=%d, key=%s",
ErrTiKVStoreLimit: "Store token is up to the limit, store id = %d",
} }
...@@ -255,5 +255,6 @@ var MySQLState = map[uint16]string{ ...@@ -255,5 +255,6 @@ var MySQLState = map[uint16]string{
ErrInvalidJSONData: "22032", ErrInvalidJSONData: "22032",
ErrInvalidJSONPathWildcard: "42000", ErrInvalidJSONPathWildcard: "42000",
ErrJSONUsedAsKey: "42000", ErrJSONUsedAsKey: "42000",
ErrJSONDocumentNULLKey: "22032",
ErrInvalidJSONPathArrayCell: "42000", ErrInvalidJSONPathArrayCell: "42000",
} }
...@@ -18,7 +18,7 @@ import ( ...@@ -18,7 +18,7 @@ import (
"io" "io"
"github.com/pingcap/errors" "github.com/pingcap/errors"
. "github.com/pingcap/parser/format" "github.com/pingcap/parser/format"
) )
// Op is opcode type. // Op is opcode type.
...@@ -141,7 +141,7 @@ func (o Op) Format(w io.Writer) { ...@@ -141,7 +141,7 @@ func (o Op) Format(w io.Writer) {
} }
// Restore the Op into a Writer // Restore the Op into a Writer
func (o Op) Restore(ctx *RestoreCtx) error { func (o Op) Restore(ctx *format.RestoreCtx) error {
if v, ok := opsLiteral[o]; ok { if v, ok := opsLiteral[o]; ok {
ctx.WriteKeyWord(v) ctx.WriteKeyWord(v)
return nil return nil
......
...@@ -24,12 +24,6 @@ import ( ...@@ -24,12 +24,6 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
// Global error instances.
var (
ErrCritical = ClassGlobal.New(CodeExecResultIsEmpty, "critical error %v")
ErrResultUndetermined = ClassGlobal.New(CodeResultUndetermined, "execution result undetermined")
)
// ErrCode represents a specific error type in a error class. // ErrCode represents a specific error type in a error class.
// Same error code can be used in different error classes. // Same error code can be used in different error classes.
type ErrCode int type ErrCode int
...@@ -57,68 +51,52 @@ const ( ...@@ -57,68 +51,52 @@ const (
type ErrClass int type ErrClass int
// Error classes. // Error classes.
const ( var (
ClassAutoid ErrClass = iota + 1 ClassAutoid = RegisterErrorClass(1, "autoid")
ClassDDL ClassDDL = RegisterErrorClass(2, "ddl")
ClassDomain ClassDomain = RegisterErrorClass(3, "domain")
ClassEvaluator ClassEvaluator = RegisterErrorClass(4, "evaluator")
ClassExecutor ClassExecutor = RegisterErrorClass(5, "executor")
ClassExpression ClassExpression = RegisterErrorClass(6, "expression")
ClassAdmin ClassAdmin = RegisterErrorClass(7, "admin")
ClassKV ClassKV = RegisterErrorClass(8, "kv")
ClassMeta ClassMeta = RegisterErrorClass(9, "meta")
ClassOptimizer ClassOptimizer = RegisterErrorClass(10, "planner")
ClassParser ClassParser = RegisterErrorClass(11, "parser")
ClassPerfSchema ClassPerfSchema = RegisterErrorClass(12, "perfschema")
ClassPrivilege ClassPrivilege = RegisterErrorClass(13, "privilege")
ClassSchema ClassSchema = RegisterErrorClass(14, "schema")
ClassServer ClassServer = RegisterErrorClass(15, "server")
ClassStructure ClassStructure = RegisterErrorClass(16, "structure")
ClassVariable ClassVariable = RegisterErrorClass(17, "variable")
ClassXEval ClassXEval = RegisterErrorClass(18, "xeval")
ClassTable ClassTable = RegisterErrorClass(19, "table")
ClassTypes ClassTypes = RegisterErrorClass(20, "types")
ClassGlobal ClassGlobal = RegisterErrorClass(21, "global")
ClassMockTikv ClassMockTikv = RegisterErrorClass(22, "mocktikv")
ClassJSON ClassJSON = RegisterErrorClass(23, "json")
ClassTiKV ClassTiKV = RegisterErrorClass(24, "tikv")
ClassSession ClassSession = RegisterErrorClass(25, "session")
ClassPlugin ClassPlugin = RegisterErrorClass(26, "plugin")
ClassUtil ClassUtil = RegisterErrorClass(27, "util")
// Add more as needed. // Add more as needed.
) )
var errClz2Str = map[ErrClass]string{ var errClass2Desc = make(map[ErrClass]string)
ClassAutoid: "autoid",
ClassDDL: "ddl", // RegisterErrorClass registers new error class for terror.
ClassDomain: "domain", func RegisterErrorClass(classCode int, desc string) ErrClass {
ClassExecutor: "executor", errClass := ErrClass(classCode)
ClassExpression: "expression", if _, exists := errClass2Desc[errClass]; exists {
ClassAdmin: "admin", panic(fmt.Sprintf("duplicate register ClassCode %d - %s", classCode, desc))
ClassMeta: "meta", }
ClassKV: "kv", errClass2Desc[errClass] = desc
ClassOptimizer: "planner", return errClass
ClassParser: "parser",
ClassPerfSchema: "perfschema",
ClassPrivilege: "privilege",
ClassSchema: "schema",
ClassServer: "server",
ClassStructure: "structure",
ClassVariable: "variable",
ClassTable: "table",
ClassTypes: "types",
ClassGlobal: "global",
ClassMockTikv: "mocktikv",
ClassJSON: "json",
ClassTiKV: "tikv",
ClassSession: "session",
ClassPlugin: "plugin",
ClassUtil: "util",
} }
// String implements fmt.Stringer interface. // String implements fmt.Stringer interface.
func (ec ErrClass) String() string { func (ec ErrClass) String() string {
if s, exists := errClz2Str[ec]; exists { if s, exists := errClass2Desc[ec]; exists {
return s return s
} }
return strconv.Itoa(int(ec)) return strconv.Itoa(int(ec))
...@@ -141,9 +119,18 @@ func (ec ErrClass) NotEqualClass(err error) bool { ...@@ -141,9 +119,18 @@ func (ec ErrClass) NotEqualClass(err error) bool {
return !ec.EqualClass(err) return !ec.EqualClass(err)
} }
// New creates an *Error with an error code and an error message. // New defines an *Error with an error code and an error message.
// Usually used to create base *Error. // Usually used to create base *Error.
// Attention:
// this method is not goroutine-safe and
// usually be used in global variable initializer
func (ec ErrClass) New(code ErrCode, message string) *Error { func (ec ErrClass) New(code ErrCode, message string) *Error {
clsMap, ok := ErrClassToMySQLCodes[ec]
if !ok {
clsMap = make(map[ErrCode]struct{})
ErrClassToMySQLCodes[ec] = clsMap
}
clsMap[code] = struct{}{}
return &Error{ return &Error{
class: ec, class: ec,
code: code, code: code,
...@@ -152,10 +139,25 @@ func (ec ErrClass) New(code ErrCode, message string) *Error { ...@@ -152,10 +139,25 @@ func (ec ErrClass) New(code ErrCode, message string) *Error {
} }
// NewStd calls New using the standard message for the error code // NewStd calls New using the standard message for the error code
// Attention:
// this method is not goroutine-safe and
// usually be used in global variable initializer
func (ec ErrClass) NewStd(code ErrCode) *Error { func (ec ErrClass) NewStd(code ErrCode) *Error {
return ec.New(code, mysql.MySQLErrName[uint16(code)]) return ec.New(code, mysql.MySQLErrName[uint16(code)])
} }
// Synthesize synthesizes an *Error in the air
// it didn't register error into ErrClassToMySQLCodes
// so it's goroutine-safe
// and often be used to create Error came from other systems like TiKV.
func (ec ErrClass) Synthesize(code ErrCode, message string) *Error {
return &Error{
class: ec,
code: code,
message: message,
}
}
// Error implements error interface and adds integer Class and Code, so // Error implements error interface and adds integer Class and Code, so
// errors with different message can be compared. // errors with different message can be compared.
type Error struct { type Error struct {
...@@ -291,21 +293,22 @@ func (e *Error) getMySQLErrorCode() uint16 { ...@@ -291,21 +293,22 @@ func (e *Error) getMySQLErrorCode() uint16 {
log.Warn("Unknown error class", zap.Int("class", int(e.class))) log.Warn("Unknown error class", zap.Int("class", int(e.class)))
return defaultMySQLErrorCode return defaultMySQLErrorCode
} }
code, ok := codeMap[e.code] _, ok = codeMap[e.code]
if !ok { if !ok {
log.Debug("Unknown error code", zap.Int("class", int(e.class)), zap.Uint16("code", code)) log.Debug("Unknown error code", zap.Int("class", int(e.class)), zap.Int("code", int(e.code)))
return defaultMySQLErrorCode return defaultMySQLErrorCode
} }
return code return uint16(e.code)
} }
var ( var (
// ErrClassToMySQLCodes is the map of ErrClass to code-map. // ErrClassToMySQLCodes is the map of ErrClass to code-set.
ErrClassToMySQLCodes map[ErrClass]map[ErrCode]uint16 ErrClassToMySQLCodes = make(map[ErrClass]map[ErrCode]struct{})
ErrCritical = ClassGlobal.New(CodeExecResultIsEmpty, "critical error %v")
ErrResultUndetermined = ClassGlobal.New(CodeResultUndetermined, "execution result undetermined")
) )
func init() { func init() {
ErrClassToMySQLCodes = make(map[ErrClass]map[ErrCode]uint16)
defaultMySQLErrorCode = mysql.ErrUnknown defaultMySQLErrorCode = mysql.ErrUnknown
} }
......
...@@ -47,6 +47,8 @@ var ( ...@@ -47,6 +47,8 @@ var (
ErrUnknownAlterLock = terror.ClassParser.New(mysql.ErrUnknownAlterLock, mysql.MySQLErrName[mysql.ErrUnknownAlterLock]) ErrUnknownAlterLock = terror.ClassParser.New(mysql.ErrUnknownAlterLock, mysql.MySQLErrName[mysql.ErrUnknownAlterLock])
// ErrUnknownAlterAlgorithm returns for no alter algorithm found error. // ErrUnknownAlterAlgorithm returns for no alter algorithm found error.
ErrUnknownAlterAlgorithm = terror.ClassParser.New(mysql.ErrUnknownAlterAlgorithm, mysql.MySQLErrName[mysql.ErrUnknownAlterAlgorithm]) ErrUnknownAlterAlgorithm = terror.ClassParser.New(mysql.ErrUnknownAlterAlgorithm, mysql.MySQLErrName[mysql.ErrUnknownAlterAlgorithm])
// ErrWrongValue returns for wrong value
ErrWrongValue = terror.ClassParser.New(mysql.ErrWrongValue, mysql.MySQLErrName[mysql.ErrWrongValue])
// SpecFieldPattern special result field pattern // SpecFieldPattern special result field pattern
SpecFieldPattern = regexp.MustCompile(`(\/\*!(M?[0-9]{5,6})?|\*\/)`) SpecFieldPattern = regexp.MustCompile(`(\/\*!(M?[0-9]{5,6})?|\*\/)`)
specCodePattern = regexp.MustCompile(`\/\*!(M?[0-9]{5,6})?([^*]|\*+[^*/])*\*+\/`) specCodePattern = regexp.MustCompile(`\/\*!(M?[0-9]{5,6})?([^*]|\*+[^*/])*\*+\/`)
...@@ -58,22 +60,6 @@ var ( ...@@ -58,22 +60,6 @@ var (
specVersionCodeValue = regexp.MustCompile(`[0-9]{5,6}`) specVersionCodeValue = regexp.MustCompile(`[0-9]{5,6}`)
) )
func init() {
parserMySQLErrCodes := map[terror.ErrCode]uint16{
mysql.ErrSyntax: mysql.ErrSyntax,
mysql.ErrParse: mysql.ErrParse,
mysql.ErrUnknownCharacterSet: mysql.ErrUnknownCharacterSet,
mysql.ErrInvalidYearColumnLength: mysql.ErrInvalidYearColumnLength,
mysql.ErrWrongArguments: mysql.ErrWrongArguments,
mysql.ErrWrongFieldTerminators: mysql.ErrWrongFieldTerminators,
mysql.ErrTooBigDisplaywidth: mysql.ErrTooBigDisplaywidth,
mysql.ErrUnknownAlterLock: mysql.ErrUnknownAlterLock,
mysql.ErrUnknownAlterAlgorithm: mysql.ErrUnknownAlterAlgorithm,
mysql.ErrTooBigPrecision: mysql.ErrTooBigPrecision,
}
terror.ErrClassToMySQLCodes[terror.ClassParser] = parserMySQLErrCodes
}
// TrimComment trim comment for special comment code of MySQL. // TrimComment trim comment for special comment code of MySQL.
func TrimComment(txt string) string { func TrimComment(txt string) string {
txt = specCodeStart.ReplaceAllString(txt, "") txt = specCodeStart.ReplaceAllString(txt, "")
......
此差异已折叠。
此差异已折叠。
...@@ -142,6 +142,7 @@ type StatementContext struct { ...@@ -142,6 +142,7 @@ type StatementContext struct {
lockWaitStartTime *time.Time // LockWaitStartTime stores the pessimistic lock wait start time lockWaitStartTime *time.Time // LockWaitStartTime stores the pessimistic lock wait start time
PessimisticLockWaited int32 PessimisticLockWaited int32
LockKeysDuration time.Duration LockKeysDuration time.Duration
LockKeysCount int32
} }
// StmtHints are SessionVars related sql hints. // StmtHints are SessionVars related sql hints.
...@@ -152,12 +153,15 @@ type StmtHints struct { ...@@ -152,12 +153,15 @@ type StmtHints struct {
ReplicaRead byte ReplicaRead byte
AllowInSubqToJoinAndAgg bool AllowInSubqToJoinAndAgg bool
NoIndexMergeHint bool NoIndexMergeHint bool
// EnableCascadesPlanner is use cascades planner for a single query only.
EnableCascadesPlanner bool
// Hint flags // Hint flags
HasAllowInSubqToJoinAndAggHint bool HasAllowInSubqToJoinAndAggHint bool
HasMemQuotaHint bool HasMemQuotaHint bool
HasReplicaReadHint bool HasReplicaReadHint bool
HasMaxExecutionTime bool HasMaxExecutionTime bool
HasEnableCascadesPlannerHint bool
} }
// GetNowTsCached getter for nowTs, if not set get now time and cache it // GetNowTsCached getter for nowTs, if not set get now time and cache it
...@@ -184,6 +188,13 @@ func (sc *StatementContext) SQLDigest() (normalized, sqlDigest string) { ...@@ -184,6 +188,13 @@ func (sc *StatementContext) SQLDigest() (normalized, sqlDigest string) {
return sc.digestMemo.normalized, sc.digestMemo.digest return sc.digestMemo.normalized, sc.digestMemo.digest
} }
// InitSQLDigest sets the normalized and digest for sql.
func (sc *StatementContext) InitSQLDigest(normalized, digest string) {
sc.digestMemo.Do(func() {
sc.digestMemo.normalized, sc.digestMemo.digest = normalized, digest
})
}
// GetPlanDigest gets the normalized plan and plan digest. // GetPlanDigest gets the normalized plan and plan digest.
func (sc *StatementContext) GetPlanDigest() (normalized, planDigest string) { func (sc *StatementContext) GetPlanDigest() (normalized, planDigest string) {
return sc.planNormalized, sc.planDigest return sc.planNormalized, sc.planDigest
...@@ -355,6 +366,15 @@ func (sc *StatementContext) AppendWarning(warn error) { ...@@ -355,6 +366,15 @@ func (sc *StatementContext) AppendWarning(warn error) {
sc.mu.Unlock() sc.mu.Unlock()
} }
// AppendWarnings appends some warnings.
func (sc *StatementContext) AppendWarnings(warns []SQLWarn) {
sc.mu.Lock()
if len(sc.mu.warnings) < math.MaxUint16 {
sc.mu.warnings = append(sc.mu.warnings, warns...)
}
sc.mu.Unlock()
}
// AppendNote appends a warning with level 'Note'. // AppendNote appends a warning with level 'Note'.
func (sc *StatementContext) AppendNote(warn error) { func (sc *StatementContext) AppendNote(warn error) {
sc.mu.Lock() sc.mu.Lock()
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册