Skip to content

Implement boolean expressions #1025

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

Merged
merged 9 commits into from
Nov 2, 2022

Conversation

katcharov
Copy link
Collaborator

JAVA-4779

This implements not/and/or/cond for boolean expressions.

@katcharov katcharov requested review from jyemin and stIncMale October 25, 2022 17:00
Copy link
Collaborator

@jyemin jyemin left a comment

Choose a reason for hiding this comment

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

Took a quick first pass. Looking good.

@katcharov katcharov requested a review from jyemin October 26, 2022 23:05
@katcharov katcharov requested a review from jyemin October 28, 2022 14:40
@katcharov katcharov requested a review from stIncMale October 28, 2022 20:18
@katcharov katcharov requested a review from stIncMale November 1, 2022 15:31
Copy link
Member

@rozza rozza left a comment

Choose a reason for hiding this comment

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

LGTM - I have one question more for my learning than anything else

getCollectionHelper().drop();
}

protected void assertExpression(final Object expectedResult, final Expression expression, final String expectedMql) {
Copy link
Member

Choose a reason for hiding this comment

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

Like it :)

* not mis-cast an expression as anything else.
*/
private static BsonValue extractBsonValue(final CodecRegistry cr, final Expression expression) {
return ((MqlExpression<?>) expression).toBsonValue(cr);
Copy link
Member

Choose a reason for hiding this comment

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

I'm surprised this doesn't issue an unchecked warning, I don't get why it doesn't?!

Copy link
Member

@stIncMale stIncMale Nov 1, 2022

Choose a reason for hiding this comment

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

The unchecked -Xlint javac key deals only with the unchecked narrowing conversions (i.e., it is not related to the fact that the cast may fail at runtime, but is rather about a situation when the cast does not fail at runtime, yet the program is incorrect and has heap pollution). The JLS states that "A narrowing reference conversion from a type S to a parameterized class or interface type T is unchecked, unless at least one of the following is true: All of the type arguments of T are unbounded wildcards. ...".

It's easy to see why the above is fine: a paremetrized type with all type arguments being unbounded wildcards is a type for which the program has no expectation on the type arguments, so there is nothing that javac was required to check but was unable to.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks :)

Copy link
Member

Choose a reason for hiding this comment

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

If the type erasure were not a thing, then the conversion could have been checked at runtime (just like casts for non-parametrized types are), and we would not have had to deal with unchecked conversions.

Copy link
Member

@stIncMale stIncMale Nov 1, 2022

Choose a reason for hiding this comment

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

While I was away (if you know what I mean), I realized that the argument "the program has no expectation on the type arguments" is applicable to raw types just as it is applicable to types parametrized with ?. However, javac warns us about raw MqlExpression and does not warn when we cast to MqlExpression<?>.

While I can't give a formal explanation, I have a hand-waving explanation via an example. I will have to use List<String> instead of Expression and ArrayList<?> instead of MqlExpression<?> because there is no practical problem with MqlExpression in the code we are discussing, but javac cannot know that, and warns us by following a simple algorithm.

The problem with rawtypes (ArrayList), which we don't have with ?-parametrized types (ArrayList<?>) and therefore, there is no need for a compiler to warn us, is demonstrated with the following example:

List<String> strings = new ArrayList<>();
ArrayList objects = (ArrayList) strings; // javac warning: [rawtypes] found raw type: ArrayList
// pollute the heap
objects.add(42); // javac warning: [unchecked] unchecked call to add(E) as a member of the raw type ArrayList
// enjoy the consequences
strings.get(0); // java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String

the same example won't compile if we use ArrayList<?>:

List<String> strings = new ArrayList<>();
ArrayList<?> objects = (ArrayList<?>) strings;
// try to pollute the heap
objects.add(42); // javac error: incompatible types: int cannot be converted to CAP#1 ... where ... CAP#1 extends Object from capture of ?
// there are no consequences as the code does not compile
strings.get(0);

So not only a ?-paremetrized type expresses no expectation on the type arguments, but also makes the values of the type kinda sorta "unmodifiable" (I have no idea how to formally express this property), which is how it is different from raw types.

@katcharov katcharov requested a review from jyemin November 2, 2022 14:32
@katcharov katcharov merged this pull request into mongodb:expressions Nov 2, 2022
@katcharov katcharov deleted the expressions-boolean branch November 2, 2022 14:58
katcharov added a commit that referenced this pull request Nov 2, 2022
This was referenced Nov 3, 2022
katcharov added a commit that referenced this pull request Jan 30, 2023
katcharov added a commit that referenced this pull request Jan 31, 2023
katcharov added a commit that referenced this pull request Jan 31, 2023
* Implement boolean expressions (#1025)

JAVA-4779

* Implement filter, map, reduce (#1031)

JAVA-4781

* Implement eq, ne, gt, gte, lt, lte (#1033)

JAVA-4784

* Implement string expressions (#1036)

JAVA-4801

* Implement arithmetic expressions (#1037)

Implement arithmetic expressions (from top 50, and others)

JAVA-4803

* Implement array expressions (#1043)

JAVA-4805

* Implement date expressions (#1045)

JAVA-4804

* Implement conversion/type expressions (#1050)

JAVA-4802

* Implement document expressions (#1052)

JAVA-4782

* Replace reduce with individual reductions (#1053)

JAVA-4814

* Implement map expressions (#1054)

JAVA-4817

* Implement switch expression (#1055)

JAVA-4813

* Test expressions in context (#1057)

JAVA-4820

* Add javadoc for boolean, date, number, integer, and expression (#1059)

 JAVA-4799

* Update and add documentation (#1059)

* Fix, tests

 JAVA-4799

* Add `@MqlUnchecked` and a few usage examples (#1059)

 JAVA-4799

* Add has to document, add tests (#1070)

 JAVA-4799

* Add javadocs for remaining classes (#1070)

 JAVA-4799

* 5.2 annotations (#1070)

 JAVA-4799

* 5.0 annotations (#1070)

 JAVA-4799

* 4.4 annotations (#1070)

 JAVA-4799

* 4.2 annotations (#1070)

 JAVA-4799

* 4.0 annotations (#1070)

 JAVA-4799

* Update and add documentation, add tests, fix minor issues (#1070)

Rename extractBsonValue

Fix access modifiers

Remove excess comments

Update docs

Fix: behaviour of get

Add notNull to API, add notNullApi test

Fix docs/annotations, tests

Fix docs, annotations, since

Fix docs

Revert external

Add missing MqlUnchecked

Fix missing null checks

Checkstyle

JAVA-4799

* Rename to Mql (automated) (#1073)

JAVA-3879

* Rename methods (automated) (#1073)

JAVA-3879

* Update naming, terms, and missing checks and annotations (#1073)

JAVA-3879

---------

Co-authored-by: Valentin Kovalenko <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants