github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sem/tree/walk.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package tree 12 13 import ( 14 "bytes" 15 "fmt" 16 "reflect" 17 "strings" 18 19 "github.com/cockroachdb/errors" 20 ) 21 22 // Visitor defines methods that are called for nodes during an expression or statement walk. 23 type Visitor interface { 24 // VisitPre is called for each node before recursing into that subtree. Upon return, if recurse 25 // is false, the visit will not recurse into the subtree (and VisitPost will not be called for 26 // this node). 27 // 28 // The returned Expr replaces the visited expression and can be used for rewriting expressions. 29 // The function should NOT modify nodes in-place; it should make copies of nodes. The Walk 30 // infrastructure will automatically make copies of parents as needed. 31 VisitPre(expr Expr) (recurse bool, newExpr Expr) 32 33 // VisitPost is called for each node after recursing into the subtree. The returned Expr 34 // replaces the visited expression and can be used for rewriting expressions. 35 // 36 // The returned Expr replaces the visited expression and can be used for rewriting expressions. 37 // The function should NOT modify nodes in-place; it should make and return copies of nodes. The 38 // Walk infrastructure will automatically make copies of parents as needed. 39 VisitPost(expr Expr) (newNode Expr) 40 } 41 42 // Walk implements the Expr interface. 43 func (expr *AndExpr) Walk(v Visitor) Expr { 44 left, changedL := WalkExpr(v, expr.Left) 45 right, changedR := WalkExpr(v, expr.Right) 46 if changedL || changedR { 47 exprCopy := *expr 48 exprCopy.Left = left 49 exprCopy.Right = right 50 return &exprCopy 51 } 52 return expr 53 } 54 55 // Walk implements the Expr interface. 56 func (expr *AnnotateTypeExpr) Walk(v Visitor) Expr { 57 e, changed := WalkExpr(v, expr.Expr) 58 if changed { 59 exprCopy := *expr 60 exprCopy.Expr = e 61 return &exprCopy 62 } 63 return expr 64 } 65 66 // Walk implements the Expr interface. 67 func (expr *BinaryExpr) Walk(v Visitor) Expr { 68 left, changedL := WalkExpr(v, expr.Left) 69 right, changedR := WalkExpr(v, expr.Right) 70 if changedL || changedR { 71 exprCopy := *expr 72 exprCopy.Left = left 73 exprCopy.Right = right 74 return &exprCopy 75 } 76 return expr 77 } 78 79 // copyNode makes a copy of this Expr without recursing in any child Exprs. 80 func (expr *CaseExpr) copyNode() *CaseExpr { 81 exprCopy := *expr 82 // Copy the Whens slice. Amortize into 1 allocation. 83 whens := make([]When, len(expr.Whens)) 84 exprCopy.Whens = make([]*When, len(expr.Whens)) 85 for i, w := range expr.Whens { 86 whens[i] = *w 87 exprCopy.Whens[i] = &whens[i] 88 } 89 return &exprCopy 90 } 91 92 // Walk implements the Expr interface. 93 func (expr *CaseExpr) Walk(v Visitor) Expr { 94 ret := expr 95 96 if expr.Expr != nil { 97 e, changed := WalkExpr(v, expr.Expr) 98 if changed { 99 ret = expr.copyNode() 100 ret.Expr = e 101 } 102 } 103 for i, w := range expr.Whens { 104 cond, changedC := WalkExpr(v, w.Cond) 105 val, changedV := WalkExpr(v, w.Val) 106 if changedC || changedV { 107 if ret == expr { 108 ret = expr.copyNode() 109 } 110 ret.Whens[i].Cond = cond 111 ret.Whens[i].Val = val 112 } 113 } 114 if expr.Else != nil { 115 e, changed := WalkExpr(v, expr.Else) 116 if changed { 117 if ret == expr { 118 ret = expr.copyNode() 119 } 120 ret.Else = e 121 } 122 } 123 return ret 124 } 125 126 // Walk implements the Expr interface. 127 func (expr *CastExpr) Walk(v Visitor) Expr { 128 e, changed := WalkExpr(v, expr.Expr) 129 if changed { 130 exprCopy := *expr 131 exprCopy.Expr = e 132 return &exprCopy 133 } 134 return expr 135 } 136 137 // Walk implements the Expr interface. 138 func (expr *CollateExpr) Walk(v Visitor) Expr { 139 e, changed := WalkExpr(v, expr.Expr) 140 if changed { 141 exprCopy := *expr 142 exprCopy.Expr = e 143 return &exprCopy 144 } 145 return expr 146 } 147 148 // Walk implements the Expr interface. 149 func (expr *ColumnAccessExpr) Walk(v Visitor) Expr { 150 e, changed := WalkExpr(v, expr.Expr) 151 if changed { 152 exprCopy := *expr 153 exprCopy.Expr = e 154 return &exprCopy 155 } 156 return expr 157 } 158 159 // Walk implements the Expr interface. 160 func (expr *TupleStar) Walk(v Visitor) Expr { 161 e, changed := WalkExpr(v, expr.Expr) 162 if changed { 163 exprCopy := *expr 164 exprCopy.Expr = e 165 return &exprCopy 166 } 167 return expr 168 } 169 170 // copyNode makes a copy of this Expr without recursing in any child Exprs. 171 func (expr *CoalesceExpr) copyNode() *CoalesceExpr { 172 exprCopy := *expr 173 return &exprCopy 174 } 175 176 // Walk implements the Expr interface. 177 func (expr *CoalesceExpr) Walk(v Visitor) Expr { 178 ret := expr 179 exprs, changed := walkExprSlice(v, expr.Exprs) 180 if changed { 181 if ret == expr { 182 ret = expr.copyNode() 183 } 184 ret.Exprs = exprs 185 } 186 return ret 187 } 188 189 // Walk implements the Expr interface. 190 func (expr *ComparisonExpr) Walk(v Visitor) Expr { 191 left, changedL := WalkExpr(v, expr.Left) 192 right, changedR := WalkExpr(v, expr.Right) 193 if changedL || changedR { 194 exprCopy := *expr 195 exprCopy.Left = left 196 exprCopy.Right = right 197 // TODO(ajwerner): Should this be updating the memoized op? It seems like 198 // it could need to change in some cases, but it also seems painful to know 199 // which ones. 200 return &exprCopy 201 } 202 return expr 203 } 204 205 // copyNode makes a copy of this Expr without recursing in any child Exprs. 206 func (expr *FuncExpr) copyNode() *FuncExpr { 207 exprCopy := *expr 208 exprCopy.Exprs = append(Exprs(nil), exprCopy.Exprs...) 209 return &exprCopy 210 } 211 212 // copyNode makes a copy of this WindowFrame without recursing. 213 func (node *WindowFrame) copyNode() *WindowFrame { 214 nodeCopy := *node 215 return &nodeCopy 216 } 217 218 func walkWindowFrame(v Visitor, frame *WindowFrame) (*WindowFrame, bool) { 219 ret := frame 220 if frame.Bounds.StartBound != nil { 221 b, changed := walkWindowFrameBound(v, frame.Bounds.StartBound) 222 if changed { 223 if ret == frame { 224 ret = frame.copyNode() 225 } 226 ret.Bounds.StartBound = b 227 } 228 } 229 if frame.Bounds.EndBound != nil { 230 b, changed := walkWindowFrameBound(v, frame.Bounds.EndBound) 231 if changed { 232 if ret == frame { 233 ret = frame.copyNode() 234 } 235 ret.Bounds.EndBound = b 236 } 237 } 238 return ret, ret != frame 239 } 240 241 // copyNode makes a copy of this WindowFrameBound without recursing. 242 func (node *WindowFrameBound) copyNode() *WindowFrameBound { 243 nodeCopy := *node 244 return &nodeCopy 245 } 246 247 func walkWindowFrameBound(v Visitor, bound *WindowFrameBound) (*WindowFrameBound, bool) { 248 ret := bound 249 if bound.HasOffset() { 250 e, changed := WalkExpr(v, bound.OffsetExpr) 251 if changed { 252 if ret == bound { 253 ret = bound.copyNode() 254 } 255 ret.OffsetExpr = e 256 } 257 } 258 return ret, ret != bound 259 } 260 261 // copyNode makes a copy of this WindowDef without recursing. 262 func (node *WindowDef) copyNode() *WindowDef { 263 nodeCopy := *node 264 return &nodeCopy 265 } 266 267 func walkWindowDef(v Visitor, windowDef *WindowDef) (*WindowDef, bool) { 268 ret := windowDef 269 if len(windowDef.Partitions) > 0 { 270 exprs, changed := walkExprSlice(v, windowDef.Partitions) 271 if changed { 272 if ret == windowDef { 273 ret = windowDef.copyNode() 274 } 275 ret.Partitions = exprs 276 } 277 } 278 if len(windowDef.OrderBy) > 0 { 279 order, changed := walkOrderBy(v, windowDef.OrderBy) 280 if changed { 281 if ret == windowDef { 282 ret = windowDef.copyNode() 283 } 284 ret.OrderBy = order 285 } 286 } 287 if windowDef.Frame != nil { 288 frame, changed := walkWindowFrame(v, windowDef.Frame) 289 if changed { 290 if ret == windowDef { 291 ret = windowDef.copyNode() 292 } 293 ret.Frame = frame 294 } 295 } 296 297 return ret, ret != windowDef 298 } 299 300 // Walk implements the Expr interface. 301 func (expr *FuncExpr) Walk(v Visitor) Expr { 302 ret := expr 303 exprs, changed := walkExprSlice(v, expr.Exprs) 304 if changed { 305 if ret == expr { 306 ret = expr.copyNode() 307 } 308 ret.Exprs = exprs 309 } 310 if expr.Filter != nil { 311 e, changed := WalkExpr(v, expr.Filter) 312 if changed { 313 if ret == expr { 314 ret = expr.copyNode() 315 } 316 ret.Filter = e 317 } 318 } 319 320 if expr.OrderBy != nil { 321 order, changed := walkOrderBy(v, expr.OrderBy) 322 if changed { 323 if ret == expr { 324 ret = expr.copyNode() 325 } 326 ret.OrderBy = order 327 } 328 } 329 return ret 330 } 331 332 // Walk implements the Expr interface. 333 func (expr *IfExpr) Walk(v Visitor) Expr { 334 c, changedC := WalkExpr(v, expr.Cond) 335 t, changedT := WalkExpr(v, expr.True) 336 e, changedE := WalkExpr(v, expr.Else) 337 if changedC || changedT || changedE { 338 exprCopy := *expr 339 exprCopy.Cond = c 340 exprCopy.True = t 341 exprCopy.Else = e 342 return &exprCopy 343 } 344 return expr 345 } 346 347 // Walk implements the Expr interface. 348 func (expr *IfErrExpr) Walk(v Visitor) Expr { 349 c, changedC := WalkExpr(v, expr.Cond) 350 t := expr.ErrCode 351 changedEC := false 352 if t != nil { 353 t, changedEC = WalkExpr(v, expr.ErrCode) 354 } 355 e := expr.Else 356 changedE := false 357 if e != nil { 358 e, changedE = WalkExpr(v, expr.Else) 359 } 360 if changedC || changedEC || changedE { 361 exprCopy := *expr 362 exprCopy.Cond = c 363 exprCopy.ErrCode = t 364 exprCopy.Else = e 365 return &exprCopy 366 } 367 return expr 368 } 369 370 // copyNode makes a copy of this Expr without recursing in any child Exprs. 371 func (expr *IndirectionExpr) copyNode() *IndirectionExpr { 372 exprCopy := *expr 373 exprCopy.Indirection = append(ArraySubscripts(nil), exprCopy.Indirection...) 374 for i, t := range exprCopy.Indirection { 375 subscriptCopy := *t 376 exprCopy.Indirection[i] = &subscriptCopy 377 } 378 return &exprCopy 379 } 380 381 // Walk implements the Expr interface. 382 func (expr *IndirectionExpr) Walk(v Visitor) Expr { 383 ret := expr 384 385 e, changed := WalkExpr(v, expr.Expr) 386 if changed { 387 if ret == expr { 388 ret = expr.copyNode() 389 } 390 ret.Expr = e 391 } 392 393 for i, t := range expr.Indirection { 394 if t.Begin != nil { 395 e, changed := WalkExpr(v, t.Begin) 396 if changed { 397 if ret == expr { 398 ret = expr.copyNode() 399 } 400 ret.Indirection[i].Begin = e 401 } 402 } 403 if t.End != nil { 404 e, changed := WalkExpr(v, t.End) 405 if changed { 406 if ret == expr { 407 ret = expr.copyNode() 408 } 409 ret.Indirection[i].End = e 410 } 411 } 412 } 413 414 return ret 415 } 416 417 // Walk implements the Expr interface. 418 func (expr *IsOfTypeExpr) Walk(v Visitor) Expr { 419 e, changed := WalkExpr(v, expr.Expr) 420 if changed { 421 exprCopy := *expr 422 exprCopy.Expr = e 423 return &exprCopy 424 } 425 return expr 426 } 427 428 // Walk implements the Expr interface. 429 func (expr *NotExpr) Walk(v Visitor) Expr { 430 e, changed := WalkExpr(v, expr.Expr) 431 if changed { 432 exprCopy := *expr 433 exprCopy.Expr = e 434 return &exprCopy 435 } 436 return expr 437 } 438 439 // Walk implements the Expr interface. 440 func (expr *IsNullExpr) Walk(v Visitor) Expr { 441 e, changed := WalkExpr(v, expr.Expr) 442 if changed { 443 exprCopy := *expr 444 exprCopy.Expr = e 445 return &exprCopy 446 } 447 return expr 448 } 449 450 // Walk implements the Expr interface. 451 func (expr *IsNotNullExpr) Walk(v Visitor) Expr { 452 e, changed := WalkExpr(v, expr.Expr) 453 if changed { 454 exprCopy := *expr 455 exprCopy.Expr = e 456 return &exprCopy 457 } 458 return expr 459 } 460 461 // Walk implements the Expr interface. 462 func (expr *NullIfExpr) Walk(v Visitor) Expr { 463 e1, changed1 := WalkExpr(v, expr.Expr1) 464 e2, changed2 := WalkExpr(v, expr.Expr2) 465 if changed1 || changed2 { 466 exprCopy := *expr 467 exprCopy.Expr1 = e1 468 exprCopy.Expr2 = e2 469 return &exprCopy 470 } 471 return expr 472 } 473 474 // Walk implements the Expr interface. 475 func (expr *OrExpr) Walk(v Visitor) Expr { 476 left, changedL := WalkExpr(v, expr.Left) 477 right, changedR := WalkExpr(v, expr.Right) 478 if changedL || changedR { 479 exprCopy := *expr 480 exprCopy.Left = left 481 exprCopy.Right = right 482 return &exprCopy 483 } 484 return expr 485 } 486 487 // Walk implements the Expr interface. 488 func (expr *ParenExpr) Walk(v Visitor) Expr { 489 e, changed := WalkExpr(v, expr.Expr) 490 if changed { 491 exprCopy := *expr 492 exprCopy.Expr = e 493 return &exprCopy 494 } 495 return expr 496 } 497 498 // Walk implements the Expr interface. 499 func (expr *RangeCond) Walk(v Visitor) Expr { 500 l, changedL := WalkExpr(v, expr.Left) 501 f, changedF := WalkExpr(v, expr.From) 502 t, changedT := WalkExpr(v, expr.To) 503 if changedL || changedF || changedT { 504 exprCopy := *expr 505 exprCopy.Left = l 506 exprCopy.From = f 507 exprCopy.To = t 508 return &exprCopy 509 } 510 return expr 511 } 512 513 // Walk implements the Expr interface. 514 func (expr *Subquery) Walk(v Visitor) Expr { 515 sel, changed := walkStmt(v, expr.Select) 516 if changed { 517 exprCopy := *expr 518 exprCopy.Select = sel.(SelectStatement) 519 return &exprCopy 520 } 521 return expr 522 } 523 524 // WalkTableExpr implements the TableExpr interface. 525 func (expr *Subquery) WalkTableExpr(v Visitor) TableExpr { 526 sel, changed := walkStmt(v, expr.Select) 527 if changed { 528 exprCopy := *expr 529 exprCopy.Select = sel.(SelectStatement) 530 return &exprCopy 531 } 532 return expr 533 } 534 535 // WalkTableExpr implements the TableExpr interface. 536 func (expr *AliasedTableExpr) WalkTableExpr(v Visitor) TableExpr { 537 newExpr, changed := walkTableExpr(v, expr.Expr) 538 if changed { 539 exprCopy := *expr 540 exprCopy.Expr = newExpr 541 return &exprCopy 542 } 543 return expr 544 } 545 546 // WalkTableExpr implements the TableExpr interface. 547 func (expr *ParenTableExpr) WalkTableExpr(v Visitor) TableExpr { 548 newExpr, changed := walkTableExpr(v, expr.Expr) 549 if changed { 550 exprCopy := *expr 551 exprCopy.Expr = newExpr 552 return &exprCopy 553 } 554 return expr 555 } 556 557 // WalkTableExpr implements the TableExpr interface. 558 func (expr *JoinTableExpr) WalkTableExpr(v Visitor) TableExpr { 559 left, changedL := walkTableExpr(v, expr.Left) 560 right, changedR := walkTableExpr(v, expr.Right) 561 if changedL || changedR { 562 exprCopy := *expr 563 exprCopy.Left = left 564 exprCopy.Right = right 565 return &exprCopy 566 } 567 return expr 568 } 569 570 func (expr *RowsFromExpr) copyNode() *RowsFromExpr { 571 exprCopy := *expr 572 exprCopy.Items = append(Exprs(nil), exprCopy.Items...) 573 return &exprCopy 574 } 575 576 // WalkTableExpr implements the TableExpr interface. 577 func (expr *RowsFromExpr) WalkTableExpr(v Visitor) TableExpr { 578 ret := expr 579 for i := range expr.Items { 580 e, changed := WalkExpr(v, expr.Items[i]) 581 if changed { 582 if ret == expr { 583 ret = expr.copyNode() 584 } 585 ret.Items[i] = e 586 } 587 } 588 return ret 589 } 590 591 // WalkTableExpr implements the TableExpr interface. 592 func (expr *StatementSource) WalkTableExpr(v Visitor) TableExpr { 593 s, changed := walkStmt(v, expr.Statement) 594 if changed { 595 exprCopy := *expr 596 exprCopy.Statement = s 597 return &exprCopy 598 } 599 return expr 600 } 601 602 // WalkTableExpr implements the TableExpr interface. 603 func (expr *TableName) WalkTableExpr(_ Visitor) TableExpr { return expr } 604 605 // WalkTableExpr implements the TableExpr interface. 606 func (expr *TableRef) WalkTableExpr(_ Visitor) TableExpr { return expr } 607 608 // WalkTableExpr implements the TableExpr interface. 609 func (expr *UnresolvedObjectName) WalkTableExpr(_ Visitor) TableExpr { return expr } 610 611 // Walk implements the Expr interface. 612 func (expr *UnaryExpr) Walk(v Visitor) Expr { 613 e, changed := WalkExpr(v, expr.Expr) 614 if changed { 615 exprCopy := *expr 616 exprCopy.Expr = e 617 return &exprCopy 618 } 619 return expr 620 } 621 622 func walkExprSlice(v Visitor, slice []Expr) ([]Expr, bool) { 623 copied := false 624 for i := range slice { 625 e, changed := WalkExpr(v, slice[i]) 626 if changed { 627 if !copied { 628 slice = append([]Expr(nil), slice...) 629 copied = true 630 } 631 slice[i] = e 632 } 633 } 634 return slice, copied 635 } 636 637 func walkKVOptions(v Visitor, opts KVOptions) (KVOptions, bool) { 638 copied := false 639 for i := range opts { 640 if opts[i].Value == nil { 641 continue 642 } 643 e, changed := WalkExpr(v, opts[i].Value) 644 if changed { 645 if !copied { 646 opts = append(KVOptions(nil), opts...) 647 copied = true 648 } 649 opts[i].Value = e 650 } 651 } 652 return opts, copied 653 } 654 655 // Walk implements the Expr interface. 656 func (expr *Tuple) Walk(v Visitor) Expr { 657 exprs, changed := walkExprSlice(v, expr.Exprs) 658 if changed { 659 exprCopy := *expr 660 exprCopy.Exprs = exprs 661 return &exprCopy 662 } 663 return expr 664 } 665 666 // Walk implements the Expr interface. 667 func (expr *Array) Walk(v Visitor) Expr { 668 if exprs, changed := walkExprSlice(v, expr.Exprs); changed { 669 exprCopy := *expr 670 exprCopy.Exprs = exprs 671 return &exprCopy 672 } 673 return expr 674 } 675 676 // Walk implements the Expr interface. 677 func (expr *DVoid) Walk(_ Visitor) Expr { return expr } 678 679 // Walk implements the Expr interface. 680 func (expr *ArrayFlatten) Walk(v Visitor) Expr { 681 if sq, changed := WalkExpr(v, expr.Subquery); changed { 682 exprCopy := *expr 683 exprCopy.Subquery = sq 684 return &exprCopy 685 } 686 return expr 687 } 688 689 // Walk implements the Expr interface. 690 func (expr UnqualifiedStar) Walk(_ Visitor) Expr { return expr } 691 692 // Walk implements the Expr interface. 693 func (expr *UnresolvedName) Walk(_ Visitor) Expr { return expr } 694 695 // Walk implements the Expr interface. 696 func (expr *AllColumnsSelector) Walk(_ Visitor) Expr { return expr } 697 698 // Walk implements the Expr interface. 699 func (expr *ColumnItem) Walk(_ Visitor) Expr { 700 // TODO(knz): When ARRAY is supported, this must be extended 701 // to recurse into the index expressions of the ColumnItems' Selector. 702 return expr 703 } 704 705 // Walk implements the Expr interface. 706 func (expr DefaultVal) Walk(_ Visitor) Expr { return expr } 707 708 // Walk implements the Expr interface. 709 func (expr PartitionMaxVal) Walk(_ Visitor) Expr { return expr } 710 711 // Walk implements the Expr interface. 712 func (expr PartitionMinVal) Walk(_ Visitor) Expr { return expr } 713 714 // Walk implements the Expr interface. 715 func (expr *NumVal) Walk(_ Visitor) Expr { return expr } 716 717 // Walk implements the Expr interface. 718 func (expr *StrVal) Walk(_ Visitor) Expr { return expr } 719 720 // Walk implements the Expr interface. 721 func (expr *Placeholder) Walk(_ Visitor) Expr { return expr } 722 723 // Walk implements the Expr interface. 724 func (expr *DBitArray) Walk(_ Visitor) Expr { return expr } 725 726 // Walk implements the Expr interface. 727 func (expr *DBool) Walk(_ Visitor) Expr { return expr } 728 729 // Walk implements the Expr interface. 730 func (expr *DBytes) Walk(_ Visitor) Expr { return expr } 731 732 // Walk implements the Expr interface. 733 func (expr *DEncodedKey) Walk(_ Visitor) Expr { return expr } 734 735 // Walk implements the Expr interface. 736 func (expr *DDate) Walk(_ Visitor) Expr { return expr } 737 738 // Walk implements the Expr interface. 739 func (expr *DTime) Walk(_ Visitor) Expr { return expr } 740 741 // Walk implements the Expr interface. 742 func (expr *DTimeTZ) Walk(_ Visitor) Expr { return expr } 743 744 // Walk implements the Expr interface. 745 func (expr *DFloat) Walk(_ Visitor) Expr { return expr } 746 747 // Walk implements the Expr interface. 748 func (expr *DEnum) Walk(_ Visitor) Expr { return expr } 749 750 // Walk implements the Expr interface. 751 func (expr *DDecimal) Walk(_ Visitor) Expr { return expr } 752 753 // Walk implements the Expr interface. 754 func (expr *DInt) Walk(_ Visitor) Expr { return expr } 755 756 // Walk implements the Expr interface. 757 func (expr *DInterval) Walk(_ Visitor) Expr { return expr } 758 759 // Walk implements the Expr interface. 760 func (expr *DBox2D) Walk(_ Visitor) Expr { return expr } 761 762 // Walk implements the Expr interface. 763 func (expr *DPGLSN) Walk(_ Visitor) Expr { return expr } 764 765 // Walk implements the Expr interface. 766 func (expr *DGeography) Walk(_ Visitor) Expr { return expr } 767 768 // Walk implements the Expr interface. 769 func (expr *DGeometry) Walk(_ Visitor) Expr { return expr } 770 771 // Walk implements the Expr interface. 772 func (expr *DJSON) Walk(_ Visitor) Expr { return expr } 773 774 // Walk implements the Expr interface. 775 func (expr *DTSQuery) Walk(_ Visitor) Expr { return expr } 776 777 // Walk implements the Expr interface. 778 func (expr *DTSVector) Walk(_ Visitor) Expr { return expr } 779 780 // Walk implements the Expr interface. 781 func (expr *DUuid) Walk(_ Visitor) Expr { return expr } 782 783 // Walk implements the Expr interface. 784 func (expr *DIPAddr) Walk(_ Visitor) Expr { return expr } 785 786 // Walk implements the Expr interface. 787 func (expr dNull) Walk(_ Visitor) Expr { return expr } 788 789 // Walk implements the Expr interface. 790 func (expr *DString) Walk(_ Visitor) Expr { return expr } 791 792 // Walk implements the Expr interface. 793 func (expr *DCollatedString) Walk(_ Visitor) Expr { return expr } 794 795 // Walk implements the Expr interface. 796 func (expr *DTimestamp) Walk(_ Visitor) Expr { return expr } 797 798 // Walk implements the Expr interface. 799 func (expr *DTimestampTZ) Walk(_ Visitor) Expr { return expr } 800 801 // Walk implements the Expr interface. 802 func (expr *DTuple) Walk(v Visitor) Expr { 803 for _, d := range expr.D { 804 // Datums never get changed by visitors, so we don't need to 805 // look for changed elements. 806 d.Walk(v) 807 } 808 return expr 809 } 810 811 // Walk implements the Expr interface. 812 func (expr *DArray) Walk(v Visitor) Expr { 813 for _, d := range expr.Array { 814 // Datums never get changed by visitors, so we don't need to 815 // look for changed elements. 816 d.Walk(v) 817 } 818 return expr 819 } 820 821 // Walk implements the Expr interface. 822 func (expr *DOid) Walk(_ Visitor) Expr { return expr } 823 824 // Walk implements the Expr interface. 825 func (expr *DOidWrapper) Walk(_ Visitor) Expr { return expr } 826 827 // WalkExpr traverses the nodes in an expression. 828 // 829 // NOTE: Do not count on the walkStmt/WalkExpr machinery to visit all 830 // expressions contained in a query. Only a sub-set of all expressions are 831 // found by walkStmt and subsequently traversed. See the comment below on 832 // walkStmt for details. 833 func WalkExpr(v Visitor, expr Expr) (newExpr Expr, changed bool) { 834 recurse, newExpr := v.VisitPre(expr) 835 836 if recurse { 837 newExpr = newExpr.Walk(v) 838 newExpr = v.VisitPost(newExpr) 839 } 840 841 // We cannot use == because some Expr implementations are not comparable (e.g. DTuple) 842 return newExpr, (reflect.ValueOf(expr) != reflect.ValueOf(newExpr)) 843 } 844 845 func walkTableExpr(v Visitor, expr TableExpr) (newExpr TableExpr, changed bool) { 846 newExpr = expr.WalkTableExpr(v) 847 return newExpr, (reflect.ValueOf(expr) != reflect.ValueOf(newExpr)) 848 } 849 850 // WalkExprConst is a variant of WalkExpr for visitors that do not modify the expression. 851 func WalkExprConst(v Visitor, expr Expr) { 852 WalkExpr(v, expr) 853 // TODO(radu): we should verify that WalkExpr returns changed == false. Unfortunately that 854 // is not the case today because walking through non-pointer implementations of Expr (like 855 // DBool, DTuple) causes new nodes to be created. We should make all Expr implementations be 856 // pointers (which will also remove the need for using reflect.ValueOf above). 857 } 858 859 // walkableStmt is implemented by statements that can appear inside an expression (selects) or 860 // we want to start a walk from (using walkStmt). 861 type walkableStmt interface { 862 Statement 863 walkStmt(Visitor) Statement 864 } 865 866 func walkReturningClause(v Visitor, clause ReturningClause) (ReturningClause, bool) { 867 switch t := clause.(type) { 868 case *ReturningExprs: 869 ret := t 870 for i, expr := range *t { 871 e, changed := WalkExpr(v, expr.Expr) 872 if changed { 873 if ret == t { 874 ret = t.copyNode() 875 } 876 (*ret)[i].Expr = e 877 } 878 } 879 return ret, (ret != t) 880 case *ReturningNothing, *NoReturningClause: 881 return t, false 882 default: 883 panic(errors.AssertionFailedf("unexpected ReturningClause type: %T", t)) 884 } 885 } 886 887 // copyNode makes a copy of this clause without recursing in any child clause. 888 func (ts *TenantSpec) copyNode() *TenantSpec { 889 tsCopy := *ts 890 return &tsCopy 891 } 892 893 func walkTenantSpec(v Visitor, ts *TenantSpec) (*TenantSpec, bool) { 894 if ts.Expr == nil { 895 return ts, false 896 } 897 e, changed := WalkExpr(v, ts.Expr) 898 if changed { 899 ret := ts.copyNode() 900 ret.Expr = e 901 return ret, true 902 } 903 return ts, false 904 } 905 906 // copyNode makes a copy of this Statement without recursing in any child Statements. 907 func (n *ShowTenantClusterSetting) copyNode() *ShowTenantClusterSetting { 908 stmtCopy := *n 909 return &stmtCopy 910 } 911 912 // walkStmt is part of the walkableStmt interface. 913 func (n *ShowTenantClusterSetting) walkStmt(v Visitor) Statement { 914 ret := n 915 sc, changed := walkStmt(v, n.ShowClusterSetting) 916 if changed { 917 ret = n.copyNode() 918 ret.ShowClusterSetting = sc.(*ShowClusterSetting) 919 } 920 ts, changed := walkTenantSpec(v, n.TenantSpec) 921 if changed { 922 if ret == n { 923 ret = n.copyNode() 924 } 925 ret.TenantSpec = ts 926 } 927 return ret 928 } 929 930 // copyNode makes a copy of this Statement without recursing in any child Statements. 931 func (n *ShowTenantClusterSettingList) copyNode() *ShowTenantClusterSettingList { 932 stmtCopy := *n 933 return &stmtCopy 934 } 935 936 // walkStmt is part of the walkableStmt interface. 937 func (n *ShowTenantClusterSettingList) walkStmt(v Visitor) Statement { 938 ret := n 939 sc, changed := walkStmt(v, n.ShowClusterSettingList) 940 if changed { 941 ret = n.copyNode() 942 ret.ShowClusterSettingList = sc.(*ShowClusterSettingList) 943 } 944 ts, changed := walkTenantSpec(v, n.TenantSpec) 945 if changed { 946 if ret == n { 947 ret = n.copyNode() 948 } 949 ret.TenantSpec = ts 950 } 951 return ret 952 } 953 954 func (n *AlterTenantCapability) walkStmt(v Visitor) Statement { 955 ret := n 956 copyNodeOnce := func() { 957 if ret == n { 958 stmtCopy := *n 959 ret = &stmtCopy 960 } 961 } 962 for i, capability := range n.Capabilities { 963 value := capability.Value 964 if value != nil { 965 e, changed := WalkExpr(v, value) 966 if changed { 967 copyNodeOnce() 968 ret.Capabilities[i].Value = e 969 } 970 } 971 } 972 ts, changed := walkTenantSpec(v, n.TenantSpec) 973 if changed { 974 copyNodeOnce() 975 ret.TenantSpec = ts 976 } 977 return ret 978 } 979 980 // copyNode makes a copy of this Statement without recursing in any child Statements. 981 func (n *AlterTenantSetClusterSetting) copyNode() *AlterTenantSetClusterSetting { 982 stmtCopy := *n 983 return &stmtCopy 984 } 985 986 // walkStmt is part of the walkableStmt interface. 987 func (n *AlterTenantSetClusterSetting) walkStmt(v Visitor) Statement { 988 ret := n 989 if n.Value != nil { 990 e, changed := WalkExpr(v, n.Value) 991 if changed { 992 ret = n.copyNode() 993 ret.Value = e 994 } 995 } 996 ts, changed := walkTenantSpec(v, n.TenantSpec) 997 if changed { 998 if ret == n { 999 ret = n.copyNode() 1000 } 1001 ret.TenantSpec = ts 1002 } 1003 return ret 1004 } 1005 1006 // copyNode makes a copy of this Statement without recursing in any child Statements. 1007 func (n *AlterTenantReplication) copyNode() *AlterTenantReplication { 1008 stmtCopy := *n 1009 if stmtCopy.Cutover != nil { 1010 cutoverCopy := *stmtCopy.Cutover 1011 stmtCopy.Cutover = &cutoverCopy 1012 } 1013 return &stmtCopy 1014 } 1015 1016 // walkStmt is part of the walkableStmt interface. 1017 func (n *AlterTenantReplication) walkStmt(v Visitor) Statement { 1018 ret := n 1019 ts, changed := walkTenantSpec(v, n.TenantSpec) 1020 if changed { 1021 if ret == n { 1022 ret = n.copyNode() 1023 } 1024 ret.TenantSpec = ts 1025 } 1026 if n.Cutover != nil && n.Cutover.Timestamp != nil { 1027 e, changed := WalkExpr(v, n.Cutover.Timestamp) 1028 if changed { 1029 if ret == n { 1030 ret = n.copyNode() 1031 } 1032 ret.Cutover.Timestamp = e 1033 } 1034 } 1035 if n.Options.Retention != nil { 1036 e, changed := WalkExpr(v, n.Options.Retention) 1037 if changed { 1038 if ret == n { 1039 ret = n.copyNode() 1040 } 1041 ret.Options.Retention = e 1042 } 1043 } 1044 if n.Options.ResumeTimestamp != nil { 1045 e, changed := WalkExpr(v, n.Options.ResumeTimestamp) 1046 if changed { 1047 if ret == n { 1048 ret = n.copyNode() 1049 } 1050 ret.Options.ResumeTimestamp = e 1051 } 1052 } 1053 1054 return ret 1055 } 1056 1057 // copyNode makes a copy of this node without recursing. 1058 func (n *LikeTenantSpec) copyNode() *LikeTenantSpec { 1059 nodeCopy := *n 1060 return &nodeCopy 1061 } 1062 1063 // copyNode makes a copy of this Statement without recursing in any child Statements. 1064 func (n *CreateTenant) copyNode() *CreateTenant { 1065 stmtCopy := *n 1066 return &stmtCopy 1067 } 1068 1069 // walkStmt is part of the walkableStmt interface. 1070 func (n *CreateTenant) walkStmt(v Visitor) Statement { 1071 ret := n 1072 if n.Like.OtherTenant != nil { 1073 ts, changed := walkTenantSpec(v, n.TenantSpec) 1074 if changed { 1075 if ret == n { 1076 ret = n.copyNode() 1077 } 1078 ret.Like = n.Like.copyNode() 1079 ret.Like.OtherTenant = ts 1080 } 1081 } 1082 return ret 1083 } 1084 1085 // copyNode makes a copy of this Statement without recursing in any child Statements. 1086 func (n *CreateTenantFromReplication) copyNode() *CreateTenantFromReplication { 1087 stmtCopy := *n 1088 return &stmtCopy 1089 } 1090 1091 // walkStmt is part of the walkableStmt interface. 1092 func (n *CreateTenantFromReplication) walkStmt(v Visitor) Statement { 1093 ret := n 1094 e, changed := WalkExpr(v, n.ReplicationSourceTenantName.Expr) 1095 if changed { 1096 if ret == n { 1097 ret = n.copyNode() 1098 } 1099 ret.ReplicationSourceTenantName = &TenantSpec{IsName: true, Expr: e} 1100 } 1101 e, changed = WalkExpr(v, n.ReplicationSourceAddress) 1102 if changed { 1103 if ret == n { 1104 ret = n.copyNode() 1105 } 1106 ret.ReplicationSourceAddress = e 1107 } 1108 if n.Options.Retention != nil { 1109 e, changed := WalkExpr(v, n.Options.Retention) 1110 if changed { 1111 if ret == n { 1112 ret = n.copyNode() 1113 } 1114 ret.Options.Retention = e 1115 } 1116 } 1117 if n.Options.ResumeTimestamp != nil { 1118 e, changed := WalkExpr(v, n.Options.ResumeTimestamp) 1119 if changed { 1120 if ret == n { 1121 ret = n.copyNode() 1122 } 1123 ret.Options.ResumeTimestamp = e 1124 } 1125 } 1126 1127 if n.Like.OtherTenant != nil { 1128 ts, changed := walkTenantSpec(v, n.TenantSpec) 1129 if changed { 1130 if ret == n { 1131 ret = n.copyNode() 1132 } 1133 ret.Like = n.Like.copyNode() 1134 ret.Like.OtherTenant = ts 1135 } 1136 } 1137 return ret 1138 } 1139 1140 // copyNode makes a copy of this Statement without recursing in any child Statements. 1141 func (n *ShowTenant) copyNode() *ShowTenant { 1142 stmtCopy := *n 1143 return &stmtCopy 1144 } 1145 1146 // walkStmt is part of the walkableStmt interface. 1147 func (n *ShowTenant) walkStmt(v Visitor) Statement { 1148 ret := n 1149 ts, changed := walkTenantSpec(v, n.TenantSpec) 1150 if changed { 1151 if ret == n { 1152 ret = n.copyNode() 1153 } 1154 ret.TenantSpec = ts 1155 } 1156 return ret 1157 } 1158 1159 // copyNode makes a copy of this Statement without recursing in any child Statements. 1160 func (n *AlterTenantRename) copyNode() *AlterTenantRename { 1161 stmtCopy := *n 1162 return &stmtCopy 1163 } 1164 1165 // walkStmt is part of the walkableStmt interface. 1166 func (n *AlterTenantRename) walkStmt(v Visitor) Statement { 1167 ret := n 1168 ts, changed := walkTenantSpec(v, n.TenantSpec) 1169 if changed { 1170 if ret == n { 1171 ret = n.copyNode() 1172 } 1173 ret.TenantSpec = ts 1174 } 1175 ts, changed = walkTenantSpec(v, n.NewName) 1176 if changed { 1177 if ret == n { 1178 ret = n.copyNode() 1179 } 1180 ret.NewName = ts 1181 } 1182 return ret 1183 } 1184 1185 // copyNode makes a copy of this Statement without recursing in any child Statements. 1186 func (n *AlterTenantService) copyNode() *AlterTenantService { 1187 stmtCopy := *n 1188 return &stmtCopy 1189 } 1190 1191 // walkStmt is part of the walkableStmt interface. 1192 func (n *AlterTenantService) walkStmt(v Visitor) Statement { 1193 ret := n 1194 ts, changed := walkTenantSpec(v, n.TenantSpec) 1195 if changed { 1196 if ret == n { 1197 ret = n.copyNode() 1198 } 1199 ret.TenantSpec = ts 1200 } 1201 return ret 1202 } 1203 1204 // copyNode makes a copy of this Statement without recursing in any child Statements. 1205 func (n *DropTenant) copyNode() *DropTenant { 1206 stmtCopy := *n 1207 return &stmtCopy 1208 } 1209 1210 // walkStmt is part of the walkableStmt interface. 1211 func (n *DropTenant) walkStmt(v Visitor) Statement { 1212 ret := n 1213 ts, changed := walkTenantSpec(v, n.TenantSpec) 1214 if changed { 1215 if ret == n { 1216 ret = n.copyNode() 1217 } 1218 ret.TenantSpec = ts 1219 } 1220 return ret 1221 } 1222 1223 // copyNode makes a copy of this Statement without recursing in any child Statements. 1224 func (stmt *Backup) copyNode() *Backup { 1225 stmtCopy := *stmt 1226 stmtCopy.IncrementalFrom = append(Exprs(nil), stmt.IncrementalFrom...) 1227 return &stmtCopy 1228 } 1229 1230 // walkStmt is part of the walkableStmt interface. 1231 func (stmt *Backup) walkStmt(v Visitor) Statement { 1232 ret := stmt 1233 if stmt.AsOf.Expr != nil { 1234 e, changed := WalkExpr(v, stmt.AsOf.Expr) 1235 if changed { 1236 if ret == stmt { 1237 ret = stmt.copyNode() 1238 } 1239 ret.AsOf.Expr = e 1240 } 1241 } 1242 for i, expr := range stmt.To { 1243 e, changed := WalkExpr(v, expr) 1244 if changed { 1245 if ret == stmt { 1246 ret = stmt.copyNode() 1247 } 1248 ret.To[i] = e 1249 } 1250 } 1251 for i, expr := range stmt.IncrementalFrom { 1252 e, changed := WalkExpr(v, expr) 1253 if changed { 1254 if ret == stmt { 1255 ret = stmt.copyNode() 1256 } 1257 ret.IncrementalFrom[i] = e 1258 } 1259 } 1260 if stmt.Options.EncryptionPassphrase != nil { 1261 pw, changed := WalkExpr(v, stmt.Options.EncryptionPassphrase) 1262 if changed { 1263 if ret == stmt { 1264 ret = stmt.copyNode() 1265 } 1266 ret.Options.EncryptionPassphrase = pw 1267 } 1268 } 1269 if stmt.Options.CaptureRevisionHistory != nil { 1270 rh, changed := WalkExpr(v, stmt.Options.CaptureRevisionHistory) 1271 if changed { 1272 if ret == stmt { 1273 ret = stmt.copyNode() 1274 } 1275 ret.Options.CaptureRevisionHistory = rh 1276 } 1277 } 1278 1279 if stmt.Options.IncludeAllSecondaryTenants != nil { 1280 include, changed := WalkExpr(v, stmt.Options.IncludeAllSecondaryTenants) 1281 if changed { 1282 if ret == stmt { 1283 ret = stmt.copyNode() 1284 } 1285 ret.Options.IncludeAllSecondaryTenants = include 1286 } 1287 } 1288 1289 if stmt.Options.ExecutionLocality != nil { 1290 rh, changed := WalkExpr(v, stmt.Options.ExecutionLocality) 1291 if changed { 1292 if ret == stmt { 1293 ret = stmt.copyNode() 1294 } 1295 ret.Options.ExecutionLocality = rh 1296 } 1297 } 1298 1299 return ret 1300 } 1301 1302 // copyNode makes a copy of this Statement without recursing in any child Statements. 1303 func (stmt *Delete) copyNode() *Delete { 1304 stmtCopy := *stmt 1305 if stmt.Where != nil { 1306 wCopy := *stmt.Where 1307 stmtCopy.Where = &wCopy 1308 } 1309 return &stmtCopy 1310 } 1311 1312 // walkStmt is part of the walkableStmt interface. 1313 func (stmt *Delete) walkStmt(v Visitor) Statement { 1314 ret := stmt 1315 if stmt.Where != nil { 1316 e, changed := WalkExpr(v, stmt.Where.Expr) 1317 if changed { 1318 ret = stmt.copyNode() 1319 ret.Where.Expr = e 1320 } 1321 } 1322 returning, changed := walkReturningClause(v, stmt.Returning) 1323 if changed { 1324 if ret == stmt { 1325 ret = stmt.copyNode() 1326 } 1327 ret.Returning = returning 1328 } 1329 return ret 1330 } 1331 1332 // copyNode makes a copy of this Statement without recursing in any child Statements. 1333 func (stmt *Explain) copyNode() *Explain { 1334 stmtCopy := *stmt 1335 return &stmtCopy 1336 } 1337 1338 // walkStmt is part of the walkableStmt interface. 1339 func (stmt *Explain) walkStmt(v Visitor) Statement { 1340 s, changed := walkStmt(v, stmt.Statement) 1341 if changed { 1342 stmt = stmt.copyNode() 1343 stmt.Statement = s 1344 } 1345 return stmt 1346 } 1347 1348 // copyNode makes a copy of this Statement without recursing in any child Statements. 1349 func (stmt *ExplainAnalyze) copyNode() *ExplainAnalyze { 1350 stmtCopy := *stmt 1351 return &stmtCopy 1352 } 1353 1354 // walkStmt is part of the walkableStmt interface. 1355 func (stmt *ExplainAnalyze) walkStmt(v Visitor) Statement { 1356 s, changed := walkStmt(v, stmt.Statement) 1357 if changed { 1358 stmt = stmt.copyNode() 1359 stmt.Statement = s 1360 } 1361 return stmt 1362 } 1363 1364 // copyNode makes a copy of this Statement without recursing in any child Statements. 1365 func (stmt *Insert) copyNode() *Insert { 1366 stmtCopy := *stmt 1367 return &stmtCopy 1368 } 1369 1370 // walkStmt is part of the walkableStmt interface. 1371 func (stmt *Insert) walkStmt(v Visitor) Statement { 1372 ret := stmt 1373 if stmt.Rows != nil { 1374 rows, changed := walkStmt(v, stmt.Rows) 1375 if changed { 1376 ret = stmt.copyNode() 1377 ret.Rows = rows.(*Select) 1378 } 1379 } 1380 returning, changed := walkReturningClause(v, stmt.Returning) 1381 if changed { 1382 if ret == stmt { 1383 ret = stmt.copyNode() 1384 } 1385 ret.Returning = returning 1386 } 1387 // TODO(dan): Walk OnConflict once the ON CONFLICT DO UPDATE form of upsert is 1388 // implemented. 1389 return ret 1390 } 1391 1392 // copyNode makes a copy of this Statement without recursing in any child Statements. 1393 func (stmt *CreateTable) copyNode() *CreateTable { 1394 stmtCopy := *stmt 1395 return &stmtCopy 1396 } 1397 1398 // walkStmt is part of the walkableStmt interface. 1399 func (stmt *CreateTable) walkStmt(v Visitor) Statement { 1400 ret := stmt 1401 if stmt.AsSource != nil { 1402 rows, changed := walkStmt(v, stmt.AsSource) 1403 if changed { 1404 ret = stmt.copyNode() 1405 ret.AsSource = rows.(*Select) 1406 } 1407 } 1408 return ret 1409 } 1410 1411 // copyNode makes a copy of this Statement without recursing in any child Statements. 1412 func (stmt *CancelQueries) copyNode() *CancelQueries { 1413 stmtCopy := *stmt 1414 return &stmtCopy 1415 } 1416 1417 // walkStmt is part of the walkableStmt interface. 1418 func (stmt *CancelQueries) walkStmt(v Visitor) Statement { 1419 sel, changed := walkStmt(v, stmt.Queries) 1420 if changed { 1421 stmt = stmt.copyNode() 1422 stmt.Queries = sel.(*Select) 1423 } 1424 return stmt 1425 } 1426 1427 // copyNode makes a copy of this Statement without recursing in any child Statements. 1428 func (stmt *CancelSessions) copyNode() *CancelSessions { 1429 stmtCopy := *stmt 1430 return &stmtCopy 1431 } 1432 1433 // walkStmt is part of the walkableStmt interface. 1434 func (stmt *CancelSessions) walkStmt(v Visitor) Statement { 1435 sel, changed := walkStmt(v, stmt.Sessions) 1436 if changed { 1437 stmt = stmt.copyNode() 1438 stmt.Sessions = sel.(*Select) 1439 } 1440 return stmt 1441 } 1442 1443 // copyNode makes a copy of this Statement without recursing in any child Statements. 1444 func (stmt *ControlJobs) copyNode() *ControlJobs { 1445 stmtCopy := *stmt 1446 return &stmtCopy 1447 } 1448 1449 // walkStmt is part of the walkableStmt interface. 1450 func (stmt *ControlJobs) walkStmt(v Visitor) Statement { 1451 sel, changed := walkStmt(v, stmt.Jobs) 1452 if changed { 1453 stmt = stmt.copyNode() 1454 stmt.Jobs = sel.(*Select) 1455 } 1456 return stmt 1457 } 1458 1459 // copyNode makes a copy of this Statement without recursing in any child Statements. 1460 func (n *ControlSchedules) copyNode() *ControlSchedules { 1461 stmtCopy := *n 1462 return &stmtCopy 1463 } 1464 1465 // walkStmt is part of the walkableStmt interface. 1466 func (n *ControlSchedules) walkStmt(v Visitor) Statement { 1467 sel, changed := walkStmt(v, n.Schedules) 1468 if changed { 1469 n = n.copyNode() 1470 n.Schedules = sel.(*Select) 1471 } 1472 return n 1473 } 1474 1475 // copyNode makes a copy of this Statement without recursing in any child Statements. 1476 func (stmt *Import) copyNode() *Import { 1477 stmtCopy := *stmt 1478 stmtCopy.Files = append(Exprs(nil), stmt.Files...) 1479 stmtCopy.Options = append(KVOptions(nil), stmt.Options...) 1480 return &stmtCopy 1481 } 1482 1483 // walkStmt is part of the walkableStmt interface. 1484 func (stmt *Import) walkStmt(v Visitor) Statement { 1485 ret := stmt 1486 for i, expr := range stmt.Files { 1487 e, changed := WalkExpr(v, expr) 1488 if changed { 1489 if ret == stmt { 1490 ret = stmt.copyNode() 1491 } 1492 ret.Files[i] = e 1493 } 1494 } 1495 { 1496 opts, changed := walkKVOptions(v, stmt.Options) 1497 if changed { 1498 if ret == stmt { 1499 ret = stmt.copyNode() 1500 } 1501 ret.Options = opts 1502 } 1503 } 1504 return ret 1505 } 1506 1507 // walkStmt is part of the walkableStmt interface. 1508 func (stmt *ParenSelect) walkStmt(v Visitor) Statement { 1509 sel, changed := walkStmt(v, stmt.Select) 1510 if changed { 1511 return &ParenSelect{sel.(*Select)} 1512 } 1513 return stmt 1514 } 1515 1516 // copyNode makes a copy of this Statement without recursing in any child Statements. 1517 func (stmt *Restore) copyNode() *Restore { 1518 stmtCopy := *stmt 1519 stmtCopy.From = append([]StringOrPlaceholderOptList(nil), stmt.From...) 1520 return &stmtCopy 1521 } 1522 1523 // walkStmt is part of the walkableStmt interface. 1524 func (stmt *Restore) walkStmt(v Visitor) Statement { 1525 ret := stmt 1526 if stmt.AsOf.Expr != nil { 1527 e, changed := WalkExpr(v, stmt.AsOf.Expr) 1528 if changed { 1529 if ret == stmt { 1530 ret = stmt.copyNode() 1531 } 1532 ret.AsOf.Expr = e 1533 } 1534 } 1535 for i, backup := range stmt.From { 1536 for j, expr := range backup { 1537 e, changed := WalkExpr(v, expr) 1538 if changed { 1539 if ret == stmt { 1540 ret = stmt.copyNode() 1541 } 1542 ret.From[i][j] = e 1543 } 1544 } 1545 } 1546 1547 if stmt.Options.EncryptionPassphrase != nil { 1548 pw, changed := WalkExpr(v, stmt.Options.EncryptionPassphrase) 1549 if changed { 1550 if ret == stmt { 1551 ret = stmt.copyNode() 1552 } 1553 ret.Options.EncryptionPassphrase = pw 1554 } 1555 } 1556 1557 if stmt.Options.IntoDB != nil { 1558 intoDB, changed := WalkExpr(v, stmt.Options.IntoDB) 1559 if changed { 1560 if ret == stmt { 1561 ret = stmt.copyNode() 1562 } 1563 ret.Options.IntoDB = intoDB 1564 } 1565 } 1566 1567 if stmt.Options.IncludeAllSecondaryTenants != nil { 1568 include, changed := WalkExpr(v, stmt.Options.IncludeAllSecondaryTenants) 1569 if changed { 1570 if ret == stmt { 1571 ret = stmt.copyNode() 1572 } 1573 ret.Options.IncludeAllSecondaryTenants = include 1574 } 1575 } 1576 1577 if stmt.Options.ExecutionLocality != nil { 1578 include, changed := WalkExpr(v, stmt.Options.ExecutionLocality) 1579 if changed { 1580 if ret == stmt { 1581 ret = stmt.copyNode() 1582 } 1583 ret.Options.ExecutionLocality = include 1584 } 1585 } 1586 1587 return ret 1588 } 1589 1590 // copyNode makes a copy of this Statement without recursing in any child Statements. 1591 func (stmt *ReturningExprs) copyNode() *ReturningExprs { 1592 stmtCopy := append(ReturningExprs(nil), *stmt...) 1593 return &stmtCopy 1594 } 1595 1596 func walkOrderBy(v Visitor, order OrderBy) (OrderBy, bool) { 1597 copied := false 1598 for i := range order { 1599 if order[i].OrderType != OrderByColumn { 1600 continue 1601 } 1602 e, changed := WalkExpr(v, order[i].Expr) 1603 if changed { 1604 if !copied { 1605 order = append(OrderBy(nil), order...) 1606 copied = true 1607 } 1608 orderByCopy := *order[i] 1609 orderByCopy.Expr = e 1610 order[i] = &orderByCopy 1611 } 1612 } 1613 return order, copied 1614 } 1615 1616 // copyNode makes a copy of this Statement without recursing in any child Statements. 1617 func (stmt *Select) copyNode() *Select { 1618 stmtCopy := *stmt 1619 if stmt.Limit != nil { 1620 lCopy := *stmt.Limit 1621 stmtCopy.Limit = &lCopy 1622 } 1623 if stmt.With != nil { 1624 withCopy := *stmt.With 1625 stmtCopy.With = &withCopy 1626 cteList := make([]CTE, len(stmt.With.CTEList)) 1627 stmtCopy.With.CTEList = make([]*CTE, len(stmt.With.CTEList)) 1628 for i, cte := range stmt.With.CTEList { 1629 cteList[i] = *cte 1630 stmtCopy.With.CTEList[i] = &cteList[i] 1631 } 1632 } 1633 return &stmtCopy 1634 } 1635 1636 func (n *CopyTo) walkStmt(v Visitor) Statement { 1637 if newStmt, changed := walkStmt(v, n.Statement); changed { 1638 // Make a copy of the CopyTo statement. 1639 stmtCopy := *n 1640 ret := &(stmtCopy) 1641 ret.Statement = newStmt 1642 } 1643 return n 1644 } 1645 1646 // walkStmt is part of the walkableStmt interface. 1647 func (stmt *Select) walkStmt(v Visitor) Statement { 1648 ret := stmt 1649 sel, changed := walkStmt(v, stmt.Select) 1650 if changed { 1651 ret = stmt.copyNode() 1652 ret.Select = sel.(SelectStatement) 1653 } 1654 order, changed := walkOrderBy(v, stmt.OrderBy) 1655 if changed { 1656 if ret == stmt { 1657 ret = stmt.copyNode() 1658 } 1659 ret.OrderBy = order 1660 } 1661 if stmt.Limit != nil { 1662 if stmt.Limit.Offset != nil { 1663 e, changed := WalkExpr(v, stmt.Limit.Offset) 1664 if changed { 1665 if ret == stmt { 1666 ret = stmt.copyNode() 1667 } 1668 ret.Limit.Offset = e 1669 } 1670 } 1671 if stmt.Limit.Count != nil { 1672 e, changed := WalkExpr(v, stmt.Limit.Count) 1673 if changed { 1674 if ret == stmt { 1675 ret = stmt.copyNode() 1676 } 1677 ret.Limit.Count = e 1678 } 1679 } 1680 } 1681 if stmt.With != nil { 1682 for i := range stmt.With.CTEList { 1683 if stmt.With.CTEList[i] != nil { 1684 withStmt, changed := walkStmt(v, stmt.With.CTEList[i].Stmt) 1685 if changed { 1686 if ret == stmt { 1687 ret = stmt.copyNode() 1688 } 1689 ret.With.CTEList[i].Stmt = withStmt 1690 } 1691 } 1692 } 1693 } 1694 1695 return ret 1696 } 1697 1698 // copyNode makes a copy of this Statement without recursing in any child Statements. 1699 func (stmt *SelectClause) copyNode() *SelectClause { 1700 stmtCopy := *stmt 1701 stmtCopy.Exprs = append(SelectExprs(nil), stmt.Exprs...) 1702 stmtCopy.From = From{ 1703 Tables: append(TableExprs(nil), stmt.From.Tables...), 1704 AsOf: stmt.From.AsOf, 1705 } 1706 if stmt.Where != nil { 1707 wCopy := *stmt.Where 1708 stmtCopy.Where = &wCopy 1709 } 1710 stmtCopy.GroupBy = append(GroupBy(nil), stmt.GroupBy...) 1711 if stmt.Having != nil { 1712 hCopy := *stmt.Having 1713 stmtCopy.Having = &hCopy 1714 } 1715 stmtCopy.Window = append(Window(nil), stmt.Window...) 1716 stmtCopy.DistinctOn = append(DistinctOn(nil), stmt.DistinctOn...) 1717 return &stmtCopy 1718 } 1719 1720 // walkStmt is part of the walkableStmt interface. 1721 func (stmt *SelectClause) walkStmt(v Visitor) Statement { 1722 ret := stmt 1723 1724 for i, expr := range stmt.Exprs { 1725 e, changed := WalkExpr(v, expr.Expr) 1726 if changed { 1727 if ret == stmt { 1728 ret = stmt.copyNode() 1729 } 1730 ret.Exprs[i].Expr = e 1731 } 1732 } 1733 1734 if stmt.From.AsOf.Expr != nil { 1735 e, changed := WalkExpr(v, stmt.From.AsOf.Expr) 1736 if changed { 1737 if ret == stmt { 1738 ret = stmt.copyNode() 1739 } 1740 ret.From.AsOf.Expr = e 1741 } 1742 } 1743 1744 if stmt.Where != nil { 1745 e, changed := WalkExpr(v, stmt.Where.Expr) 1746 if changed { 1747 if ret == stmt { 1748 ret = stmt.copyNode() 1749 } 1750 ret.Where.Expr = e 1751 } 1752 } 1753 1754 for i, expr := range stmt.GroupBy { 1755 e, changed := WalkExpr(v, expr) 1756 if changed { 1757 if ret == stmt { 1758 ret = stmt.copyNode() 1759 } 1760 ret.GroupBy[i] = e 1761 } 1762 } 1763 1764 if stmt.Having != nil { 1765 e, changed := WalkExpr(v, stmt.Having.Expr) 1766 if changed { 1767 if ret == stmt { 1768 ret = stmt.copyNode() 1769 } 1770 ret.Having.Expr = e 1771 } 1772 } 1773 1774 for i := range stmt.Window { 1775 w, changed := walkWindowDef(v, stmt.Window[i]) 1776 if changed { 1777 if ret == stmt { 1778 ret = stmt.copyNode() 1779 } 1780 ret.Window[i] = w 1781 } 1782 } 1783 1784 for i := range stmt.From.Tables { 1785 t, changed := walkTableExpr(v, stmt.From.Tables[i]) 1786 if changed { 1787 if ret == stmt { 1788 ret = stmt.copyNode() 1789 } 1790 ret.From.Tables[i] = t 1791 } 1792 } 1793 1794 for i := range stmt.DistinctOn { 1795 e, changed := WalkExpr(v, stmt.DistinctOn[i]) 1796 if changed { 1797 if ret == stmt { 1798 ret = stmt.copyNode() 1799 } 1800 ret.DistinctOn[i] = e 1801 } 1802 } 1803 1804 return ret 1805 } 1806 1807 func (stmt *UnionClause) walkStmt(v Visitor) Statement { 1808 left, changedL := walkStmt(v, stmt.Left) 1809 right, changedR := walkStmt(v, stmt.Right) 1810 if changedL || changedR { 1811 stmtCopy := *stmt 1812 stmtCopy.Left = left.(*Select) 1813 stmtCopy.Right = right.(*Select) 1814 return &stmtCopy 1815 } 1816 return stmt 1817 } 1818 1819 // copyNode makes a copy of this Statement without recursing in any child Statements. 1820 func (stmt *SetVar) copyNode() *SetVar { 1821 stmtCopy := *stmt 1822 stmtCopy.Values = append(Exprs(nil), stmt.Values...) 1823 return &stmtCopy 1824 } 1825 1826 // walkStmt is part of the walkableStmt interface. 1827 func (stmt *SetVar) walkStmt(v Visitor) Statement { 1828 ret := stmt 1829 for i, expr := range stmt.Values { 1830 e, changed := WalkExpr(v, expr) 1831 if changed { 1832 if ret == stmt { 1833 ret = stmt.copyNode() 1834 } 1835 ret.Values[i] = e 1836 } 1837 } 1838 return ret 1839 } 1840 1841 // walkStmt is part of the walkableStmt interface. 1842 func (stmt *SetZoneConfig) walkStmt(v Visitor) Statement { 1843 ret := stmt 1844 if stmt.YAMLConfig != nil { 1845 e, changed := WalkExpr(v, stmt.YAMLConfig) 1846 if changed { 1847 newStmt := *stmt 1848 ret = &newStmt 1849 ret.YAMLConfig = e 1850 } 1851 } 1852 if stmt.Options != nil { 1853 newOpts, changed := walkKVOptions(v, stmt.Options) 1854 if changed { 1855 if ret == stmt { 1856 newStmt := *stmt 1857 ret = &newStmt 1858 } 1859 ret.Options = newOpts 1860 } 1861 } 1862 return ret 1863 } 1864 1865 // copyNode makes a copy of this Statement without recursing in any child Statements. 1866 func (stmt *SetTracing) copyNode() *SetTracing { 1867 stmtCopy := *stmt 1868 stmtCopy.Values = append(Exprs(nil), stmt.Values...) 1869 return &stmtCopy 1870 } 1871 1872 // walkStmt is part of the walkableStmt interface. 1873 func (stmt *SetTracing) walkStmt(v Visitor) Statement { 1874 ret := stmt 1875 for i, expr := range stmt.Values { 1876 e, changed := WalkExpr(v, expr) 1877 if changed { 1878 if ret == stmt { 1879 ret = stmt.copyNode() 1880 } 1881 ret.Values[i] = e 1882 } 1883 } 1884 return ret 1885 } 1886 1887 // copyNode makes a copy of this Statement without recursing in any child Statements. 1888 func (stmt *SetClusterSetting) copyNode() *SetClusterSetting { 1889 stmtCopy := *stmt 1890 return &stmtCopy 1891 } 1892 1893 // walkStmt is part of the walkableStmt interface. 1894 func (stmt *SetClusterSetting) walkStmt(v Visitor) Statement { 1895 ret := stmt 1896 if stmt.Value != nil { 1897 e, changed := WalkExpr(v, stmt.Value) 1898 if changed { 1899 ret = stmt.copyNode() 1900 ret.Value = e 1901 } 1902 } 1903 return ret 1904 } 1905 1906 // copyNode makes a copy of this Statement without recursing in any child Statements. 1907 func (stmt *Update) copyNode() *Update { 1908 stmtCopy := *stmt 1909 exprs := make([]UpdateExpr, len(stmt.Exprs)) 1910 stmtCopy.Exprs = make(UpdateExprs, len(stmt.Exprs)) 1911 for i, e := range stmt.Exprs { 1912 exprs[i] = *e 1913 stmtCopy.Exprs[i] = &exprs[i] 1914 } 1915 if stmt.Where != nil { 1916 wCopy := *stmt.Where 1917 stmtCopy.Where = &wCopy 1918 } 1919 return &stmtCopy 1920 } 1921 1922 // walkStmt is part of the walkableStmt interface. 1923 func (stmt *Update) walkStmt(v Visitor) Statement { 1924 ret := stmt 1925 for i, expr := range stmt.Exprs { 1926 e, changed := WalkExpr(v, expr.Expr) 1927 if changed { 1928 if ret == stmt { 1929 ret = stmt.copyNode() 1930 } 1931 ret.Exprs[i].Expr = e 1932 } 1933 } 1934 1935 if stmt.Where != nil { 1936 e, changed := WalkExpr(v, stmt.Where.Expr) 1937 if changed { 1938 if ret == stmt { 1939 ret = stmt.copyNode() 1940 } 1941 ret.Where.Expr = e 1942 } 1943 } 1944 1945 returning, changed := walkReturningClause(v, stmt.Returning) 1946 if changed { 1947 if ret == stmt { 1948 ret = stmt.copyNode() 1949 } 1950 ret.Returning = returning 1951 } 1952 return ret 1953 } 1954 1955 // walkStmt is part of the walkableStmt interface. 1956 func (stmt *ValuesClause) walkStmt(v Visitor) Statement { 1957 ret := stmt 1958 for i, tuple := range stmt.Rows { 1959 exprs, changed := walkExprSlice(v, tuple) 1960 if changed { 1961 if ret == stmt { 1962 ret = &ValuesClause{append([]Exprs(nil), stmt.Rows...)} 1963 } 1964 ret.Rows[i] = exprs 1965 } 1966 } 1967 return ret 1968 } 1969 1970 // copyNode makes a copy of this Statement. 1971 func (stmt *BeginTransaction) copyNode() *BeginTransaction { 1972 stmtCopy := *stmt 1973 return &stmtCopy 1974 } 1975 1976 // walkStmt is part of the walkableStmt interface. 1977 func (stmt *BeginTransaction) walkStmt(v Visitor) Statement { 1978 ret := stmt 1979 if stmt.Modes.AsOf.Expr != nil { 1980 e, changed := WalkExpr(v, stmt.Modes.AsOf.Expr) 1981 if changed { 1982 ret = stmt.copyNode() 1983 ret.Modes.AsOf.Expr = e 1984 } 1985 } 1986 return ret 1987 } 1988 1989 var _ walkableStmt = &AlterTenantCapability{} 1990 var _ walkableStmt = &AlterTenantRename{} 1991 var _ walkableStmt = &AlterTenantReplication{} 1992 var _ walkableStmt = &AlterTenantService{} 1993 var _ walkableStmt = &AlterTenantSetClusterSetting{} 1994 var _ walkableStmt = &Backup{} 1995 var _ walkableStmt = &BeginTransaction{} 1996 var _ walkableStmt = &CancelQueries{} 1997 var _ walkableStmt = &CancelSessions{} 1998 var _ walkableStmt = &ControlJobs{} 1999 var _ walkableStmt = &ControlSchedules{} 2000 var _ walkableStmt = &CreateTable{} 2001 var _ walkableStmt = &CreateTenant{} 2002 var _ walkableStmt = &CreateTenantFromReplication{} 2003 var _ walkableStmt = &Delete{} 2004 var _ walkableStmt = &DropTenant{} 2005 var _ walkableStmt = &Explain{} 2006 var _ walkableStmt = &Import{} 2007 var _ walkableStmt = &Insert{} 2008 var _ walkableStmt = &ParenSelect{} 2009 var _ walkableStmt = &Restore{} 2010 var _ walkableStmt = &SelectClause{} 2011 var _ walkableStmt = &Select{} 2012 var _ walkableStmt = &SetClusterSetting{} 2013 var _ walkableStmt = &SetVar{} 2014 var _ walkableStmt = &ShowTenantClusterSetting{} 2015 var _ walkableStmt = &ShowTenant{} 2016 var _ walkableStmt = &UnionClause{} 2017 var _ walkableStmt = &Update{} 2018 var _ walkableStmt = &ValuesClause{} 2019 2020 // walkStmt walks the entire parsed stmt calling WalkExpr on each 2021 // expression, and replacing each expression with the one returned 2022 // by WalkExpr. 2023 // 2024 // NOTE: Beware that walkStmt does not necessarily traverse all parts of a 2025 // statement by itself. For example, it will not walk into Subquery nodes 2026 // within a FROM clause or into a JoinCond. Walk's logic is pretty 2027 // interdependent with the logic for constructing a query plan. 2028 func walkStmt(v Visitor, stmt Statement) (newStmt Statement, changed bool) { 2029 walkable, ok := stmt.(walkableStmt) 2030 if !ok { 2031 return stmt, false 2032 } 2033 newStmt = walkable.walkStmt(v) 2034 return newStmt, (stmt != newStmt) 2035 } 2036 2037 type simpleVisitor struct { 2038 fn SimpleVisitFn 2039 err error 2040 } 2041 2042 var _ Visitor = &simpleVisitor{} 2043 2044 func (v *simpleVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) { 2045 if v.err != nil { 2046 return false, expr 2047 } 2048 recurse, newExpr, v.err = v.fn(expr) 2049 if v.err != nil { 2050 return false, expr 2051 } 2052 return recurse, newExpr 2053 } 2054 2055 func (*simpleVisitor) VisitPost(expr Expr) Expr { return expr } 2056 2057 // SimpleVisitFn is a function that is run for every node in the VisitPre stage; 2058 // see SimpleVisit. 2059 type SimpleVisitFn func(expr Expr) (recurse bool, newExpr Expr, err error) 2060 2061 // SimpleVisit is a convenience wrapper for visitors that only have VisitPre 2062 // code and don't return any results except an error. The given function is 2063 // called in VisitPre for every node. The visitor stops as soon as an error is 2064 // returned. 2065 func SimpleVisit(expr Expr, preFn SimpleVisitFn) (Expr, error) { 2066 v := simpleVisitor{fn: preFn} 2067 newExpr, _ := WalkExpr(&v, expr) 2068 if v.err != nil { 2069 return nil, v.err 2070 } 2071 return newExpr, nil 2072 } 2073 2074 // SimpleStmtVisit is a convenience wrapper for visitors that want to visit 2075 // all part of a statement, only have VisitPre code and don't return 2076 // any results except an error. The given function is called in VisitPre 2077 // for every node. The visitor stops as soon as an error is returned. 2078 func SimpleStmtVisit(stmt Statement, preFn SimpleVisitFn) (Statement, error) { 2079 v := simpleVisitor{fn: preFn} 2080 newStmt, changed := walkStmt(&v, stmt) 2081 if v.err != nil { 2082 return nil, v.err 2083 } 2084 if changed { 2085 return newStmt, nil 2086 } 2087 return stmt, nil 2088 } 2089 2090 type debugVisitor struct { 2091 buf bytes.Buffer 2092 level int 2093 } 2094 2095 var _ Visitor = &debugVisitor{} 2096 2097 func (v *debugVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) { 2098 v.level++ 2099 fmt.Fprintf(&v.buf, "%*s", 2*v.level, " ") 2100 str := fmt.Sprintf("%#v\n", expr) 2101 // Remove "parser." to make the string more compact. 2102 str = strings.Replace(str, "parser.", "", -1) 2103 v.buf.WriteString(str) 2104 return true, expr 2105 } 2106 2107 func (v *debugVisitor) VisitPost(expr Expr) Expr { 2108 v.level-- 2109 return expr 2110 } 2111 2112 // ExprDebugString generates a multi-line debug string with one node per line in 2113 // Go format. 2114 func ExprDebugString(expr Expr) string { 2115 v := debugVisitor{} 2116 WalkExprConst(&v, expr) 2117 return v.buf.String() 2118 } 2119 2120 // StmtDebugString generates multi-line debug strings in Go format for the 2121 // expressions that are part of the given statement. 2122 func StmtDebugString(stmt Statement) string { 2123 v := debugVisitor{} 2124 walkStmt(&v, stmt) 2125 return v.buf.String() 2126 } 2127 2128 // Silence any warnings if these functions are not used. 2129 var _ = ExprDebugString 2130 var _ = StmtDebugString