为什么SparkSQL在SQL查询中需要两个文字转义反斜杠?

时间:2017-01-20 13:39:21

标签: apache-spark apache-spark-sql apache-spark-2.0

当我从Spark 2.0 REPL(spark-shell)运行下面的Scala代码时,它按照我的意图运行,用简单的正则表达式分割字符串。

import org.apache.spark.sql.SparkSession

// Create session
val sparkSession = SparkSession.builder.master("local").getOrCreate()

// Use SparkSQL to split a string
val query = "SELECT split('What is this? A string I think', '\\\\?') AS result"
println("The query is: " + query)
val dataframe = sparkSession.sql(query)

// Show the result
dataframe.show(1, false)

给出预期的输出

+---------------------------------+
|result                           |
+---------------------------------+
|[What is this,  A string I think]|
+---------------------------------+

但我很困惑需要使用单个但不是双反斜杠来逃避文字问号(这里表示为四个反斜杠,因为当不使用三重引用时我们当然必须在Scala中转义反斜杠)。

我确认我的同事为Spark 1.5 编写的一些非常相似的代码使用单个(文字)反斜杠就可以正常工作。但是如果我只在Spark 2.1中使用单个字面反斜杠,我会从JVM的正则表达式引擎"Dangling meta character '?' near index 0"中得到错误。我知道这意味着问号没有被正确转义,但它有点像反斜杠本身必须为第一个Scala和然后 SQL转义。

我猜测这对于将控制字符(如换行符)插入SQL查询本身非常有用。如果这已经从Spark 1.5变为2.1,我感到很困惑?

我已经搜索了相当多的内容,但没有找到任何东西。任何事情都发生了变化,或者我的同事的代码以无意的方式运作。

我也尝试使用Python / pyspark,并且适用相同的条件 - SQL中需要双反斜杠。

任何人都能解释一下吗?

我在Windows上运行相对简单的设置,使用Spark 2.1.0,JDK 1.8.0_111和Hadoop winutils.exe。

2 个答案:

答案 0 :(得分:2)

可能是因为反斜杠是特殊符号,用于连接多行SQL。

sql_1 = spark.sql("SELECT \
    1 AS `col1`, '{0}' AS `col2`".format(var_1))

答案 1 :(得分:0)

以下是获得相同结果的一些不同方法:

三重引号

spark.sql("""SELECT split('What is this? A string I think', '\\?') AS result""").show(false)

正则表达式字符转义

spark.sql("""SELECT split('What is this? A string I think', '\\Q?\\E') AS result""").show(false)

模式.引用

假设您的字符串在 DataFrame 中。

val df = Seq(
  ("What is this? A string I think")
).toDF("your_string")

您可以利用 Java 正则表达式引用函数来拆分字符串,如下所示:

import java.util.regex.Pattern
import org.apache.spark.sql.functions._

df
  .withColumn("split_string", split($"your_string", Pattern.quote("?")))
  .show(false)

输出如下:

+------------------------------+---------------------------------+
|your_string                   |split_string                     |
+------------------------------+---------------------------------+
|What is this? A string I think|[What is this,  A string I think]|
+------------------------------+---------------------------------+

有关详细信息,请参阅 this post