in src/spark-project/spark-common/src/main/scala/org/apache/spark/sql/SparderTypeUtil.scala [347:422]
def convertStringToValue(s: Any, rowType: RelDataType, toCalcite: Boolean): Any = {
val sqlTypeName = rowType.getSqlTypeName
if (s == null) {
null
} else if (s.toString.isEmpty) {
sqlTypeName match {
case SqlTypeName.DECIMAL => new java.math.BigDecimal(0)
case SqlTypeName.CHAR => s.toString
case SqlTypeName.VARCHAR => s.toString
case SqlTypeName.INTEGER => 0
case SqlTypeName.TINYINT => 0.toByte
case SqlTypeName.SMALLINT => 0.toShort
case SqlTypeName.BIGINT => 0L
case SqlTypeName.FLOAT => 0f
case SqlTypeName.REAL => 0f
case SqlTypeName.DOUBLE => 0d
case SqlTypeName.DATE => 0
case SqlTypeName.TIMESTAMP => 0L
case SqlTypeName.TIME => 0L
case SqlTypeName.BOOLEAN => null;
case null => null
case _ => null
}
} else {
try {
val a: Any = sqlTypeName match {
case SqlTypeName.DECIMAL => transferDecimal(s, rowType)
case SqlTypeName.CHAR => s.toString
case SqlTypeName.VARCHAR => s.toString
case SqlTypeName.INTEGER => s.toString.toInt
case SqlTypeName.TINYINT => s.toString.toByte
case SqlTypeName.SMALLINT => s.toString.toShort
case SqlTypeName.BIGINT => s.toString.toLong
case SqlTypeName.FLOAT => java.lang.Double.parseDouble(s.toString)
case SqlTypeName.DOUBLE => java.lang.Double.parseDouble(s.toString)
case SqlTypeName.DATE =>
// time over here is with timezone.
val string = s.toString
if (string.contains("-")) {
val time = DateFormat.stringToDate(string).getTime
if (toCalcite) {
//current date is local timezone, org.apache.calcite.avatica.util.AbstractCursor.DateFromNumberAccessor need to utc
DateTimeUtils.stringToDate(UTF8String.fromString(string)).get
} else {
// ms to s
time / 1000
}
} else {
// should not come to here?
if (toCalcite) {
(toCalciteTimestamp(DateFormat.stringToMillis(string)) / (3600 * 24 * 1000)).toInt
} else {
DateFormat.stringToMillis(string) / 1000
}
}
case SqlTypeName.TIMESTAMP | SqlTypeName.TIME =>
val ts = s.asInstanceOf[Timestamp].toString
if (toCalcite) {
// current ts is local timezone ,org.apache.calcite.avatica.util.AbstractCursor.TimeFromNumberAccessor need to utc
DateTimeUtils.stringToTimestamp(UTF8String.fromString(ts), TimeZone.getTimeZone("UTC").toZoneId).get / 1000
} else {
// ms to s
s.asInstanceOf[Timestamp].getTime / 1000
}
case SqlTypeName.BOOLEAN => s;
case _ => s.toString
}
a
} catch {
case _: Throwable =>
logWarning(s"""convertStringToValue failed: {"v": "$s", "cls": "${s.getClass}", "type": "$sqlTypeName"}""")
// fixme aron never come to here, for coverage ignore.
safetyConvertStringToValue(s, rowType, toCalcite)
}
}
}