@@ -167,15 +167,17 @@ final class DataFrameWriter private[sql](df: DataFrame) {
167167 }
168168
169169 private def insertInto (tableIdent : TableIdentifier ): Unit = {
170- val partitions = partitioningColumns .map(_.map(col => col -> (None : Option [String ])).toMap)
170+ val partitions = normalizedParCols .map(_.map(col => col -> (None : Option [String ])).toMap)
171171 val overwrite = mode == SaveMode .Overwrite
172172
173- // A partitioned relation schema's can be different from the input logicalPlan, since
174- // partition columns are all moved after data column. We Project to adjust the ordering.
175- // TODO: this belongs in the analyzer.
176- val input = partitioningColumns.map { parCols =>
177- val projectList = df.logicalPlan.output.filterNot(c => parCols.contains(c.name)) ++
178- parCols.map(UnresolvedAttribute (_))
173+ // A partitioned relation's schema can be different from the input logicalPlan, since
174+ // partition columns are all moved after data columns. We Project to adjust the ordering.
175+ // TODO: this belongs to the analyzer.
176+ val input = normalizedParCols.map { parCols =>
177+ val (inputPartCols, inputDataCols) = df.logicalPlan.output.partition { attr =>
178+ parCols.contains(attr.name)
179+ }
180+ val projectList = inputDataCols ++ inputPartCols.map(c => UnresolvedAttribute (c.name))
179181 Project (projectList, df.logicalPlan)
180182 }.getOrElse(df.logicalPlan)
181183
@@ -188,6 +190,16 @@ final class DataFrameWriter private[sql](df: DataFrame) {
188190 ifNotExists = false )).toRdd
189191 }
190192
193+ private def normalizedParCols : Option [Seq [String ]] = partitioningColumns.map { parCols =>
194+ parCols.map { col =>
195+ df.logicalPlan.output
196+ .map(_.name)
197+ .find(df.queryExecution.analyzer.resolver(_, col))
198+ .getOrElse(throw new AnalysisException (
199+ s " Partition column $col not found in schema ${df.logicalPlan.schema}" ))
200+ }
201+ }
202+
191203 /**
192204 * Saves the content of the [[DataFrame ]] as the specified table.
193205 *
0 commit comments