Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,23 @@ import org.apache.spark.util.ArrayImplicits._

// scalastyle:off line.size.limit
@ExpressionDescription(
usage = "_FUNC_(expr1, expr2, expr3) - If `expr1` evaluates to true, then returns `expr2`; otherwise returns `expr3`.",
usage = "_FUNC_(expr1, expr2, expr3) - If `expr1` evaluates to true, then returns `expr2`; otherwise returns `expr3`. If `expr3` is not provided, returns NULL when `expr1` is false.",
examples = """
Examples:
> SELECT _FUNC_(1 < 2, 'a', 'b');
a
> SELECT _FUNC_(1 > 2, 'a');
NULL
""",
since = "1.0.0",
group = "conditional_funcs")
// scalastyle:on line.size.limit
case class If(predicate: Expression, trueValue: Expression, falseValue: Expression)
extends ComplexTypeMergingExpression with ConditionalExpression with TernaryLike[Expression] {

def this(predicate: Expression, trueValue: Expression) =
this(predicate, trueValue, Literal(null))

@transient
override lazy val inputTypesForMerging: Seq[DataType] = {
Seq(trueValue.dataType, falseValue.dataType)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
-- Automatically generated by SQLQueryTestSuite
-- !query
SELECT if(1 < 2, 'yes')
-- !query analysis
Project [if ((1 < 2)) yes else cast(null as string) AS (IF((1 < 2), yes, NULL))#x]
+- OneRowRelation


-- !query
SELECT if(1 > 2, 'yes')
-- !query analysis
Project [if ((1 > 2)) yes else cast(null as string) AS (IF((1 > 2), yes, NULL))#x]
+- OneRowRelation


-- !query
SELECT if(id > 1, id * 10) FROM VALUES (1), (2), (3) AS t(id)
-- !query analysis
Project [if ((id#x > 1)) (id#x * 10) else cast(null as int) AS (IF((id > 1), (id * 10), NULL))#x]
+- SubqueryAlias t
+- LocalRelation [id#x]


-- !query
SELECT if(1 < 2, 'a', 'b')
-- !query analysis
Project [if ((1 < 2)) a else b AS (IF((1 < 2), a, b))#x]
+- OneRowRelation


-- !query
SELECT if(length('hello') > 3, upper('hello'))
-- !query analysis
Project [if ((length(hello) > 3)) upper(hello) else cast(null as string) AS (IF((length(hello) > 3), upper(hello), NULL))#x]
+- OneRowRelation


-- !query
SELECT if(true)
-- !query analysis
org.apache.spark.sql.AnalysisException
{
"errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
"sqlState" : "42605",
"messageParameters" : {
"actualNum" : "1",
"docroot" : "https://spark.apache.org/docs/latest",
"expectedNum" : "[2, 3]",
"functionName" : "`if`"
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
"stopIndex" : 15,
"fragment" : "if(true)"
} ]
}


-- !query
SELECT if(true, 1, 2, 3)
-- !query analysis
org.apache.spark.sql.AnalysisException
{
"errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
"sqlState" : "42605",
"messageParameters" : {
"actualNum" : "4",
"docroot" : "https://spark.apache.org/docs/latest",
"expectedNum" : "[2, 3]",
"functionName" : "`if`"
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
"stopIndex" : 24,
"fragment" : "if(true, 1, 2, 3)"
} ]
}
22 changes: 22 additions & 0 deletions sql/core/src/test/resources/sql-tests/inputs/if-two-arg.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- Tests for two-argument IF (SQL standard: IF(cond, value) returns NULL when false)

-- Two-argument IF: returns value when true
SELECT if(1 < 2, 'yes');

-- Two-argument IF: returns NULL when false
SELECT if(1 > 2, 'yes');

-- Two-argument IF: with column reference
SELECT if(id > 1, id * 10) FROM VALUES (1), (2), (3) AS t(id);

-- Three-argument IF still works (regression check)
SELECT if(1 < 2, 'a', 'b');

-- Two-argument IF with complex expression
SELECT if(length('hello') > 3, upper('hello'));

-- Error: one argument
SELECT if(true);

-- Error: four arguments
SELECT if(true, 1, 2, 3);
91 changes: 91 additions & 0 deletions sql/core/src/test/resources/sql-tests/results/if-two-arg.sql.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
-- Automatically generated by SQLQueryTestSuite
-- !query
SELECT if(1 < 2, 'yes')
-- !query schema
struct<(IF((1 < 2), yes, NULL)):string>
-- !query output
yes


-- !query
SELECT if(1 > 2, 'yes')
-- !query schema
struct<(IF((1 > 2), yes, NULL)):string>
-- !query output
NULL


-- !query
SELECT if(id > 1, id * 10) FROM VALUES (1), (2), (3) AS t(id)
-- !query schema
struct<(IF((id > 1), (id * 10), NULL)):int>
-- !query output
20
30
NULL


-- !query
SELECT if(1 < 2, 'a', 'b')
-- !query schema
struct<(IF((1 < 2), a, b)):string>
-- !query output
a


-- !query
SELECT if(length('hello') > 3, upper('hello'))
-- !query schema
struct<(IF((length(hello) > 3), upper(hello), NULL)):string>
-- !query output
HELLO


-- !query
SELECT if(true)
-- !query schema
struct<>
-- !query output
org.apache.spark.sql.AnalysisException
{
"errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
"sqlState" : "42605",
"messageParameters" : {
"actualNum" : "1",
"docroot" : "https://spark.apache.org/docs/latest",
"expectedNum" : "[2, 3]",
"functionName" : "`if`"
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
"stopIndex" : 15,
"fragment" : "if(true)"
} ]
}


-- !query
SELECT if(true, 1, 2, 3)
-- !query schema
struct<>
-- !query output
org.apache.spark.sql.AnalysisException
{
"errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
"sqlState" : "42605",
"messageParameters" : {
"actualNum" : "4",
"docroot" : "https://spark.apache.org/docs/latest",
"expectedNum" : "[2, 3]",
"functionName" : "`if`"
},
"queryContext" : [ {
"objectType" : "",
"objectName" : "",
"startIndex" : 8,
"stopIndex" : 24,
"fragment" : "if(true, 1, 2, 3)"
} ]
}