@@ -71,11 +71,66 @@ func NewModifyColumnDiffByDefinition(definition *sqlparser.ColumnDefinition) *Mo
71
71
}
72
72
73
73
type ColumnDefinitionEntity struct {
74
- columnDefinition * sqlparser.ColumnDefinition
74
+ columnDefinition * sqlparser.ColumnDefinition
75
+ tableCharsetCollate * charsetCollate
76
+ Env * Environment
75
77
}
76
78
77
- func NewColumnDefinitionEntity (c * sqlparser.ColumnDefinition ) * ColumnDefinitionEntity {
78
- return & ColumnDefinitionEntity {columnDefinition : c }
79
+ func NewColumnDefinitionEntity (env * Environment , c * sqlparser.ColumnDefinition , tableCharsetCollate * charsetCollate ) * ColumnDefinitionEntity {
80
+ return & ColumnDefinitionEntity {
81
+ columnDefinition : c ,
82
+ tableCharsetCollate : tableCharsetCollate ,
83
+ Env : env ,
84
+ }
85
+ }
86
+
87
+ func (c * ColumnDefinitionEntity ) Clone () * ColumnDefinitionEntity {
88
+ clone := & ColumnDefinitionEntity {
89
+ columnDefinition : sqlparser .Clone (c .columnDefinition ),
90
+ tableCharsetCollate : c .tableCharsetCollate ,
91
+ Env : c .Env ,
92
+ }
93
+ return clone
94
+ }
95
+
96
+ // SetExplicitCharsetCollate enriches this column definition with collation and charset. Those may be
97
+ // already present, or perhaps just one of them is present (in which case we use the one to populate the other),
98
+ // or both might be missing, in which case we use the table's charset/collation.
99
+ func (c * ColumnDefinitionEntity ) SetExplicitCharsetCollate () error {
100
+ if ! c .IsTextual () {
101
+ return nil
102
+ }
103
+ // We will now denormalize the columns charset & collate as needed (if empty, populate from table.)
104
+ // Normalizing _this_ column definition:
105
+ if c .columnDefinition .Type .Charset .Name != "" && c .columnDefinition .Type .Options .Collate == "" {
106
+ // Charset defined without collation. Assign the default collation for that charset.
107
+ collation := c .Env .CollationEnv ().DefaultCollationForCharset (c .columnDefinition .Type .Charset .Name )
108
+ if collation == collations .Unknown {
109
+ return & UnknownColumnCharsetCollationError {Column : c .columnDefinition .Name .String (), Charset : c .tableCharsetCollate .charset }
110
+ }
111
+ c .columnDefinition .Type .Options .Collate = c .Env .CollationEnv ().LookupName (collation )
112
+ }
113
+ if c .columnDefinition .Type .Charset .Name == "" && c .columnDefinition .Type .Options .Collate != "" {
114
+ // Column has explicit collation but no charset. We can infer the charset from the collation.
115
+ collationID := c .Env .CollationEnv ().LookupByName (c .columnDefinition .Type .Options .Collate )
116
+ charset := c .Env .CollationEnv ().LookupCharsetName (collationID )
117
+ if charset == "" {
118
+ return & UnknownColumnCollationCharsetError {Column : c .columnDefinition .Name .String (), Collation : c .columnDefinition .Type .Options .Collate }
119
+ }
120
+ c .columnDefinition .Type .Charset .Name = charset
121
+ }
122
+ if c .columnDefinition .Type .Charset .Name == "" {
123
+ // Still nothing? Assign the table's charset/collation.
124
+ c .columnDefinition .Type .Charset .Name = c .tableCharsetCollate .charset
125
+ if c .columnDefinition .Type .Options .Collate = c .tableCharsetCollate .collate ; c .columnDefinition .Type .Options .Collate == "" {
126
+ collation := c .Env .CollationEnv ().DefaultCollationForCharset (c .tableCharsetCollate .charset )
127
+ if collation == collations .Unknown {
128
+ return & UnknownColumnCharsetCollationError {Column : c .columnDefinition .Name .String (), Charset : c .tableCharsetCollate .charset }
129
+ }
130
+ c .columnDefinition .Type .Options .Collate = c .Env .CollationEnv ().LookupName (collation )
131
+ }
132
+ }
133
+ return nil
79
134
}
80
135
81
136
// ColumnDiff compares this table statement with another table statement, and sees what it takes to
@@ -98,100 +153,22 @@ func (c *ColumnDefinitionEntity) ColumnDiff(
98
153
env * Environment ,
99
154
tableName string ,
100
155
other * ColumnDefinitionEntity ,
101
- t1cc * charsetCollate ,
102
- t2cc * charsetCollate ,
103
156
hints * DiffHints ,
104
157
) (* ModifyColumnDiff , error ) {
158
+ cClone := c // not real clone yet
159
+ otherClone := other // not real clone yet
105
160
if c .IsTextual () || other .IsTextual () {
106
- // We will now denormalize the columns charset & collate as needed (if empty, populate from table.)
107
- // Normalizing _this_ column definition:
108
- if c .columnDefinition .Type .Charset .Name != "" && c .columnDefinition .Type .Options .Collate == "" {
109
- // Charset defined without collation. Assign the default collation for that charset.
110
- collation := env .CollationEnv ().DefaultCollationForCharset (c .columnDefinition .Type .Charset .Name )
111
- if collation == collations .Unknown {
112
- return nil , & UnknownColumnCharsetCollationError {Column : c .columnDefinition .Name .String (), Charset : t1cc .charset }
113
- }
114
- defer func () {
115
- c .columnDefinition .Type .Options .Collate = ""
116
- }()
117
- c .columnDefinition .Type .Options .Collate = env .CollationEnv ().LookupName (collation )
118
- }
119
- if c .columnDefinition .Type .Charset .Name == "" && c .columnDefinition .Type .Options .Collate != "" {
120
- // Column has explicit collation but no charset. We can infer the charset from the collation.
121
- collationID := env .CollationEnv ().LookupByName (c .columnDefinition .Type .Options .Collate )
122
- charset := env .CollationEnv ().LookupCharsetName (collationID )
123
- if charset == "" {
124
- return nil , & UnknownColumnCollationCharsetError {Column : c .columnDefinition .Name .String (), Collation : c .columnDefinition .Type .Options .Collate }
125
- }
126
- defer func () {
127
- c .columnDefinition .Type .Charset .Name = ""
128
- }()
129
- c .columnDefinition .Type .Charset .Name = charset
130
- }
131
- if c .columnDefinition .Type .Charset .Name == "" {
132
- // Still nothing? Assign the table's charset/collation.
133
- defer func () {
134
- c .columnDefinition .Type .Charset .Name = ""
135
- c .columnDefinition .Type .Options .Collate = ""
136
- }()
137
- c .columnDefinition .Type .Charset .Name = t1cc .charset
138
- if c .columnDefinition .Type .Options .Collate == "" {
139
- defer func () {
140
- c .columnDefinition .Type .Options .Collate = ""
141
- }()
142
- c .columnDefinition .Type .Options .Collate = t1cc .collate
143
- }
144
- if c .columnDefinition .Type .Options .Collate = t1cc .collate ; c .columnDefinition .Type .Options .Collate == "" {
145
- collation := env .CollationEnv ().DefaultCollationForCharset (t1cc .charset )
146
- if collation == collations .Unknown {
147
- return nil , & UnknownColumnCharsetCollationError {Column : c .columnDefinition .Name .String (), Charset : t1cc .charset }
148
- }
149
- c .columnDefinition .Type .Options .Collate = env .CollationEnv ().LookupName (collation )
150
- }
161
+ cClone = c .Clone ()
162
+ if err := cClone .SetExplicitCharsetCollate (); err != nil {
163
+ return nil , err
151
164
}
152
- // Normalizing _the other_ column definition:
153
- if other .columnDefinition .Type .Charset .Name != "" && other .columnDefinition .Type .Options .Collate == "" {
154
- // Charset defined without collation. Assign the default collation for that charset.
155
- collation := env .CollationEnv ().DefaultCollationForCharset (other .columnDefinition .Type .Charset .Name )
156
- if collation == collations .Unknown {
157
- return nil , & UnknownColumnCharsetCollationError {Column : other .columnDefinition .Name .String (), Charset : t2cc .charset }
158
- }
159
- defer func () {
160
- other .columnDefinition .Type .Options .Collate = ""
161
- }()
162
- other .columnDefinition .Type .Options .Collate = env .CollationEnv ().LookupName (collation )
163
- }
164
- if other .columnDefinition .Type .Charset .Name == "" && other .columnDefinition .Type .Options .Collate != "" {
165
- // Column has explicit collation but no charset. We can infer the charset from the collation.
166
- collationID := env .CollationEnv ().LookupByName (other .columnDefinition .Type .Options .Collate )
167
- charset := env .CollationEnv ().LookupCharsetName (collationID )
168
- if charset == "" {
169
- return nil , & UnknownColumnCollationCharsetError {Column : other .columnDefinition .Name .String (), Collation : other .columnDefinition .Type .Options .Collate }
170
- }
171
- defer func () {
172
- other .columnDefinition .Type .Charset .Name = ""
173
- }()
174
- other .columnDefinition .Type .Charset .Name = charset
175
- }
176
-
177
- if other .columnDefinition .Type .Charset .Name == "" {
178
- // Still nothing? Assign the table's charset/collation.
179
- defer func () {
180
- other .columnDefinition .Type .Charset .Name = ""
181
- other .columnDefinition .Type .Options .Collate = ""
182
- }()
183
- other .columnDefinition .Type .Charset .Name = t2cc .charset
184
- if other .columnDefinition .Type .Options .Collate = t2cc .collate ; other .columnDefinition .Type .Options .Collate == "" {
185
- collation := env .CollationEnv ().DefaultCollationForCharset (t2cc .charset )
186
- if collation == collations .Unknown {
187
- return nil , & UnknownColumnCharsetCollationError {Column : other .columnDefinition .Name .String (), Charset : t2cc .charset }
188
- }
189
- other .columnDefinition .Type .Options .Collate = env .CollationEnv ().LookupName (collation )
190
- }
165
+ otherClone = other .Clone ()
166
+ if err := otherClone .SetExplicitCharsetCollate (); err != nil {
167
+ return nil , err
191
168
}
192
169
}
193
170
194
- if sqlparser .Equals .RefOfColumnDefinition (c .columnDefinition , other .columnDefinition ) {
171
+ if sqlparser .Equals .RefOfColumnDefinition (cClone .columnDefinition , otherClone .columnDefinition ) {
195
172
return nil , nil
196
173
}
197
174
@@ -204,11 +181,11 @@ func (c *ColumnDefinitionEntity) ColumnDiff(
204
181
}
205
182
switch hints .EnumReorderStrategy {
206
183
case EnumReorderStrategyReject :
207
- otherEnumValuesMap := getEnumValuesMap (other .columnDefinition .Type .EnumValues )
208
- for ordinal , enumValue := range c .columnDefinition .Type .EnumValues {
184
+ otherEnumValuesMap := getEnumValuesMap (otherClone .columnDefinition .Type .EnumValues )
185
+ for ordinal , enumValue := range cClone .columnDefinition .Type .EnumValues {
209
186
if otherOrdinal , ok := otherEnumValuesMap [enumValue ]; ok {
210
187
if ordinal != otherOrdinal {
211
- return nil , & EnumValueOrdinalChangedError {Table : tableName , Column : c .columnDefinition .Name .String (), Value : enumValue , Ordinal : ordinal , NewOrdinal : otherOrdinal }
188
+ return nil , & EnumValueOrdinalChangedError {Table : tableName , Column : cClone .columnDefinition .Name .String (), Value : enumValue , Ordinal : ordinal , NewOrdinal : otherOrdinal }
212
189
}
213
190
}
214
191
}
0 commit comments