github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/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.
    83  	exprCopy.Whens = make([]*When, len(expr.Whens))
    84  	for i, w := range expr.Whens {
    85  		wCopy := *w
    86  		exprCopy.Whens[i] = &wCopy
    87  	}
    88  	return &exprCopy
    89  }
    90  
    91  // Walk implements the Expr interface.
    92  func (expr *CaseExpr) Walk(v Visitor) Expr {
    93  	ret := expr
    94  
    95  	if expr.Expr != nil {
    96  		e, changed := WalkExpr(v, expr.Expr)
    97  		if changed {
    98  			ret = expr.copyNode()
    99  			ret.Expr = e
   100  		}
   101  	}
   102  	for i, w := range expr.Whens {
   103  		cond, changedC := WalkExpr(v, w.Cond)
   104  		val, changedV := WalkExpr(v, w.Val)
   105  		if changedC || changedV {
   106  			if ret == expr {
   107  				ret = expr.copyNode()
   108  			}
   109  			ret.Whens[i].Cond = cond
   110  			ret.Whens[i].Val = val
   111  		}
   112  	}
   113  	if expr.Else != nil {
   114  		e, changed := WalkExpr(v, expr.Else)
   115  		if changed {
   116  			if ret == expr {
   117  				ret = expr.copyNode()
   118  			}
   119  			ret.Else = e
   120  		}
   121  	}
   122  	return ret
   123  }
   124  
   125  // Walk implements the Expr interface.
   126  func (expr *CastExpr) Walk(v Visitor) Expr {
   127  	e, changed := WalkExpr(v, expr.Expr)
   128  	if changed {
   129  		exprCopy := *expr
   130  		exprCopy.Expr = e
   131  		return &exprCopy
   132  	}
   133  	return expr
   134  }
   135  
   136  // Walk implements the Expr interface.
   137  func (expr *CollateExpr) Walk(v Visitor) Expr {
   138  	e, changed := WalkExpr(v, expr.Expr)
   139  	if changed {
   140  		exprCopy := *expr
   141  		exprCopy.Expr = e
   142  		return &exprCopy
   143  	}
   144  	return expr
   145  }
   146  
   147  // Walk implements the Expr interface.
   148  func (expr *ColumnAccessExpr) Walk(v Visitor) Expr {
   149  	e, changed := WalkExpr(v, expr.Expr)
   150  	if changed {
   151  		exprCopy := *expr
   152  		exprCopy.Expr = e
   153  		return &exprCopy
   154  	}
   155  	return expr
   156  }
   157  
   158  // Walk implements the Expr interface.
   159  func (expr *TupleStar) Walk(v Visitor) Expr {
   160  	e, changed := WalkExpr(v, expr.Expr)
   161  	if changed {
   162  		exprCopy := *expr
   163  		exprCopy.Expr = e
   164  		return &exprCopy
   165  	}
   166  	return expr
   167  }
   168  
   169  // copyNode makes a copy of this Expr without recursing in any child Exprs.
   170  func (expr *CoalesceExpr) copyNode() *CoalesceExpr {
   171  	exprCopy := *expr
   172  	return &exprCopy
   173  }
   174  
   175  // Walk implements the Expr interface.
   176  func (expr *CoalesceExpr) Walk(v Visitor) Expr {
   177  	ret := expr
   178  	exprs, changed := walkExprSlice(v, expr.Exprs)
   179  	if changed {
   180  		if ret == expr {
   181  			ret = expr.copyNode()
   182  		}
   183  		ret.Exprs = exprs
   184  	}
   185  	return ret
   186  }
   187  
   188  // Walk implements the Expr interface.
   189  func (expr *ComparisonExpr) Walk(v Visitor) Expr {
   190  	left, changedL := WalkExpr(v, expr.Left)
   191  	right, changedR := WalkExpr(v, expr.Right)
   192  	if changedL || changedR {
   193  		exprCopy := *expr
   194  		exprCopy.Left = left
   195  		exprCopy.Right = right
   196  		return &exprCopy
   197  	}
   198  	return expr
   199  }
   200  
   201  // copyNode makes a copy of this Expr without recursing in any child Exprs.
   202  func (expr *FuncExpr) copyNode() *FuncExpr {
   203  	exprCopy := *expr
   204  	exprCopy.Exprs = append(Exprs(nil), exprCopy.Exprs...)
   205  	return &exprCopy
   206  }
   207  
   208  // copyNode makes a copy of this WindowFrame without recursing.
   209  func (node *WindowFrame) copyNode() *WindowFrame {
   210  	nodeCopy := *node
   211  	return &nodeCopy
   212  }
   213  
   214  func walkWindowFrame(v Visitor, frame *WindowFrame) (*WindowFrame, bool) {
   215  	ret := frame
   216  	if frame.Bounds.StartBound != nil {
   217  		b, changed := walkWindowFrameBound(v, frame.Bounds.StartBound)
   218  		if changed {
   219  			if ret == frame {
   220  				ret = frame.copyNode()
   221  			}
   222  			ret.Bounds.StartBound = b
   223  		}
   224  	}
   225  	if frame.Bounds.EndBound != nil {
   226  		b, changed := walkWindowFrameBound(v, frame.Bounds.EndBound)
   227  		if changed {
   228  			if ret == frame {
   229  				ret = frame.copyNode()
   230  			}
   231  			ret.Bounds.EndBound = b
   232  		}
   233  	}
   234  	return ret, ret != frame
   235  }
   236  
   237  // copyNode makes a copy of this WindowFrameBound without recursing.
   238  func (node *WindowFrameBound) copyNode() *WindowFrameBound {
   239  	nodeCopy := *node
   240  	return &nodeCopy
   241  }
   242  
   243  func walkWindowFrameBound(v Visitor, bound *WindowFrameBound) (*WindowFrameBound, bool) {
   244  	ret := bound
   245  	if bound.HasOffset() {
   246  		e, changed := WalkExpr(v, bound.OffsetExpr)
   247  		if changed {
   248  			if ret == bound {
   249  				ret = bound.copyNode()
   250  			}
   251  			ret.OffsetExpr = e
   252  		}
   253  	}
   254  	return ret, ret != bound
   255  }
   256  
   257  // copyNode makes a copy of this WindowDef without recursing.
   258  func (node *WindowDef) copyNode() *WindowDef {
   259  	nodeCopy := *node
   260  	return &nodeCopy
   261  }
   262  
   263  func walkWindowDef(v Visitor, windowDef *WindowDef) (*WindowDef, bool) {
   264  	ret := windowDef
   265  	if len(windowDef.Partitions) > 0 {
   266  		exprs, changed := walkExprSlice(v, windowDef.Partitions)
   267  		if changed {
   268  			if ret == windowDef {
   269  				ret = windowDef.copyNode()
   270  			}
   271  			ret.Partitions = exprs
   272  		}
   273  	}
   274  	if len(windowDef.OrderBy) > 0 {
   275  		order, changed := walkOrderBy(v, windowDef.OrderBy)
   276  		if changed {
   277  			if ret == windowDef {
   278  				ret = windowDef.copyNode()
   279  			}
   280  			ret.OrderBy = order
   281  		}
   282  	}
   283  	if windowDef.Frame != nil {
   284  		frame, changed := walkWindowFrame(v, windowDef.Frame)
   285  		if changed {
   286  			if ret == windowDef {
   287  				ret = windowDef.copyNode()
   288  			}
   289  			ret.Frame = frame
   290  		}
   291  	}
   292  
   293  	return ret, ret != windowDef
   294  }
   295  
   296  // Walk implements the Expr interface.
   297  func (expr *FuncExpr) Walk(v Visitor) Expr {
   298  	ret := expr
   299  	exprs, changed := walkExprSlice(v, expr.Exprs)
   300  	if changed {
   301  		if ret == expr {
   302  			ret = expr.copyNode()
   303  		}
   304  		ret.Exprs = exprs
   305  	}
   306  	if expr.Filter != nil {
   307  		e, changed := WalkExpr(v, expr.Filter)
   308  		if changed {
   309  			if ret == expr {
   310  				ret = expr.copyNode()
   311  			}
   312  			ret.Filter = e
   313  		}
   314  	}
   315  
   316  	if expr.OrderBy != nil {
   317  		order, changed := walkOrderBy(v, expr.OrderBy)
   318  		if changed {
   319  			if ret == expr {
   320  				ret = expr.copyNode()
   321  			}
   322  			ret.OrderBy = order
   323  		}
   324  	}
   325  	return ret
   326  }
   327  
   328  // Walk implements the Expr interface.
   329  func (expr *IfExpr) Walk(v Visitor) Expr {
   330  	c, changedC := WalkExpr(v, expr.Cond)
   331  	t, changedT := WalkExpr(v, expr.True)
   332  	e, changedE := WalkExpr(v, expr.Else)
   333  	if changedC || changedT || changedE {
   334  		exprCopy := *expr
   335  		exprCopy.Cond = c
   336  		exprCopy.True = t
   337  		exprCopy.Else = e
   338  		return &exprCopy
   339  	}
   340  	return expr
   341  }
   342  
   343  // Walk implements the Expr interface.
   344  func (expr *IfErrExpr) Walk(v Visitor) Expr {
   345  	c, changedC := WalkExpr(v, expr.Cond)
   346  	t := expr.ErrCode
   347  	changedEC := false
   348  	if t != nil {
   349  		t, changedEC = WalkExpr(v, expr.ErrCode)
   350  	}
   351  	e := expr.Else
   352  	changedE := false
   353  	if e != nil {
   354  		e, changedE = WalkExpr(v, expr.Else)
   355  	}
   356  	if changedC || changedEC || changedE {
   357  		exprCopy := *expr
   358  		exprCopy.Cond = c
   359  		exprCopy.ErrCode = t
   360  		exprCopy.Else = e
   361  		return &exprCopy
   362  	}
   363  	return expr
   364  }
   365  
   366  // copyNode makes a copy of this Expr without recursing in any child Exprs.
   367  func (expr *IndirectionExpr) copyNode() *IndirectionExpr {
   368  	exprCopy := *expr
   369  	exprCopy.Indirection = append(ArraySubscripts(nil), exprCopy.Indirection...)
   370  	for i, t := range exprCopy.Indirection {
   371  		subscriptCopy := *t
   372  		exprCopy.Indirection[i] = &subscriptCopy
   373  	}
   374  	return &exprCopy
   375  }
   376  
   377  // Walk implements the Expr interface.
   378  func (expr *IndirectionExpr) Walk(v Visitor) Expr {
   379  	ret := expr
   380  
   381  	e, changed := WalkExpr(v, expr.Expr)
   382  	if changed {
   383  		if ret == expr {
   384  			ret = expr.copyNode()
   385  		}
   386  		ret.Expr = e
   387  	}
   388  
   389  	for i, t := range expr.Indirection {
   390  		if t.Begin != nil {
   391  			e, changed := WalkExpr(v, t.Begin)
   392  			if changed {
   393  				if ret == expr {
   394  					ret = expr.copyNode()
   395  				}
   396  				ret.Indirection[i].Begin = e
   397  			}
   398  		}
   399  		if t.End != nil {
   400  			e, changed := WalkExpr(v, t.End)
   401  			if changed {
   402  				if ret == expr {
   403  					ret = expr.copyNode()
   404  				}
   405  				ret.Indirection[i].End = e
   406  			}
   407  		}
   408  	}
   409  
   410  	return ret
   411  }
   412  
   413  // Walk implements the Expr interface.
   414  func (expr *IsOfTypeExpr) Walk(v Visitor) Expr {
   415  	e, changed := WalkExpr(v, expr.Expr)
   416  	if changed {
   417  		exprCopy := *expr
   418  		exprCopy.Expr = e
   419  		return &exprCopy
   420  	}
   421  	return expr
   422  }
   423  
   424  // Walk implements the Expr interface.
   425  func (expr *NotExpr) Walk(v Visitor) Expr {
   426  	e, changed := WalkExpr(v, expr.Expr)
   427  	if changed {
   428  		exprCopy := *expr
   429  		exprCopy.Expr = e
   430  		return &exprCopy
   431  	}
   432  	return expr
   433  }
   434  
   435  // Walk implements the Expr interface.
   436  func (expr *IsNullExpr) Walk(v Visitor) Expr {
   437  	e, changed := WalkExpr(v, expr.Expr)
   438  	if changed {
   439  		exprCopy := *expr
   440  		exprCopy.Expr = e
   441  		return &exprCopy
   442  	}
   443  	return expr
   444  }
   445  
   446  // Walk implements the Expr interface.
   447  func (expr *IsNotNullExpr) Walk(v Visitor) Expr {
   448  	e, changed := WalkExpr(v, expr.Expr)
   449  	if changed {
   450  		exprCopy := *expr
   451  		exprCopy.Expr = e
   452  		return &exprCopy
   453  	}
   454  	return expr
   455  }
   456  
   457  // Walk implements the Expr interface.
   458  func (expr *NullIfExpr) Walk(v Visitor) Expr {
   459  	e1, changed1 := WalkExpr(v, expr.Expr1)
   460  	e2, changed2 := WalkExpr(v, expr.Expr2)
   461  	if changed1 || changed2 {
   462  		exprCopy := *expr
   463  		exprCopy.Expr1 = e1
   464  		exprCopy.Expr2 = e2
   465  		return &exprCopy
   466  	}
   467  	return expr
   468  }
   469  
   470  // Walk implements the Expr interface.
   471  func (expr *OrExpr) Walk(v Visitor) Expr {
   472  	left, changedL := WalkExpr(v, expr.Left)
   473  	right, changedR := WalkExpr(v, expr.Right)
   474  	if changedL || changedR {
   475  		exprCopy := *expr
   476  		exprCopy.Left = left
   477  		exprCopy.Right = right
   478  		return &exprCopy
   479  	}
   480  	return expr
   481  }
   482  
   483  // Walk implements the Expr interface.
   484  func (expr *ParenExpr) Walk(v Visitor) Expr {
   485  	e, changed := WalkExpr(v, expr.Expr)
   486  	if changed {
   487  		exprCopy := *expr
   488  		exprCopy.Expr = e
   489  		return &exprCopy
   490  	}
   491  	return expr
   492  }
   493  
   494  // Walk implements the Expr interface.
   495  func (expr *RangeCond) Walk(v Visitor) Expr {
   496  	l, changedL := WalkExpr(v, expr.Left)
   497  	f, changedF := WalkExpr(v, expr.From)
   498  	t, changedT := WalkExpr(v, expr.To)
   499  	if changedL || changedF || changedT {
   500  		exprCopy := *expr
   501  		exprCopy.Left = l
   502  		exprCopy.From = f
   503  		exprCopy.To = t
   504  		return &exprCopy
   505  	}
   506  	return expr
   507  }
   508  
   509  // Walk implements the Expr interface.
   510  func (expr *Subquery) Walk(v Visitor) Expr {
   511  	sel, changed := walkStmt(v, expr.Select)
   512  	if changed {
   513  		exprCopy := *expr
   514  		exprCopy.Select = sel.(SelectStatement)
   515  		return &exprCopy
   516  	}
   517  	return expr
   518  }
   519  
   520  // Walk implements the Expr interface.
   521  func (expr *UnaryExpr) Walk(v Visitor) Expr {
   522  	e, changed := WalkExpr(v, expr.Expr)
   523  	if changed {
   524  		exprCopy := *expr
   525  		exprCopy.Expr = e
   526  		return &exprCopy
   527  	}
   528  	return expr
   529  }
   530  
   531  func walkExprSlice(v Visitor, slice []Expr) ([]Expr, bool) {
   532  	copied := false
   533  	for i := range slice {
   534  		e, changed := WalkExpr(v, slice[i])
   535  		if changed {
   536  			if !copied {
   537  				slice = append([]Expr(nil), slice...)
   538  				copied = true
   539  			}
   540  			slice[i] = e
   541  		}
   542  	}
   543  	return slice, copied
   544  }
   545  
   546  func walkKVOptions(v Visitor, opts KVOptions) (KVOptions, bool) {
   547  	copied := false
   548  	for i := range opts {
   549  		if opts[i].Value == nil {
   550  			continue
   551  		}
   552  		e, changed := WalkExpr(v, opts[i].Value)
   553  		if changed {
   554  			if !copied {
   555  				opts = append(KVOptions(nil), opts...)
   556  				copied = true
   557  			}
   558  			opts[i].Value = e
   559  		}
   560  	}
   561  	return opts, copied
   562  }
   563  
   564  // Walk implements the Expr interface.
   565  func (expr *Tuple) Walk(v Visitor) Expr {
   566  	exprs, changed := walkExprSlice(v, expr.Exprs)
   567  	if changed {
   568  		exprCopy := *expr
   569  		exprCopy.Exprs = exprs
   570  		return &exprCopy
   571  	}
   572  	return expr
   573  }
   574  
   575  // Walk implements the Expr interface.
   576  func (expr *Array) Walk(v Visitor) Expr {
   577  	if exprs, changed := walkExprSlice(v, expr.Exprs); changed {
   578  		exprCopy := *expr
   579  		exprCopy.Exprs = exprs
   580  		return &exprCopy
   581  	}
   582  	return expr
   583  }
   584  
   585  // Walk implements the Expr interface.
   586  func (expr *ArrayFlatten) Walk(v Visitor) Expr {
   587  	if sq, changed := WalkExpr(v, expr.Subquery); changed {
   588  		exprCopy := *expr
   589  		exprCopy.Subquery = sq
   590  		return &exprCopy
   591  	}
   592  	return expr
   593  }
   594  
   595  // Walk implements the Expr interface.
   596  func (expr UnqualifiedStar) Walk(_ Visitor) Expr { return expr }
   597  
   598  // Walk implements the Expr interface.
   599  func (expr *UnresolvedName) Walk(_ Visitor) Expr { return expr }
   600  
   601  // Walk implements the Expr interface.
   602  func (expr *AllColumnsSelector) Walk(_ Visitor) Expr { return expr }
   603  
   604  // Walk implements the Expr interface.
   605  func (expr *ColumnItem) Walk(_ Visitor) Expr {
   606  	// TODO(knz): When ARRAY is supported, this must be extended
   607  	// to recurse into the index expressions of the ColumnItems' Selector.
   608  	return expr
   609  }
   610  
   611  // Walk implements the Expr interface.
   612  func (expr DefaultVal) Walk(_ Visitor) Expr { return expr }
   613  
   614  // Walk implements the Expr interface.
   615  func (expr PartitionMaxVal) Walk(_ Visitor) Expr { return expr }
   616  
   617  // Walk implements the Expr interface.
   618  func (expr PartitionMinVal) Walk(_ Visitor) Expr { return expr }
   619  
   620  // Walk implements the Expr interface.
   621  func (expr *NumVal) Walk(_ Visitor) Expr { return expr }
   622  
   623  // Walk implements the Expr interface.
   624  func (expr *StrVal) Walk(_ Visitor) Expr { return expr }
   625  
   626  // Walk implements the Expr interface.
   627  func (expr *Placeholder) Walk(_ Visitor) Expr { return expr }
   628  
   629  // Walk implements the Expr interface.
   630  func (expr *DBitArray) Walk(_ Visitor) Expr { return expr }
   631  
   632  // Walk implements the Expr interface.
   633  func (expr *DBool) Walk(_ Visitor) Expr { return expr }
   634  
   635  // Walk implements the Expr interface.
   636  func (expr *DBytes) Walk(_ Visitor) Expr { return expr }
   637  
   638  // Walk implements the Expr interface.
   639  func (expr *DDate) Walk(_ Visitor) Expr { return expr }
   640  
   641  // Walk implements the Expr interface.
   642  func (expr *DTime) Walk(_ Visitor) Expr { return expr }
   643  
   644  // Walk implements the Expr interface.
   645  func (expr *DTimeTZ) Walk(_ Visitor) Expr { return expr }
   646  
   647  // Walk implements the Expr interface.
   648  func (expr *DFloat) Walk(_ Visitor) Expr { return expr }
   649  
   650  // Walk implements the Expr interface.
   651  func (expr *DEnum) Walk(_ Visitor) Expr { return expr }
   652  
   653  // Walk implements the Expr interface.
   654  func (expr *DDecimal) Walk(_ Visitor) Expr { return expr }
   655  
   656  // Walk implements the Expr interface.
   657  func (expr *DInt) Walk(_ Visitor) Expr { return expr }
   658  
   659  // Walk implements the Expr interface.
   660  func (expr *DInterval) Walk(_ Visitor) Expr { return expr }
   661  
   662  // Walk implements the Expr interface.
   663  func (expr *DGeography) Walk(_ Visitor) Expr { return expr }
   664  
   665  // Walk implements the Expr interface.
   666  func (expr *DGeometry) Walk(_ Visitor) Expr { return expr }
   667  
   668  // Walk implements the Expr interface.
   669  func (expr *DJSON) Walk(_ Visitor) Expr { return expr }
   670  
   671  // Walk implements the Expr interface.
   672  func (expr *DUuid) Walk(_ Visitor) Expr { return expr }
   673  
   674  // Walk implements the Expr interface.
   675  func (expr *DIPAddr) Walk(_ Visitor) Expr { return expr }
   676  
   677  // Walk implements the Expr interface.
   678  func (expr dNull) Walk(_ Visitor) Expr { return expr }
   679  
   680  // Walk implements the Expr interface.
   681  func (expr *DString) Walk(_ Visitor) Expr { return expr }
   682  
   683  // Walk implements the Expr interface.
   684  func (expr *DCollatedString) Walk(_ Visitor) Expr { return expr }
   685  
   686  // Walk implements the Expr interface.
   687  func (expr *DTimestamp) Walk(_ Visitor) Expr { return expr }
   688  
   689  // Walk implements the Expr interface.
   690  func (expr *DTimestampTZ) Walk(_ Visitor) Expr { return expr }
   691  
   692  // Walk implements the Expr interface.
   693  func (expr *DTuple) Walk(_ Visitor) Expr { return expr }
   694  
   695  // Walk implements the Expr interface.
   696  func (expr *DArray) Walk(_ Visitor) Expr { return expr }
   697  
   698  // Walk implements the Expr interface.
   699  func (expr *DOid) Walk(_ Visitor) Expr { return expr }
   700  
   701  // Walk implements the Expr interface.
   702  func (expr *DOidWrapper) Walk(_ Visitor) Expr { return expr }
   703  
   704  // WalkExpr traverses the nodes in an expression.
   705  //
   706  // NOTE: Do not count on the walkStmt/WalkExpr machinery to visit all
   707  // expressions contained in a query. Only a sub-set of all expressions are
   708  // found by walkStmt and subsequently traversed. See the comment below on
   709  // walkStmt for details.
   710  func WalkExpr(v Visitor, expr Expr) (newExpr Expr, changed bool) {
   711  	recurse, newExpr := v.VisitPre(expr)
   712  
   713  	if recurse {
   714  		newExpr = newExpr.Walk(v)
   715  		newExpr = v.VisitPost(newExpr)
   716  	}
   717  
   718  	// We cannot use == because some Expr implementations are not comparable (e.g. DTuple)
   719  	return newExpr, (reflect.ValueOf(expr) != reflect.ValueOf(newExpr))
   720  }
   721  
   722  // WalkExprConst is a variant of WalkExpr for visitors that do not modify the expression.
   723  func WalkExprConst(v Visitor, expr Expr) {
   724  	WalkExpr(v, expr)
   725  	// TODO(radu): we should verify that WalkExpr returns changed == false. Unfortunately that
   726  	// is not the case today because walking through non-pointer implementations of Expr (like
   727  	// DBool, DTuple) causes new nodes to be created. We should make all Expr implementations be
   728  	// pointers (which will also remove the need for using reflect.ValueOf above).
   729  }
   730  
   731  // walkableStmt is implemented by statements that can appear inside an expression (selects) or
   732  // we want to start a walk from (using walkStmt).
   733  type walkableStmt interface {
   734  	Statement
   735  	walkStmt(Visitor) Statement
   736  }
   737  
   738  func walkReturningClause(v Visitor, clause ReturningClause) (ReturningClause, bool) {
   739  	switch t := clause.(type) {
   740  	case *ReturningExprs:
   741  		ret := t
   742  		for i, expr := range *t {
   743  			e, changed := WalkExpr(v, expr.Expr)
   744  			if changed {
   745  				if ret == t {
   746  					ret = t.copyNode()
   747  				}
   748  				(*ret)[i].Expr = e
   749  			}
   750  		}
   751  		return ret, (ret != t)
   752  	case *ReturningNothing, *NoReturningClause:
   753  		return t, false
   754  	default:
   755  		panic(errors.AssertionFailedf("unexpected ReturningClause type: %T", t))
   756  	}
   757  }
   758  
   759  // copyNode makes a copy of this Statement without recursing in any child Statements.
   760  func (stmt *Backup) copyNode() *Backup {
   761  	stmtCopy := *stmt
   762  	stmtCopy.IncrementalFrom = append(Exprs(nil), stmt.IncrementalFrom...)
   763  	stmtCopy.Options = append(KVOptions(nil), stmt.Options...)
   764  	return &stmtCopy
   765  }
   766  
   767  // walkStmt is part of the walkableStmt interface.
   768  func (stmt *Backup) walkStmt(v Visitor) Statement {
   769  	ret := stmt
   770  	if stmt.AsOf.Expr != nil {
   771  		e, changed := WalkExpr(v, stmt.AsOf.Expr)
   772  		if changed {
   773  			if ret == stmt {
   774  				ret = stmt.copyNode()
   775  			}
   776  			ret.AsOf.Expr = e
   777  		}
   778  	}
   779  	for i, expr := range stmt.To {
   780  		e, changed := WalkExpr(v, expr)
   781  		if changed {
   782  			if ret == stmt {
   783  				ret = stmt.copyNode()
   784  			}
   785  			ret.To[i] = e
   786  		}
   787  	}
   788  	for i, expr := range stmt.IncrementalFrom {
   789  		e, changed := WalkExpr(v, expr)
   790  		if changed {
   791  			if ret == stmt {
   792  				ret = stmt.copyNode()
   793  			}
   794  			ret.IncrementalFrom[i] = e
   795  		}
   796  	}
   797  	{
   798  		opts, changed := walkKVOptions(v, stmt.Options)
   799  		if changed {
   800  			if ret == stmt {
   801  				ret = stmt.copyNode()
   802  			}
   803  			ret.Options = opts
   804  		}
   805  	}
   806  	return ret
   807  }
   808  
   809  // copyNode makes a copy of this Statement without recursing in any child Statements.
   810  func (stmt *Delete) copyNode() *Delete {
   811  	stmtCopy := *stmt
   812  	if stmt.Where != nil {
   813  		wCopy := *stmt.Where
   814  		stmtCopy.Where = &wCopy
   815  	}
   816  	return &stmtCopy
   817  }
   818  
   819  // walkStmt is part of the walkableStmt interface.
   820  func (stmt *Delete) walkStmt(v Visitor) Statement {
   821  	ret := stmt
   822  	if stmt.Where != nil {
   823  		e, changed := WalkExpr(v, stmt.Where.Expr)
   824  		if changed {
   825  			ret = stmt.copyNode()
   826  			ret.Where.Expr = e
   827  		}
   828  	}
   829  	returning, changed := walkReturningClause(v, stmt.Returning)
   830  	if changed {
   831  		if ret == stmt {
   832  			ret = stmt.copyNode()
   833  		}
   834  		ret.Returning = returning
   835  	}
   836  	return ret
   837  }
   838  
   839  // copyNode makes a copy of this Statement without recursing in any child Statements.
   840  func (stmt *Explain) copyNode() *Explain {
   841  	stmtCopy := *stmt
   842  	return &stmtCopy
   843  }
   844  
   845  // walkStmt is part of the walkableStmt interface.
   846  func (stmt *Explain) walkStmt(v Visitor) Statement {
   847  	s, changed := walkStmt(v, stmt.Statement)
   848  	if changed {
   849  		stmt = stmt.copyNode()
   850  		stmt.Statement = s
   851  	}
   852  	return stmt
   853  }
   854  
   855  // copyNode makes a copy of this Statement without recursing in any child Statements.
   856  func (stmt *ExplainAnalyzeDebug) copyNode() *ExplainAnalyzeDebug {
   857  	stmtCopy := *stmt
   858  	return &stmtCopy
   859  }
   860  
   861  // walkStmt is part of the walkableStmt interface.
   862  func (stmt *ExplainAnalyzeDebug) walkStmt(v Visitor) Statement {
   863  	s, changed := walkStmt(v, stmt.Statement)
   864  	if changed {
   865  		stmt = stmt.copyNode()
   866  		stmt.Statement = s
   867  	}
   868  	return stmt
   869  }
   870  
   871  // copyNode makes a copy of this Statement without recursing in any child Statements.
   872  func (stmt *Insert) copyNode() *Insert {
   873  	stmtCopy := *stmt
   874  	return &stmtCopy
   875  }
   876  
   877  // walkStmt is part of the walkableStmt interface.
   878  func (stmt *Insert) walkStmt(v Visitor) Statement {
   879  	ret := stmt
   880  	if stmt.Rows != nil {
   881  		rows, changed := walkStmt(v, stmt.Rows)
   882  		if changed {
   883  			ret = stmt.copyNode()
   884  			ret.Rows = rows.(*Select)
   885  		}
   886  	}
   887  	returning, changed := walkReturningClause(v, stmt.Returning)
   888  	if changed {
   889  		if ret == stmt {
   890  			ret = stmt.copyNode()
   891  		}
   892  		ret.Returning = returning
   893  	}
   894  	// TODO(dan): Walk OnConflict once the ON CONFLICT DO UPDATE form of upsert is
   895  	// implemented.
   896  	return ret
   897  }
   898  
   899  // copyNode makes a copy of this Statement without recursing in any child Statements.
   900  func (stmt *CreateTable) copyNode() *CreateTable {
   901  	stmtCopy := *stmt
   902  	return &stmtCopy
   903  }
   904  
   905  // walkStmt is part of the walkableStmt interface.
   906  func (stmt *CreateTable) walkStmt(v Visitor) Statement {
   907  	ret := stmt
   908  	if stmt.AsSource != nil {
   909  		rows, changed := walkStmt(v, stmt.AsSource)
   910  		if changed {
   911  			ret = stmt.copyNode()
   912  			ret.AsSource = rows.(*Select)
   913  		}
   914  	}
   915  	return ret
   916  }
   917  
   918  // copyNode makes a copy of this Statement without recursing in any child Statements.
   919  func (stmt *CancelQueries) copyNode() *CancelQueries {
   920  	stmtCopy := *stmt
   921  	return &stmtCopy
   922  }
   923  
   924  // walkStmt is part of the walkableStmt interface.
   925  func (stmt *CancelQueries) walkStmt(v Visitor) Statement {
   926  	sel, changed := walkStmt(v, stmt.Queries)
   927  	if changed {
   928  		stmt = stmt.copyNode()
   929  		stmt.Queries = sel.(*Select)
   930  	}
   931  	return stmt
   932  }
   933  
   934  // copyNode makes a copy of this Statement without recursing in any child Statements.
   935  func (stmt *CancelSessions) copyNode() *CancelSessions {
   936  	stmtCopy := *stmt
   937  	return &stmtCopy
   938  }
   939  
   940  // walkStmt is part of the walkableStmt interface.
   941  func (stmt *CancelSessions) walkStmt(v Visitor) Statement {
   942  	sel, changed := walkStmt(v, stmt.Sessions)
   943  	if changed {
   944  		stmt = stmt.copyNode()
   945  		stmt.Sessions = sel.(*Select)
   946  	}
   947  	return stmt
   948  }
   949  
   950  // copyNode makes a copy of this Statement without recursing in any child Statements.
   951  func (stmt *ControlJobs) copyNode() *ControlJobs {
   952  	stmtCopy := *stmt
   953  	return &stmtCopy
   954  }
   955  
   956  // walkStmt is part of the walkableStmt interface.
   957  func (stmt *ControlJobs) walkStmt(v Visitor) Statement {
   958  	sel, changed := walkStmt(v, stmt.Jobs)
   959  	if changed {
   960  		stmt = stmt.copyNode()
   961  		stmt.Jobs = sel.(*Select)
   962  	}
   963  	return stmt
   964  }
   965  
   966  // copyNode makes a copy of this Statement without recursing in any child Statements.
   967  func (stmt *Import) copyNode() *Import {
   968  	stmtCopy := *stmt
   969  	stmtCopy.Files = append(Exprs(nil), stmt.Files...)
   970  	stmtCopy.Options = append(KVOptions(nil), stmt.Options...)
   971  	return &stmtCopy
   972  }
   973  
   974  // walkStmt is part of the walkableStmt interface.
   975  func (stmt *Import) walkStmt(v Visitor) Statement {
   976  	ret := stmt
   977  	if stmt.CreateFile != nil {
   978  		e, changed := WalkExpr(v, stmt.CreateFile)
   979  		if changed {
   980  			if ret == stmt {
   981  				ret = stmt.copyNode()
   982  			}
   983  			ret.CreateFile = e
   984  		}
   985  	}
   986  	for i, expr := range stmt.Files {
   987  		e, changed := WalkExpr(v, expr)
   988  		if changed {
   989  			if ret == stmt {
   990  				ret = stmt.copyNode()
   991  			}
   992  			ret.Files[i] = e
   993  		}
   994  	}
   995  	{
   996  		opts, changed := walkKVOptions(v, stmt.Options)
   997  		if changed {
   998  			if ret == stmt {
   999  				ret = stmt.copyNode()
  1000  			}
  1001  			ret.Options = opts
  1002  		}
  1003  	}
  1004  	return ret
  1005  }
  1006  
  1007  // walkStmt is part of the walkableStmt interface.
  1008  func (stmt *ParenSelect) walkStmt(v Visitor) Statement {
  1009  	sel, changed := walkStmt(v, stmt.Select)
  1010  	if changed {
  1011  		return &ParenSelect{sel.(*Select)}
  1012  	}
  1013  	return stmt
  1014  }
  1015  
  1016  // copyNode makes a copy of this Statement without recursing in any child Statements.
  1017  func (stmt *Restore) copyNode() *Restore {
  1018  	stmtCopy := *stmt
  1019  	stmtCopy.From = append([]PartitionedBackup(nil), stmt.From...)
  1020  	stmtCopy.Options = append(KVOptions(nil), stmt.Options...)
  1021  	return &stmtCopy
  1022  }
  1023  
  1024  // walkStmt is part of the walkableStmt interface.
  1025  func (stmt *Restore) walkStmt(v Visitor) Statement {
  1026  	ret := stmt
  1027  	if stmt.AsOf.Expr != nil {
  1028  		e, changed := WalkExpr(v, stmt.AsOf.Expr)
  1029  		if changed {
  1030  			if ret == stmt {
  1031  				ret = stmt.copyNode()
  1032  			}
  1033  			ret.AsOf.Expr = e
  1034  		}
  1035  	}
  1036  	for i, backup := range stmt.From {
  1037  		for j, expr := range backup {
  1038  			e, changed := WalkExpr(v, expr)
  1039  			if changed {
  1040  				if ret == stmt {
  1041  					ret = stmt.copyNode()
  1042  				}
  1043  				ret.From[i][j] = e
  1044  			}
  1045  		}
  1046  	}
  1047  	{
  1048  		opts, changed := walkKVOptions(v, stmt.Options)
  1049  		if changed {
  1050  			if ret == stmt {
  1051  				ret = stmt.copyNode()
  1052  			}
  1053  			ret.Options = opts
  1054  		}
  1055  	}
  1056  	return ret
  1057  }
  1058  
  1059  // copyNode makes a copy of this Statement without recursing in any child Statements.
  1060  func (stmt *ReturningExprs) copyNode() *ReturningExprs {
  1061  	stmtCopy := append(ReturningExprs(nil), *stmt...)
  1062  	return &stmtCopy
  1063  }
  1064  
  1065  func walkOrderBy(v Visitor, order OrderBy) (OrderBy, bool) {
  1066  	copied := false
  1067  	for i := range order {
  1068  		if order[i].OrderType != OrderByColumn {
  1069  			continue
  1070  		}
  1071  		e, changed := WalkExpr(v, order[i].Expr)
  1072  		if changed {
  1073  			if !copied {
  1074  				order = append(OrderBy(nil), order...)
  1075  				copied = true
  1076  			}
  1077  			orderByCopy := *order[i]
  1078  			orderByCopy.Expr = e
  1079  			order[i] = &orderByCopy
  1080  		}
  1081  	}
  1082  	return order, copied
  1083  }
  1084  
  1085  // copyNode makes a copy of this Statement without recursing in any child Statements.
  1086  func (stmt *Select) copyNode() *Select {
  1087  	stmtCopy := *stmt
  1088  	if stmt.Limit != nil {
  1089  		lCopy := *stmt.Limit
  1090  		stmtCopy.Limit = &lCopy
  1091  	}
  1092  	return &stmtCopy
  1093  }
  1094  
  1095  // walkStmt is part of the walkableStmt interface.
  1096  func (stmt *Select) walkStmt(v Visitor) Statement {
  1097  	ret := stmt
  1098  	sel, changed := walkStmt(v, stmt.Select)
  1099  	if changed {
  1100  		ret = stmt.copyNode()
  1101  		ret.Select = sel.(SelectStatement)
  1102  	}
  1103  	order, changed := walkOrderBy(v, stmt.OrderBy)
  1104  	if changed {
  1105  		if ret == stmt {
  1106  			ret = stmt.copyNode()
  1107  		}
  1108  		ret.OrderBy = order
  1109  	}
  1110  	if stmt.Limit != nil {
  1111  		if stmt.Limit.Offset != nil {
  1112  			e, changed := WalkExpr(v, stmt.Limit.Offset)
  1113  			if changed {
  1114  				if ret == stmt {
  1115  					ret = stmt.copyNode()
  1116  				}
  1117  				ret.Limit.Offset = e
  1118  			}
  1119  		}
  1120  		if stmt.Limit.Count != nil {
  1121  			e, changed := WalkExpr(v, stmt.Limit.Count)
  1122  			if changed {
  1123  				if ret == stmt {
  1124  					ret = stmt.copyNode()
  1125  				}
  1126  				ret.Limit.Count = e
  1127  			}
  1128  		}
  1129  	}
  1130  	return ret
  1131  }
  1132  
  1133  // copyNode makes a copy of this Statement without recursing in any child Statements.
  1134  func (stmt *SelectClause) copyNode() *SelectClause {
  1135  	stmtCopy := *stmt
  1136  	stmtCopy.Exprs = append(SelectExprs(nil), stmt.Exprs...)
  1137  	stmtCopy.From = From{
  1138  		Tables: append(TableExprs(nil), stmt.From.Tables...),
  1139  		AsOf:   stmt.From.AsOf,
  1140  	}
  1141  	if stmt.Where != nil {
  1142  		wCopy := *stmt.Where
  1143  		stmtCopy.Where = &wCopy
  1144  	}
  1145  	stmtCopy.GroupBy = append(GroupBy(nil), stmt.GroupBy...)
  1146  	if stmt.Having != nil {
  1147  		hCopy := *stmt.Having
  1148  		stmtCopy.Having = &hCopy
  1149  	}
  1150  	stmtCopy.Window = append(Window(nil), stmt.Window...)
  1151  	return &stmtCopy
  1152  }
  1153  
  1154  // walkStmt is part of the walkableStmt interface.
  1155  func (stmt *SelectClause) walkStmt(v Visitor) Statement {
  1156  	ret := stmt
  1157  
  1158  	for i, expr := range stmt.Exprs {
  1159  		e, changed := WalkExpr(v, expr.Expr)
  1160  		if changed {
  1161  			if ret == stmt {
  1162  				ret = stmt.copyNode()
  1163  			}
  1164  			ret.Exprs[i].Expr = e
  1165  		}
  1166  	}
  1167  
  1168  	if stmt.From.AsOf.Expr != nil {
  1169  		e, changed := WalkExpr(v, stmt.From.AsOf.Expr)
  1170  		if changed {
  1171  			if ret == stmt {
  1172  				ret = stmt.copyNode()
  1173  			}
  1174  			ret.From.AsOf.Expr = e
  1175  		}
  1176  	}
  1177  
  1178  	if stmt.Where != nil {
  1179  		e, changed := WalkExpr(v, stmt.Where.Expr)
  1180  		if changed {
  1181  			if ret == stmt {
  1182  				ret = stmt.copyNode()
  1183  			}
  1184  			ret.Where.Expr = e
  1185  		}
  1186  	}
  1187  
  1188  	for i, expr := range stmt.GroupBy {
  1189  		e, changed := WalkExpr(v, expr)
  1190  		if changed {
  1191  			if ret == stmt {
  1192  				ret = stmt.copyNode()
  1193  			}
  1194  			ret.GroupBy[i] = e
  1195  		}
  1196  	}
  1197  
  1198  	if stmt.Having != nil {
  1199  		e, changed := WalkExpr(v, stmt.Having.Expr)
  1200  		if changed {
  1201  			if ret == stmt {
  1202  				ret = stmt.copyNode()
  1203  			}
  1204  			ret.Having.Expr = e
  1205  		}
  1206  	}
  1207  
  1208  	for i := range stmt.Window {
  1209  		w, changed := walkWindowDef(v, stmt.Window[i])
  1210  		if changed {
  1211  			if ret == stmt {
  1212  				ret = stmt.copyNode()
  1213  			}
  1214  			ret.Window[i] = w
  1215  		}
  1216  	}
  1217  
  1218  	return ret
  1219  }
  1220  
  1221  // copyNode makes a copy of this Statement without recursing in any child Statements.
  1222  func (stmt *SetVar) copyNode() *SetVar {
  1223  	stmtCopy := *stmt
  1224  	stmtCopy.Values = append(Exprs(nil), stmt.Values...)
  1225  	return &stmtCopy
  1226  }
  1227  
  1228  // walkStmt is part of the walkableStmt interface.
  1229  func (stmt *SetVar) walkStmt(v Visitor) Statement {
  1230  	ret := stmt
  1231  	for i, expr := range stmt.Values {
  1232  		e, changed := WalkExpr(v, expr)
  1233  		if changed {
  1234  			if ret == stmt {
  1235  				ret = stmt.copyNode()
  1236  			}
  1237  			ret.Values[i] = e
  1238  		}
  1239  	}
  1240  	return ret
  1241  }
  1242  
  1243  // walkStmt is part of the walkableStmt interface.
  1244  func (stmt *SetZoneConfig) walkStmt(v Visitor) Statement {
  1245  	ret := stmt
  1246  	if stmt.YAMLConfig != nil {
  1247  		e, changed := WalkExpr(v, stmt.YAMLConfig)
  1248  		if changed {
  1249  			newStmt := *stmt
  1250  			ret = &newStmt
  1251  			ret.YAMLConfig = e
  1252  		}
  1253  	}
  1254  	if stmt.Options != nil {
  1255  		newOpts, changed := walkKVOptions(v, stmt.Options)
  1256  		if changed {
  1257  			if ret == stmt {
  1258  				newStmt := *stmt
  1259  				ret = &newStmt
  1260  			}
  1261  			ret.Options = newOpts
  1262  		}
  1263  	}
  1264  	return ret
  1265  }
  1266  
  1267  // copyNode makes a copy of this Statement without recursing in any child Statements.
  1268  func (stmt *SetTracing) copyNode() *SetTracing {
  1269  	stmtCopy := *stmt
  1270  	stmtCopy.Values = append(Exprs(nil), stmt.Values...)
  1271  	return &stmtCopy
  1272  }
  1273  
  1274  // walkStmt is part of the walkableStmt interface.
  1275  func (stmt *SetTracing) walkStmt(v Visitor) Statement {
  1276  	ret := stmt
  1277  	for i, expr := range stmt.Values {
  1278  		e, changed := WalkExpr(v, expr)
  1279  		if changed {
  1280  			if ret == stmt {
  1281  				ret = stmt.copyNode()
  1282  			}
  1283  			ret.Values[i] = e
  1284  		}
  1285  	}
  1286  	return ret
  1287  }
  1288  
  1289  // copyNode makes a copy of this Statement without recursing in any child Statements.
  1290  func (stmt *SetClusterSetting) copyNode() *SetClusterSetting {
  1291  	stmtCopy := *stmt
  1292  	return &stmtCopy
  1293  }
  1294  
  1295  // walkStmt is part of the walkableStmt interface.
  1296  func (stmt *SetClusterSetting) walkStmt(v Visitor) Statement {
  1297  	ret := stmt
  1298  	if stmt.Value != nil {
  1299  		e, changed := WalkExpr(v, stmt.Value)
  1300  		if changed {
  1301  			ret = stmt.copyNode()
  1302  			ret.Value = e
  1303  		}
  1304  	}
  1305  	return ret
  1306  }
  1307  
  1308  // copyNode makes a copy of this Statement without recursing in any child Statements.
  1309  func (stmt *Update) copyNode() *Update {
  1310  	stmtCopy := *stmt
  1311  	stmtCopy.Exprs = make(UpdateExprs, len(stmt.Exprs))
  1312  	for i, e := range stmt.Exprs {
  1313  		eCopy := *e
  1314  		stmtCopy.Exprs[i] = &eCopy
  1315  	}
  1316  	if stmt.Where != nil {
  1317  		wCopy := *stmt.Where
  1318  		stmtCopy.Where = &wCopy
  1319  	}
  1320  	return &stmtCopy
  1321  }
  1322  
  1323  // walkStmt is part of the walkableStmt interface.
  1324  func (stmt *Update) walkStmt(v Visitor) Statement {
  1325  	ret := stmt
  1326  	for i, expr := range stmt.Exprs {
  1327  		e, changed := WalkExpr(v, expr.Expr)
  1328  		if changed {
  1329  			if ret == stmt {
  1330  				ret = stmt.copyNode()
  1331  			}
  1332  			ret.Exprs[i].Expr = e
  1333  		}
  1334  	}
  1335  
  1336  	if stmt.Where != nil {
  1337  		e, changed := WalkExpr(v, stmt.Where.Expr)
  1338  		if changed {
  1339  			if ret == stmt {
  1340  				ret = stmt.copyNode()
  1341  			}
  1342  			ret.Where.Expr = e
  1343  		}
  1344  	}
  1345  
  1346  	returning, changed := walkReturningClause(v, stmt.Returning)
  1347  	if changed {
  1348  		if ret == stmt {
  1349  			ret = stmt.copyNode()
  1350  		}
  1351  		ret.Returning = returning
  1352  	}
  1353  	return ret
  1354  }
  1355  
  1356  // walkStmt is part of the walkableStmt interface.
  1357  func (stmt *ValuesClause) walkStmt(v Visitor) Statement {
  1358  	ret := stmt
  1359  	for i, tuple := range stmt.Rows {
  1360  		exprs, changed := walkExprSlice(v, tuple)
  1361  		if changed {
  1362  			if ret == stmt {
  1363  				ret = &ValuesClause{append([]Exprs(nil), stmt.Rows...)}
  1364  			}
  1365  			ret.Rows[i] = exprs
  1366  		}
  1367  	}
  1368  	return ret
  1369  }
  1370  
  1371  // copyNode makes a copy of this Statement.
  1372  func (stmt *BeginTransaction) copyNode() *BeginTransaction {
  1373  	stmtCopy := *stmt
  1374  	return &stmtCopy
  1375  }
  1376  
  1377  // walkStmt is part of the walkableStmt interface.
  1378  func (stmt *BeginTransaction) walkStmt(v Visitor) Statement {
  1379  	ret := stmt
  1380  	if stmt.Modes.AsOf.Expr != nil {
  1381  		e, changed := WalkExpr(v, stmt.Modes.AsOf.Expr)
  1382  		if changed {
  1383  			ret = stmt.copyNode()
  1384  			ret.Modes.AsOf.Expr = e
  1385  		}
  1386  	}
  1387  	return ret
  1388  }
  1389  
  1390  var _ walkableStmt = &CreateTable{}
  1391  var _ walkableStmt = &Backup{}
  1392  var _ walkableStmt = &Delete{}
  1393  var _ walkableStmt = &Explain{}
  1394  var _ walkableStmt = &Insert{}
  1395  var _ walkableStmt = &Import{}
  1396  var _ walkableStmt = &ParenSelect{}
  1397  var _ walkableStmt = &Restore{}
  1398  var _ walkableStmt = &Select{}
  1399  var _ walkableStmt = &SelectClause{}
  1400  var _ walkableStmt = &SetClusterSetting{}
  1401  var _ walkableStmt = &SetVar{}
  1402  var _ walkableStmt = &Update{}
  1403  var _ walkableStmt = &ValuesClause{}
  1404  var _ walkableStmt = &CancelQueries{}
  1405  var _ walkableStmt = &CancelSessions{}
  1406  var _ walkableStmt = &ControlJobs{}
  1407  var _ walkableStmt = &BeginTransaction{}
  1408  
  1409  // walkStmt walks the entire parsed stmt calling WalkExpr on each
  1410  // expression, and replacing each expression with the one returned
  1411  // by WalkExpr.
  1412  //
  1413  // NOTE: Beware that walkStmt does not necessarily traverse all parts of a
  1414  // statement by itself. For example, it will not walk into Subquery nodes
  1415  // within a FROM clause or into a JoinCond. Walk's logic is pretty
  1416  // interdependent with the logic for constructing a query plan.
  1417  func walkStmt(v Visitor, stmt Statement) (newStmt Statement, changed bool) {
  1418  	walkable, ok := stmt.(walkableStmt)
  1419  	if !ok {
  1420  		return stmt, false
  1421  	}
  1422  	newStmt = walkable.walkStmt(v)
  1423  	return newStmt, (stmt != newStmt)
  1424  }
  1425  
  1426  type simpleVisitor struct {
  1427  	fn  SimpleVisitFn
  1428  	err error
  1429  }
  1430  
  1431  var _ Visitor = &simpleVisitor{}
  1432  
  1433  func (v *simpleVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) {
  1434  	if v.err != nil {
  1435  		return false, expr
  1436  	}
  1437  	recurse, newExpr, v.err = v.fn(expr)
  1438  	if v.err != nil {
  1439  		return false, expr
  1440  	}
  1441  	return recurse, newExpr
  1442  }
  1443  
  1444  func (*simpleVisitor) VisitPost(expr Expr) Expr { return expr }
  1445  
  1446  // SimpleVisitFn is a function that is run for every node in the VisitPre stage;
  1447  // see SimpleVisit.
  1448  type SimpleVisitFn func(expr Expr) (recurse bool, newExpr Expr, err error)
  1449  
  1450  // SimpleVisit is a convenience wrapper for visitors that only have VisitPre
  1451  // code and don't return any results except an error. The given function is
  1452  // called in VisitPre for every node. The visitor stops as soon as an error is
  1453  // returned.
  1454  func SimpleVisit(expr Expr, preFn SimpleVisitFn) (Expr, error) {
  1455  	v := simpleVisitor{fn: preFn}
  1456  	newExpr, _ := WalkExpr(&v, expr)
  1457  	if v.err != nil {
  1458  		return nil, v.err
  1459  	}
  1460  	return newExpr, nil
  1461  }
  1462  
  1463  type debugVisitor struct {
  1464  	buf   bytes.Buffer
  1465  	level int
  1466  }
  1467  
  1468  var _ Visitor = &debugVisitor{}
  1469  
  1470  func (v *debugVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) {
  1471  	v.level++
  1472  	fmt.Fprintf(&v.buf, "%*s", 2*v.level, " ")
  1473  	str := fmt.Sprintf("%#v\n", expr)
  1474  	// Remove "parser." to make the string more compact.
  1475  	str = strings.Replace(str, "parser.", "", -1)
  1476  	v.buf.WriteString(str)
  1477  	return true, expr
  1478  }
  1479  
  1480  func (v *debugVisitor) VisitPost(expr Expr) Expr {
  1481  	v.level--
  1482  	return expr
  1483  }
  1484  
  1485  // ExprDebugString generates a multi-line debug string with one node per line in
  1486  // Go format.
  1487  func ExprDebugString(expr Expr) string {
  1488  	v := debugVisitor{}
  1489  	WalkExprConst(&v, expr)
  1490  	return v.buf.String()
  1491  }
  1492  
  1493  // StmtDebugString generates multi-line debug strings in Go format for the
  1494  // expressions that are part of the given statement.
  1495  func StmtDebugString(stmt Statement) string {
  1496  	v := debugVisitor{}
  1497  	walkStmt(&v, stmt)
  1498  	return v.buf.String()
  1499  }
  1500  
  1501  // Silence any warnings if these functions are not used.
  1502  var _ = ExprDebugString
  1503  var _ = StmtDebugString