Skip to content

Commit

Permalink
add abs() function support
Browse files Browse the repository at this point in the history
  • Loading branch information
bomeng authored and xinyunh committed Aug 29, 2014
1 parent 7f6980a commit ff8e51e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class SqlParser extends StandardTokenParsers with PackratParsers {
protected val SUBSTR = Keyword("SUBSTR")
protected val SUBSTRING = Keyword("SUBSTRING")
protected val SQRT = Keyword("SQRT")
protected val ABS = Keyword("ABS")

// Use reflection to find the reserved words defined in this class.
protected val reservedWords =
Expand Down Expand Up @@ -328,6 +329,7 @@ class SqlParser extends StandardTokenParsers with PackratParsers {
case s ~ "," ~ p ~ "," ~ l => Substring(s,p,l)
} |
SQRT ~> "(" ~> expression <~ ")" ^^ { case exp => Sqrt(exp) } |
ABS ~> "(" ~> expression <~ ")" ^^ { case exp => Abs(exp) } |
ident ~ "(" ~ repsep(expression, ",") <~ ")" ^^ {
case udfName ~ _ ~ exprs => UnresolvedFunction(udfName, exprs)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package org.apache.spark.sql.catalyst.expressions

import org.apache.spark.sql.catalyst.analysis.UnresolvedException
import org.apache.spark.sql.catalyst.types._
import scala.math.pow

case class UnaryMinus(child: Expression) extends UnaryExpression {
type EvaluatedType = Any
Expand Down Expand Up @@ -129,3 +130,52 @@ case class MaxOf(left: Expression, right: Expression) extends Expression {

override def toString = s"MaxOf($left, $right)"
}

/**
* A function that get the absolute value of the numeric value.
*/
case class Abs(child: Expression) extends UnaryExpression {
type EvaluatedType = Any

def dataType = child.dataType
override def foldable = child.foldable
def nullable = child.nullable
override def toString = s"Abs($child)"

override def eval(input: Row): Any = n1(child, input, _.abs(_))
}

/**
* A function that get the power value of two parameters.
* First one is taken as base while second one taken as exponent
*/
case class Power(base: Expression, exponent: Expression) extends Expression {
type EvaluatedType = Any

def dataType: DataType = {
if (!resolved) throw new UnresolvedException(this, s"Cannot resolve since $children are not resolved")
DoubleType
}
override def foldable = base.foldable && exponent.foldable
def nullable: Boolean = base.nullable || exponent.nullable
override def toString = s"Power($base, $exponent)"

override def children = base :: exponent :: Nil

override def eval(input: Row): Any = {
def convertToDouble(num: EvaluatedType): Double = {
num match {
case d:Double => d
case i:Integer => i.doubleValue()
case f:Float => f.toDouble
}
}

val base_v = base.eval(input)
val exponent_v = exponent.eval(input)

if ((base_v == null) || (exponent_v == null)) null
else pow(convertToDouble(base_v), convertToDouble(exponent_v))
}

}

0 comments on commit ff8e51e

Please sign in to comment.