aboutsummaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorypcat <ypcat6@gmail.com>2015-03-22 15:49:13 +0800
committerCheng Lian <lian@databricks.com>2015-03-22 15:49:13 +0800
commit9b1e1f20d4498bda72dd53a832110883a7ca41b5 (patch)
tree0bb26e922aa752f5f5c32cc0881fb507760e1d7c /sql
parentb6090f902e6ec24923b4dde4aabc9076956521c1 (diff)
downloadspark-9b1e1f20d4498bda72dd53a832110883a7ca41b5.tar.gz
spark-9b1e1f20d4498bda72dd53a832110883a7ca41b5.tar.bz2
spark-9b1e1f20d4498bda72dd53a832110883a7ca41b5.zip
[SPARK-6408] [SQL] Fix JDBCRDD filtering string literals
Author: ypcat <ypcat6@gmail.com> Author: Pei-Lun Lee <pllee@appier.com> Closes #5087 from ypcat/spark-6408 and squashes the following commits: 1becc16 [ypcat] [SPARK-6408] [SQL] styling 1bc4455 [ypcat] [SPARK-6408] [SQL] move nested function outside e57fa4a [ypcat] [SPARK-6408] [SQL] fix test case 245ab6f [ypcat] [SPARK-6408] [SQL] add test cases for filtering quoted strings 8962534 [Pei-Lun Lee] [SPARK-6408] [SQL] Fix filtering string literals
Diffstat (limited to 'sql')
-rw-r--r--sql/core/src/main/scala/org/apache/spark/sql/jdbc/JDBCRDD.scala19
-rw-r--r--sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala12
2 files changed, 24 insertions, 7 deletions
diff --git a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JDBCRDD.scala b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JDBCRDD.scala
index 3266b97212..76f8593180 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JDBCRDD.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JDBCRDD.scala
@@ -19,6 +19,7 @@ package org.apache.spark.sql.jdbc
import java.sql.{Connection, DriverManager, ResultSet, ResultSetMetaData, SQLException}
+import org.apache.commons.lang.StringEscapeUtils.escapeSql
import org.apache.spark.{Logging, Partition, SparkContext, TaskContext}
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.catalyst.expressions.{Row, SpecificMutableRow}
@@ -227,15 +228,23 @@ private[sql] class JDBCRDD(
}
/**
+ * Converts value to SQL expression.
+ */
+ private def compileValue(value: Any): Any = value match {
+ case stringValue: String => s"'${escapeSql(stringValue)}'"
+ case _ => value
+ }
+
+ /**
* Turns a single Filter into a String representing a SQL expression.
* Returns null for an unhandled filter.
*/
private def compileFilter(f: Filter): String = f match {
- case EqualTo(attr, value) => s"$attr = $value"
- case LessThan(attr, value) => s"$attr < $value"
- case GreaterThan(attr, value) => s"$attr > $value"
- case LessThanOrEqual(attr, value) => s"$attr <= $value"
- case GreaterThanOrEqual(attr, value) => s"$attr >= $value"
+ case EqualTo(attr, value) => s"$attr = ${compileValue(value)}"
+ case LessThan(attr, value) => s"$attr < ${compileValue(value)}"
+ case GreaterThan(attr, value) => s"$attr > ${compileValue(value)}"
+ case LessThanOrEqual(attr, value) => s"$attr <= ${compileValue(value)}"
+ case GreaterThanOrEqual(attr, value) => s"$attr >= ${compileValue(value)}"
case _ => null
}
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala
index cd737c0b62..5eb6ab2e92 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala
@@ -24,6 +24,7 @@ import java.util.{Calendar, GregorianCalendar}
import org.apache.spark.sql.test._
import org.scalatest.{FunSuite, BeforeAndAfter}
import TestSQLContext._
+import TestSQLContext.implicits._
class JDBCSuite extends FunSuite with BeforeAndAfter {
val url = "jdbc:h2:mem:testdb0"
@@ -38,7 +39,7 @@ class JDBCSuite extends FunSuite with BeforeAndAfter {
conn.prepareStatement("create table test.people (name TEXT(32) NOT NULL, theid INTEGER NOT NULL)").executeUpdate()
conn.prepareStatement("insert into test.people values ('fred', 1)").executeUpdate()
conn.prepareStatement("insert into test.people values ('mary', 2)").executeUpdate()
- conn.prepareStatement("insert into test.people values ('joe', 3)").executeUpdate()
+ conn.prepareStatement("insert into test.people values ('joe ''foo'' \"bar\"', 3)").executeUpdate()
conn.commit()
sql(
@@ -129,13 +130,20 @@ class JDBCSuite extends FunSuite with BeforeAndAfter {
assert(sql("SELECT * FROM foobar WHERE THEID < 1").collect().size == 0)
assert(sql("SELECT * FROM foobar WHERE THEID != 2").collect().size == 2)
assert(sql("SELECT * FROM foobar WHERE THEID = 1").collect().size == 1)
+ assert(sql("SELECT * FROM foobar WHERE NAME = 'fred'").collect().size == 1)
+ assert(sql("SELECT * FROM foobar WHERE NAME > 'fred'").collect().size == 2)
+ assert(sql("SELECT * FROM foobar WHERE NAME != 'fred'").collect().size == 2)
+ }
+
+ test("SELECT * WHERE (quoted strings)") {
+ assert(sql("select * from foobar").where('NAME === "joe 'foo' \"bar\"").collect().size == 1)
}
test("SELECT first field") {
val names = sql("SELECT NAME FROM foobar").collect().map(x => x.getString(0)).sortWith(_ < _)
assert(names.size == 3)
assert(names(0).equals("fred"))
- assert(names(1).equals("joe"))
+ assert(names(1).equals("joe 'foo' \"bar\""))
assert(names(2).equals("mary"))
}