ESQL: Fix null comparison type checking#140660
Conversation
# Conflicts: # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
|
Pinging @elastic/es-analytical-engine (Team:Analytics) |
# Conflicts: # x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
|
buildkite test this |
There was a problem hiding this comment.
I think the fix is ok, but it needs more refining before merge:
- in
In:242the comment is no longer accurate. That specific method has been removed. - check any csv-spec tests that we have for
unsigned_long,nullandin. If we don't have any, please add some. I would start withunsigned_long.csv-spec. - same ask as the previous one, but for tests that use
nullin boolean logical operations, for examplefrom ul_logs | eval x = null OR bytes_in > nullorfrom ul_logs | eval x = null or bytes_in > 2::unsigned_long
| @@ -241,12 +242,10 @@ private static List<BiConsumer<LogicalPlan, Failures>> planCheckers(LogicalPlan | |||
| private static void checkOperationsOnUnsignedLong(LogicalPlan p, Failures failures) { | |||
There was a problem hiding this comment.
I suggest the following change to this method (simplified and with a better comment):
/**
* This validates only the negation operator, the rest of the validation is performed in
* {@link org.elasticsearch.xpack.esql.analysis.Verifier#validateBinaryComparison(BinaryComparison)}
* and
* {@link org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.EsqlBinaryComparison#areTypesCompatible(DataType, DataType)}
*/
private static void checkOperationsOnUnsignedLong(LogicalPlan p, Failures failures) {
p.forEachExpression(Neg.class, neg -> {
Failure f = validateUnsignedLongNegation(neg);
if (f != null) {
failures.add(f);
}
});
}
| * | ||
| * @return a Failure if the left operand type is not allowed, null otherwise | ||
| */ | ||
| private static Failure checkBinaryComparisonTypes(BinaryComparison bc) { |
There was a problem hiding this comment.
Change the name of this method accordingly, since now it looks only at the left side of a binary comparison.
| return null; | ||
| } | ||
|
|
||
| /** Ensure that UNSIGNED_LONG types are not implicitly converted when used in arithmetic binary operator, as this cannot be done since: |
There was a problem hiding this comment.
Save this comment somewhere, since it's valuable information regarding unsigned_long types compatibility.
| * Test that null comparisons are valid and don't produce type incompatibility errors. | ||
| * Null should be compatible with any type in binary comparisons. | ||
| */ | ||
| public void testNullComparisonValidation() { |
There was a problem hiding this comment.
Consider adding tests comparing unsigned_long with null as well.
| 10022 | Shahaf | Famili | ||
| ; | ||
|
|
||
| ############################################### |
There was a problem hiding this comment.
Add more complex tests that get a null from an operation for example.
row x = null, y = 1, z = 2 | eval t = x + 1 > z
|
|
||
| assertEquals( | ||
| "1:19: first argument of [emp_no == ?] is [numeric] so second argument must also be [numeric] but was [null]", | ||
| error("from test | where emp_no == ?", new Object[] { null }) |
There was a problem hiding this comment.
Don't remove this query entirely, but move it to the method above and validate that a param null is still being passed correctly.
|
Thank you for your review, @astefan! I’ve updated the code based on your comments. I also revised the |
|
buildkite test this |
|
Hi @astefan, I believe the failing test is not caused by this PR. It appears to be an issue specific to the CI runner. |
|
buildkite test this |
|
buildkite test this |
|
This is quite unexpected. I have switched to regex warnings and double-checked the tests to ensure they pass locally. |
|
buildkite test this |
Remove redundant comments
…null-comparison-type-check
|
Thanks for the patches, @astefan. Actually, this removal doesn't address these failures. I previously ran But I am not quite sure if |
|
buildkite test this |
|
Thank you for explaining @kanoshiou. #139262 cannot be easily reproduced, actually at all so far. Those failures have been noticed in several runs in CI, but not at all locally in tests. I have tested that query with no warnings in csv-spec file locally and both these runs were ok with it:
But, I think there is an explanation and for this test to be future-safe (multiple CI runs and highly randomized environments) I think we need to make this query (maybe others, haven't looked into it) more deterministic. Take a look at this javadoc https://github.com/elastic/elasticsearch/blob/main/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java#L184-L194 and the one from For that specific query I suggest a change like the following, if I am not missing anything: |
|
Thanks for the guidance, @astefan. The Javadocs were really helpful and cleared up my confusion about the inconsistent test results. I’ve updated the test to match your suggestion. Since there appear to be other non-deterministic tests as well, I’d be happy to address those in a separate PR if you'd like. |
|
buildkite test this |
| ; | ||
|
|
||
|
|
||
| # unsigned_long field not equal to null with WHERE (null rows filtered out) |
There was a problem hiding this comment.
This filters out all rows not only "null rows".
(cherry picked from commit b30aa50)
This PR fixes an issue where comparing
nullwith other types incorrectly produced a type incompatibility error.For example,
ROW x = null, y = 1 | WHERE x == ywould fail with a type error instead of correctly evaluating tonull. Null should be compatible with any type and evaluate to null at runtime, matching the behavior ofEsqlBinaryComparison.checkCompatibility.Fixes #140460