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

Smart tag to shortcut accessing an attribute from a related table #2033

Open
benjie opened this issue Apr 26, 2024 · 0 comments
Open

Smart tag to shortcut accessing an attribute from a related table #2033

benjie opened this issue Apr 26, 2024 · 0 comments

Comments

@benjie
Copy link
Member

benjie commented Apr 26, 2024

Feature request via Discord, essentially @ref but for attributes rather than whole tables.

From https://discord.com/channels/489127045289476126/1232250825125134400/1232250825125134400:

Discord question

I have a table, let's call it person (id, name) and a view, let's call it person_address (person_id, address_calculated_in_view). Both of them are related via a foreign key (i.e. id on person <> person_id on person_address), but note that this is NOT a materialized view, so there's no indexes on person_address.

Now with the @ref smart tag, I believe I would be able to "join" those so that in graphql I would get

person {
  personAddress {
    addressCalculatedInView
  }
}

And that is great - however, what I would actually need, is a way to get

person {
  addressCalculatedInView
}

Right now, what I do for this, is define a function

person_address_calculated_in_view(p person)
  SELECT address_calculated_in_view FROM person_address WHERE person_address.person_id = p.id

Unfortunately though, this is significantly more expensive to run than a simple join. While for my data the function takes ~5ms to execute, it'll take 5ms PER row in person, which becomes very slow very fast.
Ideally, I would like to be able to specify a @ref to a single field, such that graphile can just join the view to the base table.

Is there curerntly a way to do this for me? If not, what would be the best way forward to get this - can the @ref tag somehow be extended via plugins maybe?
Thanks in advance for any pointers!

Benjie's Discord response

Interesting idea. @ref would not be the right smart tag for this, we'd need a new one (e.g. @refColumn) but it's definitely feasible. You should file an issue about it. In the mean time, I would personally solve this via a makeExtendSchemaPlugin, something like:

export const MyPlugin = makeExtendSchemaPlugin(build => {
  return {
    typeDefs: gql`extend type Person { addressCalculatedInView: String }`,
    plans: {
      Person: {
        addressCalculatedInView($person) {
          const $view = $pgSelectSingle.sinleRelation('relationNameHere');
          // OR: const $view = build.input.pgRegistry.pgResources.person_address.get({ person_id: $person.get('id') });
          return $view.get('address_calculated_in_view');
        }
      }
    }
  }
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant