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