@@ -98,64 +98,48 @@ object ResolveSchemaEvolution extends Rule[LogicalPlan] {
9898 }
9999
100100 /**
101- * Computes the set of table changes needed to evolve `originalTarget ` schema
102- * to accommodate `originalSource ` schema. When `isByName` is true, fields are matched
101+ * Computes the set of table changes needed to evolve `target ` schema
102+ * to accommodate `source ` schema. When `isByName` is true, fields are matched
103103 * by name. When false, fields are matched by position.
104104 */
105105 def computeSchemaChanges (
106- originalTarget : StructType ,
107- originalSource : StructType ,
106+ target : StructType ,
107+ source : StructType ,
108108 isByName : Boolean ): Array [TableChange ] =
109109 computeSchemaChanges(
110- originalTarget,
111- originalSource,
112- originalTarget,
113- originalSource,
110+ target,
111+ source,
114112 fieldPath = Nil ,
115- isByName)
113+ isByName,
114+ error = throw QueryExecutionErrors .failedToMergeIncompatibleSchemasError(
115+ target, source, null ))
116116
117117 private def computeSchemaChanges (
118118 currentType : DataType ,
119119 newType : DataType ,
120- originalTarget : StructType ,
121- originalSource : StructType ,
122120 fieldPath : List [String ],
123- isByName : Boolean ): Array [TableChange ] = {
121+ isByName : Boolean ,
122+ error : => Nothing ): Array [TableChange ] = {
124123 (currentType, newType) match {
125124 case (StructType (currentFields), StructType (newFields)) =>
126125 if (isByName) {
127- computeSchemaChangesByName(
128- currentFields, newFields, originalTarget, originalSource, fieldPath)
126+ computeSchemaChangesByName(currentFields, newFields, fieldPath, error)
129127 } else {
130- computeSchemaChangesByPosition(
131- currentFields, newFields, originalTarget, originalSource, fieldPath)
128+ computeSchemaChangesByPosition(currentFields, newFields, fieldPath, error)
132129 }
133130
134131 case (ArrayType (currentElementType, _), ArrayType (newElementType, _)) =>
135132 computeSchemaChanges(
136- currentElementType,
137- newElementType,
138- originalTarget,
139- originalSource,
140- fieldPath :+ " element" ,
141- isByName)
142-
143- case (MapType (currentKeyType, currentValueType, _),
144- MapType (newKeyType, newValueType, _)) =>
133+ currentElementType, newElementType,
134+ fieldPath :+ " element" , isByName, error)
135+
136+ case (MapType (currentKeyType, currentValueType, _), MapType (newKeyType, newValueType, _)) =>
145137 val keyChanges = computeSchemaChanges(
146- currentKeyType,
147- newKeyType,
148- originalTarget,
149- originalSource,
150- fieldPath :+ " key" ,
151- isByName)
138+ currentKeyType, newKeyType,
139+ fieldPath :+ " key" , isByName, error)
152140 val valueChanges = computeSchemaChanges(
153- currentValueType,
154- newValueType,
155- originalTarget,
156- originalSource,
157- fieldPath :+ " value" ,
158- isByName)
141+ currentValueType, newValueType,
142+ fieldPath :+ " value" , isByName, error)
159143 keyChanges ++ valueChanges
160144
161145 case (currentType : AtomicType , newType : AtomicType ) if currentType != newType =>
@@ -167,8 +151,7 @@ object ResolveSchemaEvolution extends Rule[LogicalPlan] {
167151
168152 case _ =>
169153 // Do not support change between atomic and complex types for now
170- throw QueryExecutionErrors .failedToMergeIncompatibleSchemasError(
171- originalTarget, originalSource, null )
154+ error
172155 }
173156 }
174157
@@ -179,9 +162,8 @@ object ResolveSchemaEvolution extends Rule[LogicalPlan] {
179162 private def computeSchemaChangesByName (
180163 currentFields : Array [StructField ],
181164 newFields : Array [StructField ],
182- originalTarget : StructType ,
183- originalSource : StructType ,
184- fieldPath : List [String ]): Array [TableChange ] = {
165+ fieldPath : List [String ],
166+ onIncompatible : => Nothing ): Array [TableChange ] = {
185167 val currentFieldMap = toFieldMap(currentFields)
186168 val newFieldMap = toFieldMap(newFields)
187169
@@ -190,12 +172,8 @@ object ResolveSchemaEvolution extends Rule[LogicalPlan] {
190172 .filter(f => newFieldMap.contains(f.name))
191173 .flatMap { f =>
192174 computeSchemaChanges(
193- f.dataType,
194- newFieldMap(f.name).dataType,
195- originalTarget,
196- originalSource,
197- fieldPath :+ f.name,
198- isByName = true )
175+ f.dataType, newFieldMap(f.name).dataType,
176+ fieldPath :+ f.name, isByName = true , onIncompatible)
199177 }
200178
201179 // Collect newly added fields
@@ -213,18 +191,13 @@ object ResolveSchemaEvolution extends Rule[LogicalPlan] {
213191 private def computeSchemaChangesByPosition (
214192 currentFields : Array [StructField ],
215193 newFields : Array [StructField ],
216- originalTarget : StructType ,
217- originalSource : StructType ,
218- fieldPath : List [String ]): Array [TableChange ] = {
194+ fieldPath : List [String ],
195+ onIncompatible : => Nothing ): Array [TableChange ] = {
219196 // Update existing field types by pairing fields at the same position.
220197 val updates = currentFields.zip(newFields).flatMap { case (currentField, newField) =>
221198 computeSchemaChanges(
222- currentField.dataType,
223- newField.dataType,
224- originalTarget,
225- originalSource,
226- fieldPath :+ currentField.name,
227- isByName = false )
199+ currentField.dataType, newField.dataType,
200+ fieldPath :+ currentField.name, isByName = false , onIncompatible)
228201 }
229202
230203 // Extra source fields beyond the target's field count are new additions.
0 commit comments