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
Implement JSON array filtering functions #1493
Implement JSON array filtering functions #1493
Conversation
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.
Regarding your question about how to use the ArrayLength
to compose a filter like json array length is less than
(I presume that that's a valid approximation of your goal), create a DBFunctionPacked
subclass inside db.types.custom.json_array
. DBFunctionPacked
(and the whole of hints.mathesar_filter
mechanism, really) is there to bypass the lack of composition in our current UI filtering system.
db/functions/base.py
Outdated
|
||
@staticmethod | ||
def to_sa_expression(value): | ||
return func.json_array_length(value) |
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.
Actually, since this DBFunction
depends on the custom type json_array
which has its own namespace (db.types.custom.json_array
), it makes sense to put this DBFunction
in there too (some other namespaces under db.types.custom
already do this). You're actually already half-way there, since you've added these modules to the list of modules to search for DBFunction
s in (db.functions.known_db_functions._modules_to_search_in
).
json_array = _make_hint("json_array") | ||
|
||
|
||
json_object = _make_hint("json_object") |
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.
You'll want to tell Mathesar how these hints relate to actual types. Look at db/types/hintsets.py
. Note this line:
_add_to_db_type_hintsets(categories.JSON_TYPES, (hints.json,))
This says that all database types defined as categories.JSON_TYPES
are associated with the hints (hints.json,)
.
You'll probably want to make changes to this. And, to the related categories in db.types.categories
as well, since currently we only have categories.JSON_TYPES
, which is a catch-all category for everything JSON, and you probably want something more granular.
Note how the categories
sets define a sort of hierarchy, where for example time-related types are made up of point-in-time as well as duration types, those in turn are made up of other more granular categories, etc.
By the way, if this wasn't clear before (probably not), the way Mathesar finds what hints are associated with what UI type, is it takes the intersection of a UI type's DB types' hints (a UI type is effectively a set of DB types, and each of those have a set of hints, as seen in db/types/hintsets.py
); and, the way it checks whether a filter is applyable to a column of a given UI type, is that it checks if the hints of the first parameter of that filter are satisfied by the hints of the UI type. "Satisfied" here is intentionally ambiguous, since we want the freedom to evolve how this works, but at the moment this mostly means that the first param hint-set must be a subset of the UI type hint-set.
Oof, sorry for the wall of text. Thumbs up for braving through 👍👍, feel free to reach out.
db/functions/base.py
Outdated
hints.returns(hints.comparable), | ||
hints.parameter_count(1), | ||
hints.parameter(0, hints.json_array), | ||
hints.mathesar_filter, |
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 isn't actually a filter (doesn't return a boolean; not meant to be used directly by the UI). You'll probably use this function to compose a DBFunctionPacked
-based filter and you'll give that a mathesar_filter
hint, but giving this function here a mathesar_filter
will result in unexpected behaviour.
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.
Thanks for your very helpful explanation! @dmos62 , I added a DBFunctionPacked function using ArrayLength in the db/types/custom/json_array
and also moved the ArrayLength into that file. Also, I added the json array into categories.
Codecov Report
@@ Coverage Diff @@
## master #1493 +/- ##
==========================================
+ Coverage 92.27% 92.30% +0.03%
==========================================
Files 139 139
Lines 6060 6084 +24
==========================================
+ Hits 5592 5616 +24
Misses 468 468
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
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.
Hey @Jinxiao0302 , as noted through other channels I'd like you to add some tests before we merge this PR. Thank you, it's looking good so far!
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.
The changes look good to me. As @mathemancer mentioned, we can merge this in once we have tests. I'm approving from my end.
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, I think this looks good. Let's get it merged!
Related to #1410
Technical details
Added a DBFunction for getting JSON array length;
To be done: Add comparaing functions that nest array length function.
Checklist
Update index.md
).master
branch of the repositoryvisible errors.
Developer Certificate of Origin
Developer Certificate of Origin