github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/ast/misc.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package ast
    15  
    16  import (
    17  	"fmt"
    18  
    19  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    20  	"github.com/insionng/yougam/libraries/pingcap/tidb/model"
    21  	"github.com/insionng/yougam/libraries/pingcap/tidb/mysql"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx/db"
    23  )
    24  
    25  var (
    26  	_ StmtNode = &AdminStmt{}
    27  	_ StmtNode = &BeginStmt{}
    28  	_ StmtNode = &CommitStmt{}
    29  	_ StmtNode = &CreateUserStmt{}
    30  	_ StmtNode = &DeallocateStmt{}
    31  	_ StmtNode = &DoStmt{}
    32  	_ StmtNode = &ExecuteStmt{}
    33  	_ StmtNode = &ExplainStmt{}
    34  	_ StmtNode = &GrantStmt{}
    35  	_ StmtNode = &PrepareStmt{}
    36  	_ StmtNode = &RollbackStmt{}
    37  	_ StmtNode = &SetCharsetStmt{}
    38  	_ StmtNode = &SetPwdStmt{}
    39  	_ StmtNode = &SetStmt{}
    40  	_ StmtNode = &UseStmt{}
    41  
    42  	_ Node = &PrivElem{}
    43  	_ Node = &VariableAssignment{}
    44  )
    45  
    46  // TypeOpt is used for parsing data type option from SQL.
    47  type TypeOpt struct {
    48  	IsUnsigned bool
    49  	IsZerofill bool
    50  }
    51  
    52  // FloatOpt is used for parsing floating-point type option from SQL.
    53  // See: http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html
    54  type FloatOpt struct {
    55  	Flen    int
    56  	Decimal int
    57  }
    58  
    59  // AuthOption is used for parsing create use statement.
    60  type AuthOption struct {
    61  	// AuthString/HashString can be empty, so we need to decide which one to use.
    62  	ByAuthString bool
    63  	AuthString   string
    64  	HashString   string
    65  	// TODO: support auth_plugin
    66  }
    67  
    68  // ExplainStmt is a statement to provide information about how is SQL statement executed
    69  // or get columns information in a table.
    70  // See: https://dev.mysql.com/doc/refman/5.7/en/explain.html
    71  type ExplainStmt struct {
    72  	stmtNode
    73  
    74  	Stmt StmtNode
    75  }
    76  
    77  // Accept implements Node Accept interface.
    78  func (n *ExplainStmt) Accept(v Visitor) (Node, bool) {
    79  	newNode, skipChildren := v.Enter(n)
    80  	if skipChildren {
    81  		return v.Leave(newNode)
    82  	}
    83  	n = newNode.(*ExplainStmt)
    84  	node, ok := n.Stmt.Accept(v)
    85  	if !ok {
    86  		return n, false
    87  	}
    88  	n.Stmt = node.(DMLNode)
    89  	return v.Leave(n)
    90  }
    91  
    92  // PrepareStmt is a statement to prepares a SQL statement which contains placeholders,
    93  // and it is executed with ExecuteStmt and released with DeallocateStmt.
    94  // See: https://dev.mysql.com/doc/refman/5.7/en/prepare.html
    95  type PrepareStmt struct {
    96  	stmtNode
    97  
    98  	Name    string
    99  	SQLText string
   100  	SQLVar  *VariableExpr
   101  }
   102  
   103  // Accept implements Node Accept interface.
   104  func (n *PrepareStmt) Accept(v Visitor) (Node, bool) {
   105  	newNode, skipChildren := v.Enter(n)
   106  	if skipChildren {
   107  		return v.Leave(newNode)
   108  	}
   109  	n = newNode.(*PrepareStmt)
   110  	if n.SQLVar != nil {
   111  		node, ok := n.SQLVar.Accept(v)
   112  		if !ok {
   113  			return n, false
   114  		}
   115  		n.SQLVar = node.(*VariableExpr)
   116  	}
   117  	return v.Leave(n)
   118  }
   119  
   120  // DeallocateStmt is a statement to release PreparedStmt.
   121  // See: https://dev.mysql.com/doc/refman/5.7/en/deallocate-prepare.html
   122  type DeallocateStmt struct {
   123  	stmtNode
   124  
   125  	Name string
   126  }
   127  
   128  // Accept implements Node Accept interface.
   129  func (n *DeallocateStmt) Accept(v Visitor) (Node, bool) {
   130  	newNode, skipChildren := v.Enter(n)
   131  	if skipChildren {
   132  		return v.Leave(newNode)
   133  	}
   134  	n = newNode.(*DeallocateStmt)
   135  	return v.Leave(n)
   136  }
   137  
   138  // ExecuteStmt is a statement to execute PreparedStmt.
   139  // See: https://dev.mysql.com/doc/refman/5.7/en/execute.html
   140  type ExecuteStmt struct {
   141  	stmtNode
   142  
   143  	Name      string
   144  	UsingVars []ExprNode
   145  }
   146  
   147  // Accept implements Node Accept interface.
   148  func (n *ExecuteStmt) Accept(v Visitor) (Node, bool) {
   149  	newNode, skipChildren := v.Enter(n)
   150  	if skipChildren {
   151  		return v.Leave(newNode)
   152  	}
   153  	n = newNode.(*ExecuteStmt)
   154  	for i, val := range n.UsingVars {
   155  		node, ok := val.Accept(v)
   156  		if !ok {
   157  			return n, false
   158  		}
   159  		n.UsingVars[i] = node.(ExprNode)
   160  	}
   161  	return v.Leave(n)
   162  }
   163  
   164  // BeginStmt is a statement to start a new transaction.
   165  // See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
   166  type BeginStmt struct {
   167  	stmtNode
   168  }
   169  
   170  // Accept implements Node Accept interface.
   171  func (n *BeginStmt) Accept(v Visitor) (Node, bool) {
   172  	newNode, skipChildren := v.Enter(n)
   173  	if skipChildren {
   174  		return v.Leave(newNode)
   175  	}
   176  	n = newNode.(*BeginStmt)
   177  	return v.Leave(n)
   178  }
   179  
   180  // CommitStmt is a statement to commit the current transaction.
   181  // See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
   182  type CommitStmt struct {
   183  	stmtNode
   184  }
   185  
   186  // Accept implements Node Accept interface.
   187  func (n *CommitStmt) Accept(v Visitor) (Node, bool) {
   188  	newNode, skipChildren := v.Enter(n)
   189  	if skipChildren {
   190  		return v.Leave(newNode)
   191  	}
   192  	n = newNode.(*CommitStmt)
   193  	return v.Leave(n)
   194  }
   195  
   196  // RollbackStmt is a statement to roll back the current transaction.
   197  // See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
   198  type RollbackStmt struct {
   199  	stmtNode
   200  }
   201  
   202  // Accept implements Node Accept interface.
   203  func (n *RollbackStmt) Accept(v Visitor) (Node, bool) {
   204  	newNode, skipChildren := v.Enter(n)
   205  	if skipChildren {
   206  		return v.Leave(newNode)
   207  	}
   208  	n = newNode.(*RollbackStmt)
   209  	return v.Leave(n)
   210  }
   211  
   212  // UseStmt is a statement to use the DBName database as the current database.
   213  // See: https://dev.mysql.com/doc/refman/5.7/en/use.html
   214  type UseStmt struct {
   215  	stmtNode
   216  
   217  	DBName string
   218  }
   219  
   220  // Accept implements Node Accept interface.
   221  func (n *UseStmt) Accept(v Visitor) (Node, bool) {
   222  	newNode, skipChildren := v.Enter(n)
   223  	if skipChildren {
   224  		return v.Leave(newNode)
   225  	}
   226  	n = newNode.(*UseStmt)
   227  	return v.Leave(n)
   228  }
   229  
   230  // VariableAssignment is a variable assignment struct.
   231  type VariableAssignment struct {
   232  	node
   233  	Name     string
   234  	Value    ExprNode
   235  	IsGlobal bool
   236  	IsSystem bool
   237  }
   238  
   239  // Accept implements Node interface.
   240  func (n *VariableAssignment) Accept(v Visitor) (Node, bool) {
   241  	newNode, skipChildren := v.Enter(n)
   242  	if skipChildren {
   243  		return v.Leave(newNode)
   244  	}
   245  	n = newNode.(*VariableAssignment)
   246  	node, ok := n.Value.Accept(v)
   247  	if !ok {
   248  		return n, false
   249  	}
   250  	n.Value = node.(ExprNode)
   251  	return v.Leave(n)
   252  }
   253  
   254  // SetStmt is the statement to set variables.
   255  type SetStmt struct {
   256  	stmtNode
   257  	// Variables is the list of variable assignment.
   258  	Variables []*VariableAssignment
   259  }
   260  
   261  // Accept implements Node Accept interface.
   262  func (n *SetStmt) Accept(v Visitor) (Node, bool) {
   263  	newNode, skipChildren := v.Enter(n)
   264  	if skipChildren {
   265  		return v.Leave(newNode)
   266  	}
   267  	n = newNode.(*SetStmt)
   268  	for i, val := range n.Variables {
   269  		node, ok := val.Accept(v)
   270  		if !ok {
   271  			return n, false
   272  		}
   273  		n.Variables[i] = node.(*VariableAssignment)
   274  	}
   275  	return v.Leave(n)
   276  }
   277  
   278  // SetCharsetStmt is a statement to assign values to character and collation variables.
   279  // See: https://dev.mysql.com/doc/refman/5.7/en/set-statement.html
   280  type SetCharsetStmt struct {
   281  	stmtNode
   282  
   283  	Charset string
   284  	Collate string
   285  }
   286  
   287  // Accept implements Node Accept interface.
   288  func (n *SetCharsetStmt) Accept(v Visitor) (Node, bool) {
   289  	newNode, skipChildren := v.Enter(n)
   290  	if skipChildren {
   291  		return v.Leave(newNode)
   292  	}
   293  	n = newNode.(*SetCharsetStmt)
   294  	return v.Leave(n)
   295  }
   296  
   297  // SetPwdStmt is a statement to assign a password to user account.
   298  // See: https://dev.mysql.com/doc/refman/5.7/en/set-password.html
   299  type SetPwdStmt struct {
   300  	stmtNode
   301  
   302  	User     string
   303  	Password string
   304  }
   305  
   306  // Accept implements Node Accept interface.
   307  func (n *SetPwdStmt) Accept(v Visitor) (Node, bool) {
   308  	newNode, skipChildren := v.Enter(n)
   309  	if skipChildren {
   310  		return v.Leave(newNode)
   311  	}
   312  	n = newNode.(*SetPwdStmt)
   313  	return v.Leave(n)
   314  }
   315  
   316  // UserSpec is used for parsing create user statement.
   317  type UserSpec struct {
   318  	User    string
   319  	AuthOpt *AuthOption
   320  }
   321  
   322  // CreateUserStmt creates user account.
   323  // See: https://dev.mysql.com/doc/refman/5.7/en/create-user.html
   324  type CreateUserStmt struct {
   325  	stmtNode
   326  
   327  	IfNotExists bool
   328  	Specs       []*UserSpec
   329  }
   330  
   331  // Accept implements Node Accept interface.
   332  func (n *CreateUserStmt) Accept(v Visitor) (Node, bool) {
   333  	newNode, skipChildren := v.Enter(n)
   334  	if skipChildren {
   335  		return v.Leave(newNode)
   336  	}
   337  	n = newNode.(*CreateUserStmt)
   338  	return v.Leave(n)
   339  }
   340  
   341  // DoStmt is the struct for DO statement.
   342  type DoStmt struct {
   343  	stmtNode
   344  
   345  	Exprs []ExprNode
   346  }
   347  
   348  // Accept implements Node Accept interface.
   349  func (n *DoStmt) Accept(v Visitor) (Node, bool) {
   350  	newNode, skipChildren := v.Enter(n)
   351  	if skipChildren {
   352  		return v.Leave(newNode)
   353  	}
   354  	n = newNode.(*DoStmt)
   355  	for i, val := range n.Exprs {
   356  		node, ok := val.Accept(v)
   357  		if !ok {
   358  			return n, false
   359  		}
   360  		n.Exprs[i] = node.(ExprNode)
   361  	}
   362  	return v.Leave(n)
   363  }
   364  
   365  // AdminStmtType is the type for admin statement.
   366  type AdminStmtType int
   367  
   368  // Admin statement types.
   369  const (
   370  	AdminShowDDL = iota + 1
   371  	AdminCheckTable
   372  )
   373  
   374  // AdminStmt is the struct for Admin statement.
   375  type AdminStmt struct {
   376  	stmtNode
   377  
   378  	Tp     AdminStmtType
   379  	Tables []*TableName
   380  }
   381  
   382  // Accept implements Node Accpet interface.
   383  func (n *AdminStmt) Accept(v Visitor) (Node, bool) {
   384  	newNode, skipChildren := v.Enter(n)
   385  	if skipChildren {
   386  		return v.Leave(newNode)
   387  	}
   388  
   389  	n = newNode.(*AdminStmt)
   390  	for i, val := range n.Tables {
   391  		node, ok := val.Accept(v)
   392  		if !ok {
   393  			return n, false
   394  		}
   395  		n.Tables[i] = node.(*TableName)
   396  	}
   397  
   398  	return v.Leave(n)
   399  }
   400  
   401  // PrivElem is the privilege type and optional column list.
   402  type PrivElem struct {
   403  	node
   404  
   405  	Priv mysql.PrivilegeType
   406  	Cols []*ColumnName
   407  }
   408  
   409  // Accept implements Node Accept interface.
   410  func (n *PrivElem) Accept(v Visitor) (Node, bool) {
   411  	newNode, skipChildren := v.Enter(n)
   412  	if skipChildren {
   413  		return v.Leave(newNode)
   414  	}
   415  	n = newNode.(*PrivElem)
   416  	for i, val := range n.Cols {
   417  		node, ok := val.Accept(v)
   418  		if !ok {
   419  			return n, false
   420  		}
   421  		n.Cols[i] = node.(*ColumnName)
   422  	}
   423  	return v.Leave(n)
   424  }
   425  
   426  // ObjectTypeType is the type for object type.
   427  type ObjectTypeType int
   428  
   429  const (
   430  	// ObjectTypeNone is for empty object type.
   431  	ObjectTypeNone ObjectTypeType = iota + 1
   432  	// ObjectTypeTable means the following object is a table.
   433  	ObjectTypeTable
   434  )
   435  
   436  // GrantLevelType is the type for grant level.
   437  type GrantLevelType int
   438  
   439  const (
   440  	// GrantLevelNone is the dummy const for default value.
   441  	GrantLevelNone GrantLevelType = iota + 1
   442  	// GrantLevelGlobal means the privileges are administrative or apply to all databases on a given server.
   443  	GrantLevelGlobal
   444  	// GrantLevelDB means the privileges apply to all objects in a given database.
   445  	GrantLevelDB
   446  	// GrantLevelTable means the privileges apply to all columns in a given table.
   447  	GrantLevelTable
   448  )
   449  
   450  // GrantLevel is used for store the privilege scope.
   451  type GrantLevel struct {
   452  	Level     GrantLevelType
   453  	DBName    string
   454  	TableName string
   455  }
   456  
   457  // GrantStmt is the struct for GRANT statement.
   458  type GrantStmt struct {
   459  	stmtNode
   460  
   461  	Privs      []*PrivElem
   462  	ObjectType ObjectTypeType
   463  	Level      *GrantLevel
   464  	Users      []*UserSpec
   465  }
   466  
   467  // Accept implements Node Accept interface.
   468  func (n *GrantStmt) Accept(v Visitor) (Node, bool) {
   469  	newNode, skipChildren := v.Enter(n)
   470  	if skipChildren {
   471  		return v.Leave(newNode)
   472  	}
   473  	n = newNode.(*GrantStmt)
   474  	for i, val := range n.Privs {
   475  		node, ok := val.Accept(v)
   476  		if !ok {
   477  			return n, false
   478  		}
   479  		n.Privs[i] = node.(*PrivElem)
   480  	}
   481  	return v.Leave(n)
   482  }
   483  
   484  // Ident is the table identifier composed of schema name and table name.
   485  type Ident struct {
   486  	Schema model.CIStr
   487  	Name   model.CIStr
   488  }
   489  
   490  // Full returns an Ident which set schema to the current schema if it is empty.
   491  func (i Ident) Full(ctx context.Context) (full Ident) {
   492  	full.Name = i.Name
   493  	if i.Schema.O != "" {
   494  		full.Schema = i.Schema
   495  	} else {
   496  		full.Schema = model.NewCIStr(db.GetCurrentSchema(ctx))
   497  	}
   498  	return
   499  }
   500  
   501  // String implements fmt.Stringer interface
   502  func (i Ident) String() string {
   503  	if i.Schema.O == "" {
   504  		return i.Name.O
   505  	}
   506  	return fmt.Sprintf("%s.%s", i.Schema, i.Name)
   507  }