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

update vendor

上级 fb13892e
......@@ -33,7 +33,7 @@ bin/goyacc: goyacc/main.go
fmt:
@echo "gofmt (simplify)"
@ gofmt -s -l -w . 2>&1 | awk '{print} END{if(NR>0) {exit 1}}'
@gofmt -s -l -w . 2>&1 | awk '{print} END{if(NR>0) {exit 1}}'
clean:
go clean -i ./...
......
......@@ -548,6 +548,16 @@ func (n *ColumnOption) Accept(v Visitor) (Node, bool) {
return v.Leave(n)
}
// IndexVisibility is the option for index visibility.
type IndexVisibility int
// IndexVisibility options.
const (
IndexVisibilityDefault IndexVisibility = iota
IndexVisibilityVisible
IndexVisibilityInvisible
)
// IndexOption is the index options.
// KEY_BLOCK_SIZE [=] value
// | index_type
......@@ -560,6 +570,8 @@ type IndexOption struct {
KeyBlockSize uint64
Tp model.IndexType
Comment string
ParserName model.CIStr
Visibility IndexVisibility
}
// Restore implements Node interface.
......@@ -580,12 +592,34 @@ func (n *IndexOption) Restore(ctx *RestoreCtx) error {
hasPrevOption = true
}
if len(n.ParserName.O) > 0 {
if hasPrevOption {
ctx.WritePlain(" ")
}
ctx.WriteKeyWord("WITH PARSER ")
ctx.WriteName(n.ParserName.O)
hasPrevOption = true
}
if n.Comment != "" {
if hasPrevOption {
ctx.WritePlain(" ")
}
ctx.WriteKeyWord("COMMENT ")
ctx.WriteString(n.Comment)
hasPrevOption = true
}
if n.Visibility != IndexVisibilityDefault {
if hasPrevOption {
ctx.WritePlain(" ")
}
switch n.Visibility {
case IndexVisibilityVisible:
ctx.WriteKeyWord("VISIBLE")
case IndexVisibilityInvisible:
ctx.WriteKeyWord("INVISIBLE")
}
}
return nil
}
......@@ -1312,7 +1346,7 @@ func (n *CreateIndexStmt) Restore(ctx *RestoreCtx) error {
}
ctx.WritePlain(")")
if n.IndexOption.Tp != model.IndexTypeInvalid || n.IndexOption.KeyBlockSize > 0 || n.IndexOption.Comment != "" {
if n.IndexOption.Tp != model.IndexTypeInvalid || n.IndexOption.KeyBlockSize > 0 || n.IndexOption.Comment != "" || len(n.IndexOption.ParserName.O) > 0 || n.IndexOption.Visibility != IndexVisibilityDefault {
ctx.WritePlain(" ")
if err := n.IndexOption.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore CreateIndexStmt.IndexOption")
......@@ -1557,6 +1591,8 @@ const (
TableOptionSecondaryEngineNull
TableOptionInsertMethod
TableOptionTableCheckSum
TableOptionUnion
TableOptionEncryption
)
// RowFormat types
......@@ -1591,10 +1627,11 @@ const (
// TableOption is used for parsing table option from SQL.
type TableOption struct {
Tp TableOptionType
Default bool
StrValue string
UintValue uint64
Tp TableOptionType
Default bool
StrValue string
UintValue uint64
TableNames []*TableName
}
func (n *TableOption) Restore(ctx *RestoreCtx) error {
......@@ -1762,6 +1799,20 @@ func (n *TableOption) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord("TABLE_CHECKSUM ")
ctx.WritePlain("= ")
ctx.WritePlainf("%d", n.UintValue)
case TableOptionUnion:
ctx.WriteKeyWord("UNION ")
ctx.WritePlain("= (")
for i, tableName := range n.TableNames {
if i != 0 {
ctx.WritePlain(",")
}
tableName.Restore(ctx)
}
ctx.WritePlain(")")
case TableOptionEncryption:
ctx.WriteKeyWord("ENCRYPTION ")
ctx.WritePlain("= ")
ctx.WriteString(n.StrValue)
default:
return errors.Errorf("invalid TableOption: %d", n.Tp)
}
......@@ -1865,8 +1916,11 @@ const (
AlterTableDiscardPartitionTablespace
AlterTableAlterCheck
AlterTableDropCheck
AlterTableImportTablespace
AlterTableDiscardTablespace
AlterTableIndexInvisible
// TODO: Add more actions
AlterTableOrderByColumns
)
// LockType is the type for AlterTableSpec.
......@@ -1943,6 +1997,7 @@ type AlterTableSpec struct {
Name string
Constraint *Constraint
Options []*TableOption
OrderByList []*AlterOrderItem
NewTable *TableName
NewColumns []*ColumnDef
OldColumnName *ColumnName
......@@ -1958,6 +2013,25 @@ type AlterTableSpec struct {
PartDefinitions []*PartitionDefinition
WithValidation bool
Num uint64
Visibility IndexVisibility
}
// AlterOrderItem represents an item in order by at alter table stmt.
type AlterOrderItem struct {
node
Column *ColumnName
Desc bool
}
// Restore implements Node interface.
func (n *AlterOrderItem) Restore(ctx *RestoreCtx) error {
if err := n.Column.Restore(ctx); err != nil {
return errors.Annotate(err, "An error occurred while restore AlterOrderItem.Column")
}
if n.Desc {
ctx.WriteKeyWord(" DESC")
}
return nil
}
// Restore implements Node interface.
......@@ -2109,6 +2183,16 @@ func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error {
ctx.WriteKeyWord("LOCK ")
ctx.WritePlain("= ")
ctx.WriteKeyWord(n.LockType.String())
case AlterTableOrderByColumns:
ctx.WriteKeyWord("ORDER BY ")
for i, alterOrderItem := range n.OrderByList {
if i != 0 {
ctx.WritePlain(",")
}
if err := alterOrderItem.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore AlterTableSpec.OrderByList[%d]", i)
}
}
case AlterTableAlgorithm:
ctx.WriteKeyWord("ALGORITHM ")
ctx.WritePlain("= ")
......@@ -2322,6 +2406,19 @@ func (n *AlterTableSpec) Restore(ctx *RestoreCtx) error {
case AlterTableDropCheck:
ctx.WriteKeyWord("DROP CHECK ")
ctx.WriteName(n.Constraint.Name)
case AlterTableImportTablespace:
ctx.WriteKeyWord("IMPORT TABLESPACE")
case AlterTableDiscardTablespace:
ctx.WriteKeyWord("DISCARD TABLESPACE")
case AlterTableIndexInvisible:
ctx.WriteKeyWord("ALTER INDEX ")
ctx.WriteName(n.Name)
switch n.Visibility {
case IndexVisibilityVisible:
ctx.WriteKeyWord(" VISIBLE")
case IndexVisibilityInvisible:
ctx.WriteKeyWord(" INVISIBLE")
}
default:
// TODO: not support
ctx.WritePlainf(" /* AlterTableType(%d) is not supported */ ", n.Tp)
......@@ -2390,7 +2487,7 @@ func (n *AlterTableStmt) Restore(ctx *RestoreCtx) error {
return errors.Annotate(err, "An error occurred while restore AlterTableStmt.Table")
}
for i, spec := range n.Specs {
if i == 0 || spec.Tp == AlterTablePartition || spec.Tp == AlterTableRemovePartitioning {
if i == 0 || spec.Tp == AlterTablePartition || spec.Tp == AlterTableRemovePartitioning || spec.Tp == AlterTableImportTablespace || spec.Tp == AlterTableDiscardTablespace {
ctx.WritePlain(" ")
} else {
ctx.WritePlain(", ")
......
......@@ -764,6 +764,8 @@ type SelectStmt struct {
IsAfterUnionDistinct bool
// IsInBraces indicates whether it's a stmt in brace.
IsInBraces bool
// QueryBlockOffset indicates the order of this SelectStmt if counted from left to right in the sql text.
QueryBlockOffset int
}
// Restore implements Node interface.
......@@ -906,6 +908,14 @@ func (n *SelectStmt) Accept(v Visitor) (Node, bool) {
n.TableHints = newHints
}
if n.Fields != nil {
node, ok := n.Fields.Accept(v)
if !ok {
return n, false
}
n.Fields = node.(*FieldList)
}
if n.From != nil {
node, ok := n.From.Accept(v)
if !ok {
......@@ -922,14 +932,6 @@ func (n *SelectStmt) Accept(v Visitor) (Node, bool) {
n.Where = node.(ExprNode)
}
if n.Fields != nil {
node, ok := n.Fields.Accept(v)
if !ok {
return n, false
}
n.Fields = node.(*FieldList)
}
if n.GroupBy != nil {
node, ok := n.GroupBy.Accept(v)
if !ok {
......
......@@ -150,7 +150,7 @@ func (n *TraceStmt) Accept(v Visitor) (Node, bool) {
if !ok {
return n, false
}
n.Stmt = node.(DMLNode)
n.Stmt = node.(StmtNode)
return v.Leave(n)
}
......@@ -2027,13 +2027,14 @@ type TableOptimizerHint struct {
// It allows only table name or alias (if table has an alias)
HintName model.CIStr
// QBName is the default effective query block of this hint.
QBName model.CIStr
Tables []HintTable
Indexes []model.CIStr
QBName model.CIStr
Tables []HintTable
Indexes []model.CIStr
StoreType model.CIStr
// Statement Execution Time Optimizer Hints
// See https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html#optimizer-hints-execution-time
MaxExecutionTime uint64
MemoryQuota uint64
MemoryQuota int64
QueryType model.CIStr
HintFlag bool
}
......@@ -2064,7 +2065,7 @@ func (n *TableOptimizerHint) Restore(ctx *RestoreCtx) error {
}
// Hints without args except query block.
switch n.HintName.L {
case "hash_agg", "stream_agg", "read_consistent_replica", "no_index_merge", "qb_name":
case "hash_agg", "stream_agg", "agg_to_cop", "read_consistent_replica", "no_index_merge", "qb_name":
ctx.WritePlain(")")
return nil
}
......@@ -2100,7 +2101,20 @@ func (n *TableOptimizerHint) Restore(ctx *RestoreCtx) error {
case "query_type":
ctx.WriteKeyWord(n.QueryType.String())
case "memory_quota":
ctx.WritePlainf("%d M", n.MemoryQuota)
ctx.WritePlainf("%d MB", n.MemoryQuota/1024/1024)
case "read_from_storage":
ctx.WriteKeyWord(n.StoreType.String())
for i, table := range n.Tables {
if i == 0 {
ctx.WritePlain("[")
}
table.Restore(ctx)
if i == len(n.Tables)-1 {
ctx.WritePlain("]")
} else {
ctx.WritePlain(", ")
}
}
}
ctx.WritePlain(")")
return nil
......
......@@ -89,6 +89,8 @@ func init() {
initTokenByte('<', int('<'))
initTokenByte('(', int('('))
initTokenByte(')', int(')'))
initTokenByte('[', int('['))
initTokenByte(']', int(']'))
initTokenByte(';', int(';'))
initTokenByte(',', int(','))
initTokenByte('&', int('&'))
......@@ -138,6 +140,7 @@ var tokenMap = map[string]int{
"ADDDATE": addDate,
"ADMIN": admin,
"AFTER": after,
"AGG_TO_COP": hintAggToCop,
"ALL": all,
"ALGORITHM": algorithm,
"ALTER": alter,
......@@ -333,6 +336,7 @@ var tokenMap = map[string]int{
"INTERVAL": interval,
"INTERNAL": internal,
"INTO": into,
"INVISIBLE": invisible,
"INVOKER": invoker,
"IS": is,
"ISSUER": issuer,
......@@ -424,6 +428,7 @@ var tokenMap = map[string]int{
"OUTER": outer,
"PACK_KEYS": packKeys,
"PAGE": pageSym,
"PARSER": parser,
"PARTIAL": partial,
"PARTITION": partition,
"PARTITIONING": partitioning,
......@@ -456,6 +461,7 @@ var tokenMap = map[string]int{
"REBUILD": rebuild,
"READ": read,
"READ_CONSISTENT_REPLICA": hintReadConsistentReplica,
"READ_FROM_STORAGE": hintReadFromStorage,
"REAL": realType,
"RECENT": recent,
"REDUNDANT": redundant,
......@@ -575,6 +581,8 @@ var tokenMap = map[string]int{
"TIDB_HJ": hintHJ,
"TIDB_INLJ": hintINLJ,
"TIDB_SMJ": hintSMJ,
"TIKV": hintTiKV,
"TIFLASH": hintTiFlash,
"TIME": timeType,
"TIMESTAMP": timestampType,
"TIMESTAMPADD": timestampAdd,
......@@ -625,6 +633,7 @@ var tokenMap = map[string]int{
"VALUES": values,
"VARBINARY": varbinaryType,
"VARCHAR": varcharType,
"VARCHARACTER": varcharacter,
"VARIABLES": variables,
"VARIANCE": varPop,
"VARYING": varying,
......@@ -632,6 +641,7 @@ var tokenMap = map[string]int{
"VAR_SAMP": varSamp,
"VIEW": view,
"VIRTUAL": virtual,
"VISIBLE": visible,
"WARNINGS": warnings,
"ERRORS": identSQLErrors,
"WEEK": week,
......
......@@ -898,6 +898,7 @@ const (
ErrJSONUsedAsKey = 3152
ErrInvalidJSONPathArrayCell = 3165
ErrBadUser = 3162
ErrInvalidEncryptionOption = 3184
ErrRoleNotGranted = 3530
ErrWindowNoSuchWindow = 3579
ErrWindowCircularityInWindowGraph = 3580
......
......@@ -893,6 +893,7 @@ var MySQLErrName = map[uint16]string{
ErrInvalidJSONContainsPathType: "The second argument can only be either 'one' or 'all'.",
ErrJSONUsedAsKey: "JSON column '%-.192s' cannot be used in key specification.",
ErrInvalidJSONPathArrayCell: "A path expression is not a path to a cell in an array.",
ErrInvalidEncryptionOption: "Invalid encryption option.",
ErrWindowNoSuchWindow: "Window name '%s' is not defined.",
ErrWindowCircularityInWindowGraph: "There is a circularity in the window dependency graph.",
ErrWindowNoChildPartitioning: "A window which depends on another cannot define partitioning.",
......
......@@ -200,6 +200,7 @@ import (
over "OVER"
packKeys "PACK_KEYS"
partition "PARTITION"
parser "PARSER"
percentRank "PERCENT_RANK"
precisionType "PRECISION"
primary "PRIMARY"
......@@ -261,6 +262,7 @@ import (
values "VALUES"
long "LONG"
varcharType "VARCHAR"
varcharacter "VARCHARACTER"
varbinaryType "VARBINARY"
varying "VARYING"
virtual "VIRTUAL"
......@@ -361,6 +363,7 @@ import (
issuer "ISSUER"
incremental "INCREMENTAL"
indexes "INDEXES"
invisible "INVISIBLE"
invoker "INVOKER"
io "IO"
ipc "IPC"
......@@ -497,6 +500,7 @@ import (
value "VALUE"
variables "VARIABLES"
view "VIEW"
visible "VISIBLE"
binding "BINDING"
bindings "BINDINGS"
warnings "WARNINGS"
......@@ -578,6 +582,7 @@ import (
statsBuckets "STATS_BUCKETS"
statsHealthy "STATS_HEALTHY"
tidb "TIDB"
hintAggToCop "AGG_TO_COP"
hintHJ "HASH_JOIN"
hintSMJ "SM_JOIN"
hintINLJ "INL_JOIN"
......@@ -589,11 +594,14 @@ import (
hintEnablePlanCache "ENABLE_PLAN_CACHE"
hintUsePlanCache "USE_PLAN_CACHE"
hintReadConsistentReplica "READ_CONSISTENT_REPLICA"
hintReadFromStorage "READ_FROM_STORAGE"
hintQBName "QB_NAME"
hintQueryType "QUERY_TYPE"
hintMemoryQuota "MEMORY_QUOTA"
hintOLAP "OLAP"
hintOLTP "OLTP"
hintTiKV "TIKV"
hintTiFlash "TIFLASH"
topn "TOPN"
split "SPLIT"
width "WIDTH"
......@@ -833,6 +841,7 @@ import (
IndexHintListOpt "index hint list opt"
IndexHintScope "index hint scope"
IndexHintType "index hint type"
IndexInvisible "index visible/invisible"
IndexKeyTypeOpt "index key type"
IndexLockAndAlgorithmOpt "index lock and algorithm"
IndexName "index name"
......@@ -869,6 +878,8 @@ import (
ByItem "BY item"
OrderByOptional "Optional ORDER BY clause optional"
ByList "BY list"
AlterOrderItem "Alter Order item"
AlterOrderList "Alter Order list"
QuickOptional "QUICK or empty"
QueryBlockOpt "Query block identifier optional"
PartitionDefinition "Partition definition"
......@@ -1058,11 +1069,15 @@ import (
NUM "A number"
NumList "Some numbers"
LengthNum "Field length num(uint64)"
StorageOptimizerHintOpt "Storage level optimizer hint"
TableOptimizerHintOpt "Table level optimizer hint"
TableOptimizerHints "Table level optimizer hints"
TableOptimizerHintList "Table level optimizer hint list"
OptimizerHintList "optimizer hint list"
HintTable "Table in optimizer hint"
HintTableList "Table list in optimizer hint"
HintStorageType "storage type in optimizer hint"
HintStorageTypeAndTable "storage type and tables in optimizer hint"
HintStorageTypeAndTableList "storage type and tables list in optimizer hint"
HintTrueOrFalse "True or false in optimizer hint"
HintQueryType "Query type in optimizer hint"
HintMemoryQuota "Memory quota in optimizer hint"
......@@ -1087,8 +1102,8 @@ import (
ValueSym "Value or Values"
Char "{CHAR|CHARACTER}"
NChar "{NCHAR|NATIONAL CHARACTER|NATIONAL CHAR}"
Varchar "{VARCHAR|CHARACTER VARYING|CHAR VARYING}"
NVarchar "{NATIONAL VARCHAR|NVARCHAR|NCHAR VARCHAR|NATIONAL CHARACTER VARYING|NATIONAL CHAR VARYING|NCHAR VARYING}"
Varchar "{VARCHAR|VARCHARACTER|CHARACTER VARYING|CHAR VARYING}"
NVarchar "{NATIONAL VARCHAR|NATIONAL VARCHARACTER|NVARCHAR|NCHAR VARCHAR|NATIONAL CHARACTER VARYING|NATIONAL CHAR VARYING|NCHAR VARYING}"
DeallocateSym "Deallocate or drop"
OuterOpt "optional OUTER clause"
CrossOpt "Cross join option"
......@@ -1143,6 +1158,8 @@ import (
%precedence local
%precedence lowerThanRemove
%precedence remove
%precedence lowerThenOrder
%precedence order
%left join straightJoin inner cross left right full natural
/* A dummy token to force the priority of TableRef production in a join. */
......@@ -1441,6 +1458,24 @@ AlterTableSpec:
yylex.AppendError(yylex.Errorf("The DISCARD PARTITION TABLESPACE clause is parsed but ignored by all storage engines."))
parser.lastErrorAsWarn()
}
| "IMPORT" "TABLESPACE"
{
ret := &ast.AlterTableSpec{
Tp: ast.AlterTableImportTablespace,
}
$$ = ret
yylex.AppendError(yylex.Errorf("The IMPORT TABLESPACE clause is parsed but ignored by all storage engines."))
parser.lastErrorAsWarn()
}
| "DISCARD" "TABLESPACE"
{
ret := &ast.AlterTableSpec{
Tp: ast.AlterTableDiscardTablespace,
}
$$ = ret
yylex.AppendError(yylex.Errorf("The DISCARD TABLESPACE clause is parsed but ignored by all storage engines."))
parser.lastErrorAsWarn()
}
| "REBUILD" "PARTITION" NoWriteToBinLogAliasOpt AllOrPartitionNameList
{
ret := &ast.AlterTableSpec{
......@@ -1479,6 +1514,13 @@ AlterTableSpec:
Name: $5.(string),
}
}
| "ORDER" "BY" AlterOrderList %prec lowerThenOrder
{
$$ = &ast.AlterTableSpec{
Tp: ast.AlterTableOrderByColumns,
OrderByList: $3.([]*ast.AlterOrderItem),
}
}
| "DISABLE" "KEYS"
{
$$ = &ast.AlterTableSpec{
......@@ -1668,6 +1710,14 @@ AlterTableSpec:
yylex.AppendError(yylex.Errorf("The DROP CHECK clause is parsed but not implemented yet."))
parser.lastErrorAsWarn()
}
| "ALTER" "INDEX" Identifier IndexInvisible
{
$$ = &ast.AlterTableSpec{
Tp: ast.AlterTableIndexInvisible,
Name: $3,
Visibility: $4.(ast.IndexVisibility),
}
}
ReorganizePartitionRuleOpt:
/* empty */ %prec lowerThanRemove
......@@ -1741,26 +1791,24 @@ AlgorithmClause:
}
LockClause:
"LOCK" EqOpt "NONE"
{
$$ = ast.LockTypeNone
}
| "LOCK" EqOpt "DEFAULT"
"LOCK" EqOpt "DEFAULT"
{
$$ = ast.LockTypeDefault
}
| "LOCK" EqOpt "SHARED"
{
$$ = ast.LockTypeShared
}
| "LOCK" EqOpt "EXCLUSIVE"
{
$$ = ast.LockTypeExclusive
}
| "LOCK" EqOpt identifier
| "LOCK" EqOpt Identifier
{
yylex.AppendError(ErrUnknownAlterLock.GenWithStackByArgs($3))
return 1
id := strings.ToUpper($3)
if id == "NONE" {
$$ = ast.LockTypeNone
} else if id == "SHARED" {
$$ = ast.LockTypeShared
} else if id == "EXCLUSIVE" {
$$ = ast.LockTypeExclusive
} else {
yylex.AppendError(ErrUnknownAlterLock.GenWithStackByArgs($3))
return 1
}
}
KeyOrIndex: "KEY" | "INDEX"
......@@ -2335,7 +2383,7 @@ ColumnOption:
$$ = &ast.ColumnOption{Tp: ast.ColumnOptionColumnFormat, StrValue: $2.(string)}
}
ColumnFormat:
ColumnFormat:
"DEFAULT"
{
$$ = "DEFAULT"
......@@ -2655,7 +2703,9 @@ NumLiteral:
* index_option:
* KEY_BLOCK_SIZE [=] value
* | index_type
* | WITH PARSER parser_name
* | COMMENT 'string'
* | {VISIBLE | INVISIBLE}
*
* index_type:
* USING {BTREE | HASH}
......@@ -4135,7 +4185,11 @@ IndexOptionList:
} else if opt2.Tp != 0 {
opt1.Tp = opt2.Tp
} else if opt2.KeyBlockSize > 0 {
opt1.KeyBlockSize = opt2.KeyBlockSize
opt1.KeyBlockSize = opt2.KeyBlockSize
} else if len(opt2.ParserName.O) > 0 {
opt1.ParserName = opt2.ParserName
} else if opt2.Visibility != ast.IndexVisibilityDefault {
opt1.Visibility = opt2.Visibility
}
$$ = opt1
}
......@@ -4155,12 +4209,26 @@ IndexOption:
Tp: $1.(model.IndexType),
}
}
| "WITH" "PARSER" Identifier
{
$$ = &ast.IndexOption {
ParserName: model.NewCIStr($3),
}
yylex.AppendError(yylex.Errorf("The WITH PARASER clause is parsed but ignored by all storage engines."))
parser.lastErrorAsWarn()
}
| "COMMENT" stringLit
{
$$ = &ast.IndexOption {
Comment: $2,
}
}
| IndexInvisible
{
$$ = &ast.IndexOption {
Visibility: $1.(ast.IndexVisibility),
}
}
IndexType:
"USING" "BTREE"
......@@ -4185,6 +4253,16 @@ IndexTypeOpt:
$$ = $1
}
IndexInvisible:
"VISIBLE"
{
$$ = ast.IndexVisibilityVisible
}
| "INVISIBLE"
{
$$ = ast.IndexVisibilityInvisible
}
/**********************************Identifier********************************************/
Identifier:
identifier | UnReservedKeyword | NotKeywordToken | TiDBKeyword
......@@ -4206,12 +4284,12 @@ UnReservedKeyword:
| "RECOVER" | "CIPHER" | "SUBJECT" | "ISSUER" | "X509" | "NEVER" | "EXPIRE" | "ACCOUNT" | "INCREMENTAL" | "CPU" | "MEMORY" | "BLOCK" | "IO" | "CONTEXT" | "SWITCHES" | "PAGE" | "FAULTS" | "IPC" | "SWAPS" | "SOURCE"
| "TRADITIONAL" | "SQL_BUFFER_RESULT" | "DIRECTORY" | "HISTORY" | "LIST" | "NODEGROUP" | "SYSTEM_TIME" | "PARTIAL" | "SIMPLE" | "REMOVE" | "PARTITIONING" | "STORAGE" | "DISK" | "STATS_SAMPLE_PAGES" | "SECONDARY_ENGINE" | "SECONDARY_LOAD" | "SECONDARY_UNLOAD" | "VALIDATION"
| "WITHOUT" | "RTREE" | "EXCHANGE" | "COLUMN_FORMAT" | "REPAIR" | "IMPORT" | "DISCARD" | "TABLE_CHECKSUM"
| "SQL_TSI_DAY" | "SQL_TSI_HOUR" | "SQL_TSI_MINUTE" | "SQL_TSI_MONTH" | "SQL_TSI_QUARTER" | "SQL_TSI_SECOND" | "SQL_TSI_WEEK" | "SQL_TSI_YEAR"
| "SQL_TSI_DAY" | "SQL_TSI_HOUR" | "SQL_TSI_MINUTE" | "SQL_TSI_MONTH" | "SQL_TSI_QUARTER" | "SQL_TSI_SECOND" | "SQL_TSI_WEEK" | "SQL_TSI_YEAR" | "INVISIBLE" | "VISIBLE"
TiDBKeyword:
"ADMIN" | "BUCKETS" | "CANCEL" | "CMSKETCH" | "DDL" | "DEPTH" | "DRAINER" | "JOBS" | "JOB" | "NODE_ID" | "NODE_STATE" | "PUMP" | "SAMPLES" | "STATS" | "STATS_META" | "STATS_HISTOGRAMS" | "STATS_BUCKETS" | "STATS_HEALTHY" | "TIDB"
"ADMIN" | "AGG_TO_COP" |"BUCKETS" | "CANCEL" | "CMSKETCH" | "DDL" | "DEPTH" | "DRAINER" | "JOBS" | "JOB" | "NODE_ID" | "NODE_STATE" | "PUMP" | "SAMPLES" | "STATS" | "STATS_META" | "STATS_HISTOGRAMS" | "STATS_BUCKETS" | "STATS_HEALTHY" | "TIDB"
| "HASH_JOIN" | "SM_JOIN" | "INL_JOIN" | "HASH_AGG" | "STREAM_AGG" | "USE_INDEX_MERGE" | "NO_INDEX_MERGE" | "USE_TOJA" | "ENABLE_PLAN_CACHE" | "USE_PLAN_CACHE"
| "READ_CONSISTENT_REPLICA" | "QB_NAME" | "QUERY_TYPE" | "MEMORY_QUOTA" | "OLAP" | "OLTP" |"TOPN" | "SPLIT" | "OPTIMISTIC" | "PESSIMISTIC" | "WIDTH" | "REGIONS"
| "READ_CONSISTENT_REPLICA" | "READ_FROM_STORAGE" | "QB_NAME" | "QUERY_TYPE" | "MEMORY_QUOTA" | "OLAP" | "OLTP" | "TOPN" | "TIKV" | "TIFLASH" | "SPLIT" | "OPTIMISTIC" | "PESSIMISTIC" | "WIDTH" | "REGIONS"
NotKeywordToken:
"ADDDATE" | "BIT_AND" | "BIT_OR" | "BIT_XOR" | "CAST" | "COPY" | "COUNT" | "CURTIME" | "DATE_ADD" | "DATE_SUB" | "EXTRACT" | "GET_FORMAT" | "GROUP_CONCAT"
......@@ -4473,6 +4551,21 @@ StringLiteral:
$$ = expr
}
AlterOrderList:
AlterOrderItem
{
$$ = []*ast.AlterOrderItem{$1.(*ast.AlterOrderItem)}
}
| AlterOrderList ',' AlterOrderItem
{
$$ = append($1.([]*ast.AlterOrderItem), $3.(*ast.AlterOrderItem))
}
AlterOrderItem:
ColumnName Order
{
$$ = &ast.AlterOrderItem{Column: $1.(*ast.ColumnName), Desc: $2.(bool)}
}
OrderBy:
"ORDER" "BY" ByList
......@@ -6470,7 +6563,7 @@ TableOptimizerHints:
{
$$ = nil
}
| hintBegin TableOptimizerHintList hintEnd
| hintBegin OptimizerHintList hintEnd
{
$$ = $2
}
......@@ -6481,19 +6574,31 @@ TableOptimizerHints:
$$ = nil
}
TableOptimizerHintList:
OptimizerHintList:
TableOptimizerHintOpt
{
$$ = []*ast.TableOptimizerHint{$1.(*ast.TableOptimizerHint)}
}
| TableOptimizerHintList TableOptimizerHintOpt
| StorageOptimizerHintOpt
{
$$ = $1.([]*ast.TableOptimizerHint)
}
| OptimizerHintList TableOptimizerHintOpt
{
$$ = append($1.([]*ast.TableOptimizerHint), $2.(*ast.TableOptimizerHint))
}
| TableOptimizerHintList ',' TableOptimizerHintOpt
| OptimizerHintList ',' TableOptimizerHintOpt
{
$$ = append($1.([]*ast.TableOptimizerHint), $3.(*ast.TableOptimizerHint))
}
| OptimizerHintList StorageOptimizerHintOpt
{
$$ = append($1.([]*ast.TableOptimizerHint), $2.([]*ast.TableOptimizerHint)...)
}
| OptimizerHintList ',' StorageOptimizerHintOpt
{
$$ = append($1.([]*ast.TableOptimizerHint), $3.([]*ast.TableOptimizerHint)...)
}
TableOptimizerHintOpt:
index '(' QueryBlockOpt HintTable IndexNameList ')'
......@@ -6549,7 +6654,7 @@ TableOptimizerHintOpt:
}
| hintMemoryQuota '(' QueryBlockOpt HintMemoryQuota ')'
{
$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), QBName: $3.(model.CIStr), MemoryQuota: $4.(uint64)}
$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), QBName: $3.(model.CIStr), MemoryQuota: $4.(int64)}
}
| hintHASHAGG '(' QueryBlockOpt ')'
{
......@@ -6559,6 +6664,10 @@ TableOptimizerHintOpt:
{
$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), QBName: $3.(model.CIStr)}
}
| hintAggToCop '(' QueryBlockOpt ')'
{
$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), QBName: $3.(model.CIStr)}
}
| hintNoIndexMerge '(' QueryBlockOpt ')'
{
$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), QBName: $3.(model.CIStr)}
......@@ -6572,6 +6681,35 @@ TableOptimizerHintOpt:
$$ = &ast.TableOptimizerHint{HintName: model.NewCIStr($1), QBName: model.NewCIStr($3)}
}
StorageOptimizerHintOpt:
hintReadFromStorage '(' QueryBlockOpt HintStorageTypeAndTableList ')'
{
$$ = $4.([]*ast.TableOptimizerHint)
for _, hint := range $$.([]*ast.TableOptimizerHint) {
hint.HintName = model.NewCIStr($1)
hint.QBName = $3.(model.CIStr)
}
}
HintStorageTypeAndTableList:
HintStorageTypeAndTable
{
$$ = []*ast.TableOptimizerHint{$1.(*ast.TableOptimizerHint)}
}
| HintStorageTypeAndTableList ',' HintStorageTypeAndTable
{
$$ = append($1.([]*ast.TableOptimizerHint), $3.(*ast.TableOptimizerHint))
}
HintStorageTypeAndTable:
HintStorageType '[' HintTableList ']'
{
$$ = &ast.TableOptimizerHint{
StoreType: model.NewCIStr($1.(string)),
Tables: $3.([]ast.HintTable),
}
}
QueryBlockOpt:
{
$$ = model.NewCIStr("")
......@@ -6607,6 +6745,16 @@ HintTrueOrFalse:
$$ = false
}
HintStorageType:
hintTiKV
{
$$ = $1
}
| hintTiFlash
{
$$ = $1
}
HintQueryType:
hintOLAP
{
......@@ -6620,15 +6768,14 @@ HintQueryType:
HintMemoryQuota:
NUM Identifier
{
// May change into MB/MiB or GB/GiB
switch model.NewCIStr($2).L {
case "m":
$$ = getUint64FromNUM($1)
case "g":
$$ = getUint64FromNUM($1) * 1024
case "mb":
$$ = $1.(int64) * 1024 * 1024
case "gb":
$$ = $1.(int64) * 1024 * 1024 * 1024
default:
// Trigger warning in TiDB Planner
$$ = uint64(0)
// Executor handle memory quota < 0 as no memory limit, here use it to trigger warning in TiDB.
$$ = int64(-1)
}
}
......@@ -8085,6 +8232,10 @@ TraceableStmt:
| ReplaceIntoStmt
| UnionStmt
| LoadDataStmt
| BeginTransactionStmt
| CommitStmt
| RollbackStmt
| SetStmt
ExplainableStmt:
SelectStmt
......@@ -8317,6 +8468,23 @@ TableOption:
yylex.AppendError(yylex.Errorf("The SECONDARY_ENGINE clause is parsed but ignored by all storage engines."))
parser.lastErrorAsWarn()
}
| "UNION" EqOpt '(' TableNameListOpt ')'
{
// Parse it but will ignore it
$$ = &ast.TableOption{
Tp: ast.TableOptionUnion,
TableNames: $4.([]*ast.TableName),
}
yylex.AppendError(yylex.Errorf("The UNION option is parsed but ignored by all storage engines."))
parser.lastErrorAsWarn()
}
| "ENCRYPTION" EqOpt stringLit
{
// Parse it but will ignore it
$$ = &ast.TableOption{Tp: ast.TableOptionEncryption, StrValue: $3}
yylex.AppendError(yylex.Errorf("The ENCRYPTION clause is parsed but ignored by all storage engines."))
parser.lastErrorAsWarn()
}
StatsPersistentVal:
"DEFAULT"
......@@ -8725,6 +8893,24 @@ StringType:
x.Collate = charset.CollationBin
$$ = x
}
| "LONG" Varchar OptBinary
{
x := types.NewFieldType(mysql.TypeMediumBlob)
x.Charset = $3.(*ast.OptBinary).Charset
if $3.(*ast.OptBinary).IsBinary {
x.Flag |= mysql.BinaryFlag
}
$$ = x
}
| "LONG" OptBinary
{
x := types.NewFieldType(mysql.TypeMediumBlob)
x.Charset = $2.(*ast.OptBinary).Charset
if $2.(*ast.OptBinary).IsBinary {
x.Flag |= mysql.BinaryFlag
}
$$ = x
}
Char:
"CHARACTER"
......@@ -8739,11 +8925,14 @@ Varchar:
"CHARACTER" "VARYING"
| "CHAR" "VARYING"
| "VARCHAR"
| "VARCHARACTER"
NVarchar:
"NATIONAL" "VARCHAR"
| "NATIONAL" "VARCHARACTER"
| "NVARCHAR"
| "NCHAR" "VARCHAR"
| "NCHAR" "VARCHARACTER"
| "NATIONAL" "CHARACTER" "VARYING"
| "NATIONAL" "CHAR" "VARYING"
| "NCHAR" "VARYING"
......@@ -8771,6 +8960,11 @@ BlobType:
x := types.NewFieldType(mysql.TypeLongBlob)
$$ = x
}
| "LONG" "VARBINARY"
{
x := types.NewFieldType(mysql.TypeMediumBlob)
$$ = x
}
TextType:
"TINYTEXT"
......@@ -8795,16 +8989,6 @@ TextType:
x := types.NewFieldType(mysql.TypeLongBlob)
$$ = x
}
| "LONG"
{
x := types.NewFieldType(mysql.TypeMediumBlob)
$$ = x
}
| "LONG" "VARCHAR"
{
x := types.NewFieldType(mysql.TypeMediumBlob)
$$ = x
}
DateAndTimeType:
......
......@@ -76,13 +76,6 @@ type StatementContext struct {
// prefix in a strict way, only extract 0-9 and (+ or - in first bit).
CastStrToIntStrict bool
// StartTime is the query start time.
StartTime time.Time
// DurationParse is the duration of pasing SQL string to AST.
DurationParse time.Duration
// DurationCompile is the duration of compiling AST to execution plan.
DurationCompile time.Duration
// mu struct holds variables that change during execution.
mu struct {
sync.Mutex
......@@ -131,7 +124,7 @@ type StatementContext struct {
MemTracker *memory.Tracker
RuntimeStatsColl *execdetails.RuntimeStatsColl
TableIDs []int64
IndexIDs []int64
IndexNames []string
nowTs time.Time // use this variable for now/current_timestamp calculation/cache for one stmt
stmtTimeCached bool
StmtType string
......@@ -419,10 +412,7 @@ func (sc *StatementContext) ResetForRetry() {
sc.mu.allExecDetails = make([]*execdetails.ExecDetails, 0, 4)
sc.mu.Unlock()
sc.TableIDs = sc.TableIDs[:0]
sc.IndexIDs = sc.IndexIDs[:0]
sc.StartTime = time.Now()
sc.DurationCompile = time.Duration(0)
sc.DurationParse = time.Duration(0)
sc.IndexNames = sc.IndexNames[:0]
}
// MergeExecDetails merges a single region execution details into self, used to print
......
// Copyright 2019 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"strings"
"github.com/pingcap/parser/model"
)
// FieldName records the names used for mysql protocol.
type FieldName struct {
OrigTblName model.CIStr
OrigColName model.CIStr
DBName model.CIStr
TblName model.CIStr
ColName model.CIStr
}
// String implements Stringer interface.
func (name *FieldName) String() string {
builder := strings.Builder{}
if name.TblName.L != "" {
builder.WriteString(name.TblName.L + ".")
}
if name.DBName.L != "" {
builder.WriteString(name.DBName.L + ".")
}
builder.WriteString(name.ColName.L)
return builder.String()
}
......@@ -183,6 +183,12 @@ func DefaultTypeForValue(value interface{}, tp *FieldType) {
tp.Flen = len(x)
tp.Decimal = UnspecifiedLength
tp.Charset, tp.Collate = charset.GetDefaultCharsetAndCollate()
case float32:
tp.Tp = mysql.TypeFloat
s := strconv.FormatFloat(float64(x), 'f', -1, 32)
tp.Flen = len(s)
tp.Decimal = UnspecifiedLength
SetBinChsClnFlag(tp)
case float64:
tp.Tp = mysql.TypeDouble
s := strconv.FormatFloat(x, 'f', -1, 64)
......@@ -201,7 +207,7 @@ func DefaultTypeForValue(value interface{}, tp *FieldType) {
SetBinChsClnFlag(tp)
case HexLiteral:
tp.Tp = mysql.TypeVarString
tp.Flen = len(x)
tp.Flen = len(x) * 3
tp.Decimal = 0
tp.Flag |= mysql.UnsignedFlag
SetBinChsClnFlag(tp)
......
......@@ -250,6 +250,21 @@ func (d *MyDecimal) GetDigitsFrac() int8 {
return d.digitsFrac
}
// Copy copies a new *MyDecimal from itself.
func (d *MyDecimal) Copy() *MyDecimal {
if d == nil {
return nil
}
dst := &MyDecimal{
digitsInt: d.digitsInt,
digitsFrac: d.digitsFrac,
resultFrac: d.resultFrac,
negative: d.negative,
}
copy(dst.wordBuf[:], d.wordBuf[:])
return dst
}
// String returns the decimal string representation rounded to resultFrac.
func (d *MyDecimal) String() string {
tmp := *d
......
......@@ -16,6 +16,7 @@ package types
import (
"bytes"
"fmt"
"io"
"math"
"regexp"
"strconv"
......@@ -1169,6 +1170,9 @@ func ParseDuration(sc *stmtctx.StatementContext, str string, fsp int8) (Duration
return ZeroDuration, ErrTruncatedWrongVal.GenWithStackByArgs("time", origStr)
}
if terror.ErrorEqual(err, io.EOF) {
err = ErrTruncatedWrongVal.GenWithStackByArgs("time", origStr)
}
if err != nil {
return ZeroDuration, errors.Trace(err)
}
......
......@@ -49,7 +49,11 @@ type CommitDetails struct {
PrewriteTime time.Duration
CommitTime time.Duration
LocalLatchTime time.Duration
TotalBackoffTime time.Duration
CommitBackoffTime int64
Mu struct {
sync.Mutex
BackoffTypes []fmt.Stringer
}
ResolveLockTime int64
WriteKeys int
WriteSize int
......@@ -104,9 +108,15 @@ func (d ExecDetails) String() string {
if commitDetails.GetCommitTsTime > 0 {
parts = append(parts, fmt.Sprintf("Get_commit_ts_time: %v", commitDetails.GetCommitTsTime.Seconds()))
}
if commitDetails.TotalBackoffTime > 0 {
parts = append(parts, fmt.Sprintf("Total_backoff_time: %v", commitDetails.TotalBackoffTime.Seconds()))
commitBackoffTime := atomic.LoadInt64(&commitDetails.CommitBackoffTime)
if commitBackoffTime > 0 {
parts = append(parts, fmt.Sprintf("Commit_backoff_time: %v", time.Duration(commitBackoffTime).Seconds()))
}
commitDetails.Mu.Lock()
if len(commitDetails.Mu.BackoffTypes) > 0 {
parts = append(parts, fmt.Sprintf("Backoff_types: %v", commitDetails.Mu.BackoffTypes))
}
commitDetails.Mu.Unlock()
resolveLockTime := atomic.LoadInt64(&commitDetails.ResolveLockTime)
if resolveLockTime > 0 {
parts = append(parts, fmt.Sprintf("Resolve_lock_time: %v", time.Duration(resolveLockTime).Seconds()))
......@@ -163,9 +173,15 @@ func (d ExecDetails) ToZapFields() (fields []zap.Field) {
if commitDetails.GetCommitTsTime > 0 {
fields = append(fields, zap.String("get_commit_ts_time", fmt.Sprintf("%v", strconv.FormatFloat(commitDetails.GetCommitTsTime.Seconds(), 'f', -1, 64)+"s")))
}
if commitDetails.TotalBackoffTime > 0 {
fields = append(fields, zap.String("total_backoff_time", fmt.Sprintf("%v", strconv.FormatFloat(commitDetails.TotalBackoffTime.Seconds(), 'f', -1, 64)+"s")))
commitBackoffTime := atomic.LoadInt64(&commitDetails.CommitBackoffTime)
if commitBackoffTime > 0 {
fields = append(fields, zap.String("commit_backoff_time", fmt.Sprintf("%v", strconv.FormatFloat(time.Duration(commitBackoffTime).Seconds(), 'f', -1, 64)+"s")))
}
commitDetails.Mu.Lock()
if len(commitDetails.Mu.BackoffTypes) > 0 {
fields = append(fields, zap.String("backoff_types", fmt.Sprintf("%v", commitDetails.Mu.BackoffTypes)))
}
commitDetails.Mu.Unlock()
resolveLockTime := atomic.LoadInt64(&commitDetails.ResolveLockTime)
if resolveLockTime > 0 {
fields = append(fields, zap.String("resolve_lock_time", fmt.Sprintf("%v", strconv.FormatFloat(time.Duration(resolveLockTime).Seconds(), 'f', -1, 64)+"s")))
......
......@@ -32,7 +32,7 @@ func String(b []byte) MutableString {
// Use at your own risk.
func Slice(s string) (b []byte) {
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
pstring := *(*reflect.StringHeader)(unsafe.Pointer(&s))
pbytes.Data = pstring.Data
pbytes.Len = pstring.Len
pbytes.Cap = pstring.Len
......
......@@ -129,118 +129,118 @@
"revisionTime": "2019-03-07T07:54:52Z"
},
{
"checksumSHA1": "RK5vW/hPsPk0JDi1atCWaUR8iFo=",
"checksumSHA1": "wopyI0JhbHosTiSv1vL/d6xyjDs=",
"path": "github.com/pingcap/parser",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "WYPpAYqE/lpu4PBR9TCn6UigcTg=",
"checksumSHA1": "rNycpMFm1SPArRiqljKlCdtbKlE=",
"path": "github.com/pingcap/parser/ast",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "xiv40YqnvHcbIhaEzJqjh5K7ehM=",
"path": "github.com/pingcap/parser/auth",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "EvDXpplklIXmKqLclzWzaN/uHKQ=",
"path": "github.com/pingcap/parser/charset",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "Aao6Mul/qqogOwPwM2arBKZkYZs=",
"path": "github.com/pingcap/parser/format",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "GAJ7IUg0t8DCKJbJQxJLkklEj2E=",
"path": "github.com/pingcap/parser/model",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "WMkc5bRIYYfQdu9lBlVGyKTGIyg=",
"checksumSHA1": "9aEsfUW5bJTXPD7x2obSyd+6gw4=",
"path": "github.com/pingcap/parser/mysql",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "olapD16WCMBU9vrA5PtlERGFfXw=",
"path": "github.com/pingcap/parser/opcode",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "L6rzy3sJU1RPf7AkJN+0zcwW/YY=",
"path": "github.com/pingcap/parser/terror",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "u1Lmm4Fa3su4ElZMN4w0hPzFZl4=",
"path": "github.com/pingcap/parser/types",
"revision": "41d48df058643bdb2e24c64b1685c4e9ff6608f8",
"revisionTime": "2019-08-22T02:41:27Z"
"revision": "736e807a964125f7730192af0016e4fcf05c7b70",
"revisionTime": "2019-08-29T07:33:47Z"
},
{
"checksumSHA1": "cbEwgTkDlGpIIIqmNAuWrxsUwKw=",
"checksumSHA1": "ryt2yutvbgdMuS5uvtaiJqqvZXQ=",
"path": "github.com/pingcap/tidb/sessionctx/stmtctx",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "erB64jt/DCEoRs+KrywwHGJG2/k=",
"checksumSHA1": "tKaN6jgHhSXad0RSNpSe0q9fiMo=",
"path": "github.com/pingcap/tidb/types",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "gKBD02jzm/d7gn2kX7pXLi+M2ZY=",
"path": "github.com/pingcap/tidb/types/json",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "45zWX5Q6D6aTEWtc4p/lbD9WD4o=",
"path": "github.com/pingcap/tidb/types/parser_driver",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "q5aOzPGCVZNkrru6v6+uImWm1eA=",
"checksumSHA1": "uH6u5fhPvRiiOUCG8bJfphXm4jo=",
"path": "github.com/pingcap/tidb/util/execdetails",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "EFDXphVEI9ohnPky64fc+0lkRkw=",
"checksumSHA1": "zw1limoYLowZjRm8wgicyjC72+U=",
"path": "github.com/pingcap/tidb/util/hack",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "fDbwnQlRCKnr5y6MY799BEd4WlQ=",
"path": "github.com/pingcap/tidb/util/logutil",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "OveQu0ABBJmMEwmmthqSRQC2Ef0=",
"path": "github.com/pingcap/tidb/util/math",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "loL2JgZDLapEOgfM/XUJI5f0HVs=",
"path": "github.com/pingcap/tidb/util/memory",
"revision": "6f76bbe1f75e01dc40f2d0478d484aa9df2b284c",
"revisionTime": "2019-08-22T02:51:25Z"
"revision": "bdbaeb419dd5ff1b3a0b16f907a0cd7c421c83b0",
"revisionTime": "2019-08-29T06:45:52Z"
},
{
"checksumSHA1": "QPIBwDNUFF5Whrnd41S3mkKa4gQ=",
......@@ -497,68 +497,68 @@
{
"checksumSHA1": "aKn1oKcY74N8TRLm3Ayt7Q4bbI4=",
"path": "vitess.io/vitess/go/bytes2",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "bhE6CGQgZTIgLPp9lnvlKW/47xc=",
"path": "vitess.io/vitess/go/hack",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "8zh04M7R0JjzpE+w6/gxHdgZrJg=",
"checksumSHA1": "y2C3mKrC39Tffb/614ZYa/qEVGU=",
"path": "vitess.io/vitess/go/sqltypes",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "vAIRxI6MHsq3x1hLQwIyw5AvqtI=",
"path": "vitess.io/vitess/go/vt/log",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "//MHnGEq9xApvIMdwQaRrQf5ZWo=",
"path": "vitess.io/vitess/go/vt/proto/binlogdata",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "87Zndvk3Y+M+QxMx3uFa0iSbvWY=",
"checksumSHA1": "u8uuZWMqaXgQ1MduggrgIHU50FI=",
"path": "vitess.io/vitess/go/vt/proto/query",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "xpcb9NfXMEeHhEPStbJntIfa5GQ=",
"checksumSHA1": "rJ1Iqz/lvaKikIUx4oEFfYJtoBQ=",
"path": "vitess.io/vitess/go/vt/proto/topodata",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "Bv8lucvoH9AnJSYiWX8MIrJl4zY=",
"path": "vitess.io/vitess/go/vt/proto/vtgate",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "qz32abYdmm9NfKTc++K0l1EvXXM=",
"checksumSHA1": "HeUJu5njPq9iznpAOcrLpLD7f9w=",
"path": "vitess.io/vitess/go/vt/proto/vtrpc",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "0SPe/oMz50OW+yC+DGV4UJpjZ3Y=",
"checksumSHA1": "uhDAaoN8RkmdkmkbYkaX5dLPquc=",
"path": "vitess.io/vitess/go/vt/sqlparser",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
},
{
"checksumSHA1": "z9+F/lA1Xrl5S16LKssUH8VL6hs=",
"path": "vitess.io/vitess/go/vt/vterrors",
"revision": "b5207f0d590a8b596a9b465ee378be182459300f",
"revisionTime": "2019-08-21T22:46:46Z"
"revision": "ad6099c8cb9fce72a4b2d22ea55f4f693e846b3e",
"revisionTime": "2019-08-28T05:53:53Z"
}
],
"rootPath": "github.com/XiaoMi/soar"
......
......@@ -19,6 +19,8 @@ package sqltypes
import (
"bytes"
"fmt"
"math"
"strconv"
querypb "vitess.io/vitess/go/vt/proto/query"
......@@ -40,6 +42,25 @@ type numeric struct {
var zeroBytes = []byte("0")
// Add adds two values together
// if v1 or v2 is null, then it returns null
func Add(v1, v2 Value) (Value, error) {
if v1.IsNull() || v2.IsNull() {
return NULL, nil
}
lv1, err := newNumeric(v1)
lv2, err := newNumeric(v2)
lresult, err := addNumericWithError(lv1, lv2)
if err != nil {
return NULL, err
}
return castFromNumeric(lresult, lresult.typ), nil
}
// NullsafeAdd adds two Values in a null-safe manner. A null value
// is treated as 0. If both values are null, then a null is returned.
// If both values are not null, a numeric value is built
......@@ -51,7 +72,7 @@ var zeroBytes = []byte("0")
// addition, if one of the input types was Decimal, then
// a Decimal is built. Otherwise, the final type of the
// result is preserved.
func NullsafeAdd(v1, v2 Value, resultType querypb.Type) (Value, error) {
func NullsafeAdd(v1, v2 Value, resultType querypb.Type) Value {
if v1.IsNull() {
v1 = MakeTrusted(resultType, zeroBytes)
}
......@@ -61,16 +82,14 @@ func NullsafeAdd(v1, v2 Value, resultType querypb.Type) (Value, error) {
lv1, err := newNumeric(v1)
if err != nil {
return NULL, err
return NULL
}
lv2, err := newNumeric(v2)
if err != nil {
return NULL, err
}
lresult, err := addNumeric(lv1, lv2)
if err != nil {
return NULL, err
return NULL
}
lresult := addNumeric(lv1, lv2)
return castFromNumeric(lresult, resultType)
}
......@@ -224,10 +243,7 @@ func ToInt64(v Value) (int64, error) {
// ToFloat64 converts Value to float64.
func ToFloat64(v Value) (float64, error) {
num, err := newNumeric(v)
if err != nil {
return 0, err
}
num, _ := newNumeric(v)
switch num.typ {
case Int64:
return float64(num.ival), nil
......@@ -292,7 +308,7 @@ func newNumeric(v Value) (numeric, error) {
if fval, err := strconv.ParseFloat(str, 64); err == nil {
return numeric{fval: fval, typ: Float64}, nil
}
return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "could not parse value: '%s'", str)
return numeric{ival: 0, typ: Int64}, nil
}
// newIntegralNumeric parses a value and produces an Int64 or Uint64.
......@@ -323,22 +339,41 @@ func newIntegralNumeric(v Value) (numeric, error) {
return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "could not parse value: '%s'", str)
}
func addNumeric(v1, v2 numeric) (numeric, error) {
func addNumeric(v1, v2 numeric) numeric {
v1, v2 = prioritize(v1, v2)
switch v1.typ {
case Int64:
return intPlusInt(v1.ival, v2.ival), nil
return intPlusInt(v1.ival, v2.ival)
case Uint64:
switch v2.typ {
case Int64:
return uintPlusInt(v1.uval, v2.ival)
case Uint64:
return uintPlusUint(v1.uval, v2.uval), nil
return uintPlusUint(v1.uval, v2.uval)
}
case Float64:
return floatPlusAny(v1.fval, v2)
}
panic("unreachable")
}
func addNumericWithError(v1, v2 numeric) (numeric, error) {
v1, v2 = prioritize(v1, v2)
switch v1.typ {
case Int64:
return intPlusIntWithError(v1.ival, v2.ival)
case Uint64:
switch v2.typ {
case Int64:
return uintPlusIntWithError(v1.uval, v2.ival)
case Uint64:
return uintPlusUintWithError(v1.uval, v2.uval)
}
case Float64:
return floatPlusAny(v1.fval, v2), nil
}
panic("unreachable")
}
// prioritize reorders the input parameters
......@@ -353,6 +388,7 @@ func prioritize(v1, v2 numeric) (altv1, altv2 numeric) {
if v2.typ == Float64 {
return v2, v1
}
}
return v1, v2
}
......@@ -371,21 +407,47 @@ overflow:
return numeric{typ: Float64, fval: float64(v1) + float64(v2)}
}
func uintPlusInt(v1 uint64, v2 int64) (numeric, error) {
if v2 < 0 {
return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "cannot add a negative number to an unsigned integer: %d, %d", v1, v2)
func intPlusIntWithError(v1, v2 int64) (numeric, error) {
result := v1 + v2
if (result > v1) != (v2 > 0) {
return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v + %v", v1, v2)
}
return uintPlusUint(v1, uint64(v2)), nil
return numeric{typ: Int64, ival: result}, nil
}
func uintPlusInt(v1 uint64, v2 int64) numeric {
return uintPlusUint(v1, uint64(v2))
}
func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) {
if v2 >= math.MaxInt64 && v1 > 0 {
return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v + %v", v1, v2)
}
//convert to int -> uint is because for numeric operators (such as + or -)
//where one of the operands is an unsigned integer, the result is unsigned by default.
return uintPlusUintWithError(v1, uint64(v2))
}
func uintPlusUint(v1, v2 uint64) numeric {
result := v1 + v2
if result < v2 {
return numeric{typ: Float64, fval: float64(v1) + float64(v2)}
}
return numeric{typ: Uint64, uval: result}
}
func uintPlusUintWithError(v1, v2 uint64) (numeric, error) {
result := v1 + v2
if result < v2 {
return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2)
}
return numeric{typ: Uint64, uval: result}, nil
}
func floatPlusAny(v1 float64, v2 numeric) numeric {
switch v2.typ {
case Int64:
......@@ -396,37 +458,43 @@ func floatPlusAny(v1 float64, v2 numeric) numeric {
return numeric{typ: Float64, fval: v1 + v2.fval}
}
func castFromNumeric(v numeric, resultType querypb.Type) (Value, error) {
func castFromNumeric(v numeric, resultType querypb.Type) Value {
switch {
case IsSigned(resultType):
switch v.typ {
case Int64:
return MakeTrusted(resultType, strconv.AppendInt(nil, v.ival, 10)), nil
case Uint64, Float64:
return NULL, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected type conversion: %v to %v", v.typ, resultType)
return MakeTrusted(resultType, strconv.AppendInt(nil, v.ival, 10))
case Uint64:
return MakeTrusted(resultType, strconv.AppendInt(nil, int64(v.uval), 10))
case Float64:
return MakeTrusted(resultType, strconv.AppendInt(nil, int64(v.fval), 10))
}
case IsUnsigned(resultType):
switch v.typ {
case Uint64:
return MakeTrusted(resultType, strconv.AppendUint(nil, v.uval, 10)), nil
case Int64, Float64:
return NULL, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected type conversion: %v to %v", v.typ, resultType)
return MakeTrusted(resultType, strconv.AppendUint(nil, v.uval, 10))
case Int64:
return MakeTrusted(resultType, strconv.AppendUint(nil, uint64(v.ival), 10))
case Float64:
return MakeTrusted(resultType, strconv.AppendUint(nil, uint64(v.fval), 10))
}
case IsFloat(resultType) || resultType == Decimal:
switch v.typ {
case Int64:
return MakeTrusted(resultType, strconv.AppendInt(nil, v.ival, 10)), nil
return MakeTrusted(resultType, strconv.AppendInt(nil, v.ival, 10))
case Uint64:
return MakeTrusted(resultType, strconv.AppendUint(nil, v.uval, 10)), nil
return MakeTrusted(resultType, strconv.AppendUint(nil, v.uval, 10))
case Float64:
format := byte('g')
if resultType == Decimal {
format = 'f'
}
return MakeTrusted(resultType, strconv.AppendFloat(nil, v.fval, format, -1, 64)), nil
return MakeTrusted(resultType, strconv.AppendFloat(nil, v.fval, format, -1, 64))
}
}
return NULL, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected type conversion to non-numeric: %v", resultType)
return NULL
}
func compareNumeric(v1, v2 numeric) int {
......
......@@ -89,9 +89,11 @@ func NewValue(typ querypb.Type, val []byte) (v Value, err error) {
// comments. Other packages can also use the function to create
// VarBinary or VarChar values.
func MakeTrusted(typ querypb.Type, val []byte) Value {
if typ == Null {
return NULL
}
return Value{typ: typ, val: val}
}
......
......@@ -964,7 +964,7 @@ type Field struct {
ColumnLength uint32 `protobuf:"varint,7,opt,name=column_length,json=columnLength,proto3" json:"column_length,omitempty"`
// charset is actually a uint16. Only the lower 16 bits are used.
Charset uint32 `protobuf:"varint,8,opt,name=charset,proto3" json:"charset,omitempty"`
// decimals is actualy a uint8. Only the lower 8 bits are used.
// decimals is actually a uint8. Only the lower 8 bits are used.
Decimals uint32 `protobuf:"varint,9,opt,name=decimals,proto3" json:"decimals,omitempty"`
// flags is actually a uint16. Only the lower 16 bits are used.
Flags uint32 `protobuf:"varint,10,opt,name=flags,proto3" json:"flags,omitempty"`
......
......@@ -505,7 +505,7 @@ func (m *Shard_ServedType) GetCells() []string {
}
// SourceShard represents a data source for filtered replication
// accross shards. When this is used in a destination shard, the master
// across shards. When this is used in a destination shard, the master
// of that shard will run filtered replication.
type Shard_SourceShard struct {
// Uid is the unique ID for this SourceShard object.
......
......@@ -174,7 +174,7 @@ func (Code) EnumDescriptor() ([]byte, []int) {
// LegacyErrorCode is the enum values for Errors. This type is deprecated.
// Use Code instead. Background: In the initial design, we thought
// that we may end up with a different list of canonical error codes
// than the ones defined by grpc. In hindisght, we realize that
// than the ones defined by grpc. In hindsight, we realize that
// the grpc error codes are fairly generic and mostly sufficient.
// In order to avoid confusion, this type will be deprecated in
// favor of the new Code that matches exactly what grpc defines.
......
......@@ -285,6 +285,9 @@ func ExtractSetValues(sql string) (keyValues map[SetKey]interface{}, scope strin
case strings.HasPrefix(key, "@@session."):
scope = SessionStr
key = strings.TrimPrefix(key, "@@session.")
case strings.HasPrefix(key, "@@vitess_metadata."):
scope = VitessMetadataStr
key = strings.TrimPrefix(key, "@@vitess_metadata.")
case strings.HasPrefix(key, "@@"):
key = strings.TrimPrefix(key, "@@")
}
......
......@@ -662,9 +662,10 @@ type Set struct {
// Set.Scope or Show.Scope
const (
SessionStr = "session"
GlobalStr = "global"
ImplicitStr = ""
SessionStr = "session"
GlobalStr = "global"
VitessMetadataStr = "vitess_metadata"
ImplicitStr = ""
)
// Format formats the node.
......
package sqlparser
import (
"fmt"
"regexp"
"strings"
)
var (
re = regexp.MustCompile(`([^\\]?|[\\]{2})[%_]`)
)
func replacer(s string) string {
if strings.HasPrefix(s, `\\`) {
return s[2:]
}
result := strings.Replace(s, "%" ,".*", -1)
result = strings.Replace(result, "_", ".", -1)
return result
}
// LikeToRegexp converts a like sql expression to regular expression
func LikeToRegexp(likeExpr string) *regexp.Regexp {
if likeExpr == "" {
return regexp.MustCompile("^.*$") // Can never fail
}
keyPattern := regexp.QuoteMeta(likeExpr)
keyPattern = re.ReplaceAllStringFunc(keyPattern, replacer)
keyPattern = fmt.Sprintf("^%s$", keyPattern)
return regexp.MustCompile(keyPattern) // Can never fail
}
......@@ -182,7 +182,7 @@ func skipToEnd(yylex interface{}) {
%token <bytes> NULLX AUTO_INCREMENT APPROXNUM SIGNED UNSIGNED ZEROFILL
// Supported SHOW tokens
%token <bytes> COLLATION DATABASES TABLES VSCHEMA FULL PROCESSLIST COLUMNS FIELDS ENGINES PLUGINS
%token <bytes> COLLATION DATABASES TABLES VITESS_METADATA VSCHEMA FULL PROCESSLIST COLUMNS FIELDS ENGINES PLUGINS
// SET tokens
%token <bytes> NAMES CHARSET GLOBAL SESSION ISOLATION LEVEL READ WRITE ONLY REPEATABLE COMMITTED UNCOMMITTED SERIALIZABLE
......@@ -262,7 +262,7 @@ func skipToEnd(yylex interface{}) {
%type <bytes> for_from
%type <str> ignore_opt default_opt
%type <str> full_opt from_database_opt tables_or_processlist columns_or_fields
%type <showFilter> like_or_where_opt
%type <showFilter> like_or_where_opt like_opt
%type <byt> exists_opt
%type <empty> not_exists_opt non_add_drop_or_rename_operation to_opt index_opt constraint_opt
%type <bytes> reserved_keyword non_reserved_keyword
......@@ -1572,6 +1572,11 @@ show_statement:
showCollationFilterOpt := $4
$$ = &Show{Type: string($2), ShowCollationFilterOpt: &showCollationFilterOpt}
}
| SHOW VITESS_METADATA VARIABLES like_opt
{
showTablesOpt := &ShowTablesOpt{Filter: $4}
$$ = &Show{Scope: string($2), Type: string($3), ShowTablesOpt: showTablesOpt}
}
| SHOW VSCHEMA TABLES
{
$$ = &Show{Type: string($2) + " " + string($3)}
......@@ -1661,6 +1666,16 @@ like_or_where_opt:
$$ = &ShowFilter{Filter:$2}
}
like_opt:
/* empty */
{
$$ = nil
}
| LIKE STRING
{
$$ = &ShowFilter{Like:string($2)}
}
show_session_or_global:
/* empty */
{
......@@ -3393,6 +3408,7 @@ non_reserved_keyword:
| VIEW
| VINDEX
| VINDEXES
| VITESS_METADATA
| VSCHEMA
| WARNINGS
| WITH
......
......@@ -391,6 +391,7 @@ var keywords = map[string]int{
"vindex": VINDEX,
"vindexes": VINDEXES,
"view": VIEW,
"vitess_metadata": VITESS_METADATA,
"vschema": VSCHEMA,
"warnings": WARNINGS,
"when": WHEN,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册