Skip to content
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

ESQL: COALESCE function #98542

Merged
merged 10 commits into from
Aug 17, 2023
Merged

ESQL: COALESCE function #98542

merged 10 commits into from
Aug 17, 2023

Conversation

nik9000
Copy link
Member

@nik9000 nik9000 commented Aug 16, 2023

This adds a COALESCE function that returns the first non-null value.

This adds a `COALESCE` function that returns the first non-null value.
@github-actions
Copy link
Contributor

Documentation preview:

@elasticsearchmachine elasticsearchmachine added the Team:QL (Deprecated) Meta label for query languages team label Aug 16, 2023
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-ql (Team:QL)

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/elasticsearch-esql (:Query Languages/ES|QL)

@nik9000 nik9000 requested a review from astefan August 16, 2023 15:52
@nik9000 nik9000 mentioned this pull request Aug 16, 2023
75 tasks
*/
@ParametersFactory
public static Iterable<Object[]> parameters() {
List<TestCaseSupplier> suppliers = new ArrayList<>();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@not-napoleon you might be interested in this. I took a little time today to write a few functions and I ran into the need for this utility a few times actually.

new FunctionDefinition[] { def(Case.class, Case::new, "case"), def(IsNull.class, IsNull::new, "is_null"), },
new FunctionDefinition[] { def(Case.class, Case::new, "case") },
// null
new FunctionDefinition[] { def(Coalesce.class, Coalesce::new, "coalesce"), def(IsNull.class, IsNull::new, "is_null"), },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just removed the is_null / is_not_null functions. The same functionality is now available with IS NULL / IS NOT NULL.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++. I'll get that merged.

}

for (int position = 0; position < children().size(); position++) {
if (dataType == null || dataType == NULL) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this check we have Expressions.isNull() that does a similar thing.

}

@Override
public boolean foldable() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ES SQL there is a Coalesce function which is interesting because it's also coming together with an Optimizer rule and the foldable method is much simpler (thanks to the aforementioned rule).

Otherwise, there is Expressions.foldable(children()); that can be used here.

The way I see it:

  • either you merge this as is and create a GH issue to explore/improve NULL propagation for Coalesce (plus that optimizer rule)
  • have a look at Coalesce in ES SQL and SQL's Optimizer.PropagateNullable and have an adapted version in ESQL

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll open #98612 and replace with Expressions.foldable(children()) and we'll grab an optimizer rule later.

@@ -0,0 +1,79 @@
isNull
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though Coalesce can have an arbitrary number of parameters, the tests here always use two.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

y=COALESCE(true, false, null) doesn't seem to work. The value for y is null. Only if I the last value is non-null it works.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh. I thought I had tests for all that in the unit tests. I'll add more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting! the break here was with an optimizer rule. I'll push a fix.

Copy link
Contributor

@astefan astefan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general is looking good, but I think more IT tests are needed for multi-argument variants, there is an optimization that can likely simplify the internals of Coalesce from QL point of view and the PR needs an update from main to incorporate the new changes regarding is null/is not null.

@ChrisHegarty ChrisHegarty deleted the branch elastic:main August 17, 2023 13:05
@nik9000 nik9000 reopened this Aug 17, 2023
@nik9000 nik9000 changed the base branch from feature/esql to main August 17, 2023 13:37
@elasticsearchmachine
Copy link
Collaborator

Hi @nik9000, I've created a changelog YAML for you.

@nik9000
Copy link
Member Author

nik9000 commented Aug 17, 2023

run elasticsearch-ci/docs

@nik9000 nik9000 merged commit 44e6134 into elastic:main Aug 17, 2023
csoulios pushed a commit to csoulios/elasticsearch that referenced this pull request Aug 18, 2023
This adds a `COALESCE` function that returns the first non-null value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Analytics/ES|QL AKA ESQL >feature Team:QL (Deprecated) Meta label for query languages team v8.11.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants