Skip to content

Max rows improvements #596

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,4 @@

## master
- feature: Add support for aggregate functions (count, sum, avg, min, max) on collection types
- feature: Add support for per table and view `max_row` directives
10 changes: 9 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,21 @@ For more fine grained adjustments to reflected names, see [renaming](#renaming).

### Max Rows

The default page size for collections is 30 entries. To adjust the number of entries on each page, set a `max_rows` directive on the relevant schema entity.
The default page size for collections is 30 entries. To adjust the number of entries on each page, set a `max_rows` directive on the relevant schema entity, table or view.

For example, to increase the max rows per page for each table in the `public` schema:
```sql
comment on schema public is e'@graphql({"max_rows": 100})';
```

To limit the max rows per page for the `blog_post` table and `Person` view:
```sql
comment on table blog_post is e'@graphql({"max_rows": 20})';
comment on view "Person" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 10})';
```

The `max_rows` value falls back to the parent object if it is missing on the current object. For example, if a table doesn't have `max_rows` set, the value set on the table's schema will be used. If the schema also doesn't have `max_rows` set, then it falls back to default value 30. The parent object of a view is the schema, not the table on which the view is created.

### totalCount

`totalCount` is an opt-in field that extends a table's Connection type. It provides a count of the rows that match the query's filters, and ignores pagination arguments.
Expand Down
144 changes: 124 additions & 20 deletions test/expected/max_rows_directive.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ begin;
create table account(
id int primary key
);
create view "accountView" as
select * from account;
comment on view "accountView" is e'@graphql({"primary_key_columns": ["id"]})';
create view "accountViewWrapper" as
select * from "accountView";
comment on view "accountViewWrapper" is e'@graphql({"primary_key_columns": ["id"]})';
insert into public.account(id)
select * from generate_series(1, 100);
-- expect default 30 rows on first page
-- expect 30 rows on first page because of fallback to default
select graphql.resolve($$
{
accountCollection
Expand All @@ -22,8 +28,42 @@ begin;
{"data": {"accountCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}, {"node": {"id": 6}}, {"node": {"id": 7}}, {"node": {"id": 8}}, {"node": {"id": 9}}, {"node": {"id": 10}}, {"node": {"id": 11}}, {"node": {"id": 12}}, {"node": {"id": 13}}, {"node": {"id": 14}}, {"node": {"id": 15}}, {"node": {"id": 16}}, {"node": {"id": 17}}, {"node": {"id": 18}}, {"node": {"id": 19}}, {"node": {"id": 20}}, {"node": {"id": 21}}, {"node": {"id": 22}}, {"node": {"id": 23}}, {"node": {"id": 24}}, {"node": {"id": 25}}, {"node": {"id": 26}}, {"node": {"id": 27}}, {"node": {"id": 28}}, {"node": {"id": 29}}, {"node": {"id": 30}}]}}}
(1 row)

-- expect 30 rows on first page because of fallback to default
select graphql.resolve($$
{
accountViewCollection {
edges {
node {
id
}
}
}
}
$$);
resolve
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"data": {"accountViewCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}, {"node": {"id": 6}}, {"node": {"id": 7}}, {"node": {"id": 8}}, {"node": {"id": 9}}, {"node": {"id": 10}}, {"node": {"id": 11}}, {"node": {"id": 12}}, {"node": {"id": 13}}, {"node": {"id": 14}}, {"node": {"id": 15}}, {"node": {"id": 16}}, {"node": {"id": 17}}, {"node": {"id": 18}}, {"node": {"id": 19}}, {"node": {"id": 20}}, {"node": {"id": 21}}, {"node": {"id": 22}}, {"node": {"id": 23}}, {"node": {"id": 24}}, {"node": {"id": 25}}, {"node": {"id": 26}}, {"node": {"id": 27}}, {"node": {"id": 28}}, {"node": {"id": 29}}, {"node": {"id": 30}}]}}}
(1 row)

-- expect 30 rows on first page because of fallback to default
select graphql.resolve($$
{
accountViewWrapperCollection {
edges {
node {
id
}
}
}
}
$$);
resolve
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"data": {"accountViewWrapperCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}, {"node": {"id": 6}}, {"node": {"id": 7}}, {"node": {"id": 8}}, {"node": {"id": 9}}, {"node": {"id": 10}}, {"node": {"id": 11}}, {"node": {"id": 12}}, {"node": {"id": 13}}, {"node": {"id": 14}}, {"node": {"id": 15}}, {"node": {"id": 16}}, {"node": {"id": 17}}, {"node": {"id": 18}}, {"node": {"id": 19}}, {"node": {"id": 20}}, {"node": {"id": 21}}, {"node": {"id": 22}}, {"node": {"id": 23}}, {"node": {"id": 24}}, {"node": {"id": 25}}, {"node": {"id": 26}}, {"node": {"id": 27}}, {"node": {"id": 28}}, {"node": {"id": 29}}, {"node": {"id": 30}}]}}}
(1 row)

comment on schema public is e'@graphql({"max_rows": 5})';
-- expect 5 rows on first page
-- expect 5 rows on first page because of fallback to schema max_rows
select graphql.resolve($$
{
accountCollection
Expand All @@ -41,8 +81,42 @@ begin;
{"data": {"accountCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}]}}}
(1 row)

-- expect 5 rows on first page because of fallback to schema max_rows
select graphql.resolve($$
{
accountViewCollection {
edges {
node {
id
}
}
}
}
$$);
resolve
-----------------------------------------------------------------------------------------------------------------------------------------------------------
{"data": {"accountViewCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}]}}}
(1 row)

-- expect 5 rows on first page because of fallback to schema max_rows
select graphql.resolve($$
{
accountViewWrapperCollection {
edges {
node {
id
}
}
}
}
$$);
resolve
------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"data": {"accountViewWrapperCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}]}}}
(1 row)

comment on schema public is e'@graphql({"max_rows": 40})';
-- expect 40 rows on first page
-- expect 40 rows on first page because of fallback to schema max_rows
select graphql.resolve($$
{
accountCollection
Expand All @@ -60,9 +134,43 @@ begin;
{"data": {"accountCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}, {"node": {"id": 6}}, {"node": {"id": 7}}, {"node": {"id": 8}}, {"node": {"id": 9}}, {"node": {"id": 10}}, {"node": {"id": 11}}, {"node": {"id": 12}}, {"node": {"id": 13}}, {"node": {"id": 14}}, {"node": {"id": 15}}, {"node": {"id": 16}}, {"node": {"id": 17}}, {"node": {"id": 18}}, {"node": {"id": 19}}, {"node": {"id": 20}}, {"node": {"id": 21}}, {"node": {"id": 22}}, {"node": {"id": 23}}, {"node": {"id": 24}}, {"node": {"id": 25}}, {"node": {"id": 26}}, {"node": {"id": 27}}, {"node": {"id": 28}}, {"node": {"id": 29}}, {"node": {"id": 30}}, {"node": {"id": 31}}, {"node": {"id": 32}}, {"node": {"id": 33}}, {"node": {"id": 34}}, {"node": {"id": 35}}, {"node": {"id": 36}}, {"node": {"id": 37}}, {"node": {"id": 38}}, {"node": {"id": 39}}, {"node": {"id": 40}}]}}}
(1 row)

-- expect 40 rows on first page because of fallback to schema max_rows
select graphql.resolve($$
{
accountViewCollection {
edges {
node {
id
}
}
}
}
$$);
resolve
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"data": {"accountViewCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}, {"node": {"id": 6}}, {"node": {"id": 7}}, {"node": {"id": 8}}, {"node": {"id": 9}}, {"node": {"id": 10}}, {"node": {"id": 11}}, {"node": {"id": 12}}, {"node": {"id": 13}}, {"node": {"id": 14}}, {"node": {"id": 15}}, {"node": {"id": 16}}, {"node": {"id": 17}}, {"node": {"id": 18}}, {"node": {"id": 19}}, {"node": {"id": 20}}, {"node": {"id": 21}}, {"node": {"id": 22}}, {"node": {"id": 23}}, {"node": {"id": 24}}, {"node": {"id": 25}}, {"node": {"id": 26}}, {"node": {"id": 27}}, {"node": {"id": 28}}, {"node": {"id": 29}}, {"node": {"id": 30}}, {"node": {"id": 31}}, {"node": {"id": 32}}, {"node": {"id": 33}}, {"node": {"id": 34}}, {"node": {"id": 35}}, {"node": {"id": 36}}, {"node": {"id": 37}}, {"node": {"id": 38}}, {"node": {"id": 39}}, {"node": {"id": 40}}]}}}
(1 row)

-- expect 40 rows on first page because of fallback to schema max_rows
select graphql.resolve($$
{
accountViewWrapperCollection {
edges {
node {
id
}
}
}
}
$$);
resolve
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"data": {"accountViewWrapperCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}, {"node": {"id": 4}}, {"node": {"id": 5}}, {"node": {"id": 6}}, {"node": {"id": 7}}, {"node": {"id": 8}}, {"node": {"id": 9}}, {"node": {"id": 10}}, {"node": {"id": 11}}, {"node": {"id": 12}}, {"node": {"id": 13}}, {"node": {"id": 14}}, {"node": {"id": 15}}, {"node": {"id": 16}}, {"node": {"id": 17}}, {"node": {"id": 18}}, {"node": {"id": 19}}, {"node": {"id": 20}}, {"node": {"id": 21}}, {"node": {"id": 22}}, {"node": {"id": 23}}, {"node": {"id": 24}}, {"node": {"id": 25}}, {"node": {"id": 26}}, {"node": {"id": 27}}, {"node": {"id": 28}}, {"node": {"id": 29}}, {"node": {"id": 30}}, {"node": {"id": 31}}, {"node": {"id": 32}}, {"node": {"id": 33}}, {"node": {"id": 34}}, {"node": {"id": 35}}, {"node": {"id": 36}}, {"node": {"id": 37}}, {"node": {"id": 38}}, {"node": {"id": 39}}, {"node": {"id": 40}}]}}}
(1 row)

-- table-specific max_rows
comment on table account is e'@graphql({"max_rows": 5})';
-- expect 5 rows on first page
-- expect 5 rows on first page because of table max_rows
select graphql.resolve($$
{
accountCollection {
Expand All @@ -80,13 +188,11 @@ begin;
(1 row)

-- view-specific max_rows
create view person as
select * from account;
comment on view person is e'@graphql({"primary_key_columns": ["id"], "max_rows": 3})';
-- expect 3 rows on first page
comment on view "accountView" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 3})';
-- expect 3 rows on first page because of view max_rows
select graphql.resolve($$
{
personCollection {
accountViewCollection {
edges {
node {
id
Expand All @@ -95,19 +201,17 @@ begin;
}
}
$$);
resolve
------------------------------------------------------------------------------------------------------------
{"data": {"personCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}]}}}
resolve
-----------------------------------------------------------------------------------------------------------------
{"data": {"accountViewCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}, {"node": {"id": 3}}]}}}
(1 row)

-- nested view with max_rows
create view parent as
select * from person;
comment on view parent is e'@graphql({"primary_key_columns": ["id"], "max_rows": 2})';
-- expect 2 rows on first page
comment on view "accountViewWrapper" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 2})';
-- expect 2 rows on first page because of view max_rows
select graphql.resolve($$
{
parentCollection {
accountViewWrapperCollection {
edges {
node {
id
Expand All @@ -116,9 +220,9 @@ begin;
}
}
$$);
resolve
---------------------------------------------------------------------------------------
{"data": {"parentCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}]}}}
resolve
---------------------------------------------------------------------------------------------------
{"data": {"accountViewWrapperCollection": {"edges": [{"node": {"id": 1}}, {"node": {"id": 2}}]}}}
(1 row)

rollback;
Loading