谓词下推中的硬编码日期格式?

时间:2017-05-25 15:00:28

标签: apache-spark apache-spark-sql

如果在下推的过滤器表达式中使用日期文字,例如

val postingDate = java.sql.Date.valueOf("2016-06-03")
val count = jdbcDF.filter($"POSTINGDATE" === postingDate).count

其中POSTINGDATE列是JDBC类型Date,生成的下推SQL查询如下所示:

SELECT .. <columns> ... FROM <table> WHERE POSTINGDATE = '2016-06-03'

具体来说,使用java.sql.Date.toString发出的硬编码yyyy-MM-dd格式将日期编译成字符串文字。请注意JDBCRDD.compileValue

中日期(和时间戳)值的隐含字符串转换
/**
 * Converts value to SQL expression.
 */
private def compileValue(value: Any): Any = value match {
  case stringValue: String => s"'${escapeSql(stringValue)}'"
  case timestampValue: Timestamp => "'" + timestampValue + "'"
  case dateValue: Date => "'" + dateValue + "'"
  case arrayValue: Array[Any] => arrayValue.map(compileValue).mkString(", ")
  case _ => value
}

如果数据库期望日期字符串文字的格式不同,则生成的查询将失败。例如,Oracle的默认格式是“dd-MMM-yy&#39;”,因此在执行关系查询时,它会因语法错误而失败。

ORA-01861: literal does not match format string
01861. 00000 -  "literal does not match format string"

在某些情况下,可能会更改数据库的预期日期格式以匹配Java格式,但在我们的情况下,我们无法控制它。

似乎这种转换应该通过某种特定于供应商的转换(例如通过JDBCDialect)。我已经提交了一个JIRA问题,但同时,我建议如何解决这个问题?我已经尝试了各种不同的方法,无论是在火花方面还是在JDBC方面,但还没有想出任何东西。这对我们来说是一个关键问题,因为我们正在处理按日期组织的非常大的表 - 没有下推,我们最终会将整个表格拉到Spark侧过滤器。

0 个答案:

没有答案