Когда я запускаю приведенный ниже код Scala из Spark 2.0 REPL (spark-shell), он работает, как я и предполагал, разбивая строку с помощью простого регулярного выражения.
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.