github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/ast/cloner.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package ast
    15  
    16  import "fmt"
    17  
    18  // Cloner is an ast visitor that clones a node.
    19  type Cloner struct {
    20  }
    21  
    22  // Enter implements Visitor Enter interface.
    23  func (c *Cloner) Enter(node Node) (Node, bool) {
    24  	return copyStruct(node), false
    25  }
    26  
    27  // Leave implements Visitor Leave interface.
    28  func (c *Cloner) Leave(in Node) (out Node, ok bool) {
    29  	return in, true
    30  }
    31  
    32  // copyStruct copies a node's struct value, if the struct has slice member,
    33  // make a new slice and copy old slice value to new slice.
    34  func copyStruct(in Node) (out Node) {
    35  	switch v := in.(type) {
    36  	case *ValueExpr:
    37  		nv := *v
    38  		out = &nv
    39  	case *BetweenExpr:
    40  		nv := *v
    41  		out = &nv
    42  	case *BinaryOperationExpr:
    43  		nv := *v
    44  		out = &nv
    45  	case *WhenClause:
    46  		nv := *v
    47  		out = &nv
    48  	case *CaseExpr:
    49  		nv := *v
    50  		nv.WhenClauses = make([]*WhenClause, len(v.WhenClauses))
    51  		copy(nv.WhenClauses, v.WhenClauses)
    52  		out = &nv
    53  	case *SubqueryExpr:
    54  		nv := *v
    55  		out = &nv
    56  	case *CompareSubqueryExpr:
    57  		nv := *v
    58  		out = &nv
    59  	case *ColumnName:
    60  		nv := *v
    61  		out = &nv
    62  	case *ColumnNameExpr:
    63  		nv := *v
    64  		out = &nv
    65  	case *DefaultExpr:
    66  		nv := *v
    67  		out = &nv
    68  	case *ExistsSubqueryExpr:
    69  		nv := *v
    70  		out = &nv
    71  	case *PatternInExpr:
    72  		nv := *v
    73  		nv.List = make([]ExprNode, len(v.List))
    74  		copy(nv.List, v.List)
    75  		out = &nv
    76  	case *IsNullExpr:
    77  		nv := *v
    78  		out = &nv
    79  	case *IsTruthExpr:
    80  		nv := *v
    81  		out = &nv
    82  	case *PatternLikeExpr:
    83  		nv := *v
    84  		out = &nv
    85  	case *ParamMarkerExpr:
    86  		nv := *v
    87  		out = &nv
    88  	case *ParenthesesExpr:
    89  		nv := *v
    90  		out = &nv
    91  	case *PositionExpr:
    92  		nv := *v
    93  		out = &nv
    94  	case *PatternRegexpExpr:
    95  		nv := *v
    96  		out = &nv
    97  	case *RowExpr:
    98  		nv := *v
    99  		nv.Values = make([]ExprNode, len(v.Values))
   100  		copy(nv.Values, v.Values)
   101  		out = &nv
   102  	case *UnaryOperationExpr:
   103  		nv := *v
   104  		out = &nv
   105  	case *ValuesExpr:
   106  		nv := *v
   107  		out = &nv
   108  	case *VariableExpr:
   109  		nv := *v
   110  		out = &nv
   111  	case *Join:
   112  		nv := *v
   113  		out = &nv
   114  	case *TableName:
   115  		nv := *v
   116  		out = &nv
   117  	case *TableSource:
   118  		nv := *v
   119  		out = &nv
   120  	case *OnCondition:
   121  		nv := *v
   122  		out = &nv
   123  	case *WildCardField:
   124  		nv := *v
   125  		out = &nv
   126  	case *SelectField:
   127  		nv := *v
   128  		out = &nv
   129  	case *FieldList:
   130  		nv := *v
   131  		nv.Fields = make([]*SelectField, len(v.Fields))
   132  		copy(nv.Fields, v.Fields)
   133  		out = &nv
   134  	case *TableRefsClause:
   135  		nv := *v
   136  		out = &nv
   137  	case *ByItem:
   138  		nv := *v
   139  		out = &nv
   140  	case *GroupByClause:
   141  		nv := *v
   142  		nv.Items = make([]*ByItem, len(v.Items))
   143  		copy(nv.Items, v.Items)
   144  		out = &nv
   145  	case *HavingClause:
   146  		nv := *v
   147  		out = &nv
   148  	case *OrderByClause:
   149  		nv := *v
   150  		nv.Items = make([]*ByItem, len(v.Items))
   151  		copy(nv.Items, v.Items)
   152  		out = &nv
   153  	case *SelectStmt:
   154  		nv := *v
   155  		out = &nv
   156  	case *UnionSelectList:
   157  		nv := *v
   158  		nv.Selects = make([]*SelectStmt, len(v.Selects))
   159  		copy(nv.Selects, v.Selects)
   160  		out = &nv
   161  	case *UnionStmt:
   162  		nv := *v
   163  		out = &nv
   164  	default:
   165  		// We currently only handle expression and select statement.
   166  		// Will add more when we need to.
   167  		panic("unknown ast Node type " + fmt.Sprintf("%T", v))
   168  	}
   169  	return
   170  }