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

update vendor & fix spell error

上级 6474f630
......@@ -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_COMPILE := $(shell date +"%F %T %z") by $(shell go version)
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)
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 {
tb := gjson.Get(table.String(), "Name.O")
if db.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 {
if tb.String() != "" {
......@@ -177,7 +177,7 @@ func SchemaMetaInfo(sql string, defaultDatabase string) []string {
tb := gjson.Get(table, "Name.O")
if db.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 {
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)
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
```go
import (
"fmt"
"github.com/pingcap/parser"
_ "github.com/pingcap/tidb/types/parser_driver"
)
// This example show how to parse a text sql into ast.
func example() {
// 0. make sure import parser_driver implemented by TiDB(user also can implement own driver by self).
// and add `import _ "github.com/pingcap/tidb/types/parser_driver"` in the head of file.
// 1. Create a parser. The parser is NOT goroutine safe and should
// not be shared among multiple goroutines. However, parser is also
// heavy, so each goroutine should reuse its own local instance if
// possible.
p := parser.New()
- 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).
- 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.
// 2. Parse a text SQL into AST([]ast.StmtNode).
stmtNodes, _, err := p.Parse("select * from tbl where id = 1", "", "")
// 3. Use AST to do cool things.
fmt.Println(stmtNodes[0], err)
}
```
See [https://godoc.org/github.com/pingcap/parser](https://godoc.org/github.com/pingcap/parser)
## 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.
## How to use it
### 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:**
>
> - Don't forget to run `make test` before you commit!
> - Make sure `parser.go` is updated.
- Support more MySQL syntax
- Optimize the code structure, make it easier to extend
- Improve performance and benchmark
- 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/).
```
GO111MODULE=on go mod edit -replace github.com/pingcap/parser=github.com/your-repo/parser@your-branch
```
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).
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
```
GO111MODULE=on go get -u github.com/pingcap/parser@master
```
Thanks [cznic](https://github.com/cznic) for providing some great open-source tools.
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 @@
package ast
import (
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
)
var _ StmtNode = &IndexAdviseStmt{}
......@@ -31,7 +31,7 @@ type IndexAdviseStmt struct {
}
// Restore implements Node Accept interface.
func (n *IndexAdviseStmt) Restore(ctx *RestoreCtx) error {
func (n *IndexAdviseStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("INDEX ADVISE ")
if n.IsLocal {
ctx.WriteKeyWord("LOCAL ")
......@@ -66,7 +66,7 @@ type MaxIndexNumClause struct {
}
// 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")
if n.PerTable != UnspecifiedSize {
ctx.WriteKeyWord(" PER_TABLE ")
......
......@@ -18,7 +18,7 @@ package ast
import (
"io"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/types"
)
......@@ -27,7 +27,7 @@ import (
// Interfaces embed Node should have 'Node' name suffix.
type Node interface {
// Restore returns the sql text from ast tree
Restore(ctx *RestoreCtx) error
Restore(ctx *format.RestoreCtx) error
// Accept accepts Visitor to visit itself.
// The returned node should replace original node.
// ok returns false to stop visiting.
......
......@@ -16,7 +16,7 @@ package ast
import (
"github.com/pingcap/errors"
"github.com/pingcap/parser/auth"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/parser/terror"
......@@ -71,7 +71,7 @@ type DatabaseOption struct {
}
// Restore implements Node interface.
func (n *DatabaseOption) Restore(ctx *RestoreCtx) error {
func (n *DatabaseOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp {
case DatabaseOptionCharset:
ctx.WriteKeyWord("CHARACTER SET")
......@@ -102,7 +102,7 @@ type CreateDatabaseStmt struct {
}
// Restore implements Node interface.
func (n *CreateDatabaseStmt) Restore(ctx *RestoreCtx) error {
func (n *CreateDatabaseStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CREATE DATABASE ")
if n.IfNotExists {
ctx.WriteKeyWord("IF NOT EXISTS ")
......@@ -139,7 +139,7 @@ type AlterDatabaseStmt struct {
}
// Restore implements Node interface.
func (n *AlterDatabaseStmt) Restore(ctx *RestoreCtx) error {
func (n *AlterDatabaseStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ALTER DATABASE")
if !n.AlterDefaultDatabase {
ctx.WritePlain(" ")
......@@ -175,7 +175,7 @@ type DropDatabaseStmt struct {
}
// Restore implements Node interface.
func (n *DropDatabaseStmt) Restore(ctx *RestoreCtx) error {
func (n *DropDatabaseStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DROP DATABASE ")
if n.IfExists {
ctx.WriteKeyWord("IF EXISTS ")
......@@ -204,7 +204,7 @@ type IndexPartSpecification struct {
}
// Restore implements Node interface.
func (n *IndexPartSpecification) Restore(ctx *RestoreCtx) error {
func (n *IndexPartSpecification) Restore(ctx *format.RestoreCtx) error {
if n.Expr != nil {
ctx.WritePlain("(")
if err := n.Expr.Restore(ctx); err != nil {
......@@ -269,7 +269,7 @@ type ReferenceDef struct {
}
// Restore implements Node interface.
func (n *ReferenceDef) Restore(ctx *RestoreCtx) error {
func (n *ReferenceDef) Restore(ctx *format.RestoreCtx) error {
if n.Table != nil {
ctx.WriteKeyWord("REFERENCES ")
if err := n.Table.Restore(ctx); err != nil {
......@@ -385,7 +385,7 @@ type OnDeleteOpt struct {
}
// Restore implements Node interface.
func (n *OnDeleteOpt) Restore(ctx *RestoreCtx) error {
func (n *OnDeleteOpt) Restore(ctx *format.RestoreCtx) error {
if n.ReferOpt != ReferOptionNoOption {
ctx.WriteKeyWord("ON DELETE ")
ctx.WriteKeyWord(n.ReferOpt.String())
......@@ -410,7 +410,7 @@ type OnUpdateOpt struct {
}
// Restore implements Node interface.
func (n *OnUpdateOpt) Restore(ctx *RestoreCtx) error {
func (n *OnUpdateOpt) Restore(ctx *format.RestoreCtx) error {
if n.ReferOpt != ReferOptionNoOption {
ctx.WriteKeyWord("ON UPDATE ")
ctx.WriteKeyWord(n.ReferOpt.String())
......@@ -480,7 +480,7 @@ type ColumnOption struct {
}
// Restore implements Node interface.
func (n *ColumnOption) Restore(ctx *RestoreCtx) error {
func (n *ColumnOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp {
case ColumnOptionNoOption:
return nil
......@@ -606,7 +606,7 @@ type IndexOption struct {
}
// Restore implements Node interface.
func (n *IndexOption) Restore(ctx *RestoreCtx) error {
func (n *IndexOption) Restore(ctx *format.RestoreCtx) error {
hasPrevOption := false
if n.KeyBlockSize > 0 {
ctx.WriteKeyWord("KEY_BLOCK_SIZE")
......@@ -705,7 +705,7 @@ type Constraint struct {
}
// Restore implements Node interface.
func (n *Constraint) Restore(ctx *RestoreCtx) error {
func (n *Constraint) Restore(ctx *format.RestoreCtx) error {
switch n.Tp {
case ConstraintNoConstraint:
return nil
......@@ -833,7 +833,7 @@ type ColumnDef struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while splicing ColumnDef Name")
}
......@@ -909,7 +909,7 @@ type CreateTableStmt struct {
}
// Restore implements Node interface.
func (n *CreateTableStmt) Restore(ctx *RestoreCtx) error {
func (n *CreateTableStmt) Restore(ctx *format.RestoreCtx) error {
if n.IsTemporary {
ctx.WriteKeyWord("CREATE TEMPORARY TABLE ")
} else {
......@@ -1047,7 +1047,7 @@ type DropTableStmt struct {
}
// Restore implements Node interface.
func (n *DropTableStmt) Restore(ctx *RestoreCtx) error {
func (n *DropTableStmt) Restore(ctx *format.RestoreCtx) error {
if n.IsView {
ctx.WriteKeyWord("DROP VIEW ")
} else {
......@@ -1100,7 +1100,7 @@ type DropSequenceStmt struct {
}
// Restore implements Node interface.
func (n *DropSequenceStmt) Restore(ctx *RestoreCtx) error {
func (n *DropSequenceStmt) Restore(ctx *format.RestoreCtx) error {
if n.IsTemporary {
ctx.WriteKeyWord("DROP TEMPORARY SEQUENCE ")
} else {
......@@ -1152,7 +1152,7 @@ type RenameTableStmt struct {
}
// Restore implements Node interface.
func (n *RenameTableStmt) Restore(ctx *RestoreCtx) error {
func (n *RenameTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("RENAME TABLE ")
for index, table2table := range n.TableToTables {
if index != 0 {
......@@ -1202,7 +1202,7 @@ type TableToTable struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore TableToTable.OldTable")
}
......@@ -1250,7 +1250,7 @@ type CreateViewStmt struct {
}
// Restore implements Node interface.
func (n *CreateViewStmt) Restore(ctx *RestoreCtx) error {
func (n *CreateViewStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CREATE ")
if n.OrReplace {
ctx.WriteKeyWord("OR REPLACE ")
......@@ -1340,7 +1340,7 @@ type CreateSequenceStmt struct {
}
// Restore implements Node interface.
func (n *CreateSequenceStmt) Restore(ctx *RestoreCtx) error {
func (n *CreateSequenceStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CREATE ")
if n.OrReplace {
ctx.WriteKeyWord("OR REPLACE ")
......@@ -1394,7 +1394,7 @@ type IndexLockAndAlgorithm struct {
}
// Restore implements Node interface.
func (n *IndexLockAndAlgorithm) Restore(ctx *RestoreCtx) error {
func (n *IndexLockAndAlgorithm) Restore(ctx *format.RestoreCtx) error {
hasPrevOption := false
if n.AlgorithmTp != AlgorithmTypeDefault {
ctx.WriteKeyWord("ALGORITHM")
......@@ -1453,7 +1453,7 @@ type CreateIndexStmt struct {
}
// Restore implements Node interface.
func (n *CreateIndexStmt) Restore(ctx *RestoreCtx) error {
func (n *CreateIndexStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CREATE ")
switch n.KeyType {
case IndexKeyTypeUnique:
......@@ -1549,7 +1549,7 @@ type DropIndexStmt struct {
}
// Restore implements Node interface.
func (n *DropIndexStmt) Restore(ctx *RestoreCtx) error {
func (n *DropIndexStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DROP INDEX ")
if n.IfExists {
ctx.WriteKeyWord("IF EXISTS ")
......@@ -1624,7 +1624,7 @@ func (n *LockTablesStmt) Accept(v Visitor) (Node, bool) {
}
// Restore implements Node interface.
func (n *LockTablesStmt) Restore(ctx *RestoreCtx) error {
func (n *LockTablesStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("LOCK TABLES ")
for i, tl := range n.TableLocks {
if i != 0 {
......@@ -1650,7 +1650,7 @@ func (n *UnlockTablesStmt) Accept(v Visitor) (Node, bool) {
}
// Restore implements Node interface.
func (n *UnlockTablesStmt) Restore(ctx *RestoreCtx) error {
func (n *UnlockTablesStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("UNLOCK TABLES")
return nil
}
......@@ -1680,7 +1680,7 @@ func (n *CleanupTableLockStmt) Accept(v Visitor) (Node, bool) {
}
// 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 ")
for i, v := range n.Tables {
if i != 0 {
......@@ -1721,7 +1721,7 @@ func (n *RepairTableStmt) Accept(v Visitor) (Node, bool) {
}
// Restore implements Node interface.
func (n *RepairTableStmt) Restore(ctx *RestoreCtx) error {
func (n *RepairTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ADMIN REPAIR TABLE ")
if err := n.Table.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore RepairTableStmt.table : [%v]", n.Table)
......@@ -1817,7 +1817,7 @@ type TableOption struct {
TableNames []*TableName
}
func (n *TableOption) Restore(ctx *RestoreCtx) error {
func (n *TableOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp {
case TableOptionEngine:
ctx.WriteKeyWord("ENGINE ")
......@@ -2039,7 +2039,7 @@ type SequenceOption struct {
IntValue int64
}
func (n *SequenceOption) Restore(ctx *RestoreCtx) error {
func (n *SequenceOption) Restore(ctx *format.RestoreCtx) error {
switch n.Tp {
case SequenceOptionIncrementBy:
ctx.WriteKeyWord("INCREMENT BY ")
......@@ -2096,7 +2096,7 @@ type ColumnPosition struct {
}
// Restore implements Node interface.
func (n *ColumnPosition) Restore(ctx *RestoreCtx) error {
func (n *ColumnPosition) Restore(ctx *format.RestoreCtx) error {
switch n.Tp {
case ColumnPositionNone:
// do nothing
......@@ -2290,7 +2290,7 @@ type AlterOrderItem struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore AlterOrderItem.Column")
}
......@@ -2301,7 +2301,7 @@ func (n *AlterOrderItem) Restore(ctx *RestoreCtx) error {
}
// Restore implements Node interface.
func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error {
func (n *AlterTableSpec) Restore(ctx *format.RestoreCtx) error {
switch n.Tp {
case AlterTableSetTiFlashReplica:
ctx.WriteKeyWord("SET TIFLASH REPLICA ")
......@@ -2697,7 +2697,7 @@ func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error {
case AlterTableAlterCheck:
ctx.WriteKeyWord("ALTER CHECK ")
ctx.WriteName(n.Constraint.Name)
if n.Constraint.Enforced == false {
if !n.Constraint.Enforced {
ctx.WriteKeyWord(" NOT")
}
ctx.WriteKeyWord(" ENFORCED")
......@@ -2786,7 +2786,7 @@ type AlterTableStmt struct {
}
// Restore implements Node interface.
func (n *AlterTableStmt) Restore(ctx *RestoreCtx) error {
func (n *AlterTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ALTER TABLE ")
if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore AlterTableStmt.Table")
......@@ -2835,7 +2835,7 @@ type TruncateTableStmt struct {
}
// Restore implements Node interface.
func (n *TruncateTableStmt) Restore(ctx *RestoreCtx) error {
func (n *TruncateTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("TRUNCATE TABLE ")
if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore TruncateTableStmt.Table")
......@@ -2878,7 +2878,7 @@ type SubPartitionDefinition struct {
Options []*TableOption
}
func (spd *SubPartitionDefinition) Restore(ctx *RestoreCtx) error {
func (spd *SubPartitionDefinition) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("SUBPARTITION ")
ctx.WriteName(spd.Name.O)
for i, opt := range spd.Options {
......@@ -2891,7 +2891,7 @@ func (spd *SubPartitionDefinition) Restore(ctx *RestoreCtx) error {
}
type PartitionDefinitionClause interface {
restore(ctx *RestoreCtx) error
restore(ctx *format.RestoreCtx) error
acceptInPlace(v Visitor) bool
// 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
......@@ -2901,7 +2901,7 @@ type PartitionDefinitionClause interface {
type PartitionDefinitionClauseNone struct{}
func (n *PartitionDefinitionClauseNone) restore(ctx *RestoreCtx) error {
func (n *PartitionDefinitionClauseNone) restore(ctx *format.RestoreCtx) error {
return nil
}
......@@ -2926,7 +2926,7 @@ type PartitionDefinitionClauseLessThan struct {
Exprs []ExprNode
}
func (n *PartitionDefinitionClauseLessThan) restore(ctx *RestoreCtx) error {
func (n *PartitionDefinitionClauseLessThan) restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(" VALUES LESS THAN ")
ctx.WritePlain("(")
for i, expr := range n.Exprs {
......@@ -2972,7 +2972,7 @@ type PartitionDefinitionClauseIn struct {
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.
if len(n.Values) == 0 {
ctx.WriteKeyWord(" DEFAULT")
......@@ -3050,7 +3050,7 @@ type PartitionDefinitionClauseHistory struct {
Current bool
}
func (n *PartitionDefinitionClauseHistory) restore(ctx *RestoreCtx) error {
func (n *PartitionDefinitionClauseHistory) restore(ctx *format.RestoreCtx) error {
if n.Current {
ctx.WriteKeyWord(" CURRENT")
} else {
......@@ -3097,7 +3097,7 @@ func (n *PartitionDefinition) acceptInPlace(v Visitor) bool {
}
// Restore implements Node interface.
func (n *PartitionDefinition) Restore(ctx *RestoreCtx) error {
func (n *PartitionDefinition) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("PARTITION ")
ctx.WriteName(n.Name.O)
......@@ -3151,7 +3151,7 @@ type PartitionMethod struct {
}
// Restore implements the Node interface
func (n *PartitionMethod) Restore(ctx *RestoreCtx) error {
func (n *PartitionMethod) Restore(ctx *format.RestoreCtx) error {
if n.Linear {
ctx.WriteKeyWord("LINEAR ")
}
......@@ -3282,7 +3282,7 @@ func (n *PartitionOptions) Validate() error {
return nil
}
func (n *PartitionOptions) Restore(ctx *RestoreCtx) error {
func (n *PartitionOptions) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("PARTITION BY ")
if err := n.PartitionMethod.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore PartitionOptions.PartitionMethod")
......@@ -3351,7 +3351,7 @@ type RecoverTableStmt struct {
}
// Restore implements Node interface.
func (n *RecoverTableStmt) Restore(ctx *RestoreCtx) error {
func (n *RecoverTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("RECOVER TABLE ")
if n.JobID != 0 {
ctx.WriteKeyWord("BY JOB ")
......@@ -3390,20 +3390,15 @@ type FlashBackTableStmt struct {
ddlNode
Table *TableName
Timestamp ValueExpr
NewName string
}
// Restore implements Node interface.
func (n *FlashBackTableStmt) Restore(ctx *RestoreCtx) error {
func (n *FlashBackTableStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("FLASHBACK TABLE ")
if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing RecoverTableStmt Table")
}
ctx.WriteKeyWord(" UNTIL TIMESTAMP ")
if err := n.Timestamp.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while splicing FlashBackTableStmt Table")
}
if len(n.NewName) > 0 {
ctx.WriteKeyWord(" TO ")
ctx.WriteName(n.NewName)
......
......@@ -16,7 +16,7 @@ package ast
import (
"github.com/pingcap/errors"
"github.com/pingcap/parser/auth"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql"
)
......@@ -86,7 +86,7 @@ type Join struct {
}
// Restore implements Node interface.
func (n *Join) Restore(ctx *RestoreCtx) error {
func (n *Join) Restore(ctx *format.RestoreCtx) error {
if ctx.JoinLevel != 0 {
ctx.WritePlain("(")
defer ctx.WritePlain(")")
......@@ -187,7 +187,7 @@ type TableName struct {
}
// Restore implements Node interface.
func (n *TableName) restoreName(ctx *RestoreCtx) {
func (n *TableName) restoreName(ctx *format.RestoreCtx) {
if n.Schema.String() != "" {
ctx.WriteName(n.Schema.String())
ctx.WritePlain(".")
......@@ -195,7 +195,7 @@ func (n *TableName) restoreName(ctx *RestoreCtx) {
ctx.WriteName(n.Name.String())
}
func (n *TableName) restorePartitions(ctx *RestoreCtx) {
func (n *TableName) restorePartitions(ctx *format.RestoreCtx) {
if len(n.PartitionNames) > 0 {
ctx.WriteKeyWord(" PARTITION")
ctx.WritePlain("(")
......@@ -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 {
ctx.WritePlain(" ")
if err := value.Restore(ctx); err != nil {
......@@ -220,7 +220,7 @@ func (n *TableName) restoreIndexHints(ctx *RestoreCtx) error {
return nil
}
func (n *TableName) Restore(ctx *RestoreCtx) error {
func (n *TableName) Restore(ctx *format.RestoreCtx) error {
n.restoreName(ctx)
n.restorePartitions(ctx)
return n.restoreIndexHints(ctx)
......@@ -255,7 +255,7 @@ type IndexHint struct {
}
// 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 := ""
switch n.HintType {
case 1:
......@@ -312,7 +312,7 @@ type DeleteTableList struct {
}
// 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 {
if i != 0 {
ctx.WritePlain(",")
......@@ -351,7 +351,7 @@ type OnCondition struct {
}
// Restore implements Node interface.
func (n *OnCondition) Restore(ctx *RestoreCtx) error {
func (n *OnCondition) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ON ")
if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore OnCondition.Expr")
......@@ -387,7 +387,7 @@ type TableSource struct {
}
// Restore implements Node interface.
func (n *TableSource) Restore(ctx *RestoreCtx) error {
func (n *TableSource) Restore(ctx *format.RestoreCtx) error {
needParen := false
switch n.Source.(type) {
case *SelectStmt, *UnionStmt:
......@@ -482,7 +482,7 @@ type WildCardField struct {
}
// 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 != "" {
ctx.WriteName(schema)
ctx.WritePlain(".")
......@@ -526,7 +526,7 @@ type SelectField struct {
}
// Restore implements Node interface.
func (n *SelectField) Restore(ctx *RestoreCtx) error {
func (n *SelectField) Restore(ctx *format.RestoreCtx) error {
if n.WildCard != nil {
if err := n.WildCard.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore SelectField.WildCard")
......@@ -569,7 +569,7 @@ type FieldList struct {
}
// 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 {
if i != 0 {
ctx.WritePlain(", ")
......@@ -606,7 +606,7 @@ type TableRefsClause struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore TableRefsClause.TableRefs")
}
......@@ -637,7 +637,7 @@ type ByItem struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore ByItem.Expr")
}
......@@ -669,7 +669,7 @@ type GroupByClause struct {
}
// Restore implements Node interface.
func (n *GroupByClause) Restore(ctx *RestoreCtx) error {
func (n *GroupByClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("GROUP BY ")
for i, v := range n.Items {
if i != 0 {
......@@ -706,7 +706,7 @@ type HavingClause struct {
}
// Restore implements Node interface.
func (n *HavingClause) Restore(ctx *RestoreCtx) error {
func (n *HavingClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("HAVING ")
if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore HavingClause.Expr")
......@@ -737,7 +737,7 @@ type OrderByClause struct {
}
// Restore implements Node interface.
func (n *OrderByClause) Restore(ctx *RestoreCtx) error {
func (n *OrderByClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ORDER BY ")
for i, item := range n.Items {
if i != 0 {
......@@ -803,10 +803,12 @@ type SelectStmt struct {
IsInBraces bool
// QueryBlockOffset indicates the order of this SelectStmt if counted from left to right in the sql text.
QueryBlockOffset int
// SelectIntoOpt is the select-into option.
SelectIntoOpt *SelectIntoOption
}
// Restore implements Node interface.
func (n *SelectStmt) Restore(ctx *RestoreCtx) error {
func (n *SelectStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("SELECT ")
if n.SelectStmtOpts.Priority > 0 {
......@@ -922,6 +924,13 @@ func (n *SelectStmt) Restore(ctx *RestoreCtx) error {
ctx.WritePlain(" ")
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
}
......@@ -1020,7 +1029,7 @@ type UnionSelectList struct {
}
// 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 {
if i != 0 {
ctx.WriteKeyWord(" UNION ")
......@@ -1070,7 +1079,7 @@ type UnionStmt struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore UnionStmt.SelectList")
}
......@@ -1132,7 +1141,7 @@ type Assignment struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore Assignment.Column")
}
......@@ -1187,7 +1196,7 @@ type LoadDataStmt struct {
}
// Restore implements Node interface.
func (n *LoadDataStmt) Restore(ctx *RestoreCtx) error {
func (n *LoadDataStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("LOAD DATA ")
if n.IsLocal {
ctx.WriteKeyWord("LOCAL ")
......@@ -1287,6 +1296,7 @@ const (
type FieldItem struct {
Type int
Value string
OptEnclosed bool
}
// FieldsClause represents fields references clause in load data statement.
......@@ -1294,10 +1304,11 @@ type FieldsClause struct {
Terminated string
Enclosed byte
Escaped byte
OptEnclosed bool
}
// Restore for FieldsClause
func (n *FieldsClause) Restore(ctx *RestoreCtx) error {
func (n *FieldsClause) Restore(ctx *format.RestoreCtx) error {
if n.Terminated != "\t" || n.Escaped != '\\' {
ctx.WriteKeyWord(" FIELDS")
if n.Terminated != "\t" {
......@@ -1305,6 +1316,9 @@ func (n *FieldsClause) Restore(ctx *RestoreCtx) error {
ctx.WriteString(n.Terminated)
}
if n.Enclosed != 0 {
if n.OptEnclosed {
ctx.WriteKeyWord(" OPTIONALLY")
}
ctx.WriteKeyWord(" ENCLOSED BY ")
ctx.WriteString(string(n.Enclosed))
}
......@@ -1327,7 +1341,7 @@ type LinesClause struct {
}
// Restore for LinesClause
func (n *LinesClause) Restore(ctx *RestoreCtx) error {
func (n *LinesClause) Restore(ctx *format.RestoreCtx) error {
if n.Starting != "" || n.Terminated != "\n" {
ctx.WriteKeyWord(" LINES")
if n.Starting != "" {
......@@ -1359,7 +1373,7 @@ type InsertStmt struct {
}
// Restore implements Node interface.
func (n *InsertStmt) Restore(ctx *RestoreCtx) error {
func (n *InsertStmt) Restore(ctx *format.RestoreCtx) error {
if n.IsReplace {
ctx.WriteKeyWord("REPLACE ")
} else {
......@@ -1522,7 +1536,7 @@ type DeleteStmt struct {
}
// Restore implements Node interface.
func (n *DeleteStmt) Restore(ctx *RestoreCtx) error {
func (n *DeleteStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DELETE ")
if n.TableHints != nil && len(n.TableHints) != 0 {
......@@ -1664,7 +1678,7 @@ type UpdateStmt struct {
}
// Restore implements Node interface.
func (n *UpdateStmt) Restore(ctx *RestoreCtx) error {
func (n *UpdateStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("UPDATE ")
if n.TableHints != nil && len(n.TableHints) != 0 {
......@@ -1784,7 +1798,7 @@ type Limit struct {
}
// Restore implements Node interface.
func (n *Limit) Restore(ctx *RestoreCtx) error {
func (n *Limit) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("LIMIT ")
if n.Offset != nil {
if err := n.Offset.Restore(ctx); err != nil {
......@@ -1849,6 +1863,7 @@ const (
ShowIndex
ShowProcessList
ShowCreateDatabase
ShowConfig
ShowEvents
ShowStatsMeta
ShowStatsHistograms
......@@ -1867,6 +1882,9 @@ const (
ShowAnalyzeStatus
ShowRegions
ShowBuiltins
ShowTableNextRowId
ShowBackup
ShowRestore
)
const (
......@@ -1911,7 +1929,7 @@ type ShowStmt struct {
}
// Restore implements Node interface.
func (n *ShowStmt) Restore(ctx *RestoreCtx) error {
func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error {
restoreOptFull := func() {
if n.Full {
ctx.WriteKeyWord("FULL ")
......@@ -2070,6 +2088,8 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error {
switch n.Tp {
case ShowEngines:
ctx.WriteKeyWord("ENGINES")
case ShowConfig:
ctx.WriteKeyWord("CONFIG")
case ShowDatabases:
ctx.WriteKeyWord("DATABASES")
case ShowCharset:
......@@ -2154,6 +2174,17 @@ func (n *ShowStmt) Restore(ctx *RestoreCtx) error {
return err
}
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:
return errors.New("Unknown ShowStmt type")
}
......@@ -2227,7 +2258,7 @@ type WindowSpec struct {
}
// 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 != "" {
ctx.WriteName(name)
if n.OnlyAlias {
......@@ -2297,6 +2328,54 @@ func (n *WindowSpec) Accept(v Visitor) (Node, bool) {
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.
type PartitionByClause struct {
node
......@@ -2305,7 +2384,7 @@ type PartitionByClause struct {
}
// Restore implements Node interface.
func (n *PartitionByClause) Restore(ctx *RestoreCtx) error {
func (n *PartitionByClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("PARTITION BY ")
for i, v := range n.Items {
if i != 0 {
......@@ -2355,7 +2434,7 @@ type FrameClause struct {
}
// Restore implements Node interface.
func (n *FrameClause) Restore(ctx *RestoreCtx) error {
func (n *FrameClause) Restore(ctx *format.RestoreCtx) error {
switch n.Type {
case Rows:
ctx.WriteKeyWord("ROWS")
......@@ -2425,7 +2504,7 @@ type FrameBound struct {
}
// Restore implements Node interface.
func (n *FrameBound) Restore(ctx *RestoreCtx) error {
func (n *FrameBound) Restore(ctx *format.RestoreCtx) error {
if n.UnBounded {
ctx.WriteKeyWord("UNBOUNDED")
}
......@@ -2495,7 +2574,7 @@ type SplitSyntaxOption struct {
HasPartition bool
}
func (n *SplitRegionStmt) Restore(ctx *RestoreCtx) error {
func (n *SplitRegionStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("SPLIT ")
if n.SplitSyntaxOpt != nil {
if n.SplitSyntaxOpt.HasRegionFor {
......@@ -2571,7 +2650,7 @@ func (n *SplitRegionStmt) Accept(v Visitor) (Node, bool) {
return v.Leave(n)
}
func (n *SplitOption) Restore(ctx *RestoreCtx) error {
func (n *SplitOption) Restore(ctx *format.RestoreCtx) error {
if len(n.ValueLists) == 0 {
ctx.WriteKeyWord("BETWEEN ")
ctx.WritePlain("(")
......
......@@ -20,7 +20,7 @@ import (
"strings"
"github.com/pingcap/errors"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/opcode"
)
......@@ -30,6 +30,7 @@ var (
_ ExprNode = &BinaryOperationExpr{}
_ ExprNode = &CaseExpr{}
_ ExprNode = &ColumnNameExpr{}
_ ExprNode = &TableNameExpr{}
_ ExprNode = &CompareSubqueryExpr{}
_ ExprNode = &DefaultExpr{}
_ ExprNode = &ExistsSubqueryExpr{}
......@@ -46,6 +47,7 @@ var (
_ ExprNode = &ValuesExpr{}
_ ExprNode = &VariableExpr{}
_ ExprNode = &MatchAgainst{}
_ ExprNode = &SetCollationExpr{}
_ Node = &ColumnName{}
_ Node = &WhenClause{}
......@@ -63,7 +65,7 @@ type ValueExpr interface {
}
// 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.
var NewParamMarkerExpr func(offset int) ParamMarkerExpr
......@@ -82,7 +84,7 @@ type BetweenExpr struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore BetweenExpr.Expr")
}
......@@ -155,7 +157,7 @@ type BinaryOperationExpr struct {
}
// 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 {
return errors.Annotate(err, "An error occurred when restore BinaryOperationExpr.L")
}
......@@ -217,7 +219,7 @@ type WhenClause struct {
}
// Restore implements Node interface.
func (n *WhenClause) Restore(ctx *RestoreCtx) error {
func (n *WhenClause) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("WHEN ")
if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore WhenClauses.Expr")
......@@ -263,7 +265,7 @@ type CaseExpr struct {
}
// Restore implements Node interface.
func (n *CaseExpr) Restore(ctx *RestoreCtx) error {
func (n *CaseExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("CASE")
if n.Value != nil {
ctx.WritePlain(" ")
......@@ -354,7 +356,7 @@ type SubqueryExpr struct {
}
// Restore implements Node interface.
func (n *SubqueryExpr) Restore(ctx *RestoreCtx) error {
func (n *SubqueryExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WritePlain("(")
if err := n.Query.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore SubqueryExpr.Query")
......@@ -400,7 +402,7 @@ type CompareSubqueryExpr struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore CompareSubqueryExpr.L")
}
......@@ -443,6 +445,47 @@ func (n *CompareSubqueryExpr) Accept(v Visitor) (Node, bool) {
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.
type ColumnName struct {
node
......@@ -452,7 +495,7 @@ type ColumnName struct {
}
// Restore implements Node interface.
func (n *ColumnName) Restore(ctx *RestoreCtx) error {
func (n *ColumnName) Restore(ctx *format.RestoreCtx) error {
if n.Schema.O != "" {
ctx.WriteName(n.Schema.O)
ctx.WritePlain(".")
......@@ -514,7 +557,7 @@ type ColumnNameExpr struct {
}
// 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 {
return errors.Trace(err)
}
......@@ -550,7 +593,7 @@ type DefaultExpr struct {
}
// Restore implements Node interface.
func (n *DefaultExpr) Restore(ctx *RestoreCtx) error {
func (n *DefaultExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DEFAULT")
if n.Name != nil {
ctx.WritePlain("(")
......@@ -595,7 +638,7 @@ type ExistsSubqueryExpr struct {
}
// Restore implements Node interface.
func (n *ExistsSubqueryExpr) Restore(ctx *RestoreCtx) error {
func (n *ExistsSubqueryExpr) Restore(ctx *format.RestoreCtx) error {
if n.Not {
ctx.WriteKeyWord("NOT EXISTS ")
} else {
......@@ -641,7 +684,7 @@ type PatternInExpr struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore PatternInExpr.Expr")
}
......@@ -725,7 +768,7 @@ type IsNullExpr struct {
}
// 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 {
return errors.Trace(err)
}
......@@ -774,7 +817,7 @@ type IsTruthExpr struct {
}
// 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 {
return errors.Trace(err)
}
......@@ -838,7 +881,7 @@ type PatternLikeExpr struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore PatternLikeExpr.Expr")
}
......@@ -916,7 +959,7 @@ type ParenthesesExpr struct {
}
// Restore implements Node interface.
func (n *ParenthesesExpr) Restore(ctx *RestoreCtx) error {
func (n *ParenthesesExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WritePlain("(")
if err := n.Expr.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred when restore ParenthesesExpr.Expr")
......@@ -963,7 +1006,7 @@ type PositionExpr struct {
}
// Restore implements Node interface.
func (n *PositionExpr) Restore(ctx *RestoreCtx) error {
func (n *PositionExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WritePlainf("%d", n.N)
return nil
}
......@@ -1007,7 +1050,7 @@ type PatternRegexpExpr struct {
}
// 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 {
return errors.Annotate(err, "An error occurred while restore PatternRegexpExpr.Expr")
}
......@@ -1065,7 +1108,7 @@ type RowExpr struct {
}
// Restore implements Node interface.
func (n *RowExpr) Restore(ctx *RestoreCtx) error {
func (n *RowExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("ROW")
ctx.WritePlain("(")
for i, v := range n.Values {
......@@ -1112,7 +1155,7 @@ type UnaryOperationExpr struct {
}
// 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 {
return errors.Trace(err)
}
......@@ -1151,7 +1194,7 @@ type ValuesExpr struct {
}
// Restore implements Node interface.
func (n *ValuesExpr) Restore(ctx *RestoreCtx) error {
func (n *ValuesExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("VALUES")
ctx.WritePlain("(")
if err := n.Column.Restore(ctx); err != nil {
......@@ -1200,7 +1243,7 @@ type VariableExpr struct {
}
// Restore implements Node interface.
func (n *VariableExpr) Restore(ctx *RestoreCtx) error {
func (n *VariableExpr) Restore(ctx *format.RestoreCtx) error {
if n.IsSystem {
ctx.WritePlain("@@")
if n.ExplicitScope {
......@@ -1256,7 +1299,7 @@ type MaxValueExpr struct {
}
// Restore implements Node interface.
func (n *MaxValueExpr) Restore(ctx *RestoreCtx) error {
func (n *MaxValueExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("MAXVALUE")
return nil
}
......@@ -1286,7 +1329,7 @@ type MatchAgainst struct {
Modifier FulltextSearchModifier
}
func (n *MatchAgainst) Restore(ctx *RestoreCtx) error {
func (n *MatchAgainst) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("MATCH")
ctx.WritePlain(" (")
for i, v := range n.ColumnNames {
......@@ -1354,3 +1397,43 @@ func (n *MatchAgainst) Accept(v Visitor) (Node, bool) {
n.Against = newAgainst.(ExprNode)
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 (
"fmt"
"io"
"strings"
"time"
"github.com/pingcap/errors"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/types"
)
......@@ -226,6 +227,7 @@ const (
CharLength = "char_length"
CharacterLength = "character_length"
FindInSet = "find_in_set"
WeightString = "weight_string"
// information functions
Benchmark = "benchmark"
......@@ -247,6 +249,8 @@ const (
TiDBVersion = "tidb_version"
TiDBIsDDLOwner = "tidb_is_ddl_owner"
TiDBDecodePlan = "tidb_decode_plan"
FormatBytes = "format_bytes"
FormatNanoTime = "format_nano_time"
// control functions
If = "if"
......@@ -325,6 +329,11 @@ const (
// TiDB internal function.
TiDBDecodeKey = "tidb_decode_key"
// Sequence function.
NextVal = "nextval"
LastVal = "lastval"
SetVal = "setval"
)
// FuncCallExpr is for function expression.
......@@ -337,7 +346,7 @@ type FuncCallExpr struct {
}
// Restore implements Node interface.
func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error {
func (n *FuncCallExpr) Restore(ctx *format.RestoreCtx) error {
var specialLiteral string
switch n.FnName.L {
case DateLiteral:
......@@ -415,6 +424,19 @@ func (n *FuncCallExpr) Restore(ctx *RestoreCtx) error {
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:
for i, argv := range n.Args {
if i != 0 {
......@@ -497,7 +519,7 @@ type FuncCastExpr struct {
}
// Restore implements Node interface.
func (n *FuncCastExpr) Restore(ctx *RestoreCtx) error {
func (n *FuncCastExpr) Restore(ctx *format.RestoreCtx) error {
switch n.FunctionType {
case CastFunction:
ctx.WriteKeyWord("CAST")
......@@ -598,7 +620,7 @@ type TrimDirectionExpr struct {
}
// Restore implements Node interface.
func (n *TrimDirectionExpr) Restore(ctx *RestoreCtx) error {
func (n *TrimDirectionExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.Direction.String())
return nil
}
......@@ -660,6 +682,8 @@ const (
AggFuncStddevPop = "stddev_pop"
// AggFuncStddevSamp is the name of stddev_samp function
AggFuncStddevSamp = "stddev_samp"
// AggFuncJsonObjectAgg is the name of json_objectagg function
AggFuncJsonObjectAgg = "json_objectagg"
)
// AggregateFuncExpr represents aggregate function expression.
......@@ -676,7 +700,7 @@ type AggregateFuncExpr struct {
}
// Restore implements Node interface.
func (n *AggregateFuncExpr) Restore(ctx *RestoreCtx) error {
func (n *AggregateFuncExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.F)
ctx.WritePlain("(")
if n.Distinct {
......@@ -779,7 +803,7 @@ type WindowFuncExpr struct {
}
// Restore implements Node interface.
func (n *WindowFuncExpr) Restore(ctx *RestoreCtx) error {
func (n *WindowFuncExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.F)
ctx.WritePlain("(")
for i, v := range n.Args {
......@@ -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.
type TimeUnitExpr struct {
exprNode
......@@ -938,7 +986,7 @@ type TimeUnitExpr struct {
}
// Restore implements Node interface.
func (n *TimeUnitExpr) Restore(ctx *RestoreCtx) error {
func (n *TimeUnitExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.Unit.String())
return nil
}
......@@ -991,7 +1039,7 @@ func (selector GetFormatSelectorType) String() string {
}
// Restore implements Node interface.
func (n *GetFormatSelectorExpr) Restore(ctx *RestoreCtx) error {
func (n *GetFormatSelectorExpr) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord(n.Selector.String())
return nil
}
......
......@@ -15,7 +15,7 @@ package ast
import (
"github.com/pingcap/errors"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
"github.com/pingcap/parser/model"
)
......@@ -67,7 +67,7 @@ type AnalyzeOpt struct {
}
// Restore implements Node interface.
func (n *AnalyzeTableStmt) Restore(ctx *RestoreCtx) error {
func (n *AnalyzeTableStmt) Restore(ctx *format.RestoreCtx) error {
if n.Incremental {
ctx.WriteKeyWord("ANALYZE INCREMENTAL TABLE ")
} else {
......@@ -139,7 +139,7 @@ type DropStatsStmt struct {
}
// Restore implements Node interface.
func (n *DropStatsStmt) Restore(ctx *RestoreCtx) error {
func (n *DropStatsStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("DROP STATS ")
if err := n.Table.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while add table")
......@@ -171,7 +171,7 @@ type LoadStatsStmt struct {
}
// Restore implements Node interface.
func (n *LoadStatsStmt) Restore(ctx *RestoreCtx) error {
func (n *LoadStatsStmt) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("LOAD STATS ")
ctx.WriteString(n.Path)
return nil
......
......@@ -36,7 +36,14 @@ func IsReadOnly(node Node) bool {
return checker.readOnly
case *ExplainStmt:
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
default:
return false
......
......@@ -20,7 +20,7 @@ import (
"fmt"
"github.com/pingcap/errors"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
"github.com/pingcap/parser/terror"
)
......@@ -34,7 +34,7 @@ type UserIdentity struct {
}
// Restore implements Node interface.
func (user *UserIdentity) Restore(ctx *RestoreCtx) error {
func (user *UserIdentity) Restore(ctx *format.RestoreCtx) error {
if user.CurrentUser {
ctx.WriteKeyWord("CURRENT_USER")
} else {
......@@ -67,7 +67,7 @@ type RoleIdentity struct {
Hostname string
}
func (role *RoleIdentity) Restore(ctx *RestoreCtx) error {
func (role *RoleIdentity) Restore(ctx *format.RestoreCtx) error {
ctx.WriteName(role.Username)
if role.Hostname != "" {
ctx.WritePlain("@")
......
......@@ -105,11 +105,7 @@ func ValidCharsetAndCollation(cs string, co string) bool {
}
co = strings.ToLower(co)
_, ok = c.Collations[co]
if !ok {
return false
}
return true
return ok
}
// GetDefaultCollation returns the default collation for charset.
......
......@@ -114,14 +114,14 @@ func (d *sqlDigester) doDigest(sql string) (result string) {
func (d *sqlDigester) doNormalize(sql string) (result string) {
d.normalize(sql)
result = string(d.buffer.Bytes())
result = d.buffer.String()
d.buffer.Reset()
return
}
func (d *sqlDigester) doNormalizeDigest(sql string) (normalized, digest string) {
d.normalize(sql)
normalized = string(d.buffer.Bytes())
normalized = d.buffer.String()
d.hasher.Write(d.buffer.Bytes())
d.buffer.Reset()
digest = fmt.Sprintf("%x", d.hasher.Sum(nil))
......
......@@ -78,7 +78,7 @@ import (
/* TiDB hint names */
hintAggToCop "AGG_TO_COP"
hintEnablePlanCache "ENABLE_PLAN_CACHE"
hintIgnorePlanCache "IGNORE_PLAN_CACHE"
hintHashAgg "HASH_AGG"
hintIgnoreIndex "IGNORE_INDEX"
hintInlHashJoin "INL_HASH_JOIN"
......@@ -89,13 +89,15 @@ import (
hintQueryType "QUERY_TYPE"
hintReadConsistentReplica "READ_CONSISTENT_REPLICA"
hintReadFromStorage "READ_FROM_STORAGE"
hintSMJoin "SM_JOIN"
hintSMJoin "MERGE_JOIN"
hintStreamAgg "STREAM_AGG"
hintSwapJoinInputs "SWAP_JOIN_INPUTS"
hintUseIndexMerge "USE_INDEX_MERGE"
hintUseIndex "USE_INDEX"
hintUsePlanCache "USE_PLAN_CACHE"
hintUseToja "USE_TOJA"
hintTimeRange "TIME_RANGE"
hintUseCascades "USE_CASCADES"
/* Other keywords */
hintOLAP "OLAP"
......@@ -229,7 +231,7 @@ TableOptimizerHintOpt:
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
QBName: model.NewCIStr($3),
MaxExecutionTime: $4,
HintData: $4,
}
}
| "SET_VAR" '(' Identifier '=' Value ')'
......@@ -255,7 +257,7 @@ TableOptimizerHintOpt:
if $4 <= maxValue {
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
MemoryQuota: int64($4 * $5),
HintData: int64($4 * $5),
QBName: model.NewCIStr($3),
}
} else {
......@@ -264,6 +266,16 @@ TableOptimizerHintOpt:
$$ = nil
}
}
| "TIME_RANGE" '(' hintStringLit CommaOpt hintStringLit ')'
{
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
HintData: ast.HintTimeRange{
From: $3,
To: $5,
},
}
}
| BooleanHintName '(' QueryBlockOpt HintTrueOrFalse ')'
{
h := $4
......@@ -283,7 +295,7 @@ TableOptimizerHintOpt:
$$ = &ast.TableOptimizerHint{
HintName: model.NewCIStr($1),
QBName: model.NewCIStr($3),
QueryType: model.NewCIStr($4),
HintData: model.NewCIStr($4),
}
}
......@@ -314,7 +326,7 @@ HintStorageTypeAndTable:
HintStorageType '[' HintTableList ']'
{
h := $3
h.StoreType = model.NewCIStr($1)
h.HintData = model.NewCIStr($1)
$$ = h
}
......@@ -449,11 +461,11 @@ UnitOfBytes:
HintTrueOrFalse:
"TRUE"
{
$$ = &ast.TableOptimizerHint{HintFlag: true}
$$ = &ast.TableOptimizerHint{HintData: true}
}
| "FALSE"
{
$$ = &ast.TableOptimizerHint{HintFlag: false}
$$ = &ast.TableOptimizerHint{HintData: false}
}
JoinOrderOptimizerHintName:
......@@ -472,7 +484,7 @@ UnsupportedTableLevelOptimizerHintName:
| "NO_MERGE"
SupportedTableLevelOptimizerHintName:
"SM_JOIN"
"MERGE_JOIN"
| "INL_JOIN"
| "INL_HASH_JOIN"
| "SWAP_JOIN_INPUTS"
......@@ -507,7 +519,7 @@ SubqueryStrategy:
BooleanHintName:
"USE_TOJA"
| "ENABLE_PLAN_CACHE"
| "USE_CASCADES"
NullaryHintName:
"USE_PLAN_CACHE"
......@@ -516,6 +528,7 @@ NullaryHintName:
| "AGG_TO_COP"
| "NO_INDEX_MERGE"
| "READ_CONSISTENT_REPLICA"
| "IGNORE_PLAN_CACHE"
HintQueryType:
"OLAP"
......@@ -556,7 +569,7 @@ Identifier:
| "QB_NAME"
/* TiDB hint names */
| "AGG_TO_COP"
| "ENABLE_PLAN_CACHE"
| "IGNORE_PLAN_CACHE"
| "HASH_AGG"
| "IGNORE_INDEX"
| "INL_HASH_JOIN"
......@@ -567,13 +580,15 @@ Identifier:
| "QUERY_TYPE"
| "READ_CONSISTENT_REPLICA"
| "READ_FROM_STORAGE"
| "SM_JOIN"
| "MERGE_JOIN"
| "STREAM_AGG"
| "SWAP_JOIN_INPUTS"
| "USE_INDEX_MERGE"
| "USE_INDEX"
| "USE_PLAN_CACHE"
| "USE_TOJA"
| "TIME_RANGE"
| "USE_CASCADES"
/* other keywords */
| "OLAP"
| "OLTP"
......
......@@ -66,6 +66,8 @@ const (
ActionCreateSequence ActionType = 34
ActionAlterSequence ActionType = 35
ActionDropSequence ActionType = 36
ActionAddColumns ActionType = 37
ActionDropColumns ActionType = 38
)
const (
......@@ -111,6 +113,8 @@ var actionMap = map[ActionType]string{
ActionCreateSequence: "create sequence",
ActionAlterSequence: "alter sequence",
ActionDropSequence: "drop sequence",
ActionAddColumns: "add multi-columns",
ActionDropColumns: "drop multi-columns",
}
// String return current ddl action in string
......
......@@ -23,7 +23,6 @@ import (
"github.com/pingcap/parser/auth"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/parser/types"
"github.com/pingcap/tipb/go-tipb"
)
// SchemaState is the state for schema elements.
......@@ -87,6 +86,8 @@ type ColumnInfo struct {
OriginDefaultValue interface{} `json:"origin_default"`
DefaultValue interface{} `json:"default"`
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"`
GeneratedStored bool `json:"generated_stored"`
Dependences map[string]struct{} `json:"dependences"`
......@@ -350,6 +351,17 @@ type TiFlashReplicaInfo struct {
Count uint64
LocationLabels []string
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.
......@@ -724,11 +736,12 @@ type IndexInfo struct {
Name CIStr `json:"idx_name"` // Index name.
Table CIStr `json:"tbl_name"` // Table name.
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"`
Comment string `json:"comment"` // Comment
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.
......@@ -840,75 +853,6 @@ func (cis *CIStr) UnmarshalJSON(b []byte) error {
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.
type TableColumnID struct {
TableID int64
......
......@@ -18,7 +18,7 @@ import (
"strings"
"github.com/pingcap/errors"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
)
func newInvalidModeErr(s string) error {
......@@ -779,7 +779,7 @@ func Str2Priority(val string) PriorityEnum {
}
// Restore implements Node interface.
func (n *PriorityEnum) Restore(ctx *RestoreCtx) error {
func (n *PriorityEnum) Restore(ctx *format.RestoreCtx) error {
switch *n {
case NoPriority:
return nil
......
......@@ -900,6 +900,7 @@ const (
ErrInvalidJSONPathWildcard = 3149
ErrInvalidJSONContainsPathType = 3150
ErrJSONUsedAsKey = 3152
ErrJSONDocumentNULLKey = 3158
ErrBadUser = 3162
ErrUserAlreadyExists = 3163
ErrInvalidJSONPathArrayCell = 3165
......@@ -960,119 +961,12 @@ const (
ErrSequenceInvalidTableStructure = 4141
// 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
ErrWarnOptimizerHintInvalidToken = 8062
ErrWarnMemoryQuotaOverflow = 8063
ErrWarnOptimizerHintParseError = 8064
ErrWarnOptimizerHintInvalidInteger = 8065
// Error codes used by TiDB ddl package
ErrUnsupportedDDLOperation = 8200
ErrNotOwner = 8201
ErrCantDecodeIndex = 8202
ErrInvalidDDLWorker = 8203
ErrInvalidDDLJob = 8204
ErrInvalidDDLJobFlag = 8205
ErrWaitReorgTimeout = 8206
ErrInvalidStoreVersion = 8207
ErrUnknownTypeLength = 8208
ErrUnknownFractionLength = 8209
ErrInvalidDDLState = 8210
ErrReorgPanic = 8211
ErrInvalidSplitRegionRanges = 8212
ErrInvalidDDLJobVersion = 8213
ErrCancelledDDLJob = 8214
ErrRepairTable = 8215
ErrInvalidAutoRandom = 8216
ErrInvalidHashKeyFlag = 8217
ErrInvalidListIndex = 8218
ErrInvalidListMetaData = 8219
ErrWriteOnSnapshot = 8220
ErrInvalidKey = 8221
ErrInvalidIndexKey = 8222
ErrDataInConsistent = 8223
ErrDDLJobNotFound = 8224
ErrCancelFinishedDDLJob = 8225
ErrCannotCancelDDLJob = 8226
ErrSequenceUnsupportedTableOption = 8227
// TiKV/PD errors.
ErrPDServerTimeout = 9001
ErrTiKVServerTimeout = 9002
ErrTiKVServerBusy = 9003
ErrResolveLockTimeout = 9004
ErrRegionUnavailable = 9005
ErrGCTooEarly = 9006
ErrWriteConflict = 9007
ErrTiKVStoreLimit = 9008
// Stop adding error code here!
// They are moved to github.com/pingcap/tidb/errno
)
......@@ -896,6 +896,7 @@ var MySQLErrName = map[uint16]string{
ErrInvalidJSONPathWildcard: "In this situation, path expressions may not contain the * and ** tokens.",
ErrInvalidJSONContainsPathType: "The second argument can only be either 'one' or 'all'.",
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.",
ErrUserAlreadyExists: "User %s already exists.",
ErrInvalidJSONPathArrayCell: "A path expression is not a path to a cell in an array.",
......@@ -957,119 +958,9 @@ var MySQLErrName = map[uint16]string{
ErrSequenceInvalidTableStructure: "Sequence '%-.64s.%-.64s' table structure is invalid (%s)",
// 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'",
ErrWarnOptimizerHintUnsupportedHint: "Optimizer hint %s is not supported by TiDB and is ignored",
ErrWarnOptimizerHintInvalidToken: "Cannot use %s '%s' (tok = %d) in an optimizer hint",
ErrWarnMemoryQuotaOverflow: "Max value of MEMORY_QUOTA is %d bytes, ignore this invalid limit",
ErrWarnOptimizerHintParseError: "Optimizer hint syntax error at %v",
ErrSequenceUnsupportedTableOption: "Unsupported sequence table-option %s",
ErrUnsupportedType: "Unsupported type %T",
ErrAnalyzeMissIndex: "Index '%s' in field list does not exist in table '%s'",
ErrCartesianProductUnsupported: "Cartesian product is unsupported",
ErrPreparedStmtNotFound: "Prepared statement not found",
ErrWrongParamCount: "Wrong parameter count",
ErrSchemaChanged: "Schema has changed",
ErrUnknownPlan: "Unknown plan",
ErrPrepareMulti: "Can not prepare multiple statements",
ErrPrepareDDL: "Can not prepare DDL statements with parameters",
ErrResultIsEmpty: "Result is empty",
ErrBuildExecutor: "Failed to build executor",
ErrBatchInsertFail: "Batch insert failed, please clean the table and try again.",
ErrGetStartTS: "Can not get start ts",
ErrPrivilegeCheckFail: "privilege check fail", // this error message should begin lowercased to be compatible with the test
ErrInvalidWildCard: "Wildcard fields without any table name appears in wrong place",
ErrMixOfGroupFuncAndFieldsIncompatible: "In aggregated query without GROUP BY, expression #%d of SELECT list contains nonaggregated column '%s'; this is incompatible with sql_mode=only_full_group_by",
// TiKV/PD errors.
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{
ErrInvalidJSONData: "22032",
ErrInvalidJSONPathWildcard: "42000",
ErrJSONUsedAsKey: "42000",
ErrJSONDocumentNULLKey: "22032",
ErrInvalidJSONPathArrayCell: "42000",
}
......@@ -18,7 +18,7 @@ import (
"io"
"github.com/pingcap/errors"
. "github.com/pingcap/parser/format"
"github.com/pingcap/parser/format"
)
// Op is opcode type.
......@@ -141,7 +141,7 @@ func (o Op) Format(w io.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 {
ctx.WriteKeyWord(v)
return nil
......
......@@ -24,12 +24,6 @@ import (
"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.
// Same error code can be used in different error classes.
type ErrCode int
......@@ -57,68 +51,52 @@ const (
type ErrClass int
// Error classes.
const (
ClassAutoid ErrClass = iota + 1
ClassDDL
ClassDomain
ClassEvaluator
ClassExecutor
ClassExpression
ClassAdmin
ClassKV
ClassMeta
ClassOptimizer
ClassParser
ClassPerfSchema
ClassPrivilege
ClassSchema
ClassServer
ClassStructure
ClassVariable
ClassXEval
ClassTable
ClassTypes
ClassGlobal
ClassMockTikv
ClassJSON
ClassTiKV
ClassSession
ClassPlugin
ClassUtil
var (
ClassAutoid = RegisterErrorClass(1, "autoid")
ClassDDL = RegisterErrorClass(2, "ddl")
ClassDomain = RegisterErrorClass(3, "domain")
ClassEvaluator = RegisterErrorClass(4, "evaluator")
ClassExecutor = RegisterErrorClass(5, "executor")
ClassExpression = RegisterErrorClass(6, "expression")
ClassAdmin = RegisterErrorClass(7, "admin")
ClassKV = RegisterErrorClass(8, "kv")
ClassMeta = RegisterErrorClass(9, "meta")
ClassOptimizer = RegisterErrorClass(10, "planner")
ClassParser = RegisterErrorClass(11, "parser")
ClassPerfSchema = RegisterErrorClass(12, "perfschema")
ClassPrivilege = RegisterErrorClass(13, "privilege")
ClassSchema = RegisterErrorClass(14, "schema")
ClassServer = RegisterErrorClass(15, "server")
ClassStructure = RegisterErrorClass(16, "structure")
ClassVariable = RegisterErrorClass(17, "variable")
ClassXEval = RegisterErrorClass(18, "xeval")
ClassTable = RegisterErrorClass(19, "table")
ClassTypes = RegisterErrorClass(20, "types")
ClassGlobal = RegisterErrorClass(21, "global")
ClassMockTikv = RegisterErrorClass(22, "mocktikv")
ClassJSON = RegisterErrorClass(23, "json")
ClassTiKV = RegisterErrorClass(24, "tikv")
ClassSession = RegisterErrorClass(25, "session")
ClassPlugin = RegisterErrorClass(26, "plugin")
ClassUtil = RegisterErrorClass(27, "util")
// Add more as needed.
)
var errClz2Str = map[ErrClass]string{
ClassAutoid: "autoid",
ClassDDL: "ddl",
ClassDomain: "domain",
ClassExecutor: "executor",
ClassExpression: "expression",
ClassAdmin: "admin",
ClassMeta: "meta",
ClassKV: "kv",
ClassOptimizer: "planner",
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",
var errClass2Desc = make(map[ErrClass]string)
// RegisterErrorClass registers new error class for terror.
func RegisterErrorClass(classCode int, desc string) ErrClass {
errClass := ErrClass(classCode)
if _, exists := errClass2Desc[errClass]; exists {
panic(fmt.Sprintf("duplicate register ClassCode %d - %s", classCode, desc))
}
errClass2Desc[errClass] = desc
return errClass
}
// String implements fmt.Stringer interface.
func (ec ErrClass) String() string {
if s, exists := errClz2Str[ec]; exists {
if s, exists := errClass2Desc[ec]; exists {
return s
}
return strconv.Itoa(int(ec))
......@@ -141,9 +119,18 @@ func (ec ErrClass) NotEqualClass(err error) bool {
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.
// Attention:
// this method is not goroutine-safe and
// usually be used in global variable initializer
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{
class: ec,
code: code,
......@@ -152,10 +139,25 @@ func (ec ErrClass) New(code ErrCode, message string) *Error {
}
// 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 {
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
// errors with different message can be compared.
type Error struct {
......@@ -291,21 +293,22 @@ func (e *Error) getMySQLErrorCode() uint16 {
log.Warn("Unknown error class", zap.Int("class", int(e.class)))
return defaultMySQLErrorCode
}
code, ok := codeMap[e.code]
_, ok = codeMap[e.code]
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 code
return uint16(e.code)
}
var (
// ErrClassToMySQLCodes is the map of ErrClass to code-map.
ErrClassToMySQLCodes map[ErrClass]map[ErrCode]uint16
// ErrClassToMySQLCodes is the map of ErrClass to code-set.
ErrClassToMySQLCodes = make(map[ErrClass]map[ErrCode]struct{})
ErrCritical = ClassGlobal.New(CodeExecResultIsEmpty, "critical error %v")
ErrResultUndetermined = ClassGlobal.New(CodeResultUndetermined, "execution result undetermined")
)
func init() {
ErrClassToMySQLCodes = make(map[ErrClass]map[ErrCode]uint16)
defaultMySQLErrorCode = mysql.ErrUnknown
}
......
......@@ -47,6 +47,8 @@ var (
ErrUnknownAlterLock = terror.ClassParser.New(mysql.ErrUnknownAlterLock, mysql.MySQLErrName[mysql.ErrUnknownAlterLock])
// ErrUnknownAlterAlgorithm returns for no alter algorithm found error.
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 = regexp.MustCompile(`(\/\*!(M?[0-9]{5,6})?|\*\/)`)
specCodePattern = regexp.MustCompile(`\/\*!(M?[0-9]{5,6})?([^*]|\*+[^*/])*\*+\/`)
......@@ -58,22 +60,6 @@ var (
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.
func TrimComment(txt string) string {
txt = specCodeStart.ReplaceAllString(txt, "")
......
此差异已折叠。
此差异已折叠。
......@@ -142,6 +142,7 @@ type StatementContext struct {
lockWaitStartTime *time.Time // LockWaitStartTime stores the pessimistic lock wait start time
PessimisticLockWaited int32
LockKeysDuration time.Duration
LockKeysCount int32
}
// StmtHints are SessionVars related sql hints.
......@@ -152,12 +153,15 @@ type StmtHints struct {
ReplicaRead byte
AllowInSubqToJoinAndAgg bool
NoIndexMergeHint bool
// EnableCascadesPlanner is use cascades planner for a single query only.
EnableCascadesPlanner bool
// Hint flags
HasAllowInSubqToJoinAndAggHint bool
HasMemQuotaHint bool
HasReplicaReadHint bool
HasMaxExecutionTime bool
HasEnableCascadesPlannerHint bool
}
// GetNowTsCached getter for nowTs, if not set get now time and cache it
......@@ -184,6 +188,13 @@ func (sc *StatementContext) SQLDigest() (normalized, sqlDigest string) {
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.
func (sc *StatementContext) GetPlanDigest() (normalized, planDigest string) {
return sc.planNormalized, sc.planDigest
......@@ -355,6 +366,15 @@ func (sc *StatementContext) AppendWarning(warn error) {
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'.
func (sc *StatementContext) AppendNote(warn error) {
sc.mu.Lock()
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册