github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/ast/ddl.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 "github.com/insionng/yougam/libraries/pingcap/tidb/model" 18 "github.com/insionng/yougam/libraries/pingcap/tidb/util/types" 19 ) 20 21 var ( 22 _ DDLNode = &AlterTableStmt{} 23 _ DDLNode = &CreateDatabaseStmt{} 24 _ DDLNode = &CreateIndexStmt{} 25 _ DDLNode = &CreateTableStmt{} 26 _ DDLNode = &DropDatabaseStmt{} 27 _ DDLNode = &DropIndexStmt{} 28 _ DDLNode = &DropTableStmt{} 29 _ DDLNode = &TruncateTableStmt{} 30 31 _ Node = &AlterTableSpec{} 32 _ Node = &ColumnDef{} 33 _ Node = &ColumnOption{} 34 _ Node = &ColumnPosition{} 35 _ Node = &Constraint{} 36 _ Node = &IndexColName{} 37 _ Node = &ReferenceDef{} 38 ) 39 40 // CharsetOpt is used for parsing charset option from SQL. 41 type CharsetOpt struct { 42 Chs string 43 Col string 44 } 45 46 // DatabaseOptionType is the type for database options. 47 type DatabaseOptionType int 48 49 // Database option types. 50 const ( 51 DatabaseOptionNone DatabaseOptionType = iota 52 DatabaseOptionCharset 53 DatabaseOptionCollate 54 ) 55 56 // DatabaseOption represents database option. 57 type DatabaseOption struct { 58 Tp DatabaseOptionType 59 Value string 60 } 61 62 // CreateDatabaseStmt is a statement to create a database. 63 // See: https://dev.mysql.com/doc/refman/5.7/en/create-database.html 64 type CreateDatabaseStmt struct { 65 ddlNode 66 67 IfNotExists bool 68 Name string 69 Options []*DatabaseOption 70 } 71 72 // Accept implements Node Accept interface. 73 func (n *CreateDatabaseStmt) Accept(v Visitor) (Node, bool) { 74 newNode, skipChildren := v.Enter(n) 75 if skipChildren { 76 return v.Leave(newNode) 77 } 78 n = newNode.(*CreateDatabaseStmt) 79 return v.Leave(n) 80 } 81 82 // DropDatabaseStmt is a statement to drop a database and all tables in the database. 83 // See: https://dev.mysql.com/doc/refman/5.7/en/drop-database.html 84 type DropDatabaseStmt struct { 85 ddlNode 86 87 IfExists bool 88 Name string 89 } 90 91 // Accept implements Node Accept interface. 92 func (n *DropDatabaseStmt) Accept(v Visitor) (Node, bool) { 93 newNode, skipChildren := v.Enter(n) 94 if skipChildren { 95 return v.Leave(newNode) 96 } 97 n = newNode.(*DropDatabaseStmt) 98 return v.Leave(n) 99 } 100 101 // IndexColName is used for parsing index column name from SQL. 102 type IndexColName struct { 103 node 104 105 Column *ColumnName 106 Length int 107 } 108 109 // Accept implements Node Accept interface. 110 func (n *IndexColName) Accept(v Visitor) (Node, bool) { 111 newNode, skipChildren := v.Enter(n) 112 if skipChildren { 113 return v.Leave(newNode) 114 } 115 n = newNode.(*IndexColName) 116 node, ok := n.Column.Accept(v) 117 if !ok { 118 return n, false 119 } 120 n.Column = node.(*ColumnName) 121 return v.Leave(n) 122 } 123 124 // ReferenceDef is used for parsing foreign key reference option from SQL. 125 // See: http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html 126 type ReferenceDef struct { 127 node 128 129 Table *TableName 130 IndexColNames []*IndexColName 131 OnDelete *OnDeleteOpt 132 OnUpdate *OnUpdateOpt 133 } 134 135 // Accept implements Node Accept interface. 136 func (n *ReferenceDef) Accept(v Visitor) (Node, bool) { 137 newNode, skipChildren := v.Enter(n) 138 if skipChildren { 139 return v.Leave(newNode) 140 } 141 n = newNode.(*ReferenceDef) 142 node, ok := n.Table.Accept(v) 143 if !ok { 144 return n, false 145 } 146 n.Table = node.(*TableName) 147 for i, val := range n.IndexColNames { 148 node, ok = val.Accept(v) 149 if !ok { 150 return n, false 151 } 152 n.IndexColNames[i] = node.(*IndexColName) 153 } 154 onDelete, ok := n.OnDelete.Accept(v) 155 if !ok { 156 return n, false 157 } 158 n.OnDelete = onDelete.(*OnDeleteOpt) 159 onUpdate, ok := n.OnUpdate.Accept(v) 160 if !ok { 161 return n, false 162 } 163 n.OnUpdate = onUpdate.(*OnUpdateOpt) 164 return v.Leave(n) 165 } 166 167 // ReferOptionType is the type for refer options. 168 type ReferOptionType int 169 170 // Refer option types. 171 const ( 172 ReferOptionNoOption ReferOptionType = iota 173 ReferOptionRestrict 174 ReferOptionCascade 175 ReferOptionSetNull 176 ReferOptionNoAction 177 ) 178 179 // String implements fmt.Stringer interface. 180 func (r ReferOptionType) String() string { 181 switch r { 182 case ReferOptionRestrict: 183 return "RESTRICT" 184 case ReferOptionCascade: 185 return "CASCADE" 186 case ReferOptionSetNull: 187 return "SET NULL" 188 case ReferOptionNoAction: 189 return "NO ACTION" 190 } 191 return "" 192 } 193 194 // OnDeleteOpt is used for optional on delete clause. 195 type OnDeleteOpt struct { 196 node 197 ReferOpt ReferOptionType 198 } 199 200 // Accept implements Node Accept interface. 201 func (n *OnDeleteOpt) Accept(v Visitor) (Node, bool) { 202 newNode, skipChildren := v.Enter(n) 203 if skipChildren { 204 return v.Leave(newNode) 205 } 206 n = newNode.(*OnDeleteOpt) 207 return v.Leave(n) 208 } 209 210 // OnUpdateOpt is used for optional on update clause. 211 type OnUpdateOpt struct { 212 node 213 ReferOpt ReferOptionType 214 } 215 216 // Accept implements Node Accept interface. 217 func (n *OnUpdateOpt) Accept(v Visitor) (Node, bool) { 218 newNode, skipChildren := v.Enter(n) 219 if skipChildren { 220 return v.Leave(newNode) 221 } 222 n = newNode.(*OnUpdateOpt) 223 return v.Leave(n) 224 } 225 226 // ColumnOptionType is the type for ColumnOption. 227 type ColumnOptionType int 228 229 // ColumnOption types. 230 const ( 231 ColumnOptionNoOption ColumnOptionType = iota 232 ColumnOptionPrimaryKey 233 ColumnOptionNotNull 234 ColumnOptionAutoIncrement 235 ColumnOptionDefaultValue 236 ColumnOptionUniq 237 ColumnOptionIndex 238 ColumnOptionUniqIndex 239 ColumnOptionKey 240 ColumnOptionUniqKey 241 ColumnOptionNull 242 ColumnOptionOnUpdate // For Timestamp and Datetime only. 243 ColumnOptionFulltext 244 ColumnOptionComment 245 ) 246 247 // ColumnOption is used for parsing column constraint info from SQL. 248 type ColumnOption struct { 249 node 250 251 Tp ColumnOptionType 252 // The value For Default or On Update. 253 Expr ExprNode 254 } 255 256 // Accept implements Node Accept interface. 257 func (n *ColumnOption) Accept(v Visitor) (Node, bool) { 258 newNode, skipChildren := v.Enter(n) 259 if skipChildren { 260 return v.Leave(newNode) 261 } 262 n = newNode.(*ColumnOption) 263 if n.Expr != nil { 264 node, ok := n.Expr.Accept(v) 265 if !ok { 266 return n, false 267 } 268 n.Expr = node.(ExprNode) 269 } 270 return v.Leave(n) 271 } 272 273 // IndexOption is the index options. 274 // KEY_BLOCK_SIZE [=] value 275 // | index_type 276 // | WITH PARSER parser_name 277 // | COMMENT 'string' 278 // See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html 279 type IndexOption struct { 280 node 281 282 KeyBlockSize uint64 283 Tp model.IndexType 284 Comment string 285 } 286 287 // Accept implements Node Accept interface. 288 func (n *IndexOption) Accept(v Visitor) (Node, bool) { 289 newNode, skipChildren := v.Enter(n) 290 if skipChildren { 291 return v.Leave(newNode) 292 } 293 n = newNode.(*IndexOption) 294 return v.Leave(n) 295 } 296 297 // ConstraintType is the type for Constraint. 298 type ConstraintType int 299 300 // ConstraintTypes 301 const ( 302 ConstraintNoConstraint ConstraintType = iota 303 ConstraintPrimaryKey 304 ConstraintKey 305 ConstraintIndex 306 ConstraintUniq 307 ConstraintUniqKey 308 ConstraintUniqIndex 309 ConstraintForeignKey 310 ConstraintFulltext 311 ) 312 313 // Constraint is constraint for table definition. 314 type Constraint struct { 315 node 316 317 Tp ConstraintType 318 Name string 319 320 // Used for PRIMARY KEY, UNIQUE, ...... 321 Keys []*IndexColName 322 323 // Used for foreign key. 324 Refer *ReferenceDef 325 326 // Index Options 327 Option *IndexOption 328 } 329 330 // Accept implements Node Accept interface. 331 func (n *Constraint) Accept(v Visitor) (Node, bool) { 332 newNode, skipChildren := v.Enter(n) 333 if skipChildren { 334 return v.Leave(newNode) 335 } 336 n = newNode.(*Constraint) 337 for i, val := range n.Keys { 338 node, ok := val.Accept(v) 339 if !ok { 340 return n, false 341 } 342 n.Keys[i] = node.(*IndexColName) 343 } 344 if n.Refer != nil { 345 node, ok := n.Refer.Accept(v) 346 if !ok { 347 return n, false 348 } 349 n.Refer = node.(*ReferenceDef) 350 } 351 if n.Option != nil { 352 node, ok := n.Option.Accept(v) 353 if !ok { 354 return n, false 355 } 356 n.Option = node.(*IndexOption) 357 } 358 return v.Leave(n) 359 } 360 361 // ColumnDef is used for parsing column definition from SQL. 362 type ColumnDef struct { 363 node 364 365 Name *ColumnName 366 Tp *types.FieldType 367 Options []*ColumnOption 368 } 369 370 // Accept implements Node Accept interface. 371 func (n *ColumnDef) Accept(v Visitor) (Node, bool) { 372 newNode, skipChildren := v.Enter(n) 373 if skipChildren { 374 return v.Leave(newNode) 375 } 376 n = newNode.(*ColumnDef) 377 node, ok := n.Name.Accept(v) 378 if !ok { 379 return n, false 380 } 381 n.Name = node.(*ColumnName) 382 for i, val := range n.Options { 383 node, ok := val.Accept(v) 384 if !ok { 385 return n, false 386 } 387 n.Options[i] = node.(*ColumnOption) 388 } 389 return v.Leave(n) 390 } 391 392 // CreateTableStmt is a statement to create a table. 393 // See: https://dev.mysql.com/doc/refman/5.7/en/create-table.html 394 type CreateTableStmt struct { 395 ddlNode 396 397 IfNotExists bool 398 Table *TableName 399 Cols []*ColumnDef 400 Constraints []*Constraint 401 Options []*TableOption 402 } 403 404 // Accept implements Node Accept interface. 405 func (n *CreateTableStmt) Accept(v Visitor) (Node, bool) { 406 newNode, skipChildren := v.Enter(n) 407 if skipChildren { 408 return v.Leave(newNode) 409 } 410 n = newNode.(*CreateTableStmt) 411 node, ok := n.Table.Accept(v) 412 if !ok { 413 return n, false 414 } 415 n.Table = node.(*TableName) 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.(*ColumnDef) 422 } 423 for i, val := range n.Constraints { 424 node, ok = val.Accept(v) 425 if !ok { 426 return n, false 427 } 428 n.Constraints[i] = node.(*Constraint) 429 } 430 return v.Leave(n) 431 } 432 433 // DropTableStmt is a statement to drop one or more tables. 434 // See: https://dev.mysql.com/doc/refman/5.7/en/drop-table.html 435 type DropTableStmt struct { 436 ddlNode 437 438 IfExists bool 439 Tables []*TableName 440 } 441 442 // Accept implements Node Accept interface. 443 func (n *DropTableStmt) Accept(v Visitor) (Node, bool) { 444 newNode, skipChildren := v.Enter(n) 445 if skipChildren { 446 return v.Leave(newNode) 447 } 448 n = newNode.(*DropTableStmt) 449 for i, val := range n.Tables { 450 node, ok := val.Accept(v) 451 if !ok { 452 return n, false 453 } 454 n.Tables[i] = node.(*TableName) 455 } 456 return v.Leave(n) 457 } 458 459 // CreateIndexStmt is a statement to create an index. 460 // See: https://dev.mysql.com/doc/refman/5.7/en/create-index.html 461 type CreateIndexStmt struct { 462 ddlNode 463 464 IndexName string 465 Table *TableName 466 Unique bool 467 IndexColNames []*IndexColName 468 } 469 470 // Accept implements Node Accept interface. 471 func (n *CreateIndexStmt) Accept(v Visitor) (Node, bool) { 472 newNode, skipChildren := v.Enter(n) 473 if skipChildren { 474 return v.Leave(newNode) 475 } 476 n = newNode.(*CreateIndexStmt) 477 node, ok := n.Table.Accept(v) 478 if !ok { 479 return n, false 480 } 481 n.Table = node.(*TableName) 482 for i, val := range n.IndexColNames { 483 node, ok = val.Accept(v) 484 if !ok { 485 return n, false 486 } 487 n.IndexColNames[i] = node.(*IndexColName) 488 } 489 return v.Leave(n) 490 } 491 492 // DropIndexStmt is a statement to drop the index. 493 // See: https://dev.mysql.com/doc/refman/5.7/en/drop-index.html 494 type DropIndexStmt struct { 495 ddlNode 496 497 IfExists bool 498 IndexName string 499 Table *TableName 500 } 501 502 // Accept implements Node Accept interface. 503 func (n *DropIndexStmt) Accept(v Visitor) (Node, bool) { 504 newNode, skipChildren := v.Enter(n) 505 if skipChildren { 506 return v.Leave(newNode) 507 } 508 n = newNode.(*DropIndexStmt) 509 node, ok := n.Table.Accept(v) 510 if !ok { 511 return n, false 512 } 513 n.Table = node.(*TableName) 514 return v.Leave(n) 515 } 516 517 // TableOptionType is the type for TableOption 518 type TableOptionType int 519 520 // TableOption types. 521 const ( 522 TableOptionNone TableOptionType = iota 523 TableOptionEngine 524 TableOptionCharset 525 TableOptionCollate 526 TableOptionAutoIncrement 527 TableOptionComment 528 TableOptionAvgRowLength 529 TableOptionCheckSum 530 TableOptionCompression 531 TableOptionConnection 532 TableOptionPassword 533 TableOptionKeyBlockSize 534 TableOptionMaxRows 535 TableOptionMinRows 536 TableOptionDelayKeyWrite 537 TableOptionRowFormat 538 ) 539 540 // RowFormat types 541 const ( 542 RowFormatDefault uint64 = iota + 1 543 RowFormatDynamic 544 RowFormatFixed 545 RowFormatCompressed 546 RowFormatRedundant 547 RowFormatCompact 548 ) 549 550 // TableOption is used for parsing table option from SQL. 551 type TableOption struct { 552 Tp TableOptionType 553 StrValue string 554 UintValue uint64 555 } 556 557 // ColumnPositionType is the type for ColumnPosition. 558 type ColumnPositionType int 559 560 // ColumnPosition Types 561 const ( 562 ColumnPositionNone ColumnPositionType = iota 563 ColumnPositionFirst 564 ColumnPositionAfter 565 ) 566 567 // ColumnPosition represent the position of the newly added column 568 type ColumnPosition struct { 569 node 570 // ColumnPositionNone | ColumnPositionFirst | ColumnPositionAfter 571 Tp ColumnPositionType 572 // RelativeColumn is the column the newly added column after if type is ColumnPositionAfter 573 RelativeColumn *ColumnName 574 } 575 576 // Accept implements Node Accept interface. 577 func (n *ColumnPosition) Accept(v Visitor) (Node, bool) { 578 newNode, skipChildren := v.Enter(n) 579 if skipChildren { 580 return v.Leave(newNode) 581 } 582 n = newNode.(*ColumnPosition) 583 if n.RelativeColumn != nil { 584 node, ok := n.RelativeColumn.Accept(v) 585 if !ok { 586 return n, false 587 } 588 n.RelativeColumn = node.(*ColumnName) 589 } 590 return v.Leave(n) 591 } 592 593 // AlterTableType is the type for AlterTableSpec. 594 type AlterTableType int 595 596 // AlterTable types. 597 const ( 598 AlterTableOption AlterTableType = iota + 1 599 AlterTableAddColumn 600 AlterTableAddConstraint 601 AlterTableDropColumn 602 AlterTableDropPrimaryKey 603 AlterTableDropIndex 604 AlterTableDropForeignKey 605 606 // TODO: Add more actions 607 ) 608 609 // AlterTableSpec represents alter table specification. 610 type AlterTableSpec struct { 611 node 612 613 Tp AlterTableType 614 Name string 615 Constraint *Constraint 616 Options []*TableOption 617 Column *ColumnDef 618 DropColumn *ColumnName 619 Position *ColumnPosition 620 } 621 622 // Accept implements Node Accept interface. 623 func (n *AlterTableSpec) Accept(v Visitor) (Node, bool) { 624 newNode, skipChildren := v.Enter(n) 625 if skipChildren { 626 return v.Leave(newNode) 627 } 628 n = newNode.(*AlterTableSpec) 629 if n.Constraint != nil { 630 node, ok := n.Constraint.Accept(v) 631 if !ok { 632 return n, false 633 } 634 n.Constraint = node.(*Constraint) 635 } 636 if n.Column != nil { 637 node, ok := n.Column.Accept(v) 638 if !ok { 639 return n, false 640 } 641 n.Column = node.(*ColumnDef) 642 } 643 if n.DropColumn != nil { 644 node, ok := n.DropColumn.Accept(v) 645 if !ok { 646 return n, false 647 } 648 n.DropColumn = node.(*ColumnName) 649 } 650 if n.Position != nil { 651 node, ok := n.Position.Accept(v) 652 if !ok { 653 return n, false 654 } 655 n.Position = node.(*ColumnPosition) 656 } 657 return v.Leave(n) 658 } 659 660 // AlterTableStmt is a statement to change the structure of a table. 661 // See: https://dev.mysql.com/doc/refman/5.7/en/alter-table.html 662 type AlterTableStmt struct { 663 ddlNode 664 665 Table *TableName 666 Specs []*AlterTableSpec 667 } 668 669 // Accept implements Node Accept interface. 670 func (n *AlterTableStmt) Accept(v Visitor) (Node, bool) { 671 newNode, skipChildren := v.Enter(n) 672 if skipChildren { 673 return v.Leave(newNode) 674 } 675 n = newNode.(*AlterTableStmt) 676 node, ok := n.Table.Accept(v) 677 if !ok { 678 return n, false 679 } 680 n.Table = node.(*TableName) 681 for i, val := range n.Specs { 682 node, ok = val.Accept(v) 683 if !ok { 684 return n, false 685 } 686 n.Specs[i] = node.(*AlterTableSpec) 687 } 688 return v.Leave(n) 689 } 690 691 // TruncateTableStmt is a statement to empty a table completely. 692 // See: https://dev.mysql.com/doc/refman/5.7/en/truncate-table.html 693 type TruncateTableStmt struct { 694 ddlNode 695 696 Table *TableName 697 } 698 699 // Accept implements Node Accept interface. 700 func (n *TruncateTableStmt) Accept(v Visitor) (Node, bool) { 701 newNode, skipChildren := v.Enter(n) 702 if skipChildren { 703 return v.Leave(newNode) 704 } 705 n = newNode.(*TruncateTableStmt) 706 node, ok := n.Table.Accept(v) 707 if !ok { 708 return n, false 709 } 710 n.Table = node.(*TableName) 711 return v.Leave(n) 712 }