-
Notifications
You must be signed in to change notification settings - Fork 24.8k
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
SQL: Introduce Coalesce function #35253
Conversation
Add Coalesce conditional for replacing null values Fix elastic#35060
Pinging @elastic/es-search-aggs |
// | ||
|
||
dateTimeOverNull | ||
SELECT YEAR(CAST(NULL AS DATE)) d; |
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.
@matriv notice that now null
is supported in the CSV tests.
@@ -114,6 +114,11 @@ public static void assertResultSetMetadata(ResultSet expected, ResultSet actual, | |||
if (expectedType == Types.FLOAT && expected instanceof CsvResultSet) { | |||
expectedType = Types.REAL; | |||
} | |||
// csv doesn't support NULL type so skip type checking | |||
if (actualType == Types.NULL && expected instanceof CsvResultSet) { |
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.
hack to get jdbc-csv to support null. /cc @matriv
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.
Left few comments related to tests.
Also, thinking out loud, I'm wondering if wouldn't be better to add some Coalesce-specific random testing, where more null
s would be introduced in the list of values... atm, NodeSubclassTests
would do this but it is probably not generating as many null
s as we would like to see for this specific function?
|
||
|
||
divOfNull | ||
SELECT 5 / CAST(NULL AS FLOAT) + 10 AS n; |
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.
Why not SELECT 5 / NULL AS n
, without casting?
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.
Because I want to check that the a cast preserve the null value and its associated type. I've renamed the test and added a basic one without cast.
|
||
c:i | ||
124 | ||
; |
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.
Can you add a test where the first value is non-null? (all tests with COALESCE assume there is at least one null value before the first non-null)
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.
Added (there's an optimization test that tries that but anyway).
|
||
coalesceWithFirstNullOfNumber | ||
SELECT COALESCE(null, 123) AS c; | ||
|
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 also add a test where all values are null
.
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.
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.
Hm... my bad, not sure why I haven't seen that.
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.
Looks good! Left some comments/questions and request for more tests.
@@ -15,7 +15,7 @@ | |||
|
|||
static final IsNotNullProcessor INSTANCE = new IsNotNullProcessor(); | |||
|
|||
public static final String NAME = "inn"; | |||
public static final String NAME = "ninn"; |
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.
why ninn
? I'd prefer less cryptic name: isnotnull
.
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.
n=Null
inn=IsNotNull
which leads to
ninn=NullIsNotNull
Not that it is suppose to be readable. Since the name is saved in the serialization, we try to keep them short with some ad-hoc convention.
|
||
public class CoalesceProcessor implements Processor { | ||
|
||
public static final String NAME = "nco"; |
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.
also here, I don't get the n
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.
same as above:
n = null
co = coalesce
|
||
public class Coalesce extends ConditionalFunction { | ||
|
||
private DataType dataType = DataType.NULL; |
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 don't like it so much to use NULL
as it can be anything (depends on the arguments). I don't have a better suggestion for the moment though.
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 dataType gets initialized on the first value - however if that is null (or the list is empty), the dataType remains the default, namely NULL
(aka unknown) which I think it's appropriate.
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.
yes. makes sense. thx!
} | ||
|
||
public abstract Processor asProcessor(List<Processor> procs); | ||
} |
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.
don't we need equals()
here (or in the parent class) to check that instances are of the same class?
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.
No, because this check already exists. From Node#equals
:
if (obj == null || getClass() != obj.getClass()) {
return false;
}
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.
ah ok, overlooked that!
}; | ||
return def(function, builder, false, aliases); | ||
} | ||
|
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.
Really really minor: can you remove the empty line or add it to the other places between the def
variant and the iface?
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.
Sure, I've added it to the rest (the source wasn't consistent).
SELECT COALESCE(null, ABS(emp_no) + 1) AS c FROM test_emp ORDER BY emp_no LIMIT 5; | ||
|
||
coalesceHaving | ||
SELECT COALESCE(languages, 0) c FROM test_emp GROUP BY languages ORDER BY languages; |
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.
there is no having condition here. can we add one?
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.
Also, can you add a test when COALESCE is used in the WHERE filter (no aggregations).
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.
done.
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!
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
…-agg * master: (528 commits) Register Azure max_retries setting (elastic#35286) add version 6.4.4 [Docs] Add painless context details for bucket_script (elastic#35142) Upgrade jline to 3.8.2 (elastic#35288) SQL: new SQL CLI logo (elastic#35261) Logger: Merge ESLoggerFactory into Loggers (elastic#35146) Docs: Add section about range query for range type (elastic#35222) [ILM] change remove-policy-from-index http method from DELETE to POST (elastic#35268) [CCR] Forgot missing return statement, SQL: Fix null handling for AND and OR in SELECT (elastic#35277) [TEST] Mute ChangePolicyForIndexIT#testChangePolicyForIndex Serialize ignore_throttled also to 6.6 after backport Check for java 11 in buildSrc (elastic#35260) [TEST] increase await timeout in RemoteClusterConnectionTests Add missing up-to-date configuration (elastic#35255) Adapt Lucene BWC version SQL: Introduce Coalesce function (elastic#35253) Upgrade to lucene-8.0.0-snapshot-31d7dfe6b1 (elastic#35224) Fix failing ICU tests (elastic#35207) Prevent throttled indices to be searched through wildcards by default (elastic#34354) ...
Add Coalesce conditional for replacing null values.
Fix #35060
P.S. This took longer than it should due to some gradle foobar. Also more tests need to be added on the having front.