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 }