question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

set relationships on user defined functions

See original GitHub issue

To expand on [#333] it would be interesting to let UDF be used not just as a root object but also deep down in queries.

Following scenario: Have a table of entities that belong to categories and have a UDF that returns list of highlighted categories.

Query:


query {
    entities(...query...) {
        name

        highlightedCategories {
            name
        }
    }
}

One possible solution would be to infer the relationship from:

  • name (e.g. highlightedCategories) from the name of the function
  • parent relationship (e.g. under entities) from input arguments of the UDF (e.g. CREATE FUNCTION name(x entities))
  • returned schema (e.g. categories) from return type (e.g. RETURNS SETOF categories)
  • array vs. object: if returns SET or just 1 record

Other would be to define it explicitly in a relationship tab, where I could have a UDF with 1 int parameter and define a relationship similar to a table, as which local column would be passed into the UDF and I could also rename the relationship independently from the actual function name.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

7reactions
0x777commented, Mar 5, 2019

This is interesting! However having functions for relationships which take a table’s row and returns target table’s row(s) will be bad for performance. For example, for the above query with the udf as suggested, the generated sql would be something along these lines:

select id, highlightedCategories(e) from entities e;

Instead of a join between two tables it will result in an N+1 query pattern. Postgres maybe able to optimise this to a join but may not be able to do so in a general case.

Other options

Views

From the discord discussion, this is your function

CREATE FUNCTION public.highlightedCategories (current entity) RETURNS SETOF categories LANGUAGE SQL STABLE $$

    select c.* from entity_categories ec 
    inner join categories c on ec.category_id = c.category_id 
    where ec.entity_id = current.id and c.rank > 10

$$

If your function doesn’t need arguments other than the row (like in the above case), you’ll be able to do this with views.

create view highlighted_categories as
select ec.entity_id, c.* from entity_categories ec 
    inner join categories c on ec.category_id = c.category_id 
    where c.rank > 10

Now, instead of adding the relationship to categories table, I’ll add it to highlighted_categories view.

UDFs

Currently we expose UDFs which return a setof table at the top level. However maybe we can allow defining array relationships to these udfs. Not sure about object relationships though.

Let’s consider a table places which has a column location. Now you could have a udf called nearby_places which takes a location(from) and distance(within) as arguments and returns setof places. You can call this function as follows:

{
  places(args: {from: l within: d}) {
    name
  }
}

It would be interesting if I could do something like this:

{
  places {
    name
    nearbyPlaces(args: {within: d} limit:10) {
      name
    }
  }
}

I would like to get all places and their nearby places within d distance. For this to happen, we should

  1. Allow defining relationships to a udf
  2. Ability to fill in an argument from the parent table. Notice how we haven’t specified ‘from’ argument. When defining the relationship, this should be configurable.

This would definitely be interesting to have.

1reaction
tirumaraiselvancommented, Mar 26, 2020

This can now be achieved using Table Computed Fields : https://hasura.io/docs/1.0/graphql/manual/schema/computed-fields.html#table-computed-fields

Thank you all for your feedback !

Read more comments on GitHub >

github_iconTop Results From Across the Web

User-defined relationships - Advanced query tool
User-defined relationships. Within AQT, you can define relationships between tables. This is used in: the Query Builder. Once a relationship is defined ...
Read more >
Relationship Functions - Oracle Help Center
Relationship functions look up specific values within the database based on current cell location and a series of parameters. You can use these...
Read more >
Db2 - Creating a user-defined function - IBM
Like a built-in function, a user-defined function represents a relationship between a set of input values and a set of result values. The...
Read more >
Learn SQL: User-Defined Functions - SQLShack
User -defined functions are a very powerful tool in databases. Using them you'll reduce the chance to make an error and place code...
Read more >
Guide to table relationships - Microsoft Support
In the Relationships window, you can manually specify the fields to join. But, if you already have a relationship defined between the tables,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found