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
Fixes #725: OneOfThemWith{Component,} does not distinguish empty vs null #726
Fixes #725: OneOfThemWith{Component,} does not distinguish empty vs null #726
Conversation
A simpler change would be to just change the behavior to treat repeated fields uniformly always. In addition to being an incompatible change to a maintained class, I can imagine cases where the current behavior is desirable. |
@@ -64,6 +64,17 @@ public OneOfThem oneOfThem() { | |||
return new OneOfThem(fieldName); | |||
} | |||
|
|||
/** | |||
* If the associated field is a repeated one, this allows you to match against one of those values, the record will |
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.
This is a comma splice (as is the first sentence of the docs on oneOfThem()
). (More specifically, the comma between "values" and "the" is splicing; the comma between "one" and "this" is fine.)
fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/expressions/Field.java
Outdated
Show resolved
Hide resolved
fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/expressions/Field.java
Outdated
Show resolved
Hide resolved
fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/expressions/Field.java
Show resolved
Hide resolved
...-core/src/test/java/com/apple/foundationdb/record/query/expressions/QueryExpressionTest.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
@Nullable | ||
@SuppressWarnings("unchecked") | ||
protected List<Object> getValues(@Nonnull MessageOrBuilder message) { | ||
final Descriptors.FieldDescriptor field = findFieldDescriptor(message); | ||
if (message.getRepeatedFieldCount(field) == 0) { | ||
if (emptyIsUnknown && message.getRepeatedFieldCount(field) == 0) { |
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.
It's possible I'm conflating some things, but I believe that there was some discussion that one could use the null/not null behavior of the field (as referenced in #677) to determine whether an unset repeated field should be the empty list (i.e., "not null") or null. It kind of seems like those are related, though maybe it's more difficult than we want to bring those two parts of the code base together. (Perhaps I was thinking of whether one should include null
in fanout indexes, though I suppose one could also want that same control when trying to determine if one wants to put null
or the empty list into a Concatenate
index.)
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 can't figure out how to have a unified single expression of "null-handling" that works compatibly. Still, if the approach to #677 were to have some kind of "field options" that could be set at multiple levels, those options could include the new emptyIsUnknown
, set on the Query.field
instead of oneOfThem
and inherited from the meta-data's field.
Concretely, instead of
Query.field("f1").oneOfThem(false).matches(...)
have
Query.field("f1").withOptions(FieldOptions.newBuilder().setEmptyIsUnknown(false).build()).oneOfThem().matches(...)
Would something along those lines still be worth it?
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 really see how the latter (in the example) would be better, no. I think the idea was more like if you had a field option set in the meta-data on the record that the repeated field were NOT_NULL
(or equivalent), then it would fill in emptyIsUknown
to false
(or, in other words, it would evaluate the field as an empty list instead of a null list).
It's kind of hard to rendezvous those two things, though, so maybe emptyIsUnknown
as a component option is better.
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, it does seem weird that saying at the meta-data level that a field does not do null values at all still does not affect this. Perhaps, instead of fully unifying the specification, just the default value for oneOfThem()
could be influenced?
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.
Yeah, I think that's a sensible contract--that if you set emptyIsUnknown
, then it does whatever the default from the null behavior would be. I guess for now DEFAULT
is equivalent to EMPTY_IS_UNKNOWN
, but maybe that changes to "whatever the field options say" after #677?
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.
Okay, so I think the only question is whether this should be an enum here, with maybe the default option doing the same thing as the "empty is unknown" option (for now) but leaving room to make it use the field options if available.
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 made it an enum, with two values for now and a TODO comment about adding a third that means based on the null behavior of the field in the meta-data.
Do you know why 8596b15 is showing up here? Is that a GitHub artifact, or is something weird with the rebase? |
fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/expressions/Field.java
Outdated
Show resolved
Hide resolved
I think it has something to do with accepting suggested fixes. |
e11ab2b
to
b627303
Compare
Ah, I see. It might make sense to squash this one, when it's merged then, to avoid weird things happening to history, though maybe it'd be fine either way. |
b627303
to
e647f9a
Compare
Or maybe the point is moo, as the most recent push seems to have fixed it up. |
e647f9a
to
4c96a4c
Compare
…h empty vs null This introduces a new boolean parameter to `oneOfThem` and everything else in that path.
…ord/query/expressions/Field.java Co-Authored-By: Alec Grieser <alloc@apple.com>
…ord/query/expressions/Field.java Co-Authored-By: Alec Grieser <alloc@apple.com>
…a-data field options.
4c96a4c
to
7ce100d
Compare
This introduces a new boolean parameter to
oneOfThem
and everything else in that path.Note that no changes are made to the planner, which does not care about the difference, since it only turns query component into index operations in cases as part of a filter expression without anything like
IS UNKNOWN
orNOT
.