aboutsummaryrefslogtreecommitdiff
path: root/sql/catalyst
diff options
context:
space:
mode:
authorCheng Hao <hao.cheng@intel.com>2015-02-03 12:12:26 -0800
committerMichael Armbrust <michael@databricks.com>2015-02-03 12:12:26 -0800
commitca7a6cdff004eb4605fd223e127b4a46a0a214e7 (patch)
tree31e7c93b147b264557e45eea777dce63e9343ff7 /sql/catalyst
parent0c20ce69fb4bcb1cec5313a9d072826c5588cbbc (diff)
downloadspark-ca7a6cdff004eb4605fd223e127b4a46a0a214e7.tar.gz
spark-ca7a6cdff004eb4605fd223e127b4a46a0a214e7.tar.bz2
spark-ca7a6cdff004eb4605fd223e127b4a46a0a214e7.zip
[SPARK-5550] [SQL] Support the case insensitive for UDF
SQL in HiveContext, should be case insensitive, however, the following query will fail. ```scala udf.register("random0", () => { Math.random()}) assert(sql("SELECT RANDOM0() FROM src LIMIT 1").head().getDouble(0) >= 0.0) ``` Author: Cheng Hao <hao.cheng@intel.com> Closes #4326 from chenghao-intel/udf_case_sensitive and squashes the following commits: 485cf66 [Cheng Hao] Support the case insensitive for UDF
Diffstat (limited to 'sql/catalyst')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala36
1 files changed, 32 insertions, 4 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
index 760c49fbca..9f334f6d42 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
@@ -27,23 +27,25 @@ trait FunctionRegistry {
def registerFunction(name: String, builder: FunctionBuilder): Unit
def lookupFunction(name: String, children: Seq[Expression]): Expression
+
+ def caseSensitive: Boolean
}
trait OverrideFunctionRegistry extends FunctionRegistry {
- val functionBuilders = new mutable.HashMap[String, FunctionBuilder]()
+ val functionBuilders = StringKeyHashMap[FunctionBuilder](caseSensitive)
def registerFunction(name: String, builder: FunctionBuilder) = {
functionBuilders.put(name, builder)
}
abstract override def lookupFunction(name: String, children: Seq[Expression]): Expression = {
- functionBuilders.get(name).map(_(children)).getOrElse(super.lookupFunction(name,children))
+ functionBuilders.get(name).map(_(children)).getOrElse(super.lookupFunction(name, children))
}
}
-class SimpleFunctionRegistry extends FunctionRegistry {
- val functionBuilders = new mutable.HashMap[String, FunctionBuilder]()
+class SimpleFunctionRegistry(val caseSensitive: Boolean) extends FunctionRegistry {
+ val functionBuilders = StringKeyHashMap[FunctionBuilder](caseSensitive)
def registerFunction(name: String, builder: FunctionBuilder) = {
functionBuilders.put(name, builder)
@@ -64,4 +66,30 @@ object EmptyFunctionRegistry extends FunctionRegistry {
def lookupFunction(name: String, children: Seq[Expression]): Expression = {
throw new UnsupportedOperationException
}
+
+ def caseSensitive: Boolean = ???
+}
+
+/**
+ * Build a map with String type of key, and it also supports either key case
+ * sensitive or insensitive.
+ * TODO move this into util folder?
+ */
+object StringKeyHashMap {
+ def apply[T](caseSensitive: Boolean) = caseSensitive match {
+ case false => new StringKeyHashMap[T](_.toLowerCase)
+ case true => new StringKeyHashMap[T](identity)
+ }
+}
+
+class StringKeyHashMap[T](normalizer: (String) => String) {
+ private val base = new collection.mutable.HashMap[String, T]()
+
+ def apply(key: String): T = base(normalizer(key))
+
+ def get(key: String): Option[T] = base.get(normalizer(key))
+ def put(key: String, value: T): Option[T] = base.put(normalizer(key), value)
+ def remove(key: String): Option[T] = base.remove(normalizer(key))
+ def iterator: Iterator[(String, T)] = base.toIterator
}
+