aboutsummaryrefslogtreecommitdiff
path: root/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
diff options
context:
space:
mode:
Diffstat (limited to 'sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala124
1 files changed, 84 insertions, 40 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
index 20818bfb1a..38f1210a4e 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
@@ -88,9 +88,10 @@ trait PredicateHelper {
expr.references.subsetOf(plan.outputSet)
}
-
+@ExpressionDescription(
+ usage = "_FUNC_ a - Logical not")
case class Not(child: Expression)
- extends UnaryExpression with Predicate with ImplicitCastInputTypes {
+ extends UnaryExpression with Predicate with ImplicitCastInputTypes with NullIntolerant {
override def toString: String = s"NOT $child"
@@ -109,6 +110,8 @@ case class Not(child: Expression)
/**
* Evaluates to `true` if `list` contains `value`.
*/
+@ExpressionDescription(
+ usage = "expr _FUNC_(val1, val2, ...) - Returns true if expr equals to any valN.")
case class In(value: Expression, list: Seq[Expression]) extends Predicate
with ImplicitCastInputTypes {
@@ -243,6 +246,8 @@ case class InSet(child: Expression, hset: Set[Any]) extends UnaryExpression with
}
}
+@ExpressionDescription(
+ usage = "a _FUNC_ b - Logical AND.")
case class And(left: Expression, right: Expression) extends BinaryOperator with Predicate {
override def inputType: AbstractDataType = BooleanType
@@ -274,26 +279,40 @@ case class And(left: Expression, right: Expression) extends BinaryOperator with
val eval2 = right.gen(ctx)
// The result should be `false`, if any of them is `false` whenever the other is null or not.
- s"""
- ${eval1.code}
- boolean ${ev.isNull} = false;
- boolean ${ev.value} = false;
+ if (!left.nullable && !right.nullable) {
+ ev.isNull = "false"
+ s"""
+ ${eval1.code}
+ boolean ${ev.value} = false;
- if (!${eval1.isNull} && !${eval1.value}) {
- } else {
- ${eval2.code}
- if (!${eval2.isNull} && !${eval2.value}) {
- } else if (!${eval1.isNull} && !${eval2.isNull}) {
- ${ev.value} = true;
+ if (${eval1.value}) {
+ ${eval2.code}
+ ${ev.value} = ${eval2.value};
+ }
+ """
+ } else {
+ s"""
+ ${eval1.code}
+ boolean ${ev.isNull} = false;
+ boolean ${ev.value} = false;
+
+ if (!${eval1.isNull} && !${eval1.value}) {
} else {
- ${ev.isNull} = true;
+ ${eval2.code}
+ if (!${eval2.isNull} && !${eval2.value}) {
+ } else if (!${eval1.isNull} && !${eval2.isNull}) {
+ ${ev.value} = true;
+ } else {
+ ${ev.isNull} = true;
+ }
}
- }
- """
+ """
+ }
}
}
-
+@ExpressionDescription(
+ usage = "a _FUNC_ b - Logical OR.")
case class Or(left: Expression, right: Expression) extends BinaryOperator with Predicate {
override def inputType: AbstractDataType = BooleanType
@@ -325,22 +344,35 @@ case class Or(left: Expression, right: Expression) extends BinaryOperator with P
val eval2 = right.gen(ctx)
// The result should be `true`, if any of them is `true` whenever the other is null or not.
- s"""
- ${eval1.code}
- boolean ${ev.isNull} = false;
- boolean ${ev.value} = true;
+ if (!left.nullable && !right.nullable) {
+ ev.isNull = "false"
+ s"""
+ ${eval1.code}
+ boolean ${ev.value} = true;
- if (!${eval1.isNull} && ${eval1.value}) {
- } else {
- ${eval2.code}
- if (!${eval2.isNull} && ${eval2.value}) {
- } else if (!${eval1.isNull} && !${eval2.isNull}) {
- ${ev.value} = false;
+ if (!${eval1.value}) {
+ ${eval2.code}
+ ${ev.value} = ${eval2.value};
+ }
+ """
+ } else {
+ s"""
+ ${eval1.code}
+ boolean ${ev.isNull} = false;
+ boolean ${ev.value} = true;
+
+ if (!${eval1.isNull} && ${eval1.value}) {
} else {
- ${ev.isNull} = true;
+ ${eval2.code}
+ if (!${eval2.isNull} && ${eval2.value}) {
+ } else if (!${eval1.isNull} && !${eval2.isNull}) {
+ ${ev.value} = false;
+ } else {
+ ${ev.isNull} = true;
+ }
}
- }
- """
+ """
+ }
}
}
@@ -375,8 +407,10 @@ private[sql] object Equality {
}
}
-
-case class EqualTo(left: Expression, right: Expression) extends BinaryComparison {
+@ExpressionDescription(
+ usage = "a _FUNC_ b - Returns TRUE if a equals b and false otherwise.")
+case class EqualTo(left: Expression, right: Expression)
+ extends BinaryComparison with NullIntolerant {
override def inputType: AbstractDataType = AnyDataType
@@ -399,7 +433,9 @@ case class EqualTo(left: Expression, right: Expression) extends BinaryComparison
}
}
-
+@ExpressionDescription(
+ usage = """a _FUNC_ b - Returns same result with EQUAL(=) operator for non-null operands,
+ but returns TRUE if both are NULL, FALSE if one of the them is NULL.""")
case class EqualNullSafe(left: Expression, right: Expression) extends BinaryComparison {
override def inputType: AbstractDataType = AnyDataType
@@ -440,8 +476,10 @@ case class EqualNullSafe(left: Expression, right: Expression) extends BinaryComp
}
}
-
-case class LessThan(left: Expression, right: Expression) extends BinaryComparison {
+@ExpressionDescription(
+ usage = "a _FUNC_ b - Returns TRUE if a is less than b.")
+case class LessThan(left: Expression, right: Expression)
+ extends BinaryComparison with NullIntolerant {
override def inputType: AbstractDataType = TypeCollection.Ordered
@@ -452,8 +490,10 @@ case class LessThan(left: Expression, right: Expression) extends BinaryCompariso
protected override def nullSafeEval(input1: Any, input2: Any): Any = ordering.lt(input1, input2)
}
-
-case class LessThanOrEqual(left: Expression, right: Expression) extends BinaryComparison {
+@ExpressionDescription(
+ usage = "a _FUNC_ b - Returns TRUE if a is not greater than b.")
+case class LessThanOrEqual(left: Expression, right: Expression)
+ extends BinaryComparison with NullIntolerant {
override def inputType: AbstractDataType = TypeCollection.Ordered
@@ -464,8 +504,10 @@ case class LessThanOrEqual(left: Expression, right: Expression) extends BinaryCo
protected override def nullSafeEval(input1: Any, input2: Any): Any = ordering.lteq(input1, input2)
}
-
-case class GreaterThan(left: Expression, right: Expression) extends BinaryComparison {
+@ExpressionDescription(
+ usage = "a _FUNC_ b - Returns TRUE if a is greater than b.")
+case class GreaterThan(left: Expression, right: Expression)
+ extends BinaryComparison with NullIntolerant {
override def inputType: AbstractDataType = TypeCollection.Ordered
@@ -476,8 +518,10 @@ case class GreaterThan(left: Expression, right: Expression) extends BinaryCompar
protected override def nullSafeEval(input1: Any, input2: Any): Any = ordering.gt(input1, input2)
}
-
-case class GreaterThanOrEqual(left: Expression, right: Expression) extends BinaryComparison {
+@ExpressionDescription(
+ usage = "a _FUNC_ b - Returns TRUE if a is not smaller than b.")
+case class GreaterThanOrEqual(left: Expression, right: Expression)
+ extends BinaryComparison with NullIntolerant {
override def inputType: AbstractDataType = TypeCollection.Ordered