@@ -169,6 +169,7 @@ case class CreateMetastoreDataSourceAsSelect(
169169 options
170170 }
171171
172+ var existingSchema = None : Option [StructType ]
172173 if (sqlContext.catalog.tableExists(Seq (tableName))) {
173174 // Check if we need to throw an exception or just return.
174175 mode match {
@@ -188,22 +189,7 @@ case class CreateMetastoreDataSourceAsSelect(
188189 val createdRelation = LogicalRelation (resolved.relation)
189190 EliminateSubQueries (sqlContext.table(tableName).logicalPlan) match {
190191 case l @ LogicalRelation (i : InsertableRelation ) =>
191- if (l.schema != createdRelation.schema) {
192- val errorDescription =
193- s " Cannot append to table $tableName because the schema of this " +
194- s " DataFrame does not match the schema of table $tableName. "
195- val errorMessage =
196- s """
197- | $errorDescription
198- |== Schemas ==
199- | ${sideBySide(
200- s " == Expected Schema == " +:
201- l.schema.treeString.split(" \\\n " ),
202- s " == Actual Schema == " +:
203- createdRelation.schema.treeString.split(" \\\n " )).mkString(" \n " )}
204- """ .stripMargin
205- throw new AnalysisException (errorMessage)
206- } else if (i != createdRelation.relation) {
192+ if (i != createdRelation.relation) {
207193 val errorDescription =
208194 s " Cannot append to table $tableName because the resolved relation does not " +
209195 s " match the existing relation of $tableName. " +
@@ -221,6 +207,7 @@ case class CreateMetastoreDataSourceAsSelect(
221207 """ .stripMargin
222208 throw new AnalysisException (errorMessage)
223209 }
210+ existingSchema = Some (l.schema)
224211 case o =>
225212 throw new AnalysisException (s " Saving data in ${o.toString} is not supported. " )
226213 }
@@ -234,15 +221,23 @@ case class CreateMetastoreDataSourceAsSelect(
234221 createMetastoreTable = true
235222 }
236223
237- val df = DataFrame (hiveContext, query)
224+ val data = DataFrame (hiveContext, query)
225+ val df = existingSchema match {
226+ // If we are inserting into an existing table, just use the existing schema.
227+ case Some (schema) => sqlContext.createDataFrame(data.queryExecution.toRdd, schema)
228+ case None => data
229+ }
238230
239231 // Create the relation based on the data of df.
240- ResolvedDataSource (sqlContext, provider, mode, optionsWithPath, df)
232+ val resolved = ResolvedDataSource (sqlContext, provider, mode, optionsWithPath, df)
241233
242234 if (createMetastoreTable) {
235+ // We will use the schema of resolved.relation as the schema of the table (instead of
236+ // the schema of df). It is important since the nullability may be changed by the relation
237+ // provider (for example, see org.apache.spark.sql.parquet.DefaultSource).
243238 hiveContext.catalog.createDataSourceTable(
244239 tableName,
245- Some (df .schema),
240+ Some (resolved.relation .schema),
246241 provider,
247242 optionsWithPath,
248243 isExternal)
0 commit comments