Skip to content

[ES|QL] Rewrite In with EvaluatorMapper#109413

Merged
fang-xing-esql merged 36 commits intoelastic:mainfrom
fang-xing-esql:inlist
Jul 12, 2024
Merged

[ES|QL] Rewrite In with EvaluatorMapper#109413
fang-xing-esql merged 36 commits intoelastic:mainfrom
fang-xing-esql:inlist

Conversation

@fang-xing-esql
Copy link
Copy Markdown
Member

@fang-xing-esql fang-xing-esql commented Jun 6, 2024

This is a subtask of #106679 to replace EvalMapper with EvaluatorMapper. There are multiple functions/predicates that use EvalMapper, this PR focus on the IN predicate.

The result of In predicate can be different whether the inlist has nulls in it or not. Multi-valued fields/expressions are not support by In predicate.

The results below are collected from postgres, these are used as the expected results.
test=# select * from test;
 c1 | c2
----+----
  1 | a
  2 | b
  3 | c
  4 | d
  5 |
(5 rows)

When there is null in the inlist, the return value of in can be either true or null, depending whether there is a matching between LHS and RHS. If LHS is null, in returns null no matter the inlist has null or not.
test=# select c1, c2, c2 in ('e', 'f') as c3 from test;
 c1 | c2 | c3
----+----+----
  1 | a  | f
  2 | b  | f
  3 | c  | f
  4 | d  | f
  5 |    |
(5 rows)

test=# select c1, c2, c2 in ('a', 'f', null) as c3 from test;
 c1 | c2 | c3
----+----+----
  1 | a  | t
  2 | b  |
  3 | c  |
  4 | d  |
  5 |    |
(5 rows)

@fang-xing-esql fang-xing-esql marked this pull request as ready for review June 6, 2024 14:52
@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-analytical-engine (Team:Analytics)

@elasticsearchmachine elasticsearchmachine added the Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) label Jun 6, 2024
@fang-xing-esql fang-xing-esql requested a review from a team as a code owner June 17, 2024 18:55
Copy link
Copy Markdown
Member

@nik9000 nik9000 left a comment

Choose a reason for hiding this comment

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

I like this much more! I left a few questions, but I think this seems like the right thing to do for IN.

}
}

public static class InComparisons extends ExpressionTranslator<In> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we're moving these into their own top level file more often these days.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think we're moving these into their own top level file more often these days.

I just double checked, a lot of LogicalPlanOptimizer rules are in their own top level files, under optimizer/rules, the ExpressionTranslators are not in their own files yet. They are in either EsqlExpressionTranslators or ExpressionTranslators in esql-core. Perhaps keep it here for now?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Either is fine by me.

continue;
}
try {
In.process(result, nulls, mvs, lhsBlock.getBoolean(lhsBlock.getFirstValueIndex(p)), rhsValues);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wonder - should booleans be special and not use the array method? Ultimately IN (true) and IN (false) and IN () and IN (false, true) are the only possible layouts. Right? IN (false, false) has the same meaning as IN (false)`. I think.

If that's true, then this is useful: I've found sometimes I don't use the string template stuff for boolean because it's so different. In this case maybe I'd slurp more of this method into In.process's boolean flavor. But whatever make the hacking easy I'm for. I don't have a strong opinion about the right way to lay out these templates.

Copy link
Copy Markdown
Member Author

@fang-xing-esql fang-xing-esql Jul 10, 2024

Choose a reason for hiding this comment

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

Indeed, I'll simplify boolean. I ended up modifying the template to generate evaluator for boolean, as it makes it easier to handle warnings consistently with other types.

@fang-xing-esql
Copy link
Copy Markdown
Member Author

I like this much more! I left a few questions, but I think this seems like the right thing to do for IN.

Thanks for reviewing it again @nik9000 ! Most of the comments are addressed, and I cleaned it up according to the suggestions, simplified boolean a bit, left InComparisons in EsqlExpressionTranslators for now as the other ExpressionTranslators.

Copy link
Copy Markdown
Member

@nik9000 nik9000 left a comment

Choose a reason for hiding this comment

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

Looks good to me. I left a question about the Analyzer but that's pretty far outside my area of expertise so I'm happy to trust about moving that invocation rather than merging.

}
if (f instanceof In in) {
return processIn(in);
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we use processScalarFunction for this one or is it incompatible somehow?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Can we use processScalarFunction for this one or is it incompatible somehow?

This is a good point! It is not quite compatible for now, one reason is that In is not a registered function yet, it is under operator/comparison, there will be a little more work to make it a registered function. I'll look into it, and if possible, create a follow up PR for it.

import org.elasticsearch.compute.data.BytesRefVector;
$elseif(boolean)$
import org.elasticsearch.compute.data.BooleanVector;
$endif$
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I've tried to remove the import order rules from this generated code but it's a huge pain. I'm sorry about this mess.

}
}

public static class InComparisons extends ExpressionTranslator<In> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Either is fine by me.

@fang-xing-esql fang-xing-esql merged commit 0be34fe into elastic:main Jul 12, 2024
@fang-xing-esql fang-xing-esql deleted the inlist branch July 12, 2024 18:15
elasticsearchmachine pushed a commit that referenced this pull request Jul 15, 2024
Quick cleanup PR.  With
#109413 merged, nothing in
ESQL production depends on the core binary comparison classes anymore. 
This PR removes them to avoid the potential for confusion, and open the
opportunity for merging the core `BinaryComparison` class with the
`EsqlBinaryComparison` base class, which is now its only direct
inheritor (work to be done in a future PR).
tvernum pushed a commit that referenced this pull request Feb 25, 2025
* rewrite in with EvaluatorMapper
tvernum pushed a commit that referenced this pull request Feb 25, 2025
Quick cleanup PR.  With
#109413 merged, nothing in
ESQL production depends on the core binary comparison classes anymore. 
This PR removes them to avoid the potential for confusion, and open the
opportunity for merging the core `BinaryComparison` class with the
`EsqlBinaryComparison` base class, which is now its only direct
inheritor (work to be done in a future PR).
tvernum pushed a commit that referenced this pull request Feb 25, 2025
* rewrite in with EvaluatorMapper
tvernum pushed a commit that referenced this pull request Feb 25, 2025
Quick cleanup PR.  With
#109413 merged, nothing in
ESQL production depends on the core binary comparison classes anymore. 
This PR removes them to avoid the potential for confusion, and open the
opportunity for merging the core `BinaryComparison` class with the
`EsqlBinaryComparison` base class, which is now its only direct
inheritor (work to be done in a future PR).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Analytics/ES|QL AKA ESQL >refactoring Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) v8.16.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants