From b199325a2ccb54ebf81742d290f23d78d0efb318 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Fri, 13 Jun 2025 11:20:20 +0530 Subject: [PATCH 1/4] rename views --- test/expected/max_rows_directive.out | 26 +++++++++++++------------- test/sql/max_rows_directive.sql | 14 +++++++------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/test/expected/max_rows_directive.out b/test/expected/max_rows_directive.out index 6627eb9c..51a076ed 100644 --- a/test/expected/max_rows_directive.out +++ b/test/expected/max_rows_directive.out @@ -80,13 +80,13 @@ begin; (1 row) -- view-specific max_rows - create view person as + create view "accountView" as select * from account; - comment on view person is e'@graphql({"primary_key_columns": ["id"], "max_rows": 3})'; + comment on view "accountView" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 3})'; -- expect 3 rows on first page select graphql.resolve($$ { - personCollection { + accountViewCollection { edges { node { id @@ -95,19 +95,19 @@ 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})'; + create view "accountViewWrapper" as + select * from "accountView"; + comment on view "accountViewWrapper" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 2})'; -- expect 2 rows on first page select graphql.resolve($$ { - parentCollection { + accountViewWrapperCollection { edges { node { id @@ -116,9 +116,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; diff --git a/test/sql/max_rows_directive.sql b/test/sql/max_rows_directive.sql index 83177146..7a581a95 100644 --- a/test/sql/max_rows_directive.sql +++ b/test/sql/max_rows_directive.sql @@ -69,14 +69,14 @@ begin; $$); -- view-specific max_rows - create view person as + create view "accountView" as select * from account; - comment on view person is e'@graphql({"primary_key_columns": ["id"], "max_rows": 3})'; + comment on view "accountView" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 3})'; -- expect 3 rows on first page select graphql.resolve($$ { - personCollection { + accountViewCollection { edges { node { id @@ -87,14 +87,14 @@ begin; $$); -- 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})'; + create view "accountViewWrapper" as + select * from "accountView"; + comment on view "accountViewWrapper" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 2})'; -- expect 2 rows on first page select graphql.resolve($$ { - parentCollection { + accountViewWrapperCollection { edges { node { id From 9c2062755c974b6a9e4bfae03e2a46a9e5b50390 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Fri, 13 Jun 2025 11:38:05 +0530 Subject: [PATCH 2/4] refactor a test --- test/expected/max_rows_directive.out | 124 ++++++++++++++++++++++++--- test/sql/max_rows_directive.sql | 102 +++++++++++++++++++--- 2 files changed, 206 insertions(+), 20 deletions(-) diff --git a/test/expected/max_rows_directive.out b/test/expected/max_rows_directive.out index 51a076ed..7205d93b 100644 --- a/test/expected/max_rows_directive.out +++ b/test/expected/max_rows_directive.out @@ -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 @@ -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 @@ -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 @@ -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 { @@ -80,10 +188,8 @@ begin; (1 row) -- view-specific max_rows - create view "accountView" as - select * from account; comment on view "accountView" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 3})'; - -- expect 3 rows on first page + -- expect 3 rows on first page because of view max_rows select graphql.resolve($$ { accountViewCollection { @@ -101,10 +207,8 @@ begin; (1 row) -- nested view with max_rows - create view "accountViewWrapper" as - select * from "accountView"; comment on view "accountViewWrapper" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 2})'; - -- expect 2 rows on first page + -- expect 2 rows on first page because of view max_rows select graphql.resolve($$ { accountViewWrapperCollection { diff --git a/test/sql/max_rows_directive.sql b/test/sql/max_rows_directive.sql index 7a581a95..5405cdcf 100644 --- a/test/sql/max_rows_directive.sql +++ b/test/sql/max_rows_directive.sql @@ -3,10 +3,18 @@ begin; 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 @@ -20,9 +28,35 @@ begin; } $$); + -- expect 30 rows on first page because of fallback to default + select graphql.resolve($$ + { + accountViewCollection { + edges { + node { + id + } + } + } + } + $$); + + -- expect 30 rows on first page because of fallback to default + select graphql.resolve($$ + { + accountViewWrapperCollection { + edges { + node { + id + } + } + } + } + $$); + 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 @@ -36,9 +70,35 @@ begin; } $$); + -- expect 5 rows on first page because of fallback to schema max_rows + select graphql.resolve($$ + { + accountViewCollection { + edges { + node { + id + } + } + } + } + $$); + + -- expect 5 rows on first page because of fallback to schema max_rows + select graphql.resolve($$ + { + accountViewWrapperCollection { + edges { + node { + id + } + } + } + } + $$); + 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 @@ -52,10 +112,36 @@ begin; } $$); + -- expect 40 rows on first page because of fallback to schema max_rows + select graphql.resolve($$ + { + accountViewCollection { + edges { + node { + id + } + } + } + } + $$); + + -- expect 40 rows on first page because of fallback to schema max_rows + select graphql.resolve($$ + { + accountViewWrapperCollection { + edges { + node { + id + } + } + } + } + $$); + -- 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 { @@ -69,11 +155,9 @@ begin; $$); -- view-specific max_rows - create view "accountView" as - select * from account; comment on view "accountView" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 3})'; - -- expect 3 rows on first page + -- expect 3 rows on first page because of view max_rows select graphql.resolve($$ { accountViewCollection { @@ -87,11 +171,9 @@ begin; $$); -- nested view with max_rows - create view "accountViewWrapper" as - select * from "accountView"; comment on view "accountViewWrapper" is e'@graphql({"primary_key_columns": ["id"], "max_rows": 2})'; - -- expect 2 rows on first page + -- expect 2 rows on first page because of view max_rows select graphql.resolve($$ { accountViewWrapperCollection { From 96e1bbdec33ae3c03015e61d7db819c7bbd2abd3 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Fri, 13 Jun 2025 11:48:35 +0530 Subject: [PATCH 3/4] add docs --- docs/configuration.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 395df1f0..7177a394 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -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. From 53b9ac9b357490f3e561975c146300b4645f3022 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Fri, 13 Jun 2025 11:50:13 +0530 Subject: [PATCH 4/4] update changelog --- docs/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.md b/docs/changelog.md index f55f68c7..4edee810 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -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