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

Adding support for filtering on array column types #520

Merged
merged 31 commits into from
May 31, 2024

Conversation

mlabisi
Copy link
Contributor

@mlabisi mlabisi commented May 15, 2024

What kind of change does this PR introduce?

This PR adds the ability to filter by array columns and resolves #460

What is the current behavior?

Array columns are not filterable, and the schema does not create {Scalar}ListFilter types.

What is the new behavior?

Array columns are filterable, and the schema now includes {Scalar}ListFilter types!

Additional context

Note that {Scalar}ListFilter was not created for Scalar::Opaque!

Copy link
Contributor

@olirice olirice left a comment

Choose a reason for hiding this comment

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

thanks for opening

could we scope this down to just filtering on contains and contained by?

I'm not sold on overlap or ordering so it would be great if we could discuss/handle those parts separately

@mlabisi
Copy link
Contributor Author

mlabisi commented May 15, 2024

thanks for opening

could we scope this down to just filtering on contains and contained by?

I'm not sold on overlap or ordering so it would be great if we could discuss/handle those parts separately

@olirice Thanks for taking a look!

I think removing the ordering changes from this PR makes sense 💯 but I do want to make a case for the overlap filter as...

  • ...it's a built-in, native Postgres operator that's also supported by PostgREST (I don't see how exposing built-in operators can hurt!)
  • ...selfishly, I have a use case for it 😅 (checking if an array of strings overlap)

@mlabisi mlabisi requested a review from olirice May 15, 2024 17:02
@mlabisi mlabisi changed the title (WIP ⌛ ) Adding support for filtering and ordering on array column types (WIP ⌛ ) Adding support for filtering on array column types May 15, 2024
@olirice
Copy link
Contributor

olirice commented May 15, 2024

I have a use case for it 😅 (checking if an array of strings overlap)

could you expand on the specifics for this pls?

Two of my arguments against are:

  • Its an unusual need (hoping your example my clarify this one)
  • you can accomplish the same thing with combinations of and/or/contains/contained_by

@mlabisi
Copy link
Contributor Author

mlabisi commented May 15, 2024

I have a use case for it 😅 (checking if an array of strings overlap)

could you expand on the specifics for this pls?

Two of my arguments against are:

  • Its an unusual need (hoping your example my clarify this one)
  • you can accomplish the same thing with combinations of and/or/contains/contained_by

@olirice It may be an unusual need, but I hope that doesn't make it any less valid 😅

My specific use case is pretty domain-specific, but I can use the existing schema in the seed.sql file to give a general example that has the same idea!

Given the following table

create table blog_post(
    id uuid not null default gen_random_uuid() primary key,
    blog_id integer not null references blog(id) on delete cascade,
    title varchar(255) not null,
    body varchar(10000),
    tags TEXT[],
    status blog_post_status not null,
    created_at timestamp not null
);

and the following data

insert into blog_post (blog_id, title, body, tags, status, created_at)
values
    ((SELECT id FROM blog WHERE name = 'A: Blog 1'), 'Post 1 in A Blog 1', 'Content for post 1 in A Blog 1', '{"tech", "update"}', 'RELEASED', NOW()),
    ((SELECT id FROM blog WHERE name = 'A: Blog 1'), 'Post 2 in A Blog 1', 'Content for post 2 in A Blog 1', '{"announcement", "tech"}', 'PENDING', NOW()),
    ((SELECT id FROM blog WHERE name = 'A: Blog 2'), 'Post 1 in A Blog 2', 'Content for post 1 in A Blog 2', '{"personal"}', 'RELEASED', NOW()),
    ((SELECT id FROM blog WHERE name = 'A: Blog 2'), 'Post 2 in A Blog 2', 'Content for post 2 in A Blog 2', '{"update"}', 'ARCHIVED', NOW()),
    ((SELECT id FROM blog WHERE name = 'A: Blog 3'), 'Post 1 in A Blog 3', 'Content for post 1 in A Blog 3', '{"travel", "adventure"}', 'PENDING', NOW()),
    ((SELECT id FROM blog WHERE name = 'B: Blog 3'), 'Post 1 in B Blog 3', 'Content for post 1 in B Blog 3', '{"tech", "review"}', 'RELEASED', NOW()),
    ((SELECT id FROM blog WHERE name = 'B: Blog 3'), 'Post 2 in B Blog 3', 'Content for post 2 in B Blog 3', '{"coding", "tutorial"}', 'PENDING', NOW());

I'd like to be able to execute equivalent of the following valid SQL statement:

SELECT bp.id
FROM blog_post bp
WHERE array["tech", "update"] && bp.tags

Sure, it'd be possible to split that where clause into multiple contains statements, but && is a totally valid operation that's there for the taking. In my opinion, exposing it as a filter is straightforward and can simplify queries for cases like mine. I personally don't see the harm in exposing it as a filter—but that's just me 😄

@@ -58,6 +58,7 @@ create table blog_post(
blog_id integer not null references blog(id) on delete cascade,
title varchar(255) not null,
body varchar(10000),
tags TEXT[],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This column was added to allow live validation beyond just the regression tests for filtering by array columns!

src/graphql.rs Outdated Show resolved Hide resolved
@@ -3541,6 +3555,8 @@ impl ___Type for FilterTypeType {
default_value: None,
sql_type: None,
},
// shouldn't happen since we've covered all cases in supported_ops
_ => panic!("encountered unknown FilterOp")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Scalar's supported_ops won't contain any of the array-only filter operations, so we're safe to ignore them here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should restructure the FilterOp and related types so that we can avoid this catchall panic. As this PR is already long enough, I'm ok with doing that as a separate PR. Just open a ticket to handle this later.

@@ -3641,22 +3684,33 @@ impl ___Type for FilterEntityType {
not_column_exists = true;
}

match utype.unmodified_type() {
__Type::Scalar(s) => Some(__InputValue {
match utype.nullable_type() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that we support filtering by array columns, we want to respect the fact that the utype is an array, so we'll only unwrap Non-Nullables.

@mlabisi mlabisi changed the title (WIP ⌛ ) Adding support for filtering on array column types Adding support for filtering on array column types May 17, 2024
@mlabisi mlabisi marked this pull request as ready for review May 17, 2024 00:43
@mlabisi
Copy link
Contributor Author

mlabisi commented May 17, 2024

This one's ready for review whenever you have a chance @olirice @imor !

@mlabisi
Copy link
Contributor Author

mlabisi commented May 17, 2024

(Oops, just realized I forgot to update the docs—working on that now!) Done!

@mlabisi
Copy link
Contributor Author

mlabisi commented May 21, 2024

Sorry to pester, but it'd be great to get any feedback on this PR! @olirice

Copy link
Contributor

@olirice olirice left a comment

Choose a reason for hiding this comment

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

at a glance the PR looks very promising!

unfortunately I'm about to be traveling until June 3 and likely won't have a chance to look through it until then. This is a large PR so I'd like to make sure we're thorough

A couple of quick comments. Please:

  • remove the version bump, we'll do that separately
  • avoid unwrap everywhere
  • user exhaustive pattern matching, even when it feels illogical (so we can rely on the compiler to identify all references to enum types)

great work. looking forward to reviewing it once back in office & sorry for the delay!

@mlabisi
Copy link
Contributor Author

mlabisi commented May 22, 2024

@olirice no worries, safe travels! I'll address your feedback in the meantime. Thank you!!

Copy link
Contributor

@imor imor left a comment

Choose a reason for hiding this comment

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

Thank you @mlabisi for this PR, this looks great. I've left some minor actionable comments.

src/graphql.rs Outdated Show resolved Hide resolved
@@ -3541,6 +3555,8 @@ impl ___Type for FilterTypeType {
default_value: None,
sql_type: None,
},
// shouldn't happen since we've covered all cases in supported_ops
_ => panic!("encountered unknown FilterOp")
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should restructure the FilterOp and related types so that we can avoid this catchall panic. As this PR is already long enough, I'm ok with doing that as a separate PR. Just open a ticket to handle this later.

test/expected/resolve_connection_filter.out Outdated Show resolved Hide resolved
test/sql/resolve_connection_filter.sql Outdated Show resolved Hide resolved
@mlabisi mlabisi requested review from olirice and imor May 26, 2024 01:16
@imor
Copy link
Contributor

imor commented May 27, 2024

@olirice the code looks ready to merge. Needs your approval to merge. @mlabisi thanks again for this contribution.

@leefordjudes
Copy link

Kindly merge this pr. this feature is need to my project.

@imor imor dismissed olirice’s stale review May 31, 2024 07:09

Oli has been away, and in the interest of merging quickly, I'm dismissing this review.

@imor imor merged commit 53f0a9d into supabase:master May 31, 2024
4 checks passed
@mlabisi
Copy link
Contributor Author

mlabisi commented May 31, 2024

Thanks for merging, @imor! I use Supabase Cloud, so I'm excited to see these changes go live! Are you able to share when Supabase Cloud will get these changes?

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.

Support filtering on array column types
4 participants