github.com/XiaoMi/Gaea@v1.2.5/parser/ast/dml.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 "strings" 18 19 "github.com/pingcap/errors" 20 21 "github.com/XiaoMi/Gaea/mysql" 22 "github.com/XiaoMi/Gaea/parser/auth" 23 "github.com/XiaoMi/Gaea/parser/format" 24 "github.com/XiaoMi/Gaea/parser/model" 25 ) 26 27 var ( 28 _ DMLNode = &DeleteStmt{} 29 _ DMLNode = &InsertStmt{} 30 _ DMLNode = &UnionStmt{} 31 _ DMLNode = &UpdateStmt{} 32 _ DMLNode = &SelectStmt{} 33 _ DMLNode = &ShowStmt{} 34 _ DMLNode = &LoadDataStmt{} 35 36 _ Node = &Assignment{} 37 _ Node = &ByItem{} 38 _ Node = &FieldList{} 39 _ Node = &GroupByClause{} 40 _ Node = &HavingClause{} 41 _ Node = &Join{} 42 _ Node = &Limit{} 43 _ Node = &OnCondition{} 44 _ Node = &OrderByClause{} 45 _ Node = &SelectField{} 46 _ Node = &TableName{} 47 _ Node = &TableRefsClause{} 48 _ Node = &TableSource{} 49 _ Node = &UnionSelectList{} 50 _ Node = &WildCardField{} 51 _ Node = &WindowSpec{} 52 _ Node = &PartitionByClause{} 53 _ Node = &FrameClause{} 54 _ Node = &FrameBound{} 55 ) 56 57 // JoinType is join type, including cross/left/right/full. 58 type JoinType int 59 60 const ( 61 // CrossJoin is cross join type. 62 CrossJoin JoinType = iota + 1 63 // LeftJoin is left Join type. 64 LeftJoin 65 // RightJoin is right Join type. 66 RightJoin 67 ) 68 69 // Join represents table join. 70 type Join struct { 71 node 72 resultSetNode 73 74 // Left table can be TableSource or JoinNode. 75 Left ResultSetNode 76 // Right table can be TableSource or JoinNode or nil. 77 Right ResultSetNode 78 // Tp represents join type. 79 Tp JoinType 80 // On represents join on condition. 81 On *OnCondition 82 // Using represents join using clause. 83 Using []*ColumnName 84 // NaturalJoin represents join is natural join. 85 NaturalJoin bool 86 // StraightJoin represents a straight join. 87 StraightJoin bool 88 } 89 90 // Restore implements Node interface. 91 func (n *Join) Restore(ctx *format.RestoreCtx) error { 92 if ctx.JoinLevel != 0 { 93 ctx.WritePlain("(") 94 defer ctx.WritePlain(")") 95 } 96 ctx.JoinLevel++ 97 if err := n.Left.Restore(ctx); err != nil { 98 return errors.Annotate(err, "An error occurred while restore Join.Left") 99 } 100 ctx.JoinLevel-- 101 if n.Right == nil { 102 return nil 103 } 104 if n.NaturalJoin { 105 ctx.WriteKeyWord(" NATURAL") 106 } 107 switch n.Tp { 108 case LeftJoin: 109 ctx.WriteKeyWord(" LEFT") 110 case RightJoin: 111 ctx.WriteKeyWord(" RIGHT") 112 } 113 if n.StraightJoin { 114 ctx.WriteKeyWord(" STRAIGHT_JOIN ") 115 } else { 116 ctx.WriteKeyWord(" JOIN ") 117 } 118 ctx.JoinLevel++ 119 if err := n.Right.Restore(ctx); err != nil { 120 return errors.Annotate(err, "An error occurred while restore Join.Right") 121 } 122 ctx.JoinLevel-- 123 124 if n.On != nil { 125 ctx.WritePlain(" ") 126 if err := n.On.Restore(ctx); err != nil { 127 return errors.Annotate(err, "An error occurred while restore Join.On") 128 } 129 } 130 if len(n.Using) != 0 { 131 ctx.WriteKeyWord(" USING ") 132 ctx.WritePlain("(") 133 for i, v := range n.Using { 134 if i != 0 { 135 ctx.WritePlain(",") 136 } 137 if err := v.Restore(ctx); err != nil { 138 return errors.Annotate(err, "An error occurred while restore Join.Using") 139 } 140 } 141 ctx.WritePlain(")") 142 } 143 144 return nil 145 } 146 147 // Accept implements Node Accept interface. 148 func (n *Join) Accept(v Visitor) (Node, bool) { 149 newNode, skipChildren := v.Enter(n) 150 if skipChildren { 151 return v.Leave(newNode) 152 } 153 n = newNode.(*Join) 154 node, ok := n.Left.Accept(v) 155 if !ok { 156 return n, false 157 } 158 n.Left = node.(ResultSetNode) 159 if n.Right != nil { 160 node, ok = n.Right.Accept(v) 161 if !ok { 162 return n, false 163 } 164 n.Right = node.(ResultSetNode) 165 } 166 if n.On != nil { 167 node, ok = n.On.Accept(v) 168 if !ok { 169 return n, false 170 } 171 n.On = node.(*OnCondition) 172 } 173 return v.Leave(n) 174 } 175 176 // TableName represents a table name. 177 type TableName struct { 178 node 179 resultSetNode 180 181 Schema model.CIStr 182 Name model.CIStr 183 184 DBInfo *model.DBInfo 185 TableInfo *model.TableInfo 186 187 IndexHints []*IndexHint 188 PartitionNames []model.CIStr 189 } 190 191 // Restore implements Node interface. 192 func (n *TableName) restoreName(ctx *format.RestoreCtx) { 193 if n.Schema.String() != "" { 194 ctx.WriteName(n.Schema.String()) 195 ctx.WritePlain(".") 196 } 197 ctx.WriteName(n.Name.String()) 198 } 199 200 func (n *TableName) restorePartitions(ctx *format.RestoreCtx) { 201 if len(n.PartitionNames) > 0 { 202 ctx.WriteKeyWord(" PARTITION") 203 ctx.WritePlain("(") 204 for i, v := range n.PartitionNames { 205 if i != 0 { 206 ctx.WritePlain(", ") 207 } 208 ctx.WriteName(v.String()) 209 } 210 ctx.WritePlain(")") 211 } 212 } 213 214 func (n *TableName) restoreIndexHints(ctx *format.RestoreCtx) error { 215 for _, value := range n.IndexHints { 216 ctx.WritePlain(" ") 217 if err := value.Restore(ctx); err != nil { 218 return errors.Annotate(err, "An error occurred while splicing IndexHints") 219 } 220 } 221 222 return nil 223 } 224 225 func (n *TableName) Restore(ctx *format.RestoreCtx) error { 226 n.restoreName(ctx) 227 n.restorePartitions(ctx) 228 return n.restoreIndexHints(ctx) 229 } 230 231 // IndexHintType is the type for index hint use, ignore or force. 232 type IndexHintType int 233 234 // IndexHintUseType values. 235 const ( 236 HintUse IndexHintType = 1 237 HintIgnore IndexHintType = 2 238 HintForce IndexHintType = 3 239 ) 240 241 // IndexHintScope is the type for index hint for join, order by or group by. 242 type IndexHintScope int 243 244 // Index hint scopes. 245 const ( 246 HintForScan IndexHintScope = 1 247 HintForJoin IndexHintScope = 2 248 HintForOrderBy IndexHintScope = 3 249 HintForGroupBy IndexHintScope = 4 250 ) 251 252 // IndexHint represents a hint for optimizer to use/ignore/force for join/order by/group by. 253 type IndexHint struct { 254 IndexNames []model.CIStr 255 HintType IndexHintType 256 HintScope IndexHintScope 257 } 258 259 // Restore IndexHint Restore (The const field uses switch to facilitate understanding) 260 func (n *IndexHint) Restore(ctx *format.RestoreCtx) error { 261 indexHintType := "" 262 switch n.HintType { 263 case 1: 264 indexHintType = "USE INDEX" 265 case 2: 266 indexHintType = "IGNORE INDEX" 267 case 3: 268 indexHintType = "FORCE INDEX" 269 default: // Prevent accidents 270 return errors.New("IndexHintType has an error while matching") 271 } 272 273 indexHintScope := "" 274 switch n.HintScope { 275 case 1: 276 indexHintScope = "" 277 case 2: 278 indexHintScope = " FOR JOIN" 279 case 3: 280 indexHintScope = " FOR ORDER BY" 281 case 4: 282 indexHintScope = " FOR GROUP BY" 283 default: // Prevent accidents 284 return errors.New("IndexHintScope has an error while matching") 285 } 286 ctx.WriteKeyWord(indexHintType) 287 ctx.WriteKeyWord(indexHintScope) 288 ctx.WritePlain(" (") 289 for i, value := range n.IndexNames { 290 if i > 0 { 291 ctx.WritePlain(", ") 292 } 293 ctx.WriteName(value.O) 294 } 295 ctx.WritePlain(")") 296 297 return nil 298 } 299 300 // Accept implements Node Accept interface. 301 func (n *TableName) Accept(v Visitor) (Node, bool) { 302 newNode, skipChildren := v.Enter(n) 303 if skipChildren { 304 return v.Leave(newNode) 305 } 306 n = newNode.(*TableName) 307 return v.Leave(n) 308 } 309 310 // DeleteTableList is the tablelist used in delete statement multi-table mode. 311 type DeleteTableList struct { 312 node 313 Tables []*TableName 314 } 315 316 // Restore implements Node interface. 317 func (n *DeleteTableList) Restore(ctx *format.RestoreCtx) error { 318 for i, t := range n.Tables { 319 if i != 0 { 320 ctx.WritePlain(",") 321 } 322 if err := t.Restore(ctx); err != nil { 323 return errors.Annotatef(err, "An error occurred while restore DeleteTableList.Tables[%v]", i) 324 } 325 } 326 return nil 327 } 328 329 // Accept implements Node Accept interface. 330 func (n *DeleteTableList) Accept(v Visitor) (Node, bool) { 331 newNode, skipChildren := v.Enter(n) 332 if skipChildren { 333 return v.Leave(newNode) 334 } 335 n = newNode.(*DeleteTableList) 336 if n != nil { 337 for i, t := range n.Tables { 338 node, ok := t.Accept(v) 339 if !ok { 340 return n, false 341 } 342 n.Tables[i] = node.(*TableName) 343 } 344 } 345 return v.Leave(n) 346 } 347 348 // OnCondition represents JOIN on condition. 349 type OnCondition struct { 350 node 351 352 Expr ExprNode 353 } 354 355 // Restore implements Node interface. 356 func (n *OnCondition) Restore(ctx *format.RestoreCtx) error { 357 ctx.WriteKeyWord("ON ") 358 if err := n.Expr.Restore(ctx); err != nil { 359 return errors.Annotate(err, "An error occurred while restore OnCondition.Expr") 360 } 361 return nil 362 } 363 364 // Accept implements Node Accept interface. 365 func (n *OnCondition) Accept(v Visitor) (Node, bool) { 366 newNode, skipChildren := v.Enter(n) 367 if skipChildren { 368 return v.Leave(newNode) 369 } 370 n = newNode.(*OnCondition) 371 node, ok := n.Expr.Accept(v) 372 if !ok { 373 return n, false 374 } 375 n.Expr = node.(ExprNode) 376 return v.Leave(n) 377 } 378 379 // TableSource represents table source with a name. 380 type TableSource struct { 381 node 382 383 // Source is the source of the data, can be a TableName, 384 // a SelectStmt, a UnionStmt, or a JoinNode. 385 Source ResultSetNode 386 387 // AsName is the alias name of the table source. 388 AsName model.CIStr 389 } 390 391 // Restore implements Node interface. 392 func (n *TableSource) Restore(ctx *format.RestoreCtx) error { 393 needParen := false 394 switch n.Source.(type) { 395 case *SelectStmt, *UnionStmt: 396 needParen = true 397 } 398 399 if tn, tnCase := n.Source.(*TableName); tnCase { 400 if needParen { 401 ctx.WritePlain("(") 402 } 403 404 tn.restoreName(ctx) 405 tn.restorePartitions(ctx) 406 407 if asName := n.AsName.String(); asName != "" { 408 ctx.WriteKeyWord(" AS ") 409 ctx.WriteName(asName) 410 } 411 if err := tn.restoreIndexHints(ctx); err != nil { 412 return errors.Annotate(err, "An error occurred while restore TableSource.Source.(*TableName).IndexHints") 413 } 414 415 if needParen { 416 ctx.WritePlain(")") 417 } 418 } else { 419 if needParen { 420 ctx.WritePlain("(") 421 } 422 if err := n.Source.Restore(ctx); err != nil { 423 return errors.Annotate(err, "An error occurred while restore TableSource.Source") 424 } 425 if needParen { 426 ctx.WritePlain(")") 427 } 428 if asName := n.AsName.String(); asName != "" { 429 ctx.WriteKeyWord(" AS ") 430 ctx.WriteName(asName) 431 } 432 } 433 434 return nil 435 } 436 437 // Accept implements Node Accept interface. 438 func (n *TableSource) Accept(v Visitor) (Node, bool) { 439 newNode, skipChildren := v.Enter(n) 440 if skipChildren { 441 return v.Leave(newNode) 442 } 443 n = newNode.(*TableSource) 444 node, ok := n.Source.Accept(v) 445 if !ok { 446 return n, false 447 } 448 n.Source = node.(ResultSetNode) 449 return v.Leave(n) 450 } 451 452 // SelectLockType is the lock type for SelectStmt. 453 type SelectLockType int 454 455 // Select lock types. 456 const ( 457 SelectLockNone SelectLockType = iota 458 SelectLockForUpdate 459 SelectLockInShareMode 460 ) 461 462 // String implements fmt.Stringer. 463 func (slt SelectLockType) String() string { 464 switch slt { 465 case SelectLockNone: 466 return "none" 467 case SelectLockForUpdate: 468 return "for update" 469 case SelectLockInShareMode: 470 return "in share mode" 471 } 472 return "unsupported select lock type" 473 } 474 475 // WildCardField is a special type of select field content. 476 type WildCardField struct { 477 node 478 479 Table model.CIStr 480 Schema model.CIStr 481 } 482 483 // Restore implements Node interface. 484 func (n *WildCardField) Restore(ctx *format.RestoreCtx) error { 485 if schema := n.Schema.String(); schema != "" { 486 ctx.WriteName(schema) 487 ctx.WritePlain(".") 488 } 489 if table := n.Table.String(); table != "" { 490 ctx.WriteName(table) 491 ctx.WritePlain(".") 492 } 493 ctx.WritePlain("*") 494 return nil 495 } 496 497 // Accept implements Node Accept interface. 498 func (n *WildCardField) Accept(v Visitor) (Node, bool) { 499 newNode, skipChildren := v.Enter(n) 500 if skipChildren { 501 return v.Leave(newNode) 502 } 503 n = newNode.(*WildCardField) 504 return v.Leave(n) 505 } 506 507 // SelectField represents fields in select statement. 508 // There are two type of select field: wildcard 509 // and expression with optional alias name. 510 type SelectField struct { 511 node 512 513 // Offset is used to get original text. 514 Offset int 515 // WildCard is not nil, Expr will be nil. 516 WildCard *WildCardField 517 // Expr is not nil, WildCard will be nil. 518 Expr ExprNode 519 // AsName is alias name for Expr. 520 AsName model.CIStr 521 // Auxiliary stands for if this field is auxiliary. 522 // When we add a Field into SelectField list which is used for having/orderby clause but the field is not in select clause, 523 // we should set its Auxiliary to true. Then the TrimExec will trim the field. 524 Auxiliary bool 525 } 526 527 // Restore implements Node interface. 528 func (n *SelectField) Restore(ctx *format.RestoreCtx) error { 529 if n.WildCard != nil { 530 if err := n.WildCard.Restore(ctx); err != nil { 531 return errors.Annotate(err, "An error occurred while restore SelectField.WildCard") 532 } 533 } 534 if n.Expr != nil { 535 if err := n.Expr.Restore(ctx); err != nil { 536 return errors.Annotate(err, "An error occurred while restore SelectField.Expr") 537 } 538 } 539 if asName := n.AsName.String(); asName != "" { 540 ctx.WriteKeyWord(" AS ") 541 ctx.WriteName(asName) 542 } 543 return nil 544 } 545 546 // Accept implements Node Accept interface. 547 func (n *SelectField) Accept(v Visitor) (Node, bool) { 548 newNode, skipChildren := v.Enter(n) 549 if skipChildren { 550 return v.Leave(newNode) 551 } 552 n = newNode.(*SelectField) 553 if n.Expr != nil { 554 node, ok := n.Expr.Accept(v) 555 if !ok { 556 return n, false 557 } 558 n.Expr = node.(ExprNode) 559 } 560 return v.Leave(n) 561 } 562 563 // FieldList represents field list in select statement. 564 type FieldList struct { 565 node 566 567 Fields []*SelectField 568 } 569 570 // Restore implements Node interface. 571 func (n *FieldList) Restore(ctx *format.RestoreCtx) error { 572 for i, v := range n.Fields { 573 if i != 0 { 574 ctx.WritePlain(", ") 575 } 576 if err := v.Restore(ctx); err != nil { 577 return errors.Annotatef(err, "An error occurred while restore FieldList.Fields[%d]", i) 578 } 579 } 580 return nil 581 } 582 583 // Accept implements Node Accept interface. 584 func (n *FieldList) Accept(v Visitor) (Node, bool) { 585 newNode, skipChildren := v.Enter(n) 586 if skipChildren { 587 return v.Leave(newNode) 588 } 589 n = newNode.(*FieldList) 590 for i, val := range n.Fields { 591 node, ok := val.Accept(v) 592 if !ok { 593 return n, false 594 } 595 n.Fields[i] = node.(*SelectField) 596 } 597 return v.Leave(n) 598 } 599 600 // TableRefsClause represents table references clause in dml statement. 601 type TableRefsClause struct { 602 node 603 604 TableRefs *Join 605 } 606 607 // Restore implements Node interface. 608 func (n *TableRefsClause) Restore(ctx *format.RestoreCtx) error { 609 if err := n.TableRefs.Restore(ctx); err != nil { 610 return errors.Annotate(err, "An error occurred while restore TableRefsClause.TableRefs") 611 } 612 return nil 613 } 614 615 // Accept implements Node Accept interface. 616 func (n *TableRefsClause) Accept(v Visitor) (Node, bool) { 617 newNode, skipChildren := v.Enter(n) 618 if skipChildren { 619 return v.Leave(newNode) 620 } 621 n = newNode.(*TableRefsClause) 622 node, ok := n.TableRefs.Accept(v) 623 if !ok { 624 return n, false 625 } 626 n.TableRefs = node.(*Join) 627 return v.Leave(n) 628 } 629 630 // ByItem represents an item in order by or group by. 631 type ByItem struct { 632 node 633 634 Expr ExprNode 635 Desc bool 636 } 637 638 // Restore implements Node interface. 639 func (n *ByItem) Restore(ctx *format.RestoreCtx) error { 640 if err := n.Expr.Restore(ctx); err != nil { 641 return errors.Annotate(err, "An error occurred while restore ByItem.Expr") 642 } 643 if n.Desc { 644 ctx.WriteKeyWord(" DESC") 645 } 646 return nil 647 } 648 649 // Accept implements Node Accept interface. 650 func (n *ByItem) Accept(v Visitor) (Node, bool) { 651 newNode, skipChildren := v.Enter(n) 652 if skipChildren { 653 return v.Leave(newNode) 654 } 655 n = newNode.(*ByItem) 656 node, ok := n.Expr.Accept(v) 657 if !ok { 658 return n, false 659 } 660 n.Expr = node.(ExprNode) 661 return v.Leave(n) 662 } 663 664 // GroupByClause represents group by clause. 665 type GroupByClause struct { 666 node 667 Items []*ByItem 668 } 669 670 // Restore implements Node interface. 671 func (n *GroupByClause) Restore(ctx *format.RestoreCtx) error { 672 ctx.WriteKeyWord("GROUP BY ") 673 for i, v := range n.Items { 674 if i != 0 { 675 ctx.WritePlain(",") 676 } 677 if err := v.Restore(ctx); err != nil { 678 return errors.Annotatef(err, "An error occurred while restore GroupByClause.Items[%d]", i) 679 } 680 } 681 return nil 682 } 683 684 // Accept implements Node Accept interface. 685 func (n *GroupByClause) Accept(v Visitor) (Node, bool) { 686 newNode, skipChildren := v.Enter(n) 687 if skipChildren { 688 return v.Leave(newNode) 689 } 690 n = newNode.(*GroupByClause) 691 for i, val := range n.Items { 692 node, ok := val.Accept(v) 693 if !ok { 694 return n, false 695 } 696 n.Items[i] = node.(*ByItem) 697 } 698 return v.Leave(n) 699 } 700 701 // HavingClause represents having clause. 702 type HavingClause struct { 703 node 704 Expr ExprNode 705 } 706 707 // Restore implements Node interface. 708 func (n *HavingClause) Restore(ctx *format.RestoreCtx) error { 709 ctx.WriteKeyWord("HAVING ") 710 if err := n.Expr.Restore(ctx); err != nil { 711 return errors.Annotate(err, "An error occurred while restore HavingClause.Expr") 712 } 713 return nil 714 } 715 716 // Accept implements Node Accept interface. 717 func (n *HavingClause) Accept(v Visitor) (Node, bool) { 718 newNode, skipChildren := v.Enter(n) 719 if skipChildren { 720 return v.Leave(newNode) 721 } 722 n = newNode.(*HavingClause) 723 node, ok := n.Expr.Accept(v) 724 if !ok { 725 return n, false 726 } 727 n.Expr = node.(ExprNode) 728 return v.Leave(n) 729 } 730 731 // OrderByClause represents order by clause. 732 type OrderByClause struct { 733 node 734 Items []*ByItem 735 ForUnion bool 736 } 737 738 // Restore implements Node interface. 739 func (n *OrderByClause) Restore(ctx *format.RestoreCtx) error { 740 ctx.WriteKeyWord("ORDER BY ") 741 for i, item := range n.Items { 742 if i != 0 { 743 ctx.WritePlain(",") 744 } 745 if err := item.Restore(ctx); err != nil { 746 return errors.Annotatef(err, "An error occurred while restore OrderByClause.Items[%d]", i) 747 } 748 } 749 return nil 750 } 751 752 // Accept implements Node Accept interface. 753 func (n *OrderByClause) Accept(v Visitor) (Node, bool) { 754 newNode, skipChildren := v.Enter(n) 755 if skipChildren { 756 return v.Leave(newNode) 757 } 758 n = newNode.(*OrderByClause) 759 for i, val := range n.Items { 760 node, ok := val.Accept(v) 761 if !ok { 762 return n, false 763 } 764 n.Items[i] = node.(*ByItem) 765 } 766 return v.Leave(n) 767 } 768 769 // SelectStmt represents the select query node. 770 // See https://dev.mysql.com/doc/refman/5.7/en/select.html 771 type SelectStmt struct { 772 dmlNode 773 resultSetNode 774 775 // SelectStmtOpts wraps around select hints and switches. 776 *SelectStmtOpts 777 // Distinct represents whether the select has distinct option. 778 Distinct bool 779 // From is the from clause of the query. 780 From *TableRefsClause 781 // Where is the where clause in select statement. 782 Where ExprNode 783 // Fields is the select expression list. 784 Fields *FieldList 785 // GroupBy is the group by expression list. 786 GroupBy *GroupByClause 787 // Having is the having condition. 788 Having *HavingClause 789 // WindowSpecs is the window specification list. 790 WindowSpecs []WindowSpec 791 // OrderBy is the ordering expression list. 792 OrderBy *OrderByClause 793 // Limit is the limit clause. 794 Limit *Limit 795 // LockTp is the lock type 796 LockTp SelectLockType 797 // TableHints represents the table level Optimizer Hint for join type 798 TableHints []*TableOptimizerHint 799 // IsAfterUnionDistinct indicates whether it's a stmt after "union distinct". 800 IsAfterUnionDistinct bool 801 // IsInBraces indicates whether it's a stmt in brace. 802 IsInBraces bool 803 } 804 805 // Restore implements Node interface. 806 func (n *SelectStmt) Restore(ctx *format.RestoreCtx) error { 807 ctx.WriteKeyWord("SELECT ") 808 809 if n.SelectStmtOpts.Priority > 0 { 810 ctx.WriteKeyWord(mysql.Priority2Str[n.SelectStmtOpts.Priority]) 811 ctx.WritePlain(" ") 812 } 813 814 if !n.SelectStmtOpts.SQLCache { 815 ctx.WriteKeyWord("SQL_NO_CACHE ") 816 } 817 818 if n.TableHints != nil && len(n.TableHints) != 0 { 819 ctx.WritePlain("/*+ ") 820 for i, tableHint := range n.TableHints { 821 if err := tableHint.Restore(ctx); err != nil { 822 errors.Annotatef(err, "An error occurred while restore SelectStmt.TableHints[%d]", i) 823 } 824 } 825 ctx.WritePlain("*/ ") 826 } 827 828 if n.Distinct { 829 ctx.WriteKeyWord("DISTINCT ") 830 } 831 if n.SelectStmtOpts.StraightJoin { 832 ctx.WriteKeyWord("STRAIGHT_JOIN ") 833 } 834 if n.Fields != nil { 835 for i, field := range n.Fields.Fields { 836 if i != 0 { 837 ctx.WritePlain(",") 838 } 839 if err := field.Restore(ctx); err != nil { 840 errors.Annotatef(err, "An error occurred while restore SelectStmt.Fields[%d]", i) 841 } 842 } 843 } 844 845 if n.From != nil { 846 ctx.WriteKeyWord(" FROM ") 847 if err := n.From.Restore(ctx); err != nil { 848 errors.Annotate(err, "An error occurred while restore SelectStmt.From") 849 } 850 } 851 852 if n.From == nil && n.Where != nil { 853 ctx.WriteKeyWord(" FROM DUAL") 854 } 855 if n.Where != nil { 856 ctx.WriteKeyWord(" WHERE ") 857 if err := n.Where.Restore(ctx); err != nil { 858 errors.Annotate(err, "An error occurred while restore SelectStmt.Where") 859 } 860 } 861 862 if n.GroupBy != nil { 863 ctx.WritePlain(" ") 864 if err := n.GroupBy.Restore(ctx); err != nil { 865 errors.Annotate(err, "An error occurred while restore SelectStmt.GroupBy") 866 } 867 } 868 869 if n.Having != nil { 870 ctx.WritePlain(" ") 871 if err := n.Having.Restore(ctx); err != nil { 872 errors.Annotate(err, "An error occurred while restore SelectStmt.Having") 873 } 874 } 875 876 if n.WindowSpecs != nil { 877 ctx.WriteKeyWord(" WINDOW ") 878 for i, windowsSpec := range n.WindowSpecs { 879 if i != 0 { 880 ctx.WritePlain(",") 881 } 882 if err := windowsSpec.Restore(ctx); err != nil { 883 errors.Annotatef(err, "An error occurred while restore SelectStmt.WindowSpec[%d]", i) 884 } 885 } 886 } 887 888 if n.OrderBy != nil { 889 ctx.WritePlain(" ") 890 if err := n.OrderBy.Restore(ctx); err != nil { 891 errors.Annotate(err, "An error occurred while restore SelectStmt.OrderBy") 892 } 893 } 894 895 if n.Limit != nil { 896 ctx.WritePlain(" ") 897 if err := n.Limit.Restore(ctx); err != nil { 898 errors.Annotate(err, "An error occurred while restore SelectStmt.Limit") 899 } 900 } 901 902 switch n.LockTp { 903 case SelectLockInShareMode: 904 ctx.WriteKeyWord(" LOCK ") 905 ctx.WriteKeyWord(n.LockTp.String()) 906 case SelectLockForUpdate: 907 ctx.WritePlain(" ") 908 ctx.WriteKeyWord(n.LockTp.String()) 909 } 910 return nil 911 } 912 913 // Accept implements Node Accept interface. 914 func (n *SelectStmt) Accept(v Visitor) (Node, bool) { 915 newNode, skipChildren := v.Enter(n) 916 if skipChildren { 917 return v.Leave(newNode) 918 } 919 920 n = newNode.(*SelectStmt) 921 if n.TableHints != nil && len(n.TableHints) != 0 { 922 newHints := make([]*TableOptimizerHint, len(n.TableHints)) 923 for i, hint := range n.TableHints { 924 node, ok := hint.Accept(v) 925 if !ok { 926 return n, false 927 } 928 newHints[i] = node.(*TableOptimizerHint) 929 } 930 n.TableHints = newHints 931 } 932 933 if n.From != nil { 934 node, ok := n.From.Accept(v) 935 if !ok { 936 return n, false 937 } 938 n.From = node.(*TableRefsClause) 939 } 940 941 if n.Where != nil { 942 node, ok := n.Where.Accept(v) 943 if !ok { 944 return n, false 945 } 946 n.Where = node.(ExprNode) 947 } 948 949 if n.Fields != nil { 950 node, ok := n.Fields.Accept(v) 951 if !ok { 952 return n, false 953 } 954 n.Fields = node.(*FieldList) 955 } 956 957 if n.GroupBy != nil { 958 node, ok := n.GroupBy.Accept(v) 959 if !ok { 960 return n, false 961 } 962 n.GroupBy = node.(*GroupByClause) 963 } 964 965 if n.Having != nil { 966 node, ok := n.Having.Accept(v) 967 if !ok { 968 return n, false 969 } 970 n.Having = node.(*HavingClause) 971 } 972 973 for i, spec := range n.WindowSpecs { 974 node, ok := spec.Accept(v) 975 if !ok { 976 return n, false 977 } 978 n.WindowSpecs[i] = *node.(*WindowSpec) 979 } 980 981 if n.OrderBy != nil { 982 node, ok := n.OrderBy.Accept(v) 983 if !ok { 984 return n, false 985 } 986 n.OrderBy = node.(*OrderByClause) 987 } 988 989 if n.Limit != nil { 990 node, ok := n.Limit.Accept(v) 991 if !ok { 992 return n, false 993 } 994 n.Limit = node.(*Limit) 995 } 996 997 return v.Leave(n) 998 } 999 1000 // UnionSelectList represents the select list in a union statement. 1001 type UnionSelectList struct { 1002 node 1003 1004 Selects []*SelectStmt 1005 } 1006 1007 // Restore implements Node interface. 1008 func (n *UnionSelectList) Restore(ctx *format.RestoreCtx) error { 1009 for i, selectStmt := range n.Selects { 1010 if i != 0 { 1011 ctx.WriteKeyWord(" UNION ") 1012 if !selectStmt.IsAfterUnionDistinct { 1013 ctx.WriteKeyWord("ALL ") 1014 } 1015 } 1016 if selectStmt.IsInBraces { 1017 ctx.WritePlain("(") 1018 } 1019 if err := selectStmt.Restore(ctx); err != nil { 1020 errors.Annotate(err, "An error occurred while restore UnionSelectList.SelectStmt") 1021 } 1022 if selectStmt.IsInBraces { 1023 ctx.WritePlain(")") 1024 } 1025 } 1026 return nil 1027 } 1028 1029 // Accept implements Node Accept interface. 1030 func (n *UnionSelectList) Accept(v Visitor) (Node, bool) { 1031 newNode, skipChildren := v.Enter(n) 1032 if skipChildren { 1033 return v.Leave(newNode) 1034 } 1035 n = newNode.(*UnionSelectList) 1036 for i, sel := range n.Selects { 1037 node, ok := sel.Accept(v) 1038 if !ok { 1039 return n, false 1040 } 1041 n.Selects[i] = node.(*SelectStmt) 1042 } 1043 return v.Leave(n) 1044 } 1045 1046 // UnionStmt represents "union statement" 1047 // See https://dev.mysql.com/doc/refman/5.7/en/union.html 1048 type UnionStmt struct { 1049 dmlNode 1050 resultSetNode 1051 1052 SelectList *UnionSelectList 1053 OrderBy *OrderByClause 1054 Limit *Limit 1055 } 1056 1057 // Restore implements Node interface. 1058 func (n *UnionStmt) Restore(ctx *format.RestoreCtx) error { 1059 if err := n.SelectList.Restore(ctx); err != nil { 1060 errors.Annotate(err, "An error occurred while restore UnionStmt.SelectList") 1061 } 1062 1063 if n.OrderBy != nil { 1064 ctx.WritePlain(" ") 1065 if err := n.OrderBy.Restore(ctx); err != nil { 1066 errors.Annotate(err, "An error occurred while restore UnionStmt.OrderBy") 1067 } 1068 } 1069 1070 if n.Limit != nil { 1071 ctx.WritePlain(" ") 1072 if err := n.Limit.Restore(ctx); err != nil { 1073 errors.Annotate(err, "An error occurred while restore UnionStmt.Limit") 1074 } 1075 } 1076 return nil 1077 } 1078 1079 // Accept implements Node Accept interface. 1080 func (n *UnionStmt) Accept(v Visitor) (Node, bool) { 1081 newNode, skipChildren := v.Enter(n) 1082 if skipChildren { 1083 return v.Leave(newNode) 1084 } 1085 n = newNode.(*UnionStmt) 1086 if n.SelectList != nil { 1087 node, ok := n.SelectList.Accept(v) 1088 if !ok { 1089 return n, false 1090 } 1091 n.SelectList = node.(*UnionSelectList) 1092 } 1093 if n.OrderBy != nil { 1094 node, ok := n.OrderBy.Accept(v) 1095 if !ok { 1096 return n, false 1097 } 1098 n.OrderBy = node.(*OrderByClause) 1099 } 1100 if n.Limit != nil { 1101 node, ok := n.Limit.Accept(v) 1102 if !ok { 1103 return n, false 1104 } 1105 n.Limit = node.(*Limit) 1106 } 1107 return v.Leave(n) 1108 } 1109 1110 // Assignment is the expression for assignment, like a = 1. 1111 type Assignment struct { 1112 node 1113 // Column is the column name to be assigned. 1114 Column *ColumnName 1115 // Expr is the expression assigning to ColName. 1116 Expr ExprNode 1117 } 1118 1119 // Restore implements Node interface. 1120 func (n *Assignment) Restore(ctx *format.RestoreCtx) error { 1121 if err := n.Column.Restore(ctx); err != nil { 1122 return errors.Annotate(err, "An error occurred while restore Assignment.Column") 1123 } 1124 ctx.WritePlain("=") 1125 if err := n.Expr.Restore(ctx); err != nil { 1126 return errors.Annotate(err, "An error occurred while restore Assignment.Expr") 1127 } 1128 return nil 1129 } 1130 1131 // Accept implements Node Accept interface. 1132 func (n *Assignment) Accept(v Visitor) (Node, bool) { 1133 newNode, skipChildren := v.Enter(n) 1134 if skipChildren { 1135 return v.Leave(newNode) 1136 } 1137 n = newNode.(*Assignment) 1138 node, ok := n.Column.Accept(v) 1139 if !ok { 1140 return n, false 1141 } 1142 n.Column = node.(*ColumnName) 1143 node, ok = n.Expr.Accept(v) 1144 if !ok { 1145 return n, false 1146 } 1147 n.Expr = node.(ExprNode) 1148 return v.Leave(n) 1149 } 1150 1151 // LoadDataStmt is a statement to load data from a specified file, then insert this rows into an existing table. 1152 // See https://dev.mysql.com/doc/refman/5.7/en/load-data.html 1153 type LoadDataStmt struct { 1154 dmlNode 1155 1156 IsLocal bool 1157 Path string 1158 Table *TableName 1159 Columns []*ColumnName 1160 FieldsInfo *FieldsClause 1161 LinesInfo *LinesClause 1162 IgnoreLines uint64 1163 } 1164 1165 // Restore implements Node interface. 1166 func (n *LoadDataStmt) Restore(ctx *format.RestoreCtx) error { 1167 ctx.WriteKeyWord("LOAD DATA ") 1168 if n.IsLocal { 1169 ctx.WriteKeyWord("LOCAL ") 1170 } 1171 ctx.WriteKeyWord("INFILE ") 1172 ctx.WriteString(n.Path) 1173 ctx.WriteKeyWord(" INTO TABLE ") 1174 if err := n.Table.Restore(ctx); err != nil { 1175 return errors.Annotate(err, "An error occurred while restore LoadDataStmt.Table") 1176 } 1177 n.FieldsInfo.Restore(ctx) 1178 n.LinesInfo.Restore(ctx) 1179 if n.IgnoreLines != 0 { 1180 ctx.WriteKeyWord(" IGNORE ") 1181 ctx.WritePlainf("%d", n.IgnoreLines) 1182 ctx.WriteKeyWord(" LINES") 1183 } 1184 if len(n.Columns) != 0 { 1185 ctx.WritePlain(" (") 1186 for i, column := range n.Columns { 1187 if i != 0 { 1188 ctx.WritePlain(",") 1189 } 1190 if err := column.Restore(ctx); err != nil { 1191 return errors.Annotate(err, "An error occurred while restore LoadDataStmt.Columns") 1192 } 1193 } 1194 ctx.WritePlain(")") 1195 } 1196 return nil 1197 } 1198 1199 // Accept implements Node Accept interface. 1200 func (n *LoadDataStmt) Accept(v Visitor) (Node, bool) { 1201 newNode, skipChildren := v.Enter(n) 1202 if skipChildren { 1203 return v.Leave(newNode) 1204 } 1205 n = newNode.(*LoadDataStmt) 1206 if n.Table != nil { 1207 node, ok := n.Table.Accept(v) 1208 if !ok { 1209 return n, false 1210 } 1211 n.Table = node.(*TableName) 1212 } 1213 for i, val := range n.Columns { 1214 node, ok := val.Accept(v) 1215 if !ok { 1216 return n, false 1217 } 1218 n.Columns[i] = node.(*ColumnName) 1219 } 1220 return v.Leave(n) 1221 } 1222 1223 // FieldsClause represents fields references clause in load data statement. 1224 type FieldsClause struct { 1225 Terminated string 1226 Enclosed byte 1227 Escaped byte 1228 } 1229 1230 // Restore for FieldsClause 1231 func (n *FieldsClause) Restore(ctx *format.RestoreCtx) error { 1232 if n.Terminated != "\t" || n.Escaped != '\\' { 1233 ctx.WriteKeyWord(" FIELDS") 1234 if n.Terminated != "\t" { 1235 ctx.WriteKeyWord(" TERMINATED BY ") 1236 ctx.WriteString(n.Terminated) 1237 } 1238 if n.Enclosed != 0 { 1239 ctx.WriteKeyWord(" ENCLOSED BY ") 1240 ctx.WriteString(string(n.Enclosed)) 1241 } 1242 if n.Escaped != '\\' { 1243 ctx.WriteKeyWord(" ESCAPED BY ") 1244 if n.Escaped == 0 { 1245 ctx.WritePlain("''") 1246 } else { 1247 ctx.WriteString(string(n.Escaped)) 1248 } 1249 } 1250 } 1251 return nil 1252 } 1253 1254 // LinesClause represents lines references clause in load data statement. 1255 type LinesClause struct { 1256 Starting string 1257 Terminated string 1258 } 1259 1260 // Restore for LinesClause 1261 func (n *LinesClause) Restore(ctx *format.RestoreCtx) error { 1262 if n.Starting != "" || n.Terminated != "\n" { 1263 ctx.WriteKeyWord(" LINES") 1264 if n.Starting != "" { 1265 ctx.WriteKeyWord(" STARTING BY ") 1266 ctx.WriteString(n.Starting) 1267 } 1268 if n.Terminated != "\n" { 1269 ctx.WriteKeyWord(" TERMINATED BY ") 1270 ctx.WriteString(n.Terminated) 1271 } 1272 } 1273 return nil 1274 } 1275 1276 // InsertStmt is a statement to insert new rows into an existing table. 1277 // See https://dev.mysql.com/doc/refman/5.7/en/insert.html 1278 type InsertStmt struct { 1279 dmlNode 1280 1281 IsReplace bool 1282 IgnoreErr bool 1283 Table *TableRefsClause 1284 Columns []*ColumnName 1285 Lists [][]ExprNode 1286 Setlist []*Assignment 1287 Priority mysql.PriorityEnum 1288 OnDuplicate []*Assignment 1289 Select ResultSetNode 1290 } 1291 1292 // Restore implements Node interface. 1293 func (n *InsertStmt) Restore(ctx *format.RestoreCtx) error { 1294 if n.IsReplace { 1295 ctx.WriteKeyWord("REPLACE ") 1296 } else { 1297 ctx.WriteKeyWord("INSERT ") 1298 } 1299 if err := n.Priority.Restore(ctx); err != nil { 1300 return errors.Trace(err) 1301 } 1302 if n.Priority != mysql.NoPriority { 1303 ctx.WritePlain(" ") 1304 } 1305 if n.IgnoreErr { 1306 ctx.WriteKeyWord("IGNORE ") 1307 } 1308 ctx.WriteKeyWord("INTO ") 1309 if err := n.Table.Restore(ctx); err != nil { 1310 return errors.Annotate(err, "An error occurred while restore InsertStmt.Table") 1311 } 1312 if n.Columns != nil { 1313 ctx.WritePlain(" (") 1314 for i, v := range n.Columns { 1315 if i != 0 { 1316 ctx.WritePlain(",") 1317 } 1318 if err := v.Restore(ctx); err != nil { 1319 return errors.Annotatef(err, "An error occurred while restore InsertStmt.Columns[%d]", i) 1320 } 1321 } 1322 ctx.WritePlain(")") 1323 } 1324 if n.Lists != nil { 1325 ctx.WriteKeyWord(" VALUES ") 1326 for i, row := range n.Lists { 1327 if i != 0 { 1328 ctx.WritePlain(",") 1329 } 1330 ctx.WritePlain("(") 1331 for j, v := range row { 1332 if j != 0 { 1333 ctx.WritePlain(",") 1334 } 1335 if err := v.Restore(ctx); err != nil { 1336 return errors.Annotatef(err, "An error occurred while restore InsertStmt.Lists[%d][%d]", i, j) 1337 } 1338 } 1339 ctx.WritePlain(")") 1340 } 1341 } 1342 if n.Select != nil { 1343 ctx.WritePlain(" ") 1344 switch v := n.Select.(type) { 1345 case *SelectStmt, *UnionStmt: 1346 if err := v.Restore(ctx); err != nil { 1347 return errors.Annotate(err, "An error occurred while restore InsertStmt.Select") 1348 } 1349 default: 1350 return errors.Errorf("Incorrect type for InsertStmt.Select: %T", v) 1351 } 1352 } 1353 if n.Setlist != nil { 1354 ctx.WriteKeyWord(" SET ") 1355 for i, v := range n.Setlist { 1356 if i != 0 { 1357 ctx.WritePlain(",") 1358 } 1359 if err := v.Restore(ctx); err != nil { 1360 return errors.Annotatef(err, "An error occurred while restore InsertStmt.Setlist[%d]", i) 1361 } 1362 } 1363 } 1364 if n.OnDuplicate != nil { 1365 ctx.WriteKeyWord(" ON DUPLICATE KEY UPDATE ") 1366 for i, v := range n.OnDuplicate { 1367 if i != 0 { 1368 ctx.WritePlain(",") 1369 } 1370 if err := v.Restore(ctx); err != nil { 1371 return errors.Annotatef(err, "An error occurred while restore InsertStmt.OnDuplicate[%d]", i) 1372 } 1373 } 1374 } 1375 1376 return nil 1377 } 1378 1379 // Accept implements Node Accept interface. 1380 func (n *InsertStmt) Accept(v Visitor) (Node, bool) { 1381 newNode, skipChildren := v.Enter(n) 1382 if skipChildren { 1383 return v.Leave(newNode) 1384 } 1385 1386 n = newNode.(*InsertStmt) 1387 if n.Select != nil { 1388 node, ok := n.Select.Accept(v) 1389 if !ok { 1390 return n, false 1391 } 1392 n.Select = node.(ResultSetNode) 1393 } 1394 1395 node, ok := n.Table.Accept(v) 1396 if !ok { 1397 return n, false 1398 } 1399 n.Table = node.(*TableRefsClause) 1400 1401 for i, val := range n.Columns { 1402 node, ok := val.Accept(v) 1403 if !ok { 1404 return n, false 1405 } 1406 n.Columns[i] = node.(*ColumnName) 1407 } 1408 for i, list := range n.Lists { 1409 for j, val := range list { 1410 node, ok := val.Accept(v) 1411 if !ok { 1412 return n, false 1413 } 1414 n.Lists[i][j] = node.(ExprNode) 1415 } 1416 } 1417 for i, val := range n.Setlist { 1418 node, ok := val.Accept(v) 1419 if !ok { 1420 return n, false 1421 } 1422 n.Setlist[i] = node.(*Assignment) 1423 } 1424 for i, val := range n.OnDuplicate { 1425 node, ok := val.Accept(v) 1426 if !ok { 1427 return n, false 1428 } 1429 n.OnDuplicate[i] = node.(*Assignment) 1430 } 1431 return v.Leave(n) 1432 } 1433 1434 // DeleteStmt is a statement to delete rows from table. 1435 // See https://dev.mysql.com/doc/refman/5.7/en/delete.html 1436 type DeleteStmt struct { 1437 dmlNode 1438 1439 // TableRefs is used in both single table and multiple table delete statement. 1440 TableRefs *TableRefsClause 1441 // Tables is only used in multiple table delete statement. 1442 Tables *DeleteTableList 1443 Where ExprNode 1444 Order *OrderByClause 1445 Limit *Limit 1446 Priority mysql.PriorityEnum 1447 IgnoreErr bool 1448 Quick bool 1449 IsMultiTable bool 1450 BeforeFrom bool 1451 // TableHints represents the table level Optimizer Hint for join type. 1452 TableHints []*TableOptimizerHint 1453 } 1454 1455 // Restore implements Node interface. 1456 func (n *DeleteStmt) Restore(ctx *format.RestoreCtx) error { 1457 ctx.WriteKeyWord("DELETE ") 1458 1459 if n.TableHints != nil && len(n.TableHints) != 0 { 1460 ctx.WritePlain("/*+ ") 1461 for i, tableHint := range n.TableHints { 1462 if err := tableHint.Restore(ctx); err != nil { 1463 return errors.Annotatef(err, "An error occurred while restore UpdateStmt.TableHints[%d]", i) 1464 } 1465 } 1466 ctx.WritePlain("*/ ") 1467 } 1468 1469 if err := n.Priority.Restore(ctx); err != nil { 1470 return errors.Trace(err) 1471 } 1472 if n.Priority != mysql.NoPriority { 1473 ctx.WritePlain(" ") 1474 } 1475 if n.Quick { 1476 ctx.WriteKeyWord("QUICK ") 1477 } 1478 if n.IgnoreErr { 1479 ctx.WriteKeyWord("IGNORE ") 1480 } 1481 1482 if n.IsMultiTable { // Multiple-Table Syntax 1483 if n.BeforeFrom { 1484 if err := n.Tables.Restore(ctx); err != nil { 1485 return errors.Annotate(err, "An error occurred while restore DeleteStmt.Tables") 1486 } 1487 1488 ctx.WriteKeyWord(" FROM ") 1489 if err := n.TableRefs.Restore(ctx); err != nil { 1490 return errors.Annotate(err, "An error occurred while restore DeleteStmt.TableRefs") 1491 } 1492 } else { 1493 ctx.WriteKeyWord("FROM ") 1494 if err := n.Tables.Restore(ctx); err != nil { 1495 return errors.Annotate(err, "An error occurred while restore DeleteStmt.Tables") 1496 } 1497 1498 ctx.WriteKeyWord(" USING ") 1499 if err := n.TableRefs.Restore(ctx); err != nil { 1500 return errors.Annotate(err, "An error occurred while restore DeleteStmt.TableRefs") 1501 } 1502 } 1503 } else { // Single-Table Syntax 1504 ctx.WriteKeyWord("FROM ") 1505 1506 if err := n.TableRefs.Restore(ctx); err != nil { 1507 return errors.Annotate(err, "An error occurred while restore DeleteStmt.TableRefs") 1508 } 1509 } 1510 1511 if n.Where != nil { 1512 ctx.WriteKeyWord(" WHERE ") 1513 if err := n.Where.Restore(ctx); err != nil { 1514 return errors.Annotate(err, "An error occurred while restore DeleteStmt.Where") 1515 } 1516 } 1517 1518 if n.Order != nil { 1519 ctx.WritePlain(" ") 1520 if err := n.Order.Restore(ctx); err != nil { 1521 return errors.Annotate(err, "An error occurred while restore DeleteStmt.Order") 1522 } 1523 } 1524 1525 if n.Limit != nil { 1526 ctx.WritePlain(" ") 1527 if err := n.Limit.Restore(ctx); err != nil { 1528 return errors.Annotate(err, "An error occurred while restore DeleteStmt.Limit") 1529 } 1530 } 1531 1532 return nil 1533 } 1534 1535 // Accept implements Node Accept interface. 1536 func (n *DeleteStmt) Accept(v Visitor) (Node, bool) { 1537 newNode, skipChildren := v.Enter(n) 1538 if skipChildren { 1539 return v.Leave(newNode) 1540 } 1541 1542 n = newNode.(*DeleteStmt) 1543 node, ok := n.TableRefs.Accept(v) 1544 if !ok { 1545 return n, false 1546 } 1547 n.TableRefs = node.(*TableRefsClause) 1548 1549 if n.Tables != nil { 1550 node, ok = n.Tables.Accept(v) 1551 if !ok { 1552 return n, false 1553 } 1554 n.Tables = node.(*DeleteTableList) 1555 } 1556 1557 if n.Where != nil { 1558 node, ok = n.Where.Accept(v) 1559 if !ok { 1560 return n, false 1561 } 1562 n.Where = node.(ExprNode) 1563 } 1564 if n.Order != nil { 1565 node, ok = n.Order.Accept(v) 1566 if !ok { 1567 return n, false 1568 } 1569 n.Order = node.(*OrderByClause) 1570 } 1571 if n.Limit != nil { 1572 node, ok = n.Limit.Accept(v) 1573 if !ok { 1574 return n, false 1575 } 1576 n.Limit = node.(*Limit) 1577 } 1578 return v.Leave(n) 1579 } 1580 1581 // UpdateStmt is a statement to update columns of existing rows in tables with new values. 1582 // See https://dev.mysql.com/doc/refman/5.7/en/update.html 1583 type UpdateStmt struct { 1584 dmlNode 1585 1586 TableRefs *TableRefsClause 1587 List []*Assignment 1588 Where ExprNode 1589 Order *OrderByClause 1590 Limit *Limit 1591 Priority mysql.PriorityEnum 1592 IgnoreErr bool 1593 MultipleTable bool 1594 TableHints []*TableOptimizerHint 1595 } 1596 1597 // Restore implements Node interface. 1598 func (n *UpdateStmt) Restore(ctx *format.RestoreCtx) error { 1599 ctx.WriteKeyWord("UPDATE ") 1600 1601 if n.TableHints != nil && len(n.TableHints) != 0 { 1602 ctx.WritePlain("/*+ ") 1603 for i, tableHint := range n.TableHints { 1604 if err := tableHint.Restore(ctx); err != nil { 1605 return errors.Annotatef(err, "An error occurred while restore UpdateStmt.TableHints[%d]", i) 1606 } 1607 } 1608 ctx.WritePlain("*/ ") 1609 } 1610 1611 if err := n.Priority.Restore(ctx); err != nil { 1612 return errors.Trace(err) 1613 } 1614 if n.Priority != mysql.NoPriority { 1615 ctx.WritePlain(" ") 1616 } 1617 if n.IgnoreErr { 1618 ctx.WriteKeyWord("IGNORE ") 1619 } 1620 1621 if err := n.TableRefs.Restore(ctx); err != nil { 1622 return errors.Annotate(err, "An error occur while restore UpdateStmt.TableRefs") 1623 } 1624 1625 ctx.WriteKeyWord(" SET ") 1626 for i, assignment := range n.List { 1627 if i != 0 { 1628 ctx.WritePlain(", ") 1629 } 1630 1631 if err := assignment.Column.Restore(ctx); err != nil { 1632 return errors.Annotatef(err, "An error occur while restore UpdateStmt.List[%d].Column", i) 1633 } 1634 1635 ctx.WritePlain("=") 1636 1637 if err := assignment.Expr.Restore(ctx); err != nil { 1638 return errors.Annotatef(err, "An error occur while restore UpdateStmt.List[%d].Expr", i) 1639 } 1640 } 1641 1642 if n.Where != nil { 1643 ctx.WriteKeyWord(" WHERE ") 1644 if err := n.Where.Restore(ctx); err != nil { 1645 return errors.Annotate(err, "An error occur while restore UpdateStmt.Where") 1646 } 1647 } 1648 1649 if n.Order != nil { 1650 ctx.WritePlain(" ") 1651 if err := n.Order.Restore(ctx); err != nil { 1652 return errors.Annotate(err, "An error occur while restore UpdateStmt.Order") 1653 } 1654 } 1655 1656 if n.Limit != nil { 1657 ctx.WritePlain(" ") 1658 if err := n.Limit.Restore(ctx); err != nil { 1659 return errors.Annotate(err, "An error occur while restore UpdateStmt.Limit") 1660 } 1661 } 1662 1663 return nil 1664 } 1665 1666 // Accept implements Node Accept interface. 1667 func (n *UpdateStmt) Accept(v Visitor) (Node, bool) { 1668 newNode, skipChildren := v.Enter(n) 1669 if skipChildren { 1670 return v.Leave(newNode) 1671 } 1672 n = newNode.(*UpdateStmt) 1673 node, ok := n.TableRefs.Accept(v) 1674 if !ok { 1675 return n, false 1676 } 1677 n.TableRefs = node.(*TableRefsClause) 1678 for i, val := range n.List { 1679 node, ok = val.Accept(v) 1680 if !ok { 1681 return n, false 1682 } 1683 n.List[i] = node.(*Assignment) 1684 } 1685 if n.Where != nil { 1686 node, ok = n.Where.Accept(v) 1687 if !ok { 1688 return n, false 1689 } 1690 n.Where = node.(ExprNode) 1691 } 1692 if n.Order != nil { 1693 node, ok = n.Order.Accept(v) 1694 if !ok { 1695 return n, false 1696 } 1697 n.Order = node.(*OrderByClause) 1698 } 1699 if n.Limit != nil { 1700 node, ok = n.Limit.Accept(v) 1701 if !ok { 1702 return n, false 1703 } 1704 n.Limit = node.(*Limit) 1705 } 1706 return v.Leave(n) 1707 } 1708 1709 // Limit is the limit clause. 1710 type Limit struct { 1711 node 1712 1713 Count ExprNode 1714 Offset ExprNode 1715 } 1716 1717 // Restore implements Node interface. 1718 func (n *Limit) Restore(ctx *format.RestoreCtx) error { 1719 ctx.WriteKeyWord("LIMIT ") 1720 if n.Offset != nil { 1721 if err := n.Offset.Restore(ctx); err != nil { 1722 return errors.Annotate(err, "An error occurred while restore Limit.Offset") 1723 } 1724 ctx.WritePlain(",") 1725 } 1726 if err := n.Count.Restore(ctx); err != nil { 1727 return errors.Annotate(err, "An error occurred while restore Limit.Count") 1728 } 1729 return nil 1730 } 1731 1732 // Accept implements Node Accept interface. 1733 func (n *Limit) Accept(v Visitor) (Node, bool) { 1734 newNode, skipChildren := v.Enter(n) 1735 if skipChildren { 1736 return v.Leave(newNode) 1737 } 1738 if n.Count != nil { 1739 node, ok := n.Count.Accept(v) 1740 if !ok { 1741 return n, false 1742 } 1743 n.Count = node.(ExprNode) 1744 } 1745 if n.Offset != nil { 1746 node, ok := n.Offset.Accept(v) 1747 if !ok { 1748 return n, false 1749 } 1750 n.Offset = node.(ExprNode) 1751 } 1752 1753 n = newNode.(*Limit) 1754 return v.Leave(n) 1755 } 1756 1757 // ShowStmtType is the type for SHOW statement. 1758 type ShowStmtType int 1759 1760 // Show statement types. 1761 const ( 1762 ShowNone = iota 1763 ShowEngines 1764 ShowDatabases 1765 ShowTables 1766 ShowTableStatus 1767 ShowColumns 1768 ShowWarnings 1769 ShowCharset 1770 ShowVariables 1771 ShowStatus 1772 ShowCollation 1773 ShowCreateTable 1774 ShowCreateView 1775 ShowCreateUser 1776 ShowGrants 1777 ShowTriggers 1778 ShowProcedureStatus 1779 ShowIndex 1780 ShowProcessList 1781 ShowCreateDatabase 1782 ShowEvents 1783 ShowStatsMeta 1784 ShowStatsHistograms 1785 ShowStatsBuckets 1786 ShowStatsHealthy 1787 ShowPlugins 1788 ShowProfiles 1789 ShowMasterStatus 1790 ShowPrivileges 1791 ShowErrors 1792 ShowBindings 1793 ShowPumpStatus 1794 ShowDrainerStatus 1795 ) 1796 1797 // ShowStmt is a statement to provide information about databases, tables, columns and so on. 1798 // See https://dev.mysql.com/doc/refman/5.7/en/show.html 1799 type ShowStmt struct { 1800 dmlNode 1801 resultSetNode 1802 1803 Tp ShowStmtType // Databases/Tables/Columns/.... 1804 DBName string 1805 Table *TableName // Used for showing columns. 1806 Column *ColumnName // Used for `desc table column`. 1807 Flag int // Some flag parsed from sql, such as FULL. 1808 Full bool 1809 User *auth.UserIdentity // Used for show grants/create user. 1810 IfNotExists bool // Used for `show create database if not exists` 1811 1812 // GlobalScope is used by `show variables` and `show bindings` 1813 GlobalScope bool 1814 Pattern *PatternLikeExpr 1815 Where ExprNode 1816 } 1817 1818 // Restore implements Node interface. 1819 func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error { 1820 restoreOptFull := func() { 1821 if n.Full { 1822 ctx.WriteKeyWord("FULL ") 1823 } 1824 } 1825 restoreShowDatabaseNameOpt := func() { 1826 if n.DBName != "" { 1827 // FROM OR IN 1828 ctx.WriteKeyWord(" IN ") 1829 ctx.WriteName(n.DBName) 1830 } 1831 } 1832 restoreGlobalScope := func() { 1833 if n.GlobalScope { 1834 ctx.WriteKeyWord("GLOBAL ") 1835 } else { 1836 ctx.WriteKeyWord("SESSION ") 1837 } 1838 } 1839 restoreShowLikeOrWhereOpt := func() error { 1840 if n.Pattern != nil && n.Pattern.Pattern != nil { 1841 ctx.WriteKeyWord(" LIKE ") 1842 if err := n.Pattern.Pattern.Restore(ctx); err != nil { 1843 return errors.Annotate(err, "An error occurred while restore ShowStmt.Pattern") 1844 } 1845 } else if n.Where != nil { 1846 ctx.WriteKeyWord(" WHERE ") 1847 if err := n.Where.Restore(ctx); err != nil { 1848 return errors.Annotate(err, "An error occurred while restore ShowStmt.Where") 1849 } 1850 } 1851 return nil 1852 } 1853 1854 ctx.WriteKeyWord("SHOW ") 1855 switch n.Tp { 1856 case ShowCreateTable: 1857 ctx.WriteKeyWord("CREATE TABLE ") 1858 if err := n.Table.Restore(ctx); err != nil { 1859 return errors.Annotate(err, "An error occurred while restore ShowStmt.Table") 1860 } 1861 case ShowCreateView: 1862 ctx.WriteKeyWord("CREATE VIEW ") 1863 if err := n.Table.Restore(ctx); err != nil { 1864 return errors.Annotate(err, "An error occurred while restore ShowStmt.VIEW") 1865 } 1866 case ShowCreateDatabase: 1867 ctx.WriteKeyWord("CREATE DATABASE ") 1868 if n.IfNotExists { 1869 ctx.WriteKeyWord("IF NOT EXISTS ") 1870 } 1871 ctx.WriteName(n.DBName) 1872 case ShowCreateUser: 1873 ctx.WriteKeyWord("CREATE USER ") 1874 if err := n.User.Restore(ctx); err != nil { 1875 return errors.Annotate(err, "An error occurred while restore ShowStmt.User") 1876 } 1877 case ShowGrants: 1878 ctx.WriteKeyWord("GRANTS") 1879 if n.User != nil { 1880 ctx.WriteKeyWord(" FOR ") 1881 if err := n.User.Restore(ctx); err != nil { 1882 return errors.Annotate(err, "An error occurred while restore ShowStmt.User") 1883 } 1884 } 1885 case ShowMasterStatus: 1886 ctx.WriteKeyWord("MASTER STATUS") 1887 case ShowProcessList: 1888 restoreOptFull() 1889 ctx.WriteKeyWord("PROCESSLIST") 1890 case ShowStatsMeta: 1891 ctx.WriteKeyWord("STATS_META") 1892 if err := restoreShowLikeOrWhereOpt(); err != nil { 1893 return err 1894 } 1895 case ShowStatsHistograms: 1896 ctx.WriteKeyWord("STATS_HISTOGRAMS") 1897 if err := restoreShowLikeOrWhereOpt(); err != nil { 1898 return err 1899 } 1900 case ShowStatsBuckets: 1901 ctx.WriteKeyWord("STATS_BUCKETS") 1902 if err := restoreShowLikeOrWhereOpt(); err != nil { 1903 return err 1904 } 1905 case ShowStatsHealthy: 1906 ctx.WriteKeyWord("STATS_HEALTHY") 1907 if err := restoreShowLikeOrWhereOpt(); err != nil { 1908 return err 1909 } 1910 case ShowProfiles: 1911 ctx.WriteKeyWord("PROFILES") 1912 case ShowPrivileges: 1913 ctx.WriteKeyWord("PRIVILEGES") 1914 // ShowTargetFilterable 1915 default: 1916 switch n.Tp { 1917 case ShowEngines: 1918 ctx.WriteKeyWord("ENGINES") 1919 case ShowDatabases: 1920 ctx.WriteKeyWord("DATABASES") 1921 case ShowCharset: 1922 ctx.WriteKeyWord("CHARSET") 1923 case ShowTables: 1924 restoreOptFull() 1925 ctx.WriteKeyWord("TABLES") 1926 restoreShowDatabaseNameOpt() 1927 case ShowTableStatus: 1928 ctx.WriteKeyWord("TABLE STATUS") 1929 restoreShowDatabaseNameOpt() 1930 case ShowIndex: 1931 // here can be INDEX INDEXES KEYS 1932 // FROM or IN 1933 ctx.WriteKeyWord("INDEX IN ") 1934 if err := n.Table.Restore(ctx); err != nil { 1935 return errors.Annotate(err, "An error occurred while resotre ShowStmt.Table") 1936 } // TODO: remember to check this case 1937 case ShowColumns: // equivalent to SHOW FIELDS 1938 restoreOptFull() 1939 ctx.WriteKeyWord("COLUMNS") 1940 if n.Table != nil { 1941 // FROM or IN 1942 ctx.WriteKeyWord(" IN ") 1943 if err := n.Table.Restore(ctx); err != nil { 1944 return errors.Annotate(err, "An error occurred while resotre ShowStmt.Table") 1945 } 1946 } 1947 restoreShowDatabaseNameOpt() 1948 case ShowWarnings: 1949 ctx.WriteKeyWord("WARNINGS") 1950 case ShowErrors: 1951 ctx.WriteKeyWord("ERRORS") 1952 case ShowVariables: 1953 restoreGlobalScope() 1954 ctx.WriteKeyWord("VARIABLES") 1955 case ShowStatus: 1956 restoreGlobalScope() 1957 ctx.WriteKeyWord("STATUS") 1958 case ShowCollation: 1959 ctx.WriteKeyWord("COLLATION") 1960 case ShowTriggers: 1961 ctx.WriteKeyWord("TRIGGERS") 1962 restoreShowDatabaseNameOpt() 1963 case ShowProcedureStatus: 1964 ctx.WriteKeyWord("PROCEDURE STATUS") 1965 case ShowEvents: 1966 ctx.WriteKeyWord("EVENTS") 1967 restoreShowDatabaseNameOpt() 1968 case ShowPlugins: 1969 ctx.WriteKeyWord("PLUGINS") 1970 case ShowBindings: 1971 if n.GlobalScope { 1972 ctx.WriteKeyWord("GLOBAL ") 1973 } else { 1974 ctx.WriteKeyWord("SESSION ") 1975 } 1976 ctx.WriteKeyWord("BINDINGS") 1977 case ShowPumpStatus: 1978 ctx.WriteKeyWord("PUMP STATUS") 1979 case ShowDrainerStatus: 1980 ctx.WriteKeyWord("DRAINER STATUS") 1981 default: 1982 return errors.New("Unknown ShowStmt type") 1983 } 1984 restoreShowLikeOrWhereOpt() 1985 } 1986 return nil 1987 } 1988 1989 // Accept implements Node Accept interface. 1990 func (n *ShowStmt) Accept(v Visitor) (Node, bool) { 1991 newNode, skipChildren := v.Enter(n) 1992 if skipChildren { 1993 return v.Leave(newNode) 1994 } 1995 n = newNode.(*ShowStmt) 1996 if n.Table != nil { 1997 node, ok := n.Table.Accept(v) 1998 if !ok { 1999 return n, false 2000 } 2001 n.Table = node.(*TableName) 2002 } 2003 if n.Column != nil { 2004 node, ok := n.Column.Accept(v) 2005 if !ok { 2006 return n, false 2007 } 2008 n.Column = node.(*ColumnName) 2009 } 2010 if n.Pattern != nil { 2011 node, ok := n.Pattern.Accept(v) 2012 if !ok { 2013 return n, false 2014 } 2015 n.Pattern = node.(*PatternLikeExpr) 2016 } 2017 2018 switch n.Tp { 2019 case ShowTriggers, ShowProcedureStatus, ShowProcessList, ShowEvents: 2020 // We don't have any data to return for those types, 2021 // but visiting Where may cause resolving error, so return here to avoid error. 2022 return v.Leave(n) 2023 } 2024 2025 if n.Where != nil { 2026 node, ok := n.Where.Accept(v) 2027 if !ok { 2028 return n, false 2029 } 2030 n.Where = node.(ExprNode) 2031 } 2032 return v.Leave(n) 2033 } 2034 2035 // WindowSpec is the specification of a window. 2036 type WindowSpec struct { 2037 node 2038 2039 Name model.CIStr 2040 // Ref is the reference window of this specification. For example, in `w2 as (w1 order by a)`, 2041 // the definition of `w2` references `w1`. 2042 Ref model.CIStr 2043 2044 PartitionBy *PartitionByClause 2045 OrderBy *OrderByClause 2046 Frame *FrameClause 2047 } 2048 2049 // Restore implements Node interface. 2050 func (n *WindowSpec) Restore(ctx *format.RestoreCtx) error { 2051 if name := n.Name.String(); name != "" { 2052 ctx.WriteName(name) 2053 ctx.WriteKeyWord(" AS ") 2054 } 2055 ctx.WritePlain("(") 2056 sep := "" 2057 if refName := n.Ref.String(); refName != "" { 2058 ctx.WriteName(refName) 2059 sep = " " 2060 } 2061 if n.PartitionBy != nil { 2062 ctx.WritePlain(sep) 2063 if err := n.PartitionBy.Restore(ctx); err != nil { 2064 return errors.Annotate(err, "An error occurred while restore WindowSpec.PartitionBy") 2065 } 2066 sep = " " 2067 } 2068 if n.OrderBy != nil { 2069 ctx.WritePlain(sep) 2070 if err := n.OrderBy.Restore(ctx); err != nil { 2071 return errors.Annotate(err, "An error occurred while restore WindowSpec.OrderBy") 2072 } 2073 sep = " " 2074 } 2075 if n.Frame != nil { 2076 ctx.WritePlain(sep) 2077 if err := n.Frame.Restore(ctx); err != nil { 2078 return errors.Annotate(err, "An error occurred while restore WindowSpec.Frame") 2079 } 2080 } 2081 ctx.WritePlain(")") 2082 2083 return nil 2084 } 2085 2086 // Accept implements Node Accept interface. 2087 func (n *WindowSpec) Accept(v Visitor) (Node, bool) { 2088 newNode, skipChildren := v.Enter(n) 2089 if skipChildren { 2090 return v.Leave(newNode) 2091 } 2092 n = newNode.(*WindowSpec) 2093 if n.PartitionBy != nil { 2094 node, ok := n.PartitionBy.Accept(v) 2095 if !ok { 2096 return n, false 2097 } 2098 n.PartitionBy = node.(*PartitionByClause) 2099 } 2100 if n.OrderBy != nil { 2101 node, ok := n.OrderBy.Accept(v) 2102 if !ok { 2103 return n, false 2104 } 2105 n.OrderBy = node.(*OrderByClause) 2106 } 2107 if n.Frame != nil { 2108 node, ok := n.Frame.Accept(v) 2109 if !ok { 2110 return n, false 2111 } 2112 n.Frame = node.(*FrameClause) 2113 } 2114 return v.Leave(n) 2115 } 2116 2117 // PartitionByClause represents partition by clause. 2118 type PartitionByClause struct { 2119 node 2120 2121 Items []*ByItem 2122 } 2123 2124 // Restore implements Node interface. 2125 func (n *PartitionByClause) Restore(ctx *format.RestoreCtx) error { 2126 ctx.WriteKeyWord("PARTITION BY ") 2127 for i, v := range n.Items { 2128 if i != 0 { 2129 ctx.WritePlain(", ") 2130 } 2131 if err := v.Restore(ctx); err != nil { 2132 return errors.Annotatef(err, "An error occurred while restore PartitionByClause.Items[%d]", i) 2133 } 2134 } 2135 return nil 2136 } 2137 2138 // Accept implements Node Accept interface. 2139 func (n *PartitionByClause) Accept(v Visitor) (Node, bool) { 2140 newNode, skipChildren := v.Enter(n) 2141 if skipChildren { 2142 return v.Leave(newNode) 2143 } 2144 n = newNode.(*PartitionByClause) 2145 for i, val := range n.Items { 2146 node, ok := val.Accept(v) 2147 if !ok { 2148 return n, false 2149 } 2150 n.Items[i] = node.(*ByItem) 2151 } 2152 return v.Leave(n) 2153 } 2154 2155 // FrameType is the type of window function frame. 2156 type FrameType int 2157 2158 // Window function frame types. 2159 // MySQL only supports `ROWS` and `RANGES`. 2160 const ( 2161 Rows = iota 2162 Ranges 2163 Groups 2164 ) 2165 2166 // FrameClause represents frame clause. 2167 type FrameClause struct { 2168 node 2169 2170 Type FrameType 2171 Extent FrameExtent 2172 } 2173 2174 // Restore implements Node interface. 2175 func (n *FrameClause) Restore(ctx *format.RestoreCtx) error { 2176 switch n.Type { 2177 case Rows: 2178 ctx.WriteKeyWord("ROWS") 2179 case Ranges: 2180 ctx.WriteKeyWord("RANGE") 2181 default: 2182 return errors.New("Unsupported window function frame type") 2183 } 2184 ctx.WriteKeyWord(" BETWEEN ") 2185 if err := n.Extent.Start.Restore(ctx); err != nil { 2186 return errors.Annotate(err, "An error occurred while restore FrameClause.Extent.Start") 2187 } 2188 ctx.WriteKeyWord(" AND ") 2189 if err := n.Extent.End.Restore(ctx); err != nil { 2190 return errors.Annotate(err, "An error occurred while restore FrameClause.Extent.End") 2191 } 2192 2193 return nil 2194 } 2195 2196 // Accept implements Node Accept interface. 2197 func (n *FrameClause) Accept(v Visitor) (Node, bool) { 2198 newNode, skipChildren := v.Enter(n) 2199 if skipChildren { 2200 return v.Leave(newNode) 2201 } 2202 n = newNode.(*FrameClause) 2203 node, ok := n.Extent.Start.Accept(v) 2204 if !ok { 2205 return n, false 2206 } 2207 n.Extent.Start = *node.(*FrameBound) 2208 node, ok = n.Extent.End.Accept(v) 2209 if !ok { 2210 return n, false 2211 } 2212 n.Extent.End = *node.(*FrameBound) 2213 return v.Leave(n) 2214 } 2215 2216 // FrameExtent represents frame extent. 2217 type FrameExtent struct { 2218 Start FrameBound 2219 End FrameBound 2220 } 2221 2222 // BoundType is the type of window function frame bound. 2223 type BoundType int 2224 2225 // Frame bound types. 2226 const ( 2227 Following = iota 2228 Preceding 2229 CurrentRow 2230 ) 2231 2232 // FrameBound represents frame bound. 2233 type FrameBound struct { 2234 node 2235 2236 Type BoundType 2237 UnBounded bool 2238 Expr ExprNode 2239 // `Unit` is used to indicate the units in which the `Expr` should be interpreted. 2240 // For example: '2:30' MINUTE_SECOND. 2241 Unit ExprNode 2242 } 2243 2244 // Restore implements Node interface. 2245 func (n *FrameBound) Restore(ctx *format.RestoreCtx) error { 2246 if n.UnBounded { 2247 ctx.WriteKeyWord("UNBOUNDED") 2248 } 2249 switch n.Type { 2250 case CurrentRow: 2251 ctx.WriteKeyWord("CURRENT ROW") 2252 case Preceding, Following: 2253 if n.Unit != nil { 2254 ctx.WriteKeyWord("INTERVAL ") 2255 } 2256 if n.Expr != nil { 2257 if err := n.Expr.Restore(ctx); err != nil { 2258 return errors.Annotate(err, "An error occurred while restore FrameBound.Expr") 2259 } 2260 } 2261 if n.Unit != nil { 2262 // Here the Unit string should not be quoted. 2263 // TODO: This is a temporary workaround that should be changed once something like "Keyword Expression" is implemented. 2264 var sb strings.Builder 2265 n.Unit.Restore(format.NewRestoreCtx(0, &sb)) 2266 ctx.WritePlain(" ") 2267 ctx.WriteKeyWord(sb.String()) 2268 } 2269 if n.Type == Preceding { 2270 ctx.WriteKeyWord(" PRECEDING") 2271 } else { 2272 ctx.WriteKeyWord(" FOLLOWING") 2273 } 2274 } 2275 return nil 2276 } 2277 2278 // Accept implements Node Accept interface. 2279 func (n *FrameBound) Accept(v Visitor) (Node, bool) { 2280 newNode, skipChildren := v.Enter(n) 2281 if skipChildren { 2282 return v.Leave(newNode) 2283 } 2284 n = newNode.(*FrameBound) 2285 if n.Expr != nil { 2286 node, ok := n.Expr.Accept(v) 2287 if !ok { 2288 return n, false 2289 } 2290 n.Expr = node.(ExprNode) 2291 } 2292 if n.Unit != nil { 2293 node, ok := n.Unit.Accept(v) 2294 if !ok { 2295 return n, false 2296 } 2297 n.Unit = node.(ExprNode) 2298 } 2299 return v.Leave(n) 2300 }