Skip to content
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
5 changes: 3 additions & 2 deletions src/pages/postgraphile/computed-columns.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ table type, but, unlike an actual column, the value for this field is the result
of calling a function defined in the PostgreSQL schema. This function will
automatically be exposed to the resultant GraphQL schema as a field on the type;
it can accept arguments that influence its result, and may return either a
scalar, record, list or a set. Sets (denoted by `RETURNS SETOF ...`) are exposed
as [connections](/postgraphile/connections/).
scalar, record, [enum](/postgraphile/enums/#functions-returning-table-enums),
list or a set. Sets (denoted by `RETURNS SETOF ...`) are exposed as
[connections](/postgraphile/connections/).

_Performance note: we inline these function calls into the original `SELECT`
statement, so there's no N+1 issues - it's very efficient._
Expand Down
3 changes: 2 additions & 1 deletion src/pages/postgraphile/custom-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ title: Custom Queries
You can add root-level `Query` fields to your GraphQL schema using "Custom
Queries". These are PostgreSQL functions, similar to
[computed columns](/postgraphile/computed-columns/), that can return scalars,
records, lists or sets. Sets (denoted by `RETURNS SETOF ...`) are exposed as
records, [enums](/postgraphile/enums/#functions-returning-table-enums), lists or
sets. Sets (denoted by `RETURNS SETOF ...`) are exposed as
[connections](/postgraphile/connections/). The arguments to these functions will
be exposed via GraphQL - named arguments are preferred, if your arguments are
not named we will assign them an auto-generated name such as `arg1`.
Expand Down
86 changes: 86 additions & 0 deletions src/pages/postgraphile/enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,92 @@ comment on table animal_type is E'@enum\n@enumName TypeOfAnimal';

The name must conform to the GraphQL identifier restrictions.

#### Functions and table enums

_Since 4.14.0_

Functions exposed via GraphQL (as custom queries, computed columns and custom
mutations) need a little assistance in order to indicate that an argument type
or return type references a enum table and should be typed as a GraphQL enum.

You can achieve this by creating a domain for your enum that either:

- has a name that ends with `_enum_domain`, or
- is tagged with `@enum the_enum_table_it_references`.

Example:

```sql
create table stage_options (
type text primary key
);
comment on table stage_options is E'@enum';
insert into stage_options
(type) values
('pending'),
('round 1'),
('round 2'),
('rejected'),
('hired');

-- Either follow the convention of [enum_name]_enum_domain:
create domain stage_options_enum_domain as text;
-- or use any name for the domain and add a smart comment:
-- create domain stage as text;
-- comment on domain stage is E'@enum stage_options';

-- This function will add a `nextStage` field to applicant with GraphQL type
-- `StageOptions` (our table enum):
create function applicants_next_stage(a applicants)
returns stage_options_enum_domain
as $$
select (case
when a.stage = 'round 2' then 'hired'
else 'rejected'
end)::stage_options_enum_domain;
$$ language sql stable;

-- This function allows to filter applicants by `StageOptions` value:
create function applicants_by_stage(wanted_stage stage_options_enum_domain)
returns setof applicants
as $$
select * from applicants a where a.stage = wanted_stage
$$ language sql stable;
```

For enums using unique constraints, you can achieve the same result by creating
a domain that either:

- has a name that follows this pattern:
`[enum_table_name]_[constraint_name]_enum_domain`, or
- is that tagged with `@enum [enum_table_name]_[constraint_name]`.

For example:

```sql
create table my_enums (
transportation text not null constraint transportation_mean unique
);

comment on constraint transportation_mean on my_enums is E'@enum';
insert into my_enums
(transportation) values
('CAR'),
('BIKE'),
('SUBWAY');

-- Either follow the convention of [enum_table_name]_[constraint_name]_enum_domain:
create domain my_enums_transportation_mean_enum_domain as text;

-- Or use any name for the domain and add a smart comment referencing the enum
-- via `[enum_table_name]_[constraint_name]`:
create domain transportation as text;
comment on domain transportation is E'@enum my_enums_transportation_mean';

-- Then you can create functions that take this domain as the type of their
-- arguments or return value like in the previous example.
```

### With makeExtendSchemaPlugin

Use the standard `enum` GraphQL interface definition language (IDL/SDL) to
Expand Down