Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,14 @@ object StructType extends AbstractDataType {
*/
def fromDDL(ddl: String): StructType = CatalystSqlParser.parseTableSchema(ddl)

/**
* Converts a value of StructType to a string in DDL format. For example:
* `StructType(Seq(StructField("a", IntegerType)))` should be converted to `a int`
*/
def toDDL(struct: StructType): String = {
struct.map(field => s"${quoteIdentifier(field.name)} ${field.dataType.sql}").mkString(",")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this also handle the special character ('\n', '\t', '', ...) that needs an escape?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use similar code in SHOW CREATE TABLE:

s"${quoteIdentifier(column.name)} ${column.dataType.catalogString}${comment.getOrElse("")}"

}

def apply(fields: Seq[StructField]): StructType = StructType(fields.toArray)

def apply(fields: java.util.List[StructField]): StructType = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.spark.sql.types

import org.apache.spark.SparkFunSuite
import org.apache.spark.sql.types.StructType.{fromDDL, toDDL}

class StructTypeSuite extends SparkFunSuite {

Expand All @@ -37,4 +38,29 @@ class StructTypeSuite extends SparkFunSuite {
val e = intercept[IllegalArgumentException](s.fieldIndex("c")).getMessage
assert(e.contains("Available fields: a, b"))
}

test("SPARK-24849: toDDL - simple struct") {
val struct = StructType(Seq(StructField("a", IntegerType)))

assert(toDDL(struct) == "`a` INT")
}

test("SPARK-24849: round trip toDDL - fromDDL") {
val struct = new StructType().add("a", IntegerType).add("b", StringType)

assert(fromDDL(toDDL(struct)) === struct)
}

test("SPARK-24849: round trip fromDDL - toDDL") {
val struct = "`a` MAP<INT, STRING>,`b` INT"

assert(toDDL(fromDDL(struct)) === struct)
}

test("SPARK-24849: toDDL must take into account case") {
val struct = new StructType()
.add("metaData", new StructType().add("eventId", StringType))

assert(toDDL(struct) == "`metaData` STRUCT<`eventId`: STRING>")
}
}