-
Notifications
You must be signed in to change notification settings - Fork 25.2k
SQL: Implement IIF(<cond>, <result1>, <result2>) #41420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Pinging @elastic/es-search |
Implement a more trivial case of the `CASE` expression which is expressed as a traditional function with 2 or 3 arguments. e.g.: ``` IF(a = 1, 'one', 'many') ``` ``` IF(a > 0, 'positive) ``` Closes: elastic#40917
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
The only comment is whether this should be only IIF
instead of IF
since:
Oracle and SQL Server has a different syntax for IF
(IF THEN)
SQL Server does support IIF in this form
Postgres does not support IF
Essentially only MySQL has this flavor of IF
and frankly I would go after the IF THEN format in SQLServer/Oracle instead and drop this one since there would be too many choices IMO.
|
||
public class If extends Case { | ||
|
||
public If(Source source, Expression condition, Expression result, Expression defaultValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defaultValue
should be really else
across the whole hierarchy. (if then else - vs if then default).
ifGroupByAndHaving | ||
schema::count:l|gender:s|languages:byte | ||
SELECT count(*) AS count, gender, languages FROM test_emp | ||
GROUP BY 2, 3 HAVING IF(count(*) > 10, 'many', 'a few') = 'many' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@astefan what do you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I left few small comments.
Regarding IIF
vs. IF
debate, I would keep IIF
only. On one hand we have a bunch of aliases for all the date parts functions - ie "DAY_OF_MONTH", "DAYOFMONTH", "DAY", "DOM"
where DAYOFMONTH
is the "true" function name and others being just aliases we added for ease of use. But all these aliases do have the same functional behavior are cannot be confused with something else, whereas IF
could potentially have a different meaning based on other SQL providers. And if we keep IF
, some users might want to use it as they know it's used in Oracle PL/SQL.
|
||
[TIP] | ||
================= | ||
If functions can be combined to implement more complex logic simulating the <<sql-functions-conditional-case>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Capital letters IF
.
@@ -2095,6 +2097,51 @@ elastic | |||
; | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to see, based on a previous issue fixed in the past, a query where you use a CONVERT
without the optional parameter for IIF, with an alias and grouped by alias: SELECT CONVERT(IIF(languages > 1, IIF(languages = 3, '3')), SQL_BIGINT) AS cond FROM test_emp GROUP BY cond ORDER BY cond DESC
.
|
||
private List<Expression> mutateChildren(If iif) { | ||
List<Expression> expressions = new ArrayList<>(3); | ||
expressions.add(new Equals(randomSource(), randomStringLiteral(), randomStringLiteral())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Equals here shouldn't have either first string different from the original one, either the second one, either both? I know there are small chances for this to happen in tests, but it can happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be but the chances are really small and on top we are changing for sure the thenResult
and the elseResult
. But anyway for 100% correctness I'm changing it to create also a different Equals
condition.
Implement a more trivial case of the CASE expression which is expressed as a traditional function with 2 or 3 arguments. e.g.: IIF(a = 1, 'one', 'many') IIF(a > 0, 'positive') Closes: elastic#40917
Implement a more trivial case of the
CASE
expression which isexpressed as a traditional function with 2 or 3 arguments. e.g.:
Closes: #40917