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

Demonstrate how to call computed column functions #2337

Merged
merged 1 commit into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions postgraphile/website/postgraphile/computed-columns.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,55 @@ queried like this:
}
```

PostgreSQL's documentation on [function
calls](https://www.postgresql.org/docs/17/sql-expressions.html#SQL-EXPRESSIONS-FUNCTION-CALLS)
notes:

> A function that takes a single argument of composite type can optionally be
> called using field-selection syntax, and conversely field selection can be
> written in functional style. That is, **the notations `col(table)` and `table.col`
> are interchangeable**. This behavior is not SQL-standard but is provided in
> PostgreSQL because it allows use of functions to emulate “computed fields”.
>
> -- https://www.postgresql.org/docs/17/sql-expressions.html, emphasis added.

Thus to query this computed column yourself outside of PostGraphile you could
execute:

```sql {3,5}
select
person.id,
person.person_full_name as full_name
-- or, equivalently:
-- person_full_name(person) as full_name
from person
where id = $1;
```

This `person.person_full_name` syntax makes the function `person_full_name`
appear as if it were a column of `person` even though no such column exists,
hence our name for it: computed column function.

:::note Computed columns can also return sets

If your function, for example `person_favorite_posts(person)`, returns a set
then PostGraphile will automatically wrap this selection in a subquery
aggregation for you to prevent the parent query from yielding more rows than
expected; if you wanted to query it yourself it might look something like:

```sql {3-6}
select
person.id,
array(
select posts.*
from person_favorite_posts(person) posts
) as favorite_posts
from person
where id = $1;
```

:::

### Example

This example creates two computed columns, one returning a simple varchar and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,55 @@ queried like this:
}
```

PostgreSQL's documentation on [function
calls](https://www.postgresql.org/docs/17/sql-expressions.html#SQL-EXPRESSIONS-FUNCTION-CALLS)
notes:

> A function that takes a single argument of composite type can optionally be
> called using field-selection syntax, and conversely field selection can be
> written in functional style. That is, **the notations `col(table)` and `table.col`
> are interchangeable**. This behavior is not SQL-standard but is provided in
> PostgreSQL because it allows use of functions to emulate “computed fields”.
>
> -- https://www.postgresql.org/docs/17/sql-expressions.html, emphasis added.

Thus to query this computed column yourself outside of PostGraphile you could
execute:

```sql {3,5}
select
person.id,
person.person_full_name as full_name
-- or, equivalently:
-- person_full_name(person) as full_name
from person
where id = $1;
```

This `person.person_full_name` syntax makes the function `person_full_name`
appear as if it were a column of `person` even though no such column exists,
hence our name for it: computed column function.

:::note Computed columns can also return sets

If your function, for example `person_favorite_posts(person)`, returns a set
then PostGraphile will automatically wrap this selection in a subquery
aggregation for you to prevent the parent query from yielding more rows than
expected; if you wanted to query it yourself it might look something like:

```sql {3-6}
select
person.id,
array(
select posts.*
from person_favorite_posts(person) posts
) as favorite_posts
from person
where id = $1;
```

:::

### Example

This example creates two computed columns, one returning a simple varchar and
Expand Down
Loading