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 }